How To Speed Up VBA Code

I have an excel file with a VBA code (Not written by me) How this code works is user enters a 6 digit number in a user form, the VBA then checks another sheet and if this 6 digit number is present on the worksheet. If it does, it changes the stage, but if it doesn't it adds this 6 digit number to the worksheet

It used to work perfectly, but now because the excel file has grown in the number of rows, almost 6000 rows, this code is become very slow, takes up to 20 seconds to update the sheet

Can someone please help me speed this code up, or suggest another way to acheive it

The code is below

Private Sub cmdPSDUdate_Click()
Dim x
If (Me.PSDUDateRow = "") + (Me.PSDStageCB.ListIndex = -1) Then Exit Sub
With Sheets("psdata stage cals").ListObjects("PSDataStageCals")
    x = Application.Match(Val(Me.PSDUDateRow), .ListColumns(1).DataBodyRange, 0)
    If IsNumeric(x) Then
        .ListRows(x).Range(2) = Me.PSDStageCB.Value
    Else
        .ListRows.Add.Range = Array(Val(Me.PSDUDateRow), Me.PSDStageCB)
    End If
End With
Me.PSDUDateRow.Value = ""
Me.PSDStageCB.Value = ""
Me.PSDUDateRow.SetFocus
End Sub

Thanks in advance

Rahul


Solution 1:

You could turn off screenupdating, automatic calculations etc

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False

‘Place your macro code here

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True

Solution 2:

In general, there are two ways to speed up VBA code:

  1. Write good code, that does not use Select, Activate, ActiveCell, Selection etc - How to avoid using Select in Excel VBA

  2. Refer to these routines on the start and on the end of the code:


Public Sub OnEnd()

    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.AskToUpdateLinks = True
    Application.DisplayAlerts = True
    Application.Calculation = xlAutomatic
    ThisWorkbook.Date1904 = False        
    Application.StatusBar = False
    
End Sub

Public Sub OnStart()
    
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.AskToUpdateLinks = False
    Application.DisplayAlerts = False
    Application.Calculation = xlAutomatic
    ThisWorkbook.Date1904 = False
    ActiveWindow.View = xlNormalView

End Sub

(For improvement ideas, kindly make PullRequest)

  • I think that Calculation should be always set to xlAutomatic, as far as if you need xlCalculationManual to speed up, it is a good idea to refactor the code. Furthermore manual calculation is too risky.
  • The same goes for Date1904 - it is always set to False.

Solution 3:

In addition to the tweaks suggested by Storax, your code is slow because you are bringing data cell-by-cell over the Excel/VBA divide.

Furthermore, you can radically speed up your MATCH function by using the Binary version of it. Have a read of http://dailydoseofexcel.com/archives/2015/04/23/how-much-faster-is-the-double-vlookup-trick/ and also try to minimise the amount of individual transfers you do across the Excel/VBA divide by either performing the lookups entirely within the Excel sheet (by using VBA to write the formula in the sheet and execute it there) or by bringing all the data into VBA in one go using variant arrays, performing your logic, and then by dumping it back in one go. Google "Efficient way to transfer data between Excel and VBA" or something similar. Also check out any articles from Charles Williams on the subject.