VBA populating cells with an array (code works but very slow sometimes)

Viewed 46

I have a macro that generates a table of contents in excel. Basically I have a code that creates an array and im using that array to fill cell content. The code works but its very slow. Im wondering if anyone has a way to speed it up a bit.

I have multiple worksheets named 1,2,3.. etc. the sheets have the same layout and looks like this:

Paragraph | some text | appendix no.

example:

1.0 | Preface | Appendix A1

So i have a code that looks for non empty cells and if the paragraph cell is not empty it adds it to an array (using multiple arrays). Here is my code below, any help will be greatly appreciated!

Option Explicit


Sub inhoudsopgave()
Application.ScreenUpdating = False

Dim SheetNameArray() As Variant
Dim shts As Variant

SheetNameArray = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50")

Dim Paragraaf As Variant
Dim Array2 As Variant
Dim Array3 As Variant
Dim Array4 As Variant

Dim i As Integer
Dim NoBlankSize As Long
Dim sh As Integer
Dim n As Integer
Dim rng As Range

Set rng = Sheets("INHHULP").Range("A2:J100")
rng.ClearContents

NoBlankSize = 0
n = 0


ReDim Paragraaf(0 To 0)
ReDim Array2(0 To 0)
ReDim Array3(0 To 0)
ReDim Array4(0 To 0)

For Each shts In SheetNameArray()
Sheets(shts).Activate
On Error Resume Next

For i = 5 To 70
    If Cells(i, 1) <> "" Then
        NoBlankSize = NoBlankSize + 1
        ReDim Preserve Paragraaf(1 To NoBlankSize)
        Paragraaf(NoBlankSize) = Cells(i, 1)
        ReDim Preserve Array2(1 To NoBlankSize)
        Array2(NoBlankSize) = Cells(i, 4)
        ReDim Preserve Array3(1 To NoBlankSize)
        Array3(NoBlankSize) = Cells(i, 39)
        ReDim Preserve Array4(1 To NoBlankSize)
        Array4(NoBlankSize) = Cells(3, 35)
        Debug.Print Paragraaf(NoBlankSize)
        Debug.Print Array2(NoBlankSize)
        Debug.Print Array3(NoBlankSize)
        Debug.Print Array3(NoBlankSize)

    ElseIf Cells(i, 1) = "" Then

    End If
Next i

Next shts

For n = 1 To NoBlankSize

With Sheets("INHHULP")

.Cells(n + 1, 1) = Paragraaf(n)
.Cells(n + 1, 2) = Array2(n)
.Cells(n + 1, 3) = Array3(n)
.Cells(n + 1, 4) = Array4(n)
.Cells(n + 1, 6) = n
End With


Next n

Sheets("A").Activate
Application.ScreenUpdating = True
MsgBox ("Inhoudsopgave is gegenereerd")


End Sub
1 Answers

Append Criteria Columns

Option Explicit

Sub inhoudsopgave()

    ' Define constants.

    ' Source
    Const sRows As String = "5:70"
    Const sColsList As String = "A,D,AM"
    Const sAddress As String = "AI3"
    Dim swsNamesList As String: swsNamesList _
        = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20," _
        & "21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40," _
        & "41,42,43,44,45,46,47,48,49,50"
    ' Destination
    Const dName As String = "INHHULP"
    Const dFirstCellAddress As String = "A2"
    Const dIdColumn As String = "F"
    
    ' Reference the workbook ('wb').
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' Split the values from the strings to string arrays.
    Dim swsNames() As String: swsNames = Split(swsNamesList, ",")
    Dim sCols() As String: sCols = Split(sColsList, ",")
    
    ' Determine the size of the arrays ('cArr') in the jagged array.
    Dim cUpper As Long: cUpper = UBound(sCols)
    Dim cArr() As Variant: ReDim cArr(0 To cUpper + 2)
    
    ' Reference the destination worksheet ('dws').
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    ' Use the destination worksheet to calculate the number of rows
    ' identified by the 'sRows' constant, the address of the rows
    ' in the source worksheets.
    Dim srCount As Long: srCount = dws.Rows(sRows).Rows.Count
    
    ' Write the values from the source ranges to arrays located in the first
    ' columns of the arrays of a jagged array ('Jag'). Write the titles
    ' to the column before the last column of the jagged array.
    ' Shift the matching values to the beginning of the arrays
    ' and write the number of matches to the last column.
    
    Dim nUpper As Long: nUpper = UBound(swsNames)
    Dim Jag() As Variant: ReDim Jag(1 To nUpper + 1)
    
    Dim sws As Worksheet
    Dim scrg As Range
    Dim sr As Long
    Dim n As Long
    Dim j As Long
    Dim c As Long
    Dim dr As Long
    Dim drCount As Long
    
    For n = 0 To nUpper ' all worksheets
        On Error Resume Next
            Set sws = wb.Worksheets(swsNames(n))
        On Error GoTo 0
        If Not sws Is Nothing Then ' the worksheet exists
            j = j + 1 ' found worksheets
            Jag(j) = cArr
            For c = 0 To cUpper
                Jag(j)(c) = sws.Rows(sRows).Columns(sCols(c)).Value
            Next c
            Jag(j)(c) = sws.Range(sAddress).Value
            For sr = 1 To srCount
                If Len(Jag(j)(0)(sr, 1)) > 0 Then
                    dr = dr + 1
                    For c = 0 To cUpper
                        Jag(j)(c)(dr, 1) = Jag(j)(c)(sr, 1)
                    Next c
                    Jag(j)(c + 1) = dr
                 End If
            Next sr
            drCount = drCount + dr
            dr = 0
            Set sws = Nothing
        'Else ' the worksheet doesn't exist; do nothing
        End If
    Next n
    
    ' Write the values from the jagged array to the destination array ('dData').
    
    Dim dcCount As Long: dcCount = cUpper + 2
    
    Dim dData() As Variant: ReDim dData(1 To drCount, 1 To dcCount)
    Dim Item As Variant
    Dim r As Long
    
    For j = 1 To j
        For dr = 1 To Jag(j)(cUpper + 2)
            r = r + 1
            For c = 0 To cUpper
                dData(r, c + 1) = Jag(j)(c)(dr, 1)
            Next c
            dData(r, c + 1) = Jag(j)(c)
        Next dr
    Next j
    
    ' Reference the destination range ('drg').
    Dim drg As Range
    Set drg = dws.Range(dFirstCellAddress).Resize(drCount, dcCount)
    
    ' Write the values from the destination array to the destination range.
    drg.Value = dData
    
    ' Clear below.
    drg.Resize(dws.Rows.Count - drg.Row - drCount + 1).Offset(drCount).Clear
    
    ' Generate and write the id column.
    Dim dirg As Range: Set dirg = drg.EntireRow.Columns(dIdColumn)
    dirg.Value = dws.Evaluate("ROW(1:" & drCount & ")")
    
    ' Inform.
    MsgBox "Inhoudsopgave is gegenereerd", vbInformation

End Sub
Related