I have a VBA macro, that writes in data into a cleared out worksheet, but it's really slow!
I'm instantiating Excel from a Project Professional.
Set xlApp = New Excel.Application
xlApp.ScreenUpdating = False
Dim NewBook As Excel.WorkBook
Dim ws As Excel.Worksheet
Set NewBook = xlApp.Workbooks.Add()
With NewBook
.Title = "SomeData"
Set ws = NewBook.Worksheets.Add()
ws.Name = "SomeData"
End With
xlApp.Calculation = xlCalculationManual 'I am setting this to manual here
RowNumber=2
Some random foreach cycle
ws.Cells(RowNumber, 1).Value = some value
ws.Cells(RowNumber, 2).Value = some value
ws.Cells(RowNumber, 3).Value = some value
...............
ws.Cells(RowNumber, 12).Value = some value
RowNumber=RowNumber+1
Next
My problem is, that the foreach cycle is kinda big. At the end, I'll get around 29000 rows. It takes more than 25 minutes to do this on a pretty OK computer.
Are there any tricks to speed up the writing to the cells? I've done the following:
xlApp.ScreenUpdating = False
xlApp.Calculation = xlCalculationManual
Am I referencing the cells in a wrong way? Would it be possible, to write in a whole row, instead of the single cells?
Would that be faster?
I've tested my code, the foreach cycle goes through pretty quicky (i wrote the values into some random variables), so I know, that writing into the cells is what takes up all this time.
If you need further information, code snipplets please let me know.
Thank you for your time.
Yes and yes. This is exactly where you can improve performance. Reading/writing to cells is notoriously slow. It matters very little how many cells you are reading/writing, but rather how many calls you are making to the COM object to do so. Therefore read and write your data in blocks utilizing two-dimensional arrays.
Here is an example procedure that writes MS Project task data to Excel. I mocked up a schedule with 29,000 tasks and this runs in a few seconds.
Do it like this:
Where arr is an array of your
some value
values e.g.Or if possible (even faster):
Where
twoDimensionalArray
is a 2 dimensional array of yoursome value
values e.g.A previous answer mentions doing
cells(1,1).select
.My suggestion is to do
Worksheets("Sheet2").Activate
before your update loop.replace
Sheet2
above with any sheet that isn't the one having cells updated. This results in a really substantial improvement.even though you can set application displayupdating false, changing the activated sheet truly removes the overhead.
I was in a situation where I was populating huge table and I had to go cell by cell, then row by row. Painfully slow. I'm still not sure why but before my loop I added:
(that is cell outside my table if that matters -idk) and speed was significantly improved. I mean from 10 minutes to about 30 sec. So if you are writing to cells in a table give it a go.
I should add that first thing I always do is disabling events, screen updates and switching to manual calculations. That did not helped before I tried this workaround