4
\$\begingroup\$

There is a main page with this macro assigned to a button. Once the button is pressed it asks if you wish to continue and mentions it takes a while to run the macro. I'm looking to speed it up some if possible.

Sub Picture11_Click() 
Dim sht As Worksheet

If MsgBox("Do you wish to print summary pages? Will take approximately 1-2 minutes to run the macro", vbYesNo) = vbNo Then Exit Sub

Application.Calculation = xlCalculationManual 
Application.ScreenUpdating = False    
Application.Dialogs(xlDialogPrinterSetup).Show

PrintSummaryArray = Array(Sheet10.Name, Sheet11.Name, Sheet12.Name, Sheet16.Name, Sheet2.Name, Sheet8.Name, Sheet9.Name)

    For Each sht In Worksheets(PrintSummaryArray)
       sht.PageSetup.Zoom = False
       sht.PageSetup.FitToPagesWide = 1
       sht.PageSetup.FitToPagesTall = 1
       sht.PageSetup.BlackAndWhite = False
       sht.PageSetup.PrintArea = "A1:X62"
    Next
     Sheets(PrintSummaryArray).Select

ActiveWindow.SelectedSheets.PrintOut

Worksheets(Sheet1.Name).Select

Application.ScreenUpdating = True 
Application.Calculation = xlCalculationAutomatic

End Sub
\$\endgroup\$
5
  • 1
    \$\begingroup\$ In your for loop you might want to use the with statement on sht.PageSetup. It decreases the amount of code your need to write and it is faster. \$\endgroup\$ Commented Aug 1, 2016 at 16:17
  • \$\begingroup\$ @pacmaninbw That looks like an answer to me (even if it's small). \$\endgroup\$ Commented Aug 1, 2016 at 16:41
  • \$\begingroup\$ @pacmaninbw Yeah, not sure if it helped with speed much. Not noticeable at least but does look better. Think the answer below by Zak might be the one but will wait to see if anyone else knows a way. \$\endgroup\$ Commented Aug 1, 2016 at 16:45
  • 3
    \$\begingroup\$ @Zak is always good. \$\endgroup\$ Commented Aug 1, 2016 at 16:46
  • \$\begingroup\$ @Marc-Andre Zak does have it covered. I couldn't provide as much information as he did. \$\endgroup\$ Commented Aug 1, 2016 at 16:47

1 Answer 1

2
\$\begingroup\$

I don't think this can be sped up

It's *possible* that selecting all the pages and printing-as-one is noticeably slower than printing each page iteratively (I recommend you try it out and see), but probably not by a significant amount.

The printer does take a certain amount of time to perform a print operation and that can't be optimised away.


Other Thoughts on your code


Codenames

Sheet10, Sheet11, Sheet12 etc. are codenames. They can be changed in the VBE by clicking on a sheet in the properties window. Like so:

enter image description here

The (name) property is the codename. It should be changed to something descriptive and useful e.g.

wsFrontpage, wsInitialSummary, wsSomethingAnalysis, wsOtherAnalysis, wsConclusions

And now you won't have to keep trying to remember which one was sheet11, which one was sheet13 etc.


Use With

With let's you hold an object reference, so this:

   sht.PageSetup.Zoom = False
   sht.PageSetup.FitToPagesWide = 1
   sht.PageSetup.FitToPagesTall = 1
   sht.PageSetup.BlackAndWhite = False
   sht.PageSetup.PrintArea = "A1:X62"

Becomes:

With sht.PageSetup
   .Zoom = False
   .FitToPagesWide = 1
   .FitToPagesTall = 1
   .BlackAndWhite = False
   .PrintArea = "A1:X62"
End With

Much easier to work with.


Only Exit In One Place

If you've got a random Exit Sub halfway through your code, on the end of a long if statement, it's very easy for someone to miss it. When you miss something like that, it's easy to change the code in a way that you *think* is safe, but is actually going to cause unexpected behaviour.

So, instead of using an Exit here, you should just wrap everything in an If statement:

Sub Picture11_Click()

    Const USER_PRINT_DIALOG As String = "Do you wish to print summary pages? Will take approximately 1-2 minutes to run the macro"

    If MsgBox(USER_PRINT_DIALOG, vbYesNo) = vbYes Then

        With Application
            .Calculation = xlCalculationManual
            .ScreenUpdating = False
            .Dialogs(xlDialogPrinterSetup).Show
        End With

        PrintSummaryArray = Array(Sheet10.Name, Sheet11.Name, Sheet12.Name, Sheet16.Name, Sheet2.Name, Sheet8.Name, Sheet9.Name)

        Dim sht As Worksheet
        For Each sht In Worksheets(PrintSummaryArray)
           sht.PageSetup.Zoom = False
           sht.PageSetup.FitToPagesWide = 1
           sht.PageSetup.FitToPagesTall = 1
           sht.PageSetup.BlackAndWhite = False
           sht.PageSetup.PrintArea = "A1:X62"
        Next

        Sheets(PrintSummaryArray).Select
        ActiveWindow.SelectedSheets.PrintOut

        Sheet1.Select

        With Application
            .ScreenUpdating = True
            .Calculation = xlCalculationAutomatic
        End With

    End If

End Sub

Refactor Everything

Right now, your Picture11_Click Event only has to handle printing a specific set of worksheets. What if you want to do something else as well before/after? What if you want to print your sheets from another button somewhere else?

Picture11_Click is an Event Handler. It should not contain business logic. You should move your *Print Sheets* Logic into an appropriately named Sub and then call that from the event handler. Like so:

Option Explicit

Sub Picture11_Click()

    Const USER_PRINT_DIALOG As String = "Do you wish to print summary pages? Will take approximately 1-2 minutes to run the macro"

    If MsgBox(USER_PRINT_DIALOG, vbYesNo) = vbYes Then

        PrintThingyReport

    End If

End Sub

Public Sub PrintThingyReport()

    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .Dialogs(xlDialogPrinterSetup).Show
    End With

    PrintSummaryArray = Array(Sheet10.Name, Sheet11.Name, Sheet12.Name, Sheet16.Name, Sheet2.Name, Sheet8.Name, Sheet9.Name)

    Dim sht As Worksheet
    For Each sht In Worksheets(PrintSummaryArray)
       sht.PageSetup.Zoom = False
       sht.PageSetup.FitToPagesWide = 1
       sht.PageSetup.FitToPagesTall = 1
       sht.PageSetup.BlackAndWhite = False
       sht.PageSetup.PrintArea = "A1:X62"
    Next

    Sheets(PrintSummaryArray).Select
    ActiveWindow.SelectedSheets.PrintOut

    Sheet1.Select

    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
    End With

End Sub

And now you can call that method from as many places as you like.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the help. Took a few of your suggestions and adjusted. \$\endgroup\$ Commented Aug 2, 2016 at 21:05
  • \$\begingroup\$ @ross Awesome! Please feel free to post a follow-up question \$\endgroup\$ Commented Aug 3, 2016 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.