Forum Discussion

CHileman's avatar
CHileman
Copper Contributor
Jul 01, 2022

Help with Macro Hygiene Please

It's not that the macros run slowly, or that Excel crashes, but it just takes a while to get excel selected when coming from another program or webpage. 

 

I tend to have to cut and paste a good deal of data into cells in the table I use. When it comes time to select the cell to paste the data into there is an annoying delay. When I remove all the macros it stops, but when I put them back in it starts again. 

 

All of the macros are just ways to manage the view of the table - selecting criteria from filters on the headers and/or hiding columns I won't need to bother with. 

 

I suspect that perhaps there is a better way to write my codes, but all my coding experience relies mainly on googling and adapting. 

 

I'm also pretty new to this - so not too sure what would be the best way to post the codes I have for someone who might be willing to review. But here's what I use:

 

Unhide_All (I don't think this one is problematic)

 

Sub Unhide_All()

If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
  ActiveSheet.ShowAllData
End If

Columns.EntireColumn.Hidden = False
Rows.EntireRow.Hidden = False

End Sub

 

 

Here's another for entering new information without having to look at columns and rows I don't need - my guess is it's one of the ones like this that are problematic:

 

Sub Referral_Entry()

Call Unhide_All

ActiveSheet.ListObjects("DG_TABLE").Range.AutoFilter Field:=1, Criteria1:= _
        Array("Open Referral", "Approved", "Accepted"), Operator:= _
        xlFilterValues
        
Dim Lastcolumn As Long
Lastcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
    For i = 1 To Lastcolumn
        If Cells(1, i).Value = "NOA Submitted" Or Cells(1, i).Value = "Auth #" Or Cells(1, i).Value = "1st Auth Day" Or Cells(1, i).Value = "LCD" Or Cells(1, i).Value = "CCR Due Date" Or Cells(1, i).Value = "CCR Submitted" Or Cells(1, i).Value = "DC Date" Or Cells(1, i).Value = "DC Submitted" Or Cells(1, i).Value = "Encounters Authed" Or Cells(1, i).Value = "Encounters Total" Or Cells(1, i).Value = "ART dates in DG" Or Cells(1, i).Value = "Injection Dates" Or Cells(1, i).Value = "H&P Sent" Or Cells(1, i).Value = "Signed H&P Uploaded" Or Cells(1, i).Value = "Billing Config Service Code" Or Cells(1, i).Value = "Bed Night Adjusted intake Date" Or Cells(1, i).Value = "Bed Night Adjusted DC" Or Cells(1, i).Value = "Mbr Bed Night Count" Then Columns(i).Hidden = True
    Next
    
    
End Sub

 

 

I could post more, but I would bet if I can figure out the solution from one, I can repeat it for the others. 

 

TIA!

 

Chileman

 

 

 

  • CHileman 

    Try setting up your macro like this, it should actually be faster.

     

    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With
    
    'Here insert your code
    
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
    End With

     

    Example according to your code specifications.

     

    'Example with your first code
    
    Sub Unhide_All()
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With
    If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
      ActiveSheet.ShowAllData
    End If
    
    Columns.EntireColumn.Hidden = False
    Rows.EntireRow.Hidden = False
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
    End With
    End Sub

     

     

    Hope I was able to help you :).

     

    NikolinoDE

    I know I don't know anything (Socrates)

  • amit_bhola's avatar
    amit_bhola
    Iron Contributor

    CHileman , when does the sub Referral_Entry get called (run)?

    Are you using any events like Worksheet_SelectionChange or Workbook_Activate etc?
    Such events are fired too frequently and may become one reason of slow activation of Excel window or cell. If so, then may see if you can avoid using these events to run the subs. For example, you can choose to run the macros manually by adding them on QAT

    https://support.microsoft.com/en-us/office/assign-a-macro-to-a-button-728c83ec-61d0-40bd-b6ba-927f84eb5d2c

     

    • CHileman's avatar
      CHileman
      Copper Contributor
      Thanks amit_bhola, I appreciate very much you taking the time to look and reply. I did get a fix from NikolinoDE that seems to be approaching the same considerations you give here. FWIW though, in this case, all the macros were already only running from a button already on the QAT. But his suggestion was to disable events (and screen updating and autocalculations) at the start of the macro call, and then re-enabling before exiting it. It's working, though I don't really see how. But again, I do appreciate your help here!
      • amit_bhola's avatar
        amit_bhola
        Iron Contributor

        CHileman 

        'lags I was experiencing were not happening while a macro was running'

         

        That's why I thought that some event might be slowing down the window/cell activation from another program.

        Just to be clear, did disabling events just make the macro execution fast or did it also solve the Excel window/cell reactivation slow issue?

        If it solved, then I share your (not so) mile long puzzle!

         

        Otherwise, you can check if there are many macros installed, and is it some other macro which is depending on events to execute, and if those can be avoided as well.

  • NikolinoDE's avatar
    NikolinoDE
    Gold Contributor

    CHileman 

    Try setting up your macro like this, it should actually be faster.

     

    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With
    
    'Here insert your code
    
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
    End With

     

    Example according to your code specifications.

     

    'Example with your first code
    
    Sub Unhide_All()
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .EnableEvents = False
    End With
    If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
      ActiveSheet.ShowAllData
    End If
    
    Columns.EntireColumn.Hidden = False
    Rows.EntireRow.Hidden = False
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
        .EnableEvents = True
    End With
    End Sub

     

     

    Hope I was able to help you :).

     

    NikolinoDE

    I know I don't know anything (Socrates)

    • CHileman's avatar
      CHileman
      Copper Contributor
      Thank you so much!!!! I still get small hiccups, but nothing like it had been. At the risk of being the man who asks for a mile after an inch, and if it's not too much trouble, could you help explain why it's working?

      As I read it, it looks like with these code segments added in, when a macro is run, it is shutting off the RAM intensive bits of excel (calculations, screen updates and events) but then before it exits the macro, it re-enables them.

      But the macros wouldn't run unless I called them to run, and the lags I was experiencing were not happening while a macro was running - just when selecting back into excel from another program. So why would turning them off and back on only within the execution of a macro change anything?

      Am I pondering this the right way?

      Regardless, it is working, so again, thank you!!!
      • NikolinoDE's avatar
        NikolinoDE
        Gold Contributor

        CHileman 

        Try to explain 🙂 in a few words why these commands could be used.

        Please also consider that I do not know the formula and VBA structure of your workbook.

         

        Calculation:

        If you change cells/columns, etc. with VBA, to which functions of other cells refer, a recalculation is always started.

        Depending on the functions and the associated number of calculations, it can have an impact (mostly negative) on performance.

        While Excel is working on the recalculation, the processing of the program code is slowed down because the program flow only continues when the calculation has been completed for the time being.

        You can avoid this problem by switching off the automatic calculation in the initial code.

         

        EnableEvents:

        The Select methods in the macro would re-invoke the macro called by moving the cursor around the worksheet. Setting the EnableEvent property to False prevents this from happening.

         

        Disabling screen updating speeds up your macro code. While you won't be able to see what the macro is doing, it will run much faster. The ScreenUpdating property should end up being set back to True when your macro exits.

         

        Excel VBA reference (here you can find general information about VBA)

Resources