I've read that .Select statements force Excel to display each of those events on the screen and slow Macros considerably.
I'd like to speed up some old Macros that were written with record Macro methods and have many .Select statements.
Would Application.ScreenUpdating = False eliminate the time wasted displaying the .Select events?
Thanks in advance for any advice.
Of curse it would speed up your old Macros,but i would be better to change to code and avoid the .Select Statment. Because there is no need for Example to Select a Cell and then write to the Cell. It's more efficent to write directly to the cell.
Take a look at this entrys. They will give you help optimizingyour VBA Code.
Optimizing VBA macro
How to prevent a macro from freezing / turning white the Excel window?
How to avoid using Select in Excel VBA
Related
Whenever I run a certain report macro in Excel I cannot use Copy and Paste elsewhere. For instance say I start up the report(depending on how many lines can take 30+ minutes) and then go work elsewhere while its running in the background it doesn't allow me to copy and paste. The only thing it does paste is whatever the Macro is currently working on and If I try to copy something it gets inserted into the next cell on the report messing that report up.
Looking for any advice or if anyone else has heard of this.
Thanks.
Do you even need copy/paste? Perhaps under the covers VBA isn't really copy/pasting, per-se, but if you only need the values, why not:
Range("B1").Value = Range("A1").Value
Bear in mind you can truly do this for ranges, not just cells
Range("B1:B100").Value = Range("A1:A100").Value
This won't copy formats and such, but you can add those as well:
Range("A1").NumberFormat = Range("B1").NumberFormat
This may not be as tidy, code-wise as what you seek with a copy/paste, but I'd encourage you to benchmark it and see which is more efficient. Again, perhaps it's all the same under the hood; I really don't know.
By using:
Range("A1").Select
Selection.Copy
Range("B1").Select
Selection.Paste
I was using my Active Clipboard ergo why I couldn't Copy and Paste by altering it to:
Range("A1?).Copy Destination:=Range("B1?)
It will do the same thing only not use your active clipboard and be way more efficient.
I am formatting two different reports using the same macro. The performance between the two spreadsheets is dramatically different. The macro functions instantaneously on the first report and takes about 10 seconds on the other. I have narrowed it down to the statement which makes cell A1 bold. When the bolding statement is omitted, both spreadsheets execute the macro instantaneously. I have tried the following methods of formatting cell A1.
Range("A1").Font.Bold = True
Range("A1:A1").Font.Bold = True
With Range("A1")
.Font.Bold = True
End With
ActiveSheet.Cells(1, 1).Font.Bold = True
As far as I know, .Font.Bold = True is the only way to make a cell bold, so the problem cannot be circumvented by using another command. The above are all the ways Google has suggested calling such action. Both spreadsheets are .xls extensions. Why might one spreadsheet's performance be dramatically different when executing the same statement?
There may be a lot of reasons. The main in my opinion being that the changes require ScreenUpdating and both Worksheets use a different amount of memory to compute your Worksheet layout e.g. having shapes, pivots, charts, hidden rows etc.
To workaround this turn off ScreenUpdating before your computations. Then turn it on again like below
Application.ScreenUpdating = False
'Your code here
Application.ScreenUpdating = True
Additionally to optimize your code utilize the following:
Turn off AutomaticCalculations
Save your file as binary Excel: .xslb
Columns("DV").Cut
Columns("P").Insert Shift:=xlToRight
I am using this code above to basically move a column, but every time I run the macro, it slows the process so much. Is there a more efficient way to do this so my macro isn't bogged down?
Thanks.
You might try inserting this line at the beginning of the macro:
Application.Calculation = xlCalculationManual
And insert this at the end:
Application.Calculation = xlCalculationAutomatic
If you have a lot of formulas in the data you are moving around it is attempting to recalculate while the macro is running. The above lines will tell Excel to not calculate during the macro run.
I have a macro that runs on a shared workbook. it copy/pastes from an un-shared workbook into the shared workbook, closes the un-shared workbook, and then does a series of lookups. I find that while shared, the update hangs a bit when it performs the open/copy/paste/close of the un-shared workbook. Is there any way to speed this up?
I have set displayupdate = false and calculations = manual and that did help the lookups but it has not solved the delay on the open/copy/paste/close operation. Any advice?
I know that shared workbooks aren't the best, but my users are keen on it...
do: Application.ScreenUpdating = false I find that helps alot in my work, and i believe is different than displayupdates. Also, make sure that .activate is happening as little as possible. each cell or sheet activation is one more processing instruction that often doesnt need to happen. instead, use offset(rows, Columns) if possible, or see if you can refer to a sheet and range like Sheets(1).Range("Cell"). check for if's / loop's that are coded poorly. replace multiple if's with elseif's if possible.
edit
I got this from another site -
If ActiveWorkbook.MultiUserEditing Then
ActiveWorkbook.ExclusiveAccess
End If
I haven't tested it, but maybe you could adapt that to unshare the workbook before doing the copy / paste?
If you're correct in concluding that the open/copy/paste/close process time while having a shared workbook open is increased exponentially, but otherwise is only increased marginally, then I think the best method for improving performance would be to copy/paste all the un-shared workbooks into another un-shared workbook that will serve as a buffer. Then use your code to open the shared workbook and copy/paste code from the buffer into said shared workbook.
This will help if the hangup is occurring in the open/close and not in the copy/paste--which I suspect is the case.
I have a macro for Excel, nothing too fancy, no objects, just plain old cycles with formulas. Basically it's this:
I cycle through rows in one column, assigning pretty big SUMPRODUCT functions to the cells without executing them. Once I cycled through the row I do Range.Value = Range.Value twice to execute the formulas and to save result as value. Then I go for the next column.
With each column memory used by Excel increases significantly and after the macro is done and I save the file - the memory is still used (if I can trust Task Manager). After I close and reopen the file - all memory is, of course, freed and I can continue to work. I've reached a point where I can't process all the columns I need on a 32 bit Excel due to memory limit.
I was wondering, maybe there's some trick I could implement between the columns to make Excel forget whatever it keeps remembering? I don't really care if it will hit performance (in case it has cached anything useful for further calculations), I just need to keep memory usage from growing too huge to process. I googled a bit but all the advises are related to setting big objects to nothing - I don't really set much of anything to anything, just cycle through, so that probably won't apply to my case.
Code is like this (don't have it on me right now, but it's a general simplified version of what is in it):
for i = 1 to 12
ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Font.Color = vbWhite
for m = 1 to x
ThisWorkbook.ActiveWorksheet.Cells(m, i).Formula = "'=SUMPRODUCT(blah)"
next m
ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Value = ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Value
ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Value = ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Value
ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Font.Color = vbBlack
next i
Basically, I color them white so I don't see the messy function text, add function, execute it, save as values, color text black.
Important addition: I use SUMPRODUCT to sum some cells from closed files.
This isn't really enough code to help you improve the efficiency. I can point out a few tips for you now though.
The first thing to remember is to switch application screen updating to false at the start of the macro.
Application.ScreenUpdating = False
then switch it back just before the end of the macro code
Application.ScreenUpdating = True
Changing the font color is unnecessary now. Your screen will be locked for refreshing while the macro is being executed so you will not be seeing the changes until the macro has finished working.
Consider, disabling Events too.
Application.EnableEvents = False and Application.EnableEvents = true same idea as with the screen updating.
The second thing is to make use of Evaluate() function. Please google it and read about how efficient that function can be.
Instead of putting a function into cell and then doing .Value = .Value you can just Evaluate() an expression and return the result straight to the cell which is much faster!
So you could do something like
for i = 1 to 12
ThisWorkbook.ActiveWorksheet.Range(Cells(1,i),Cells(x,i)).Value = Evaluate("=SUM(blah)")
next i
I hope you get the idea.
Here are a few links with tips on how to speed up your macro:
http://msdn.microsoft.com/en-us/library/office/ff193019.aspx
http://fastexcel.wordpress.com/2011/11/02/evaluate-functions-and-formulas-fun-how-to-make-excels-evaluate-method-twice-as-fast/
http://www.soa.org/news-and-publications/newsletters/compact/2012/january/com-2012-iss42-roper.aspx
http://xlvba.fr.yuku.com/topic/278/The-Evaluate-Method#.UmZP6Pmkp8s
I know this is an old question but a way that seems to work is saving the Workbook. Run ThisWorkbook.Save every once in a while and if you monitor EXCEL in the Task Manager you will notice that it clears up a significant amount of memory.
It seems as though Excel may be caching certain function calls or something and saving clears this cache.