For-Next loop really slow, can I use an array instead?

TheWennerWoman

Active Member
Joined
Aug 1, 2019
Messages
301
Office Version
  1. 365
Platform
  1. Windows
Hello, this is a small subset of the code I am using which is taking forever to loop through 74,000 records (the full code has a lot more bits to it).
Code:
Sub create_journal()
Dim LastRow As Long
Dim a As Long
Dim b As Long

LastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
b = 2
For a = 2 To LastRow
Sheet2.Range("A" & b).Value = "C5678"
Sheet2.Range("B" & b).Value = "103000"
Sheet2.Range("C" & b).Value = Range("C" & a).Value
Sheet2.Range("D" & b).Value = Range("B" & a).Value
b = b + 1
If Range("D" & a).Value <> 0 Then
    Sheet2.Range("A" & b).Value = Range("A" & a).Value
    Sheet2.Range("B" & b).Value = "145444"
    Sheet2.Range("C" & b).Value = Range("D" & a).Value
    Sheet2.Range("D" & b).Value = Range("B" & a).Value
    b = b + 1
End If
If Range("E" & a).Value <> 0 Then
    Sheet2.Range("A" & b).Value = Range("A" & a).Value
    Sheet2.Range("B" & b).Value = "173000"
    Sheet2.Range("C" & b).Value = Range("E" & a).Value
    Sheet2.Range("D" & b).Value = Range("B" & a).Value
    b = b + 1
End If
If Range("F" & a).Value <> 0 Then
    Sheet2.Range("A" & b).Value = Range("A" & a).Value
    Sheet2.Range("B" & b).Value = "199000"
    Sheet2.Range("C" & b).Value = Range("F" & a).Value
    Sheet2.Range("D" & b).Value = Range("B" & a).Value
    b = b + 1
End If
If Range("G" & a).Value <> 0 Then
    Sheet2.Range("A" & b).Value = Range("A" & a).Value
    Sheet2.Range("B" & b).Value = "212000"
    Sheet2.Range("C" & b).Value = Range("G" & a).Value
    Sheet2.Range("D" & b).Value = Range("B" & a).Value
    b = b + 1
End If
If Range("H" & a).Value <> 0 Then
    Sheet2.Range("A" & b).Value = Range("A" & a).Value
    Sheet2.Range("B" & b).Value = "255666"
    Sheet2.Range("C" & b).Value = Range("H" & a).Value
    Sheet2.Range("D" & b).Value = Range("B" & a).Value
    b = b + 1
End If
Next

End Sub

How would I go about maybe reading this into an array and tghen just writing back once?

Thank you for reading.
 

Excel Facts

Lock one reference in a formula
Need 1 part of a formula to always point to the same range? use $ signs: $V$2:$Z$99 will always point to V2:Z99, even after copying
It would be helpful to see (with XL2BB) say 5-10 rows of dummy sample data for the 'active sheet' from columns A:H
 
Upvote 0
See if this works for you (on a copy of your workbook)

VBA Code:
Sub create_journal_arr()
Dim LastRow As Long
Dim a As Long
Dim b As Long
Dim arrA As Variant, arrB As Variant
Dim wsA As Worksheet
Dim rngA As Range, rngB As Range

Set wsA = ActiveSheet
With wsA
    LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    Set rngA = .Range(.Cells(2, "A"), .Cells(LastRow, "H"))
    arrA = rngA.Value2
End With

Set rngB = Sheet2.Range("A2")
ReDim arrB(1 To UBound(arrA) * 7, 1 To 4)

b = 1
For a = 1 To UBound(arrA)
arrB(b, 1) = "C5678"
arrB(b, 2) = "103000"
arrB(b, 3) = arrA(a, 3)
arrB(b, 4) = arrA(a, 2)
b = b + 1

If arrA(a, 4) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "145444"
    arrB(b, 3) = arrA(a, 4)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 5) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "173000"
    arrB(b, 3) = arrA(a, 5)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 6) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "199000"
    arrB(b, 3) = arrA(a, 6)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 7) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "212000"
    arrB(b, 3) = arrA(a, 7)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 8) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "255666"
    arrB(b, 3) = arrA(a, 8)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
Next

' Write out Array
rngB.Resize(b, UBound(arrB, 2)).Value = arrB

End Sub
 
Upvote 1
Solution
It would be helpful to see (with XL2BB) say 5-10 rows of dummy sample data for the 'active sheet' from columns A:H
Book2
ABCDEFGH
1SiteEmployeeTotalType 1Type 2Type 3Type 4Type 5
2X00001ZV00011002820192013
3X00002ZV0002901719271611
4X00003ZV000380151032149
5X00004ZV000470132710128
6X00005ZV000560112110108
7X00006ZV000650991787
8X00007ZV000740722065
9X00008ZV00083057954
10X00009ZV00092035903
11X00010ZV00101016021
Sheet1
 
Upvote 0
See if this works for you (on a copy of your workbook)

VBA Code:
Sub create_journal_arr()
Dim LastRow As Long
Dim a As Long
Dim b As Long
Dim arrA As Variant, arrB As Variant
Dim wsA As Worksheet
Dim rngA As Range, rngB As Range

Set wsA = ActiveSheet
With wsA
    LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    Set rngA = .Range(.Cells(2, "A"), .Cells(LastRow, "H"))
    arrA = rngA.Value2
End With

Set rngB = Sheet2.Range("A2")
ReDim arrB(1 To UBound(arrA) * 7, 1 To 4)

b = 1
For a = 1 To UBound(arrA)
arrB(b, 1) = "C5678"
arrB(b, 2) = "103000"
arrB(b, 3) = arrA(a, 3)
arrB(b, 4) = arrA(a, 2)
b = b + 1

If arrA(a, 4) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "145444"
    arrB(b, 3) = arrA(a, 4)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 5) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "173000"
    arrB(b, 3) = arrA(a, 5)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 6) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "199000"
    arrB(b, 3) = arrA(a, 6)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 7) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "212000"
    arrB(b, 3) = arrA(a, 7)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
If arrA(a, 8) <> 0 Then
    arrB(b, 1) = arrA(a, 1)
    arrB(b, 2) = "255666"
    arrB(b, 3) = arrA(a, 8)
    arrB(b, 4) = arrA(a, 2)
    b = b + 1
End If
Next

' Write out Array
rngB.Resize(b, UBound(arrB, 2)).Value = arrB

End Sub
That works perfectly, and on a sample dataset of 35000 records was almost instant.

Many, many thanks.

The efficiency of arrays is much underestimated :)
 
Upvote 0

Forum statistics

Threads
1,223,886
Messages
6,175,191
Members
452,616
Latest member
intern444

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