Multiple Array vba code - looking for tips

Ragnar1211

Well-known Member
Joined
Jul 10, 2008
Messages
572
Hello everyone,

I am looking for some feedback on the code I have written. It is my first attempt at using arrays in code for the purpose of accumulating data, and subesequently using the same data to create a report.

My code below looks at a table that is 10 columns wide and reads all of the data into 10 different arrays - this is where feedback may be useful, should I have used a multi dimensional array (if so show me how please).

After it reads the data into the arrays it looks at the first array and finds the unique items in that array, which are then used to create a nice report outlined by the groupings.

Once again any feedback on ways to improve the code would be great - learning lots.

Thanks

Code:
Option Explicit
Sub investment1()
'Macro to create investment portfolio report - By Gerry on March 9, 2009
    Dim lr As Long, i As Long, j As Long, k As Long, l As Long
    Dim CUname As String, RPdate As String
    Dim grp1() As Variant, grp2() As Variant, grp3() As Variant, grp4() As Variant
    Dim grp5() As Variant, grp6() As Variant, grp7() As Variant, grp8() As Variant
    Dim grp9() As Variant, grp10() As Variant
    Dim hdg() As Variant, hdg1 As Long
    Application.ScreenUpdating = False
'Get the relevant data - 10 columns of data, 1 array for each column
    With Worksheets("Inputs")
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row
        ReDim grp1(1 To lr), grp2(1 To lr), grp3(1 To lr), grp4(1 To lr), grp5(1 To lr)
        ReDim grp6(1 To lr), grp7(1 To lr), grp8(1 To lr), grp9(1 To lr), grp10(1 To lr)

        For i = 8 To lr
        
            grp1(i) = .Cells(i, 1).Value
            grp2(i) = .Cells(i, 2).Value
            grp3(i) = .Cells(i, 3).Value
            grp4(i) = .Cells(i, 4).Value
            grp5(i) = .Cells(i, 5).Value
            grp6(i) = .Cells(i, 6).Value
            grp7(i) = .Cells(i, 7).Value
            grp8(i) = .Cells(i, 8).Value
            grp9(i) = .Cells(i, 9).Value
            grp10(i) = .Cells(i, 10).Value
        Next
    'Get the CU name and report date
        CUname = .Range("A1").Value
        RPdate = Format(.Range("C5").Value, "MMMM DD, YYYY")
    End With

'Get the category headings and count using custom function called UniqueItems
        hdg = UniqueItems(grp1, False)
        hdg1 = UniqueItems(grp1)

Sheets.Add
ActiveSheet.Name = "newSht"


'Set Starting row for report
    k = 7
'Put the data into report format
    For i = 1 To hdg1 'counter for each group heading
        Cells(k, 1).Value = hdg(i)
        Cells(k, 4).Value = "Start"
        Cells(k, 5).Value = "Maturity"
        Cells(k, 6).Value = "Face Value"
        Cells(k, 7).Value = "Amortization"
        Cells(k, 8).Value = "Book Value"
        Cells(k, 9).Value = "Yield"
        Cells(k, 10).Value = "Bond Rating"
        l = k 'Counter for top row of group
            For j = 1 To UBound(grp1) 'search array for data that matches heading
                If grp1(j) = hdg(i) Then
                        k = k + 1
                        Cells(k, 2).Value = grp2(j)
                        Cells(k, 3).Value = grp3(j)
                        Cells(k, 4).Value = grp4(j)
                        Cells(k, 5).Value = grp5(j)
                        Cells(k, 6).Value = grp6(j)
                        Cells(k, 7).Value = grp7(j)
                        Cells(k, 8).Value = grp8(j)
                        Cells(k, 9).Value = grp9(j)
                        Cells(k, 10).Value = grp10(j)
                End If
            Next j
        'Insert Totals
            k = k + 2
            l = k - l - 1
                Cells(k, 1).Value = hdg(i) & " Total"
                Cells(k, 6).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 7).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 8).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 9).FormulaR1C1 = "=sumproduct(--(R[-" & l & "]C[-3]:R[-1]C[-3]),--(R[-" & l & "]C:R[-1]C))/RC[-3]"
                
        'Format display
                With Union(Range(Cells(k, 1), Cells(k, 10)), Range(Cells(k - l - 1, 1), Cells(k - l - 1, 10)))
                    .Font.Bold = True
                    With .Borders(xlEdgeTop)
                        .LineStyle = xlContinuous
                        .Weight = xlThin
                        .ColorIndex = xlAutomatic
                    End With
                    With .Borders(xlEdgeBottom)
                        .LineStyle = xlContinuous
                        .Weight = xlThin
                        .ColorIndex = xlAutomatic
                    End With
                End With
          'Put two blank rows in between
            k = k + 3
        Next i

'Finish Formatting - make it look pretty
    Range("F:H").NumberFormat = "_(* #,##0_);_(* (#,##0);_(* ""-""??_);_(@_)"
    Range("I:I").NumberFormat = "0.00%"
    Columns.AutoFit
    Columns("A:A").ColumnWidth = 4
    Range("A1").Value = CUname
    Range("A2").Value = "Board Report on Investment Management"
    Range("A3").Value = "Part 4 - Investment Quality"
    Range("A4").Value = RPdate
        With Range("A1:J4")
            .HorizontalAlignment = xlCenterAcrossSelection
            .Font.Bold = True
        End With


ActiveWindow.DisplayGridlines = False
Application.ScreenUpdating = True
End Sub
 

Excel Facts

Pivot Table Drill Down
Double-click any number in a pivot table to create a new report showing all detail rows that make up that number
Instead of using multiple arrays Grp1, Grp2, ..., why not use a multi-dimension single array.
 
Upvote 0
Ok, so now I have done my first multi demensional array - any feedback/tips would be great. Here is the revised code:

Code:
Option Explicit
Sub investment2()
'Macro to create investment portfolio report - By Gerry on March 9, 2009
    Dim lr As Long, lc As Long, i As Long, j As Long, jj As Long, k As Long, l As Long
    Dim CUname As String, RPdate As String
    Dim grp1() As Variant
    Dim hdg() As Variant, hdg1 As Long
    Application.ScreenUpdating = False
'Get the relevant data - 10 columns of data, 1 array for each column
    With Worksheets("Inputs")
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row
        lc = .Cells(7, .Columns.Count).End(xlToLeft).Column
        ReDim grp1(1 To lr, 1 To lc)

        For i = 8 To lr
            For j = 1 To lc
                grp1(i, j) = .Cells(i, j).Value
            Next j
        Next i
    'Get the CU name and report date
        CUname = .Range("A1").Value
        RPdate = Format(.Range("C5").Value, "MMMM DD, YYYY")
    End With

'Get the category headings and count using custom function called UniqueItems
        ReDim hdg(1 To UBound(grp1))
        For i = 1 To UBound(grp1())
            hdg(i) = grp1(i, 1)
        
        Next i
        hdg = UniqueItems(hdg, False)
        hdg1 = UniqueItems(hdg)

Sheets.Add
'ActiveSheet.Name = "newSht"


'Set Starting row for report
    k = 7
'Put the data into report format
    For i = 1 To hdg1 'counter for each group heading
        Cells(k, 1).Value = hdg(i)
        Cells(k, 4).Value = "Start"
        Cells(k, 5).Value = "Maturity"
        Cells(k, 6).Value = "Face Value"
        Cells(k, 7).Value = "Amortization"
        Cells(k, 8).Value = "Book Value"
        Cells(k, 9).Value = "Yield"
        Cells(k, 10).Value = "Bond Rating"
        l = k 'Counter for top row of group
            For j = 1 To UBound(grp1) 'search array for data that matches heading
                If grp1(j, 1) = hdg(i) Then
                    k = k + 1
                        For jj = 2 To 10
                          Cells(k, jj).Value = grp1(j, jj)
                        Next jj
                End If
            Next j
        'Insert Totals
            k = k + 2
            l = k - l - 1
                Cells(k, 1).Value = hdg(i) & " Total"
                Cells(k, 6).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 7).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 8).FormulaR1C1 = "=SUBTOTAL(9,R[-" & l & "]C:R[-1]C)"
                Cells(k, 9).FormulaR1C1 = "=sumproduct(--(R[-" & l & "]C[-3]:R[-1]C[-3]),--(R[-" & l & "]C:R[-1]C))/RC[-3]"
                
        'Format display
                With Union(Range(Cells(k, 1), Cells(k, 10)), Range(Cells(k - l - 1, 1), Cells(k - l - 1, 10)))
                    .Font.Bold = True
                    With .Borders(xlEdgeTop)
                        .LineStyle = xlContinuous
                        .Weight = xlThin
                        .ColorIndex = xlAutomatic
                    End With
                    With .Borders(xlEdgeBottom)
                        .LineStyle = xlContinuous
                        .Weight = xlThin
                        .ColorIndex = xlAutomatic
                    End With
                End With
          'Put two blank rows in between
            k = k + 3
        Next i

'Finish Formatting - make it look pretty
    Range("F:H").NumberFormat = "_(* #,##0_);_(* (#,##0);_(* ""-""??_);_(@_)"
    Range("I:I").NumberFormat = "0.00%"
    Columns("J:J").HorizontalAlignment = xlCenter
    Columns.AutoFit
    Columns("A:A").ColumnWidth = 4
    Range("A1").Value = CUname
    Range("A2").Value = "Board Report on Investment Management"
    Range("A3").Value = "Part 4 - Investment Quality"
    Range("A4").Value = RPdate
        With Range("A1:J4")
            .HorizontalAlignment = xlCenterAcrossSelection
            .Font.Bold = True
        End With


ActiveWindow.DisplayGridlines = False
Application.ScreenUpdating = True
End Sub
 
Upvote 0
Shouldn't this

Code:
        For i = 8 To lr
            For j = 1 To lc
                grp1(i, j) = .Cells(i, j).Value
            Next j
        Next i

read

Code:
        For i = 8 To lr
            For j = 1 To lc
                grp1(i - 7, j) = .Cells(i, j).Value
            Next j
        Next i
 
Last edited:
Upvote 0
You can also do it directly

Code:
    Dim grp1 As Variant
    Dim hdg() As Variant, hdg1 As Long
    
    Application.ScreenUpdating = False

'Get the relevant data - 10 columns of data, 1 array for each column
    With Worksheets("Inputs")
        lr = .Cells(.Rows.Count, 1).End(xlUp).Row
        lc = .Cells(7, .Columns.Count).End(xlToLeft).Column
        grp1 = .Range("A8").Resize(lr - 7, lc)
 
Upvote 0
You can also reduce this

Code:
        Cells(k, 1).Value = hdg(i)
        Cells(k, 4).Value = "Start"
        Cells(k, 5).Value = "Maturity"
        Cells(k, 6).Value = "Face Value"
        Cells(k, 7).Value = "Amortization"
        Cells(k, 8).Value = "Book Value"
        Cells(k, 9).Value = "Yield"
        Cells(k, 10).Value = "Bond Rating"

to

Code:
        Cells(k, 1).Resize(, 10).Value = Array( _
            "Start", "Maturity", "Face Value", "Amortization", _
            "Book Value", "Yield", "Bond Rating")
 
Upvote 0
Good eye. I guess the reason the code still works is because the array is dimmed to the rows count, so using grp(i,j) still works, thus leaving grp(1-7,j)
blank.

I should tidy this bit up, as well as the upper bound of the array. Thanks for catching that.
 
Upvote 0

Forum statistics

Threads
1,214,642
Messages
6,120,700
Members
448,979
Latest member
DET4492

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top