fx Practical VBA Projects

Bulk PDF export loop

⏱ 15 min

What you'll learn

  • One line: sheet to PDF
  • Simple loop: every sheet as its own PDF
  • The real job: one PDF per customer from a template

Concept

1. One line: sheet to PDF

Worksheets("Invoice").ExportAsFixedFormat _
    Type:=xlTypePDF, _
    Filename:=ThisWorkbook.Path & Application.PathSeparator & "Invoice.pdf", _
    Quality:=xlQualityStandard, _
    IgnorePrintAreas:=False, _
    OpenAfterPublish:=False

The PDF follows the sheet's Page Layout settings: print area, orientation, margins, Fit to 1 page wide. Set those once on the template, and every PDF looks right.

2. Simple loop: every sheet as its own PDF

Sub ExportEverySheet()
    Dim sh As Worksheet, folder As String
    folder = ThisWorkbook.Path & Application.PathSeparator
    For Each sh In ThisWorkbook.Worksheets
        If sh.Visible = xlSheetVisible Then
            sh.ExportAsFixedFormat Type:=xlTypePDF, _
                Filename:=folder & sh.Name & ".pdf"
        End If
    Next sh
End Sub

3. The real job: one PDF per customer from a template

Sheet "Customers" (list):

A B C
1 CustomerID Name Email
2 C001 Rahul Sharma rahul@example.com
3 C002 Neha Gupta neha@example.com

Sheet "Statement" (template): cell B3 holds the CustomerID. Everything else — name, address, list of invoices, total — is pulled with XLOOKUP/SUMIFS/FILTER formulas based on B3. Change B3, and the whole statement changes.

The macro just changes B3, recalculates, and exports — again and again.

Option Explicit

Sub ExportStatements()
    Dim wsList As Worksheet, wsTpl As Worksheet
    Dim lastRow As Long, i As Long, count As Long
    Dim folder As String, custID As String, custName As String
    Dim calcMode As XlCalculation

    On Error GoTo ErrHandler
    Set wsList = ThisWorkbook.Worksheets("Customers")
    Set wsTpl = ThisWorkbook.Worksheets("Statement")
    lastRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row

    folder = ThisWorkbook.Path & Application.PathSeparator & "PDF_" & Format(Date, "yyyy-mm")
    If Dir(folder, vbDirectory) = "" Then MkDir folder

    calcMode = Application.Calculation
    Application.ScreenUpdating = False

    For i = 2 To lastRow
        custID = Trim(CStr(wsList.Cells(i, "A").Value))
        custName = Trim(CStr(wsList.Cells(i, "B").Value))
        If Len(custID) > 0 Then
            wsTpl.Range("B3").Value = custID
            Application.Calculate                    ' make sure formulas update

            wsTpl.ExportAsFixedFormat Type:=xlTypePDF, _
                Filename:=folder & Application.PathSeparator & custID & "_" & custName & ".pdf", _
                Quality:=xlQualityStandard, IgnorePrintAreas:=False
            count = count + 1
        End If
    Next i

    MsgBox count & " PDFs saved in:" & vbCrLf & folder, vbInformation

CleanExit:
    Application.Calculation = calcMode
    Application.ScreenUpdating = True
    Exit Sub

ErrHandler:
    MsgBox "Stopped at row " & i & ": " & Err.Description, vbExclamation
    Resume CleanExit
End Sub

File names like C001_Rahul Sharma.pdf make them easy to find and to attach in the next lesson.

4. Skip customers with nothing to send

If the template shows a total in, say, F30, skip zero-balance customers:

If wsTpl.Range("F30").Value <> 0 Then
    ' export
End If

5. Several sheets in one PDF

Select them as a group and export the active selection:

ThisWorkbook.Worksheets(Array("Summary", "Details")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=folder & "\Report.pdf"
Worksheets("Summary").Select     ' ungroup afterwards

This is one of the few places where .Select is genuinely needed.

6. Page setup checklist for good PDFs

On the template: Page Layout → Print Area set; Orientation chosen; Width: 1 page; Print Titles if the table runs over pages; header/footer with page numbers. Check File → Print preview once before running the loop.

Common mistakes

No print area, so the PDF includes empty pages or extra columns. Forgetting Application.Calculate when calculation is manual (every PDF shows the first customer). Invalid characters in names (reuse SafeName from Lesson 1). Leaving sheets grouped after a multi-sheet export.

Exercises

mediumBuild a Statement template with XLOOKUP for name and a FILTER/SUMIFS block for invoices, driven by B3. Add 5 customers, run ExportStatements, and verify each PDF shows the right customer. Then add the zero-balance skip.
Drive Statement with customer ID in B3, recalculate before exporting, and use a fixed print area. Customers has five IDs with balances 1200, 0, 800, 0, 500: skip zero balances to produce three PDFs. Compare each PDF ID and balance with Invoices; a previous customer must never remain in the next PDF.

Quiz

Which method creates the PDF?
ExportAsFixedFormat with Type:=xlTypePDF
What controls what part of the sheet goes into the PDF?
Page Layout settings — print area, orientation, scaling
Why call Application.Calculate in the loop?
So the template updates for each customer
Bulk PDF export loop · Automation | ExcelWalaa