I have an identical piece of code which was running nearly instantly in an previous iteration which now takes about 5 minutes to run. I edited other parts of the code, but whenever I break the code within that 5 minute period of time, it is working through this sub.
Sub cleanup() For i = 2 To 100000 'exits loop when it reaches a blank cell If IsEmpty(Cells(i, 1)) = True Then Exit For ' formats for blanks If Cells(i, 1) = Cells(i - 1, 1) Then For j = 4 To 15 If IsEmpty(Cells(i - 1, j)) = True Then Cells(i - 1, j) = Cells(i, j) End If Next j Rows(i).Delete i = i - 1 End If Next i End Sub
I’ve tried disabling events and screen updating etc, but can’t figure it out. Keep in mind this used to run literally instantly and I only changed other functions in my code since those changes. Not sure what to do.
The other part which is very weird is when I run the macro again (after all the rows are deleted) it still takes a very long time. In the above macro, the second time through it should never even enter the first conditional but it still takes a long time.
Sub cleanup() For i = Range("A" & Rows.Count).End(xlUp).Row + To 2 step -1 If Cells(i, 1) = Cells(i - 1, 1) Then For j = 4 To 15 If IsEmpty(Cells(i - 1, j)) Then Cells(i - 1, j) = Cells(i, j) Next j If CellArray Is Nothing Then Set CellArray = Rows(i) Else Set CellArray = Union(CellArray, Rows(i)) End If End If Next i CellArray.Delete End Sub
I may be oversimplifying your task, but if you use the built-in
counta function within Excel, I think it would be very efficient at determining if a row had values in it or not:
If Excel.WorksheetFunction.CountA(rw.EntireRow) = 0 Then rw.Delete End If
Of course, this looks at the entire row and you probably want to bound that to columns 4 – 15 (or whatever you showed above).
Also, I think @Marcucciboy2 made a good point, and I would start from the bottom up.
If you really wanted to make this hum, you could probably define these in a range context (ie 1:4,5:7 etc) and delete the entire collection of rows at one time.
In the excel, if you can avoid the for loops, its very slow. For example: my work i use 7000x746x3 rows, and its running about 15 minutes(i5 7300u,but not mucher faster on desktop 7770. Maybe little optimazition here: https://www.ozgrid.com/VBA/SpeedingUpVBACode.htm or use foreach. And if you use for you can count the row/column. Example row count:
LastRow = Worksheets("Sheet").Cells(Worksheets("Sheet").Rows.Count, "A").End(xlUp).Row