I have a workbook that on open, turns the used cells into a table, and then injects different formulas into each column. I'm injecting the formulas to save file size from exploding by pre-dragging formulas down farther than needed. The VBA I have to do this works fine, but is incredibly slow. I've already run performance checks and can confirm that the slowness is caused by the formula injection (only 141 rows can be injected per second). I have already done the basic calculation/screen update related optimizations. What else can be done to speed up the following code? (Note I have reduced to the relevant portion of the code):
Sub OptimizeVBA(isOn As Boolean)
Application.Calculation = IIf(isOn, xlCalculationManual, xlCalculationAutomatic)
Application.EnableEvents = Not(isOn)
Application.ScreenUpdating = Not(isOn)
' ActiveSheet.DisplayPageBreaks = Not(isOn)
End Sub
Private Sub Workbook_Open()
OptimizeVBA True
Dim ws As Worksheet
Set ws = Worksheets("Book1")
Dim tbl As ListObject
Set tbl = ws.ListObjects("Table1")
tbl.ListColumns("Dollar Share ").DataBodyRange.Formula = "=IFERROR(([@[Dollar Share ]] - MEDIAN([[Dollar Share ]])) / STDEV.P([[Dollar Share ]]), """")"
tbl.ListColumns("Unit Share ").DataBodyRange.Formula = "=IFERROR(([@[Unit Share ]] - MEDIAN([[Unit Share ]])) / STDEV.P([[Unit Share ]]), """")"
tbl.ListColumns("Units PSPW ").DataBodyRange.Formula = "=IFERROR(([@[Units PSPW ]] - MEDIAN([[Units PSPW ]])) / STDEV.P([[Units PSPW ]]), """")"
tbl.ListColumns("Dollar Growth ").DataBodyRange.Formula = "=IFERROR(IF(OR([@[Dollar Growth ]] = """", [@[Dollars, Yago]] < New_Item_Floor), """", ([@[Dollar Growth ]] - MEDIAN([[Dollar Growth ]])) / STDEV.P([[Dollar Growth ]])), """")"
tbl.ListColumns("Unit Growth ").DataBodyRange.Formula = "=IFERROR(IF(OR([@[Unit Growth ]] = """", [@[Dollars, Yago]] < New_Item_Floor), """", ([@[Unit Growth ]] - MEDIAN([[Unit Growth ]])) / STDEV.P([[Unit Growth ]])), """")"
tbl.ListColumns("Comp Avg % ACV ").DataBodyRange.Formula = "=IFERROR(([@[Comp Avg % ACV ]] - MEDIAN([[Comp Avg % ACV ]])) / STDEV.P([[Comp Avg % ACV ]]), """")"
OptimizeVBA False
End Sub
I'm aware that selects/other interactions with Excel objects are expensive, but given that the above formulas are different, I couldn't figure out an easy way to reduce the separate interactions for each column.
Notes:
- There are actually more injections than shown above, with different formulas of roughly equal string length.
- On average
tblwill have 16k rows.
Thanks in advance for the help!
tbl.ListRows(1).Range, but how could I set each cell to the different formula and then autofill? - ZaxRRange(A2:A200000).Value="test"- SnowGroomer