Reputation: 3272
I have seen others with similar questions with no real answer.
When i run a sub that imports data onto 3 worksheets and then compiles a 4th sheet from those 3 worksheets it runs in just over 17secs.
The main part of the 17 secs is writing 10,000 rows (26 columns each) of data to the output sheet in 13.86sec doing just over 720 rows a second.
The problem arises when i run this sub again without closing excel , it takes forever! the import stage is no slower but writing to the output sheets slows down to a consistently poor 17 rows a second. (35X decrease in speed)
i have tested every thing i know about VBA and i cannot find out why this is.
the start of the Sub always erases each sheet using
If sh.AutoFilterMode Then sh.AutoFilterMode = False
sh.Columns.Hidden = False
sh.Rows.Hidden = False
sh.Cells.Clear
sh.Cells.Delete
i have always used this to clear sheets and never had an issue, until i found a fix for my problem , by actually deleting the 4 sheets and recreating them ,this fixes the terrible slowdown in speed.
What is left behind on my sheets that the above code is not removing and causing this slowdown issue?
I have also left the sheets full of data and saved and closed the workbook, and i still get perfect performance on the first run after opening excel so its not the actual data on the sheets.
NB - The rest of the code is just standard loops and writing to cells and i am 100% sure that its not the problem with this issue
Upvotes: 3
Views: 1035
Reputation: 21
It dates back a long time, but anyway: Today I have faced the same issue with my VBA-tool (Excel 2010, invoking via UF, Import of > 40000 lines of data and performing of some calculations): -> Runtime at 1st run: 40sec and 11MIN at 2nd run (after the UF was closed and opened again). I was able to solve the issue by erasing explicitly the arrays I have used in the code via the "Erase" command and setting the WorkBook-object to "Nothing" explicitly before the UF is closed.
Example:
*Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) If CloseMode = vbFormControlMenu Then Logger_End
Erase allAsmFileREVsArray()
Erase allAsmFileURLsArray()
Set xlWorkBook = Nothing
End If
End Sub*
Maybe it helps...
Upvotes: 1
Reputation: 2689
based on you description, i think the possible solutions as below.
application.screenupdating = false
at the first of your sub, and application.screenupdating = true
before exit sub.application.calculation = xlCalculationManual
at first of your sub, and application.calculation = xlCalculationAutomatic
before exit sub.Using array variable. If you want to input a 100000 x 26 to range("A1:Z100000"), the normal and slow way as below
for i = 1 to 100000
for j = 1 to 26
cells(i,j).value = 123
next j
next i
the fast way is
dim ary(100000 - 1, 26 -1) as variant
'make an array
for i = lbound(ary, 1) to ubound(ary, 1)
for j = lbound(ary, 2) to ubound(ary, 2)
ary(i, j) = 123
next j
next i
range("a1").resize(ubound(ary, 1) - lbound(ary, 1) + 1, ubound(ary, 2) - lbound(ary, 2) +1).value = ary
Upvotes: 0