views:

2503

answers:

3

The print functionality of Excel (in VBA) is extremely slow, I hoping someone has a way of speeding the printing up (without using the Excel 4 Macro trick). Here's how I do it now:

    Application.ScreenUpdating = False

    With ActiveSheet.PageSetup

      -various setup statements which I've already minimized-

    End With   
    ActiveSheet.PrintOut

    Application.ScreenUpdating = True
+3  A: 

Yes, the PageSetup properties are very slow when you set them.

You have already set Application.ScreenUpdating = False, which is good, but an equally (or more) important step in this case is to set Application.Calculation = xlCalculationManual. (It is best if you save these settings and then restore them to the original at the end.)

Additionally, the property get for each PageSetup property is very fast, while it is only the property set that is so slow. Therefore, you should test the new property setting to make sure it isn't already the same as the existing property value in order to prevent an unnecessary (and expensive) call.

With all this in mind, you should be able to use code that looks something like the following:

Dim origScreenUpdating As Boolean
origScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False

Dim origCalcMode As xlCalculation
origCalcMode =  Application.Calculation
Application.Calculation = xlCalculationManual

With ActiveSheet.PageSetup
    If .PrintHeadings <> False Then .PrintHeadings = False
    If .PrintGridlines <> False Then .PrintGridlines = False
    If .PrintComments <> xlPrintNoComments Then .PrintComments = xlPrintNoComments
    ' Etc...
End With

Application.ScreenUpdating = origScreenUpdating
Application.Calculation = origCalcMode

Edit: A couple of updates:

  1. For Excel 2010 and above you can make use of the 'Application.PrintCommunication' property, while for Excel 2007 and below, you can make use of 'ExecuteExcel4Macro'. For more details, see Migrating Excel 4 Macros to VBA.

  2. For Excel 2007 and below, another interesting trick is to temporarily assign the printer driver to the 'Microsoft XPS Document Writer' and then set it back. Printing speed can improve by 3x. See: Slow Excel PageSetup Methods.

Hope this helps...

Mike Rosenblum
I'll test that out, and let you know how it worked for me.
Lance Roberts
I was able to get quite an increase, most of my sets were non-boolean values, do you know if Print Setup is by sheet or workbook?
Lance Roberts
Hey Lance, yes, you can get a very big improvement by following this approach -- I'm glad it worked for you. :-) The page setup is for each worksheet individually, not for the workbook as a whole. (The Worksheeet class has a PageSetup property, but the Workbook class does not.)
Mike Rosenblum
A: 

if you want to have basicly the same page settings for every tab in a workbook can you speed things up by setting up one workshet and then copying that worksheet's settings somehow to the other worksheets? Is this possible?

+1  A: 

In furthering Michael's post and answering @rhc's question, the following code may also help you if need to copy Page Setup customizations from a single worksheet to multiple worksheets in a workbook:

Public Sub CopyPageSetupToAll(ByRef SourceSheet As Worksheet)
    ' Raise error if invalid source sheet is passed to procedure
    '
    If (SourceSheet Is Nothing) Then
        Err.Raise _
            Number:=vbErrorObjectVariableNotSet, _
            Source:="CopyPageSetupToAll", _
            Description:="Unable to copy Page Setup settings: " _
                 & "invalid reference to source sheet."
        Exit Sub
    End If

    SourceSheet.Activate

    With SourceSheet.PageSetup
        ' ...
        ' place PageSetup customizations here
        ' ...
    End With

    SourceSheet.Parent.Worksheets.Select
    Application.SendKeys "{ENTER}", True
    Application.Dialogs(xlDialogPageSetup).Show
End Sub

Alternatively, you could also modify the procedure to create a temporary worksheet to host your Page Setup changes, and then propagate those changes out to the other worksheets in your workbook:

Public Sub CopyPageSetupToAll(ByRef SourceBook As Workbook)
    Dim tempSheet As Worksheet

    ' Raise error if invalid workbook is passed to procedure
    '
    If (SourceBook Is Nothing) Then
        Err.Raise _
            Number:=vbErrorObjectVariableNotSet, _
            Source:="CopyPageSetupToAll", _
            Description:="Unable to copy Page Setup settings: " _
                 & "invalid reference to source workbook."
        Exit Sub
    End If

    Set tempSheet = SourceBook.Worksheets.Add

    tempSheet.Activate

    With tempSheet.PageSetup
        ' ...
        ' place PageSetup customizations here
        ' ...
    End With

    SourceBook.Worksheets.Select
    Application.SendKeys "{ENTER}", True
    Application.Dialogs(xlDialogPageSetup).Show
    tempSheet.Delete

    Set tempSheet = Nothing
End Sub

Due to the use of the SendKeys() function and Application.Dialogs functionality, this code does not offer the cleanest possible solution. However, it gets the job done. :)

Adam Parrott