Editing properties in the VBA PageSetup object is notoriously slow because the object sends a call to the print drivers each time it wants to update a PageSetup property. Even if you disable events and screen updating, PageSetup is still slow. It’s not until you set Application.PrintCommunication = False
before you start noticing considerable improvements in performance..
You don’t have to use the slow PageSetup method, though. There is another way to update your page setup properties without relying on any of the sluggish Worksheet.PageSetup statements. This alternate solution lies in a really old version of Excel…
The Excel 4.0 compatible macro method, Application.ExecuteExcel4Macro, has a PAGE.SETUP function that is much faster than changing properties using the slow Worksheet.PageSetup object. The speed differences aren’t as significant if you disable the time-wasting events, which we’ll talk about below, but it’s still a bit faster. This tutorial will help you if you’re searching for ways to speed up your VBA PageSetup statements and nothing you’ve tried has worked.
VBA PAGE.SETUP Routine
Private Sub PageSetupXL4M( _
Optional LeftHead As String, Optional CenterHead As String, Optional RightHead As String, Optional LeftFoot As String, _
Optional CenterFoot As String, Optional RightFoot As String, Optional LeftMarginInches As String, Optional RightMarginInches As String, _
Optional TopMarginInches As String, Optional BottomMarginInches As String, Optional HeaderMarginInches As String, Optional FooterMarginInches As String, _
Optional PrintHeadings As String, Optional PrintGridlines As String, Optional PrintComments As String, Optional PrintQuality As String, _
Optional CenterHorizontally As String, Optional CenterVertically As String, Optional Orientation As String, Optional Draft As String, _
Optional PaperSize As String, Optional FirstPageNumber As String, Optional Order As String, Optional BlackAndWhite As String, _
Optional Zoom As String)
Const c As String = ","
Dim pgSetup As String
Dim head As String
Dim foot As String
If LeftHead <> "" Then head = "&L" & LeftHead
If CenterHead <> "" Then head = head & "&C" & CenterHead
If RightHead <> "" Then head = head & "&R" & RightHead
If Not head = "" Then head = """" & head & """"
If LeftFoot <> "" Then foot = "&L" & LeftFoot
If CenterFoot <> "" Then foot = foot & "&C" & CenterFoot
If RightFoot <> "" Then foot = foot & "&R" & RightFoot
If Not foot = "" Then foot = """" & foot & """"
pgSetup = "PAGE.SETUP(" & head & c & foot & c & _
LeftMarginInches & c & RightMarginInches & c & _
TopMarginInches & c & BottomMarginInches & c & _
PrintHeadings & c & PrintGridlines & c & _
CenterHorizontally & c & CenterVertically & c & _
Orientation & c & PaperSize & c & Zoom & c & _
FirstPageNumber & c & Order & c & BlackAndWhite & c & _
PrintQuality & c & HeaderMarginInches & c & _
FooterMarginInches & c & PrintComments & c & Draft & ")"
Application.ExecuteExcel4Macro pgSetup
End Sub
Make powerful macros with our free VBA Developer Kit It’s easy to copy and paste a macro like this, but it’s harder make one on your own. To help you make macros like this, we built a free VBA Developer Kit and wrote the Big Book of Excel VBA Macros full of hundreds of pre-built macros to help you master file I/O, arrays, strings and more - grab your free copy below.
How to Call PageSetupXL4M
I first came across this subroutine in an article from 2004. It’s a great VBA routine but without an explanation for how to use it, it can be a bit intimidating. The routine organizes each argument into the old Excel 4.0 PAGE.SETUP
function style. The PAGE.SETUP
function in Excel 4.0 is complicated and requires the arguments be entered as one massive string organized in a specific manner. The syntax varies based on whether you’re adjusting a worksheet or a chart sheet, but we’re going to focus on worksheets in this tutorial.
In short, you have to call the PageSetupXL4M routine with a really long call statement, like this:
Sub FasterPageSetup()
Call PageSetupXL4M(Orientation:="2", _
LeftMarginInches:="0.25", _
RightMarginInches:="0.25", _
TopMarginInches:="0.5", _
BottomMarginInches:="0.5", _
HeaderMarginInches:="0.3", _
FooterMarginInches:="0.3", _
Zoom:="{2,1}", _
CenterVertically:="False", _
CenterHorizontally:="True")
End Sub
This lengthy statement adjusts the page setup properties on the active sheet, and is equivalent to this slower (but newer) method:
Sub SlowPageSetup()
With ActiveSheet.PageSetup
.Zoom = False
.Orientation = xlLandscape
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.5)
.BottomMargin = Application.InchesToPoints(0.5)
.HeaderMargin = Application.InchesToPoints(0.3)
.FooterMargin = Application.InchesToPoints(0.3)
.FitToPagesWide = 2
.FitToPagesTall = 1
.CenterHorizontally = True
.CenterVertically = False
End With
End Sub
The first thing you’ll notice is that each property is entered as a string in the Call
statement of the Call
statement. All the arguments are optional and the PageSetupXL4M macro organizes them in the proper format for the PAGE.SETUP function. This makes your job a lot easier, because the PAGE.SETUP function is just as finicky as the Worksheet.PageSetup method is slow.
The syntax for some of the PAGE.SETUP properties is unusual, especially for the Zoom
and Orientation
properties. If you’re unfamiliar with Excel 4.0 macro statements, it’s hard to know the different ways to enter each string. To make it easier, I’ve compiled a description of all the accepted properties, examples of how to use them, and their corresponding Worksheet.PageSetup equivalent methods:
Detailed PageSetupXL4M Argument Explanations
PageSetupXL4M Argument | Description | .PageSetup Equivalent | Example(s) |
---|---|---|---|
LeftHead | Text you want displayed in the upper left of your page | .LeftHeader | LeftHead:="Header Text" |
CenterHead | Text you want displayed in the top center of your page | .CenterHeader | CenterHead:="Header Text" |
RightHead | Text you want displayed in the upper right of your page | .RightHeader | RightHead:="Header Text" |
LeftFoot | Text you want displayed in the lower left of your page | .LeftFooter | LeftFoot:="Footer Text" |
CenterFoot | Text you want displayed in the bottom center of your page | .CenterFooter | CenterFoot:="Footer Text" |
RightFoot | Text you want displayed in the lower right of your page | .RightFooter | RightFoot:="Footer Text" |
LeftMarginInches | Left page margin in inches | .LeftMargin (with InchesToPoints) | LeftMarginInches:="0.25" |
RightMarginInches | Right page margin in inches | .RightMargin (with InchesToPoints) | RightMarginInches:="0.25" |
TopMarginInches | Top page margin in inches | .TopMargin (with InchesToPoints) | TopMarginInches:="0.5" |
BottomMarginInches | Bottom page margin in inches | .BottomMargin (with InchesToPoints) | BottomMarginInches:="0.5" |
HeaderMarginInches | Header margin in inches | .HeaderMargin (with InchesToPoints) | HeaderMarginInches:="0.75" |
FooterMarginInches | Footer margin in inches | .FooterMargin (with InchesToPoints) | FooterMarginInches:="0.75" |
PrintHeadings | Toggle to print Row and Column letters/numbers | .PrintHeadings | PrintHeadings:="TRUE" |
PrintGridlines | Toggle to print gridlines | .PrintGridlines | PrintGridlines:="FALSE" |
PrintComments | Toggle to print comments | .PrintComments | PrintComments:="FALSE" |
PrintQuality | Print quality in dots per inch. Horizontal and vertical values can be different and must be entered as an array, like "{90,72}" | .PrintQuality | PrintQuality:="{72,90}" PrintQuality:="90" |
CenterHorizontally | Center on page horizontally | .CenterHorizontally | CenterHorizontally:="TRUE" |
CenterVertically | Center on page vertically | .CenterVertically | CenterVertically:="FALSE" |
Orientation | Numeric value representing page orientation "1" is portrait, "2" is landscape |
.Orientation | Orientation:="2" |
Draft | Toggle for draft quality printing | .Draft | Draft:="TRUE" |
PaperSize | Numeric value representing the desired page size. Typically an integer from 1 through 26. 1 Letter, 2 Letter (small), 3 Tabloid, 4 Ledger, 5 Legal, 6 Statement, 7 Executive, 8 A3, 9 A4, 10 A4 (small), 11 A5, 12 B4, 13 B5, 14 Folio, 15 Quarto, 16 10x14, 17 11x17, 18 Note, 19 ENV9, 20 ENV10, 21 ENV11, 22 ENV12, 23 ENV14, 24 C Sheet, 25 D Sheet, 26 E Sheet |
.PaperSize | PaperSize:="9" |
FirstPageNumber | Page number to start numbering pages from | .FirstPageNumber | FirstPageNumber:="12" FirstPageNumber:="AUTO" |
Order | Specifies whether pages are printed top-to-bottom, then right ("1") or left-to-right, then down ("2") | .Order | Order:="1" |
BlackAndWhite | Toggle to print pages in black and white | .BlackAndWhite | BlackAndWhite:="FALSE" |
Zoom | Can be a logical toggle to fit the printed area on a page ("TRUE"), a percentage to scale the page ("75"), or an array defining how many pages you want to print ("{2,1}" for 2 pages wide, 1 page tall) | .Zoom .FitToPagesWide .FitToPagesTall |
Zoom:="{2,1}" Zoom:="75" Zoom:="TRUE" |
Performance Comparison
To prove how much faster the ExecuteExcel4Macro version of PAGE.SETUP is, I ran the following macros on a workbook with 30 spreadsheets and recorded the timing differences.
Sub SlowPageSetup_Loop()
For Each sht In ActiveWorkbook.Sheets
With sht.PageSetup
.Zoom = False
.Orientation = xlLandscape
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.5)
.BottomMargin = Application.InchesToPoints(0.5)
.HeaderMargin = Application.InchesToPoints(0.3)
.FooterMargin = Application.InchesToPoints(0.3)
.FitToPagesWide = 2
.FitToPagesTall = 1
.CenterHorizontally = True
.CenterVertically = False
End With
Next sht
End Sub
Sub FasterPageSetup_Loop()
For Each sht In ActiveWorkbook.Sheets
sht.Select
Call PageSetupXL4M(Orientation:="2", _
LeftMarginInches:="0.25", _
RightMarginInches:="0.25", _
TopMarginInches:="0.5", _
BottomMarginInches:="0.5", _
HeaderMarginInches:="0.3", _
FooterMarginInches:="0.3", _
Zoom:="{2,1}", _
CenterVertically:="False", _
CenterHorizontally:="True")
Next sht
End Sub
The
Disabling Application Flags
You can improve the performance even more by disabling certain Application flags. The difference between the PAGE.SETUP and Worksheet.PageSetup approaches isn’t nearly as dramatic once the following properties are disabled:
With Application
.ScreenUpdating = False
.EnableEvents = False
.PrintCommunication = False
End With
I highly recommend you set these to False at the beginning of your macro. You can set them back to True right before the end. When I disabled these time-wasting events, the PAGE.SETUP method finished in 4.87 seconds and the .PageSetup method finished in 5.42 seconds. Both methods show considerable speed improvements, but the .PageSetup method improvement is downright staggering. The time reduced from 37.29 seconds down to 5.42 seconds.
Of the three disabled properties, the PrintCommunication property is the one that had the biggest impact on macro speed. This was especially true for the slow .PageSetup macro.
Between the two optimized codes, the PAGE.SETUP routine performed about 10% faster for me, but your results may vary. I actually had some test cases where the results were slower with PAGE.SETUP.
Although the timing results with these two macros are closer, you have to keep in mind the “fast” VBA PAGE.SETUP method wastes time by selecting the sheet you want to edit, whereas the slow VBA .PageSetup method doesn’t have to activate each new sheet before adjusting the properties. Recognizing this fact, it’s likely the actual page setup portion of the “fast” code is a bit faster, even with the the Application events above disabled.
Either way, this tutorial shows you should at least disable ScreenUpdating, EnableEvents and PrintCommunications before adjusting your page setup properties. The PrintCommunications property alone can easily cut your macro execution time in half. By playing with alternative methods, we were able to speed up the VBA PageSetup execution time from 37.29 seconds down to 4.87 seconds. That’s still not very fast, but it’s a big improvement!
I hope you enjoyed this little experiment with VBA page setup speeds. When you’re ready to take your VBA to the next level, subscribe using the form below.