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
FasterPageSetup
routine. You’ll also notice I didn’t use all of the available properties in my
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"
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
FasterPageSetup_Loop
macro uses the old Excel 4.0 PAGE.SETUP function and finished in
8.91 seconds
. This still isn’t fast, but it’s much faster than the
SlowPageSetup_Loop
which took a whopping
37.29 seconds
.
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.
Before we go, I want to let you know we designed a suite of
VBA Cheat Sheets
to make it easier for you to write better macros. We included over 200 tips and 140 macro examples so they have everything you need to know to become a better VBA programmer.
Get your cheat sheets
Enable Excel Developer Tab
Open VBA Editor in Excel
Writing a macro
Using the Macro Recorder
Commenting in VBA
Using the VBA Range object
How to select cells with VBA
Controlling different workbooks
Macros to control worksheets
VBA Variable Types
How to Declare Variables
Variable Scope and Lifetime
Understanding Option Explicit
Create an Excel Splash Screen for your Spreadsheet
The Complete Guide to Excel VBA Form Control Checkboxes
Make Dot Grid Paper with Word Document
Beautiful VBA Progress Bar with Step by Step Instructions
Show System Tray Notification Balloon when your Macro is done
FormulaR1C1 Makes Relative References in VBA Easy
Use VBA Range.Find to Search and Retrieve Data
VBA AdvancedFilter with Multiple Criteria
VBA Sgn Function to Check for Positive or Negative Numbers