Macros for booklet printing

Article contributed by Richard Keijzer and Dave Rado

Note that Word 2002 (part of Office XP), has the built-in ability to print booklets with automatically numbered pages.

Limitation: The macro-based method doesn't allow for page numbering with multiple restarts. Using the method described in the article: Booklet printing, you can (for instance) have front matter paginated with lowercase roman numerals followed by the document body paginated with Arabic numerals followed by appendixes paginated separately with A-1, A-2, B-1, B-2, etc., and the method still works, whereas the following macros won't allow you to do this (because of a limitation of Word's Print dialog).

On the other hand, the macros save time, and also allow you to duplex a booklet in two passes to the printer, whereas the manual method requires four. (Only an issue if you want to print it in-house).

Word 2000

Word 2000 allows you to print 2 pages per sheet. Before starting on your booklet, you need to:

1.

Select File + Page + Setup

2.

On the Margins tab, select "2 pages per sheet"

3.

On the Paper Size tab, set the orientation to landscape, and the paper size to double the size of your booklet pages (e.g. set it to A4 for A5 booklets, etc.).

4.

Set up the other margins as you want them, and close the dialog. The page will now appear on screen at half the size of the sheet (for instance, if you specified A4, 2 pages per sheet, you will see an A5 page on screen; or if you chose US Letter, you will see a 4.25" x 5.5" half-page – equivalent to Statement paper – on screen).

5.

Set up the Headers and Footers as appropriate. If you don't want the page number to print on the back page, you will need to insert the following field construction for your page number in the Header or Footer. To insert the field braces {}, press Ctrl+F9 (don't type them):

{ = IF { PAGE }  <  { NUMPAGES { PAGE } "" }

If you don't want the page number to print on the front page select Different first page on the Layout tab of the File + Page Setup dialog.

For more on page number fields see How to control the page numbering in a Word document.

For a warning about using the NUMPAGES field see: Page X of Y displays or prints as Page 1 of 1, Page 2 of 2 etc.

6.

Save this as a template (select File + Save As, and where it says Files of Type, select Document Template).

7.

Insert the following macros into your template. Assign the Booklet2000DuplexPrinter() and/or the Booklet2000SimplexPrinter() macro to toolbar buttons. Or alternatively, you could rename one of these macros to FilePrintDefault(), which would make it automatically intercept the Standard toolbar's print button when that template is in use.

7.

Create a new document based on your template and you're ready to go.

The Booklet2000DuplexPrinter() macro puts the page numbers into a single string, in the required order, and prints using that string. If the number of pages in the document is not a multiple of 4, it first inserts the required number of temporary page breaks so that it is, then deletes them after printing.

If the pages to print string is longer than 256 characters (which it will be if the booklet is more than 88 pages long), it chops the string into chunks and prints the chunks separately (making sure that number of pages listed in each chunk is a multiple of 4).

The Booklet2000SimplexPrinter() macro is very similar, but it prints the odd sheets in one pass (that is, pages 1 and 20 on one sheet, then 3 and 18, and so on); then it displays a message box so you can turn the paper in the printer over, before printing the even sheets on the reverse side of the paper (pages 2 and 19, then 4 and 17 and so on).

Option Explicit

Dim PageNum As Long, NumPages As Long, XtraPages As Long, MyRange As Range, _
    PagestoPrint As String, OddPagesToPrint As String, EvenPagesToPrint As String

Sub Booklet2000DuplexPrinter()
    NumCopies = Inputbox "
    NumPages = Selection.Information(wdNumberOfPagesInDocument)
    'If number of pages not a multiple of 4, add manual page breaks at the end
    If NumPages Mod 4 > 0 Then Call AddExtraPages
    'Put the pages to be printed into a single string, in the correct order
    Call GetPagesToPrintDuplex
    'Print
    Call PrintPages(PagestoPrint)
    'If any page breaks were added, delete them again
    If XtraPages > 0 Then Call DeleteExtraPages
    Call ClearVariables
End Sub


Sub Booklet2000SimplexPrinter()
    NumPages = Selection.Information(wdNumberOfPagesInDocument)
    'If number of pages not a multiple of 4, add manual page breaks at the end
    If NumPages Mod 4 > 0 Then Call AddExtraPages
    'Put the pages to be printed into a single string, in the correct order
    Call GetPagesToPrintSimplex
    Call PrintPages(OddPagesToPrint)
    MsgBox "Please turn the paper over and press OK when you'r ready to print"
    Call PrintPages(EvenPagesToPrint)
    'If any page breaks were added, delete them again
    If XtraPages > 0 Then Call DeleteExtraPages
    Call ClearVariables
End Sub


Sub AddExtraPages()
    'Adds page breaks to make the number of pages a multiple of 4
    XtraPages = 4 - NumPages Mod 4
    For PageNum = 1 To XtraPages
        Set MyRange = ActiveDocument.Range
        MyRange.Collapse wdCollapseEnd
        MyRange.InsertBreak Type:=wdPageBreak
    Next PageNum
    NumPages = Selection.Information(wdNumberOfPagesInDocument)
End Sub


Sub GetPagesToPrintDuplex()
    For PageNum = 1 To NumPages / 2
        If Len(PagestoPrint) > 0 Then PagestoPrint = PagestoPrint & ","
        If PageNum Mod 2 = 1 Then
            'odd page
            PagestoPrint = PagestoPrint & (NumPages + 1 - PageNum) & "," & PageNum
        Else
            ' even page
            PagestoPrint = PagestoPrint & PageNum & "," & (NumPages + 1 - PageNum)
        End If
    Next PageNum
End Sub


Sub GetPagesToPrintSimplex()
    For PageNum = 1 To NumPages / 2
        If PageNum Mod 2 = 1 Then
            'odd page
            If Len(OddPagesToPrint) > 0 Then OddPagesToPrint = _
                    OddPagesToPrint & ","
            OddPagesToPrint = OddPagesToPrint & (NumPages + 1 - PageNum) & _
                      "," & PageNum
        Else
            'even page
     
      If Len(EvenPagesToPrint) > 0 Then EvenPagesToPrint = _
                    EvenPagesToPrint & ","
            EvenPagesToPrint = EvenPagesToPrint & PageNum & "," & _
                    (NumPages + 1 - PageNum)
        End If
    Next PageNum
End Sub


Sub PrintPages(PagestoPrint As String)
Dim Pos As Long, PagesToPrintChunk As String, TestPages As Variant

'The 'pages to print' string can only be a maximum of 256 characters long
'(Word limitation). If > 256 characters, prints it in smaller chunks
'(otherwise just prints it)
Do While Len(PagestoPrint) > 256
    PagesToPrintChunk = Left$(PagestoPrint, 256)
    'Strip the chunk string so it ends before the final comma
    Pos = InStrRev(PagesToPrintChunk, ",")
    PagesToPrintChunk = Left$(PagesToPrintChunk, Pos - 1)
    'find out how many pages are now listed in the string (needs to be a multiple of 4)
    TestPages = Split(PagesToPrintChunk, ",")
    NumPages = UBound(TestPages) + 1
    'If not a multipke of 4, removes some page numbers so that it is
     If NumPages Mod 4 > 0 Then
        For PageNum = 1 To NumPages Mod 4
            Pos = InStrRev(PagesToPrintChunk, ",")
            PagesToPrintChunk = Left$(PagesToPrintChunk, Pos - 1)
        Next
     End If
     Application.PrintOut Pages:=PagesToPrintChunk, _
    Range:=wdPrintRangeOfPages, Background:=False
     'Strip main string so it starts just after the same comma
     PagestoPrint = Mid$(PagestoPrint, Pos + 1)
Loop

Application.PrintOut Pages:=PagestoPrint, _
Range:=wdPrintRangeOfPages, Background:=False

End Sub


Sub DeleteExtraPages()
    'If manual page breaks were added earlier, deletes them again
    Set MyRange = ActiveDocument.Range
    MyRange.Collapse wdCollapseEnd
    MyRange.MoveStart unit:=wdCharacter, Count:=-(XtraPages + 1)
    MyRange.Delete
End Sub


Sub ClearVariables()
    Set MyRange = Nothing
    PageNum = 0
    NumPages = 0
    XtraPages = 0
    PagestoPrint = vbNullString
    OddPagesToPrint = vbNullString
    EvenPagesToPrint = vbNullString
End Sub


  

If you want to print multiple copies

Wherever the macro says:

Application.PrintOut Pages:=PagestoPrint, _
        Range:=wdPrintRangeOfPages, Background:=False

... modify it to say:

Application.PrintOut Pages:=PagestoPrint, _
        Range:=wdPrintRangeOfPages, Background:=False, Copies:=2, Collate:=False

Where 2 is the number of copies you want to print.

Collate = False means you will have to collate it manually; if you would rather not have to do this, you can change to it say Collate:=True; but that would dramatically increase print times (and may cause the printer to seize up, if it's a big job). If Collate is switched on in Word, the printer has to process every copy of every page from scratch; whereas otherwise it only has to process the first copy and can print the rest at high speed. High-end printers can do the collating at their end, and if you have such a printer, that gives you the best of both worlds (let the printer, rather than Word, do the collating).

If you would like the macro to ask you how many copies you want, each time you run it, you could add the following code:

At the very top, where it says Dim, add a NumCopies variable, as follows:

Dim PageNum As Long, NumPages As Long, XtraPages As Long, _
        MyRange As Range, PagestoPrint As String, OddPagesToPrint As String, _
        EvenPagesToPrint As String, NumCopies As Long

At the start of the Booklet2000DuplexPrinter() and/or the Booklet2000SimplexPrinter() macros, insert the following:

NumCopies = InputBox("How many copies would you like to print?", _
        "Type number of copies", "1")

and wherever the macro says:

Application.PrintOut Pages:=PagestoPrint, _
        Range:=wdPrintRangeOfPages, Background:=False

Modify it to say:

Application.PrintOut Pages:=PagestoPrint, _
        Range:=wdPrintRangeOfPages, Background:=False, _
        Copies:=NumCopies, Collate:=False