Home > database >  Excel Populate column with Multi-Dimensional Array
Excel Populate column with Multi-Dimensional Array

Time:12-13

I have a table with five columns: Project #, Phase #, $$$$, Completion % M1, Completion % M2

I am trying to write a code that takes the transfers Completion % M2 to Completion % M1 when the Data gets updated. The data gets updated every month and sometimes project numbers drop off or phases are added to projects.

What I am struggling to figure out is if I can use a multi-dimensional array to store the data, then sort it to match the new data and update the corresponding cells.

Option Explicit

'Public variable to define date at woorkbook initialization (start-up)
Public inDate As Date

'Public variable to define table length at woorkbook initialization (start-up)
Public intTotalRows As Long

'Public variables to define PM % complete arrays
Public strArray0() As Variant

Sub LoadArray2()

    Dim i As Long
    Dim n As Long
    
    'Set Array element length
    ReDim strArray0(intTotalRows, 3)

    'Collect PM enetered % complete information
    For i = 1 To intTotalRows
        strArray0(i, 1) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 1).Value
        strArray0(i, 2) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 2).Value
        strArray0(i, 3) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 5).Value
    Next
    
End Sub


Private Sub Workbook_Open()

    ' Get previous data pull date prior to pull updating (Get Data)
    inDate = Worksheets("Data Pull Date").Range("F2")
    Debug.Print ("inDate " & inDate)
    
    Dim tbl1 As ListObject
    ' Count # of Rows in Raw Data Table prior to pull updating (Get Data)
    Set tbl1 = Worksheets("Raw Data (Transformed)").ListObjects("Stream_Data_Centers_3_Month_Review")
    intTotalRows = tbl1.Range.Rows.Count - 1
    Debug.Print ("intTotalRows " & intTotalRows)
    
End Sub


Private Sub Worksheet_TableUpdate(ByVal Target As TableObject)

    Dim curDate As Date
    Dim curTotalRows As Long

    'Get current data pull date after pull updating (Get Data)
    curDate = Worksheets("Data Pull Date").Range("F2")
    Debug.Print ("curDate " & curDate)
    
    'Update PM entered % Complete if curDate is month after inDate
    If Month(curDate) = Month(inDate) Then
        'nothing
    Else
        LoadArray2
        'Shift PM % Complete value over to left, Clear Last Row
        For i = 1 To intTotalRows
            Worksheets("Stream 3 Month Financial Review").Cells(i   1, 4).Value = strArray1(i)
        Next
    End If
    
End Sub


I need a code to take strArray0(i, 3) and populate column 4 with the data if strArray0(i, 1) and strArray0(i, 2) match the value is columns 1 and 2.

I decided to add a column in the transformed data to create a UID for each line. So now I just need to match strArray0(i, 1) to a value in column 1.

CodePudding user response:

I used a few work arounds to make it happen but here is the code:

Private Sub Workbook_Open()

    MsgBox ("Please wait while the data refreshes. This may take a minute.")

    ' Get previous data pull date prior to query updating (Get Data)
    inDate = Worksheets("Data Pull Date").Range("F2")
    Debug.Print ("inDate " & inDate)
    
    LoadArray2
    
    'Refresh Query Tables after LoadArray2 has ran.
    ActiveWorkbook.RefreshAll
    
End Sub

The above code runs while the workbook opens and defines some variables and collects user inputs prior to refreshing the data in the query tables. Then after the data has refreshed it triggers this code to run:

Private Sub Worksheet_TableUpdate(ByVal Target As TableObject)

    'Variable to define date after Query table update
    Dim curDate As Date
    
    curDate = Worksheets("Data Pull Date").Range("F2")
    Debug.Print ("curDate: " & curDate)

    If Month(curDate) <> Month(inDate) Then
        LookupArray
        MsgBox ("PM % Complete Estimates have been updated using last month's projections.")
    Else
        MsgBox ("Your data is ready.")
    End If
    
    inDate = curDate
    
    
End Sub

The key to making the Worksheet_TableUpdate(ByVal Target As TableObject) method work is to have the query table added to the Data Model. You can do this in the Query Ribbon that pops up when you select the query table. In 'Load To' options, select the box for 'Add this Data to the Data Model'.

enter image description here

Here is Module1 with the called subs and Public variables:

Option Explicit

'Public variable to define date at woorkbook initialization (start-up)
Public inDate As Date

'Public variable to define table length at woorkbook initialization (start-up)
Public intTotalRows As Long

'Public variable to define PM % complete arrays
Public strArray0() As Variant

Sub LoadArray2()

    Dim i As Long
    Dim disVal As Variant
    Dim tbl1 As ListObject
    
    ' Count # of Rows in Raw Data Table prior to pull updating (Get Data)
    Set tbl1 = Worksheets("Stream 3 Month Financial Review").ListObjects("Table3")
    intTotalRows = tbl1.Range.Rows.Count - 1
    
    'Set Array element length
    ReDim strArray0(1 To intTotalRows, 1 To 4)
    
    'Collect PM enetered % complete information
    For i = 1 To intTotalRows
        strArray0(i, 1) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 9).Value
        strArray0(i, 2) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 11).Value
        strArray0(i, 3) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 12).Value
        strArray0(i, 4) = Worksheets("Stream 3 Month Financial Review").Cells(i   1, 13).Value
    Next
    
    'Debug check for strArray0 values
    disVal = strArray0(4, 1) & " 1: " & strArray0(4, 2) & " 2: " & strArray0(4, 3) & " 3: " & strArray0(4, 4)
    Debug.Print ("strArray0 " & disVal)
    Debug.Print ("intTotalRows " & intTotalRows)
    
End Sub

Sub LookupArray()

    Dim disVal0 As Variant
    Dim disVal1 As Variant
    Dim ArrayCheck As Variant
    Dim UIDstr As Range
    Dim ColUp As Range
    
    'Check inputs from Public variables.
    ArrayCheck = strArray0(4, 1) & " 1: " & strArray0(4, 2) & " 2: " & strArray0(4, 3) & " 3: " & strArray0(4, 4)
    Debug.Print ("ArrayCheck " & ArrayCheck)
    
    'UID column range
    Set ColUp = Worksheets("Stream 3 Month Financial Review").Range("I2:I979")
    
    On Error Resume Next
    For Each UIDstr In ColUp
        If IsError(UIDstr) Then
        'Nothing
        Else
            disVal0 = Application.WorksheetFunction.VLookup(UIDstr.Value, strArray0, 3, 0)
            disVal1 = Application.WorksheetFunction.VLookup(UIDstr.Value, strArray0, 4, 0)
            UIDstr.Offset(0, 2).Value = disVal0
            UIDstr.Offset(0, 3).Value = disVal1
            UIDstr.Offset(0, 4).Value = ""
        
            'Debug.Print ("Lookup UIDstr: " & UIDstr.Value & " disVal0: " & disVal0 & " disVal1: " & disVal1)
        End If
    Next
    
End Sub
  • Related