VBAでシートをPDF出力・自動保存する方法|ExportAsFixedFormatで請求書・報告書を自動化

スポンサーリンク

毎月、請求書や月次報告書を1枚ずつPDFに保存していませんか。「ファイル」→「エクスポート」→「PDFの作成」→保存先選択→ファイル名入力。1枚なら数十秒ですが、取引先10社・部署5部門となると、これだけで30分が消えていきます。

この作業はVBAの ExportAsFixedFormat メソッドで丸ごと自動化できます。ボタン1つで保存先フォルダの作成、日付入りファイル名の生成、印刷範囲の制御まで自動でこなせます。

この記事では、ExportAsFixedFormat の基本構文から実用サンプルまでを順に解説します。具体的には、保存先フォルダの自動作成、ファイル名への日付付与、複数シート一括PDF化、印刷範囲の指定です。請求書や月次報告書の自動保存テンプレートも掲載しているので、明日からそのまま現場で使えます。

VBAでPDF出力するExportAsFixedFormatとは?

ExportAsFixedFormat は、ExcelのワークシートやブックをPDFまたはXPS形式で書き出すVBAメソッドです。Excel 2007以降のすべてのバージョンで標準搭載されており、追加のアドインやライブラリは不要です。

「ファイル」→「エクスポート」→「PDFの作成」と同じ動作を、コードから自動実行できると考えてください。手動操作とまったく同じレイアウト・印刷品質でPDFを生成できます。

ExportAsFixedFormatでできること

このメソッド1つで、PDF保存に関するほとんどの操作を自動化できます。

  • 単一シートをPDF化して任意フォルダへ保存
  • ブック全体(複数シート)を1つのPDFにまとめて保存
  • 印刷範囲(PrintArea)で指定した部分だけをPDF化
  • ファイル名にシート名・日付・取引先名などを自動で組み込む
  • 保存先フォルダを動的に作成(年月別・部署別など)
  • パスワード設定、ページ範囲指定、画質指定

手動でPDF保存する場合と違って、保存先・ファイル名・対象範囲がコードに固定化されます。そのため、毎回同じ品質でアウトプットでき、担当者が変わってもファイル名の表記ゆれが発生しません。

手動PDF保存との違い

手動とVBAでは、所要時間と再現性が決定的に違います。

項目手動操作VBA(ExportAsFixedFormat)
1ファイル保存時間30秒〜1分0.5秒未満
10ファイル保存時間5〜10分約3秒
ファイル名の統一性担当者依存で揺れるコードで完全統一
保存先フォルダ作成手動でmkdirコードで自動作成
印刷範囲指定毎回設定コードで固定

10ファイル以上のPDF出力を月次で行う作業なら、初回1時間の自動化で年間60時間以上が浮きます。

ExportAsFixedFormatの基本構文

ExportAsFixedFormat メソッドは、ワークシートやブックなど、PDF化したいオブジェクトに対して呼び出します。

構文の基本形

最もシンプルな書き方は次のとおりです。

Worksheets("Sheet1").ExportAsFixedFormat _
    Type:=xlTypePDF, _
    Filename:="C:PDFsample.pdf"

Type:=xlTypePDF でPDF形式を指定し、Filename で保存先のフルパスを渡します。たったこれだけで、Sheet1がPDFとして指定パスに保存されます。

主要な引数一覧

ExportAsFixedFormat メソッドにはオプション引数が複数あります。実務でよく使うのは次の6つです。

引数名役割主な値
Type出力形式xlTypePDF / xlTypeXPS
Filename保存先フルパス“C:PDFsample.pdf”
Quality画質xlQualityStandard / xlQualityMinimum
IncludeDocPropertiesプロパティ埋込True / False
IgnorePrintAreas印刷範囲を無視True / False(既定False)
OpenAfterPublish保存後にPDFを開くTrue / False(既定False)

IgnorePrintAreas は重要です。既定値の False だと印刷範囲(PrintArea)の設定が反映されます。True を指定するとシート全体がPDF化されます。

VBE(Visual Basic Editor)の起動とコードの準備

VBAコードを実行するには、まずVBEを開いて標準モジュールにコードを貼り付けます。

  1. Excelを開いた状態で Alt + F11 キーを押す(VBEが起動)
  2. リボン経由の場合は「開発」タブ→「Visual Basic」をクリック
  3. 「開発」タブが表示されていない場合は、「ファイル」→「オプション」→「リボンのユーザー設定」で「開発」にチェック
  4. VBE画面で「挿入」→「標準モジュール」をクリック
  5. 開いたコードウィンドウに本記事のサンプルを貼り付けて F5 で実行

NOTE

ファイルは「Excel マクロ有効ブック(.xlsm)」または「Excel バイナリブック(.xlsb)」で保存してください。通常の .xlsx ではマクロが保存されません。

VBAで単一シートをPDF出力する基本コード

まずは1枚のシートをPDF化する最小構成のコードから始めます。

Sub Sample_ExportSinglePDF()
    '--- 保存先パスを指定 ---
    Dim sPath As String
    sPath = "C:PDFreport.pdf"

    '--- アクティブシートをPDF出力 ---
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sPath, _
        Quality:=xlQualityStandard, _
        OpenAfterPublish:=False

    MsgBox "PDF出力完了: " & sPath
End Sub

このコードを実行すると、現在表示中のシートが C:PDFreport.pdf として保存されます。OpenAfterPublish:=False にしておけば、PDFが自動で開くことがなく、バッチ処理向きの動作になります。

シート名で出力対象を指定する

特定のシートだけをPDF化したい場合は、ActiveSheet の代わりに Worksheets("シート名") で対象を明示します。

Sub Sample_ExportNamedSheet()
    '--- シート名で出力対象を指定 ---
    Dim sBefore As String
    Dim sAfter As String
    sBefore = "請求書ひな形"
    sAfter = "C:PDF請求書.pdf"

    Worksheets(sBefore).ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sAfter

    MsgBox "出力: " & sBefore & " → " & sAfter
End Sub

Worksheets("請求書ひな形") のようにシートを明示すると、どのシートがアクティブでも常に同じシートをPDF化できます。複数シートを処理するブックでは、必ずこの形式で対象を指定してください。

ファイル名に日付を自動付与する

毎日・毎月の繰り返し処理では、ファイル名に日付を入れて履歴を残すのが定石です。同名ファイルの上書きを防げます。

Format関数で日付を文字列に変換する

Format 関数は、日付や数値を任意の書式の文字列に変換するVBA組み込み関数です。

Sub Sample_DatedFilename()
    '--- 日付付きファイル名を生成 ---
    Dim sToday As String
    Dim sPath As String
    sToday = Format(Date, "yyyymmdd")
    sPath = "C:PDF日報_" & sToday & ".pdf"

    '--- アクティブシートを日付付きファイル名で出力 ---
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sPath

    MsgBox "保存完了: " & sPath
End Sub

Format(Date, "yyyymmdd") は、今日の日付を 20260509 のような8桁文字列に変換します。これをファイル名に組み込むと、日報_20260509.pdf というファイルが生成されます。

日付フォーマットの主な書式

Format 関数の書式指定は、用途によって使い分けます。

書式指定出力例用途
yyyymmdd20260509日次ファイル(短縮)
yyyy-mm-dd2026-05-09日次ファイル(区切り付き)
yyyymm202605月次ファイル
yyyy年m月2026年5月報告書名向け
yyyymmdd_hhmmss20260509_143052同日複数回保存(時刻付き)

同じ日に複数回PDFを出力する可能性があるなら、hhmmss(時刻)まで含めるとファイルがぶつかりません。Format(Now, "yyyymmdd_hhmmss") のように Now 関数を使います。

TIP

ファイル名にシート名を含めたい場合は、ActiveSheet.Name & "_" & sToday & ".pdf" のように連結します。シートを追加するたびに自動で命名されるため、保守性が高くなります。

保存先フォルダを自動作成する

「保存先フォルダが存在しないとエラーになる」のはVBA初心者がつまずきやすいポイントです。フォルダを動的に作成する処理を入れておくと、毎月新しいフォルダが必要になっても安全に運用できます。

MkDir関数でフォルダを作成する

VBAの MkDir 関数は、指定パスにフォルダを作成します。ただし、すでに存在するフォルダに MkDir を実行するとエラーになります。Dir 関数で存在チェックしてから作成するのが定石です。

Sub Sample_CreateFolderAndExport()
    '--- 保存先フォルダのパスを生成 ---
    Dim sFolder As String
    Dim sFile As String
    Dim sToday As String
    sToday = Format(Date, "yyyymm")
    sFolder = "C:PDF" & sToday
    sFile = sFolder & "日報_" & Format(Date, "yyyymmdd") & ".pdf"

    '--- フォルダが存在しなければ作成 ---
    If Dir(sFolder, vbDirectory) = "" Then
        MkDir sFolder
    End If

    '--- PDFを出力 ---
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sFile

    MsgBox "保存完了: " & sFile
End Sub

このコードでは、C:PDF202605 という年月別フォルダを自動作成し、その中に日付付きPDFを保存します。月が変わるたびに自動で新しいフォルダが作られるため、年間ファイル管理がスッキリします。

階層フォルダを一気に作成するMkDirRecursive

MkDir は1階層しか作れません。C:PDF20265 のような多階層をまとめて作りたい場合は、自作関数を1つ用意しておくと便利です。

Sub MkDirRecursive(ByVal sPath As String)
    '--- 階層フォルダを再帰的に作成 ---
    Dim sParent As String

    If Dir(sPath, vbDirectory) <> "" Then Exit Sub

    sParent = Left(sPath, InStrRev(sPath, "") - 1)
    If Len(sParent) > 0 Then
        MkDirRecursive sParent
    End If
    MkDir sPath
End Sub

Sub Sample_DeepFolder()
    '--- 階層フォルダ + PDF出力 ---
    Dim sFolder As String
    Dim sFile As String
    sFolder = "C:PDF" & Format(Date, "yyyy") & "" & Format(Date, "mm")
    sFile = sFolder & "日報.pdf"

    MkDirRecursive sFolder

    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sFile
End Sub

MkDirRecursive を1度書いておくと、年/月/日の3階層構造でも安心してフォルダを生成できます。InStrRev で末尾の 位置を特定し、親フォルダから再帰的に作成する仕組みです。

複数シートを一括PDF出力する

請求書を取引先ごとに、月次報告を部署ごとに分けて保存する場合は、ループで複数シートを順番にPDF化します。

For Eachで全シートを個別PDF化する

ブック内のすべてのシートを、シート名でPDFファイルに分けて保存するコードです。

Sub Sample_ExportAllSheetsSeparately()
    '--- 全シートを個別PDFで出力 ---
    Dim ws As Worksheet
    Dim sFolder As String
    Dim sFile As String
    Dim sToday As String
    sToday = Format(Date, "yyyymmdd")
    sFolder = "C:PDF" & sToday

    '--- フォルダ作成 ---
    If Dir(sFolder, vbDirectory) = "" Then
        MkDir sFolder
    End If

    '--- 全シートをループ ---
    For Each ws In ThisWorkbook.Worksheets
        sFile = sFolder & "" & ws.Name & ".pdf"
        ws.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=sFile
    Next ws

    MsgBox "全シートのPDF出力完了"
End Sub

For Each ws In ThisWorkbook.Worksheets で、ブック内のすべてのワークシートを順に処理します。10シートあれば、10ファイルのPDFが一気に作られます。

For ループの基本構文はExcel VBAでFor文を使う方法を参照してください。コレクション処理に最適化された For EachExcel VBAでFor Each Nextを使う方法で解説しています。

特定シートだけを1つのPDFにまとめる

複数シートを「1つのPDFファイル」としてまとめて出力するパターンもよく使います。役員報告用の資料一式などです。

Sub Sample_ExportSelectedSheetsAsOnePDF()
    '--- 指定シートを配列で選択して1つのPDFに ---
    Dim sFile As String
    sFile = "C:PDF月次報告_" & Format(Date, "yyyymm") & ".pdf"

    '--- 複数シートを選択 ---
    ThisWorkbook.Sheets(Array("売上", "コスト", "利益")).Select

    '--- 選択中のシートをまとめてPDF化 ---
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=sFile

    '--- 選択を解除(先頭シートを単独選択) ---
    ThisWorkbook.Sheets(1).Select

    MsgBox "結合PDF出力完了: " & sFile
End Sub

Sheets(Array("売上", "コスト", "利益")).Select で複数シートを同時選択した状態にしておき、ActiveSheet.ExportAsFixedFormat を呼ぶと、選択中のシートがすべて1つのPDFにまとめられます。

NOTE

ブック全体をまとめたい場合は ThisWorkbook.ExportAsFixedFormat を使います。ActiveSheet ではなくブック自体に対してメソッドを呼ぶと、すべてのシートが1ファイルにまとまります。

シート名でフィルタしてPDF化する

「月次」で始まるシートだけPDF化したい、といった条件付き出力も可能です。

Sub Sample_ExportFilteredSheets()
    '--- 「月次」で始まるシートだけ個別PDFに ---
    Dim ws As Worksheet
    Dim sFolder As String
    sFolder = "C:PDF月次レポート_" & Format(Date, "yyyymm")

    If Dir(sFolder, vbDirectory) = "" Then
        MkDir sFolder
    End If

    For Each ws In ThisWorkbook.Worksheets
        '--- シート名先頭が「月次」のものだけ処理 ---
        If Left(ws.Name, 2) = "月次" Then
            ws.ExportAsFixedFormat _
                Type:=xlTypePDF, _
                Filename:=sFolder & "" & ws.Name & ".pdf"
        End If
    Next ws
End Sub

If Left(ws.Name, 2) = "月次" Then の条件で、シート名の先頭2文字が「月次」のシートだけをPDF化します。命名規則を活用すると、ブックを開きっぱなしのまま対象だけ抽出して出力できます。

印刷範囲を指定してPDF化する

シート全体ではなく、特定のセル範囲だけをPDFにしたい場面もあります。請求書テンプレートの「明細部分のみ」や、ダッシュボードの「グラフ部分のみ」など、用途は多岐にわたります。

PrintAreaで印刷範囲を設定する

ワークシートの PageSetup.PrintArea プロパティに範囲文字列を代入すると、その範囲だけが印刷対象になります。

Sub Sample_ExportWithPrintArea()
    '--- 印刷範囲を設定してPDF化 ---
    Dim ws As Worksheet
    Set ws = Worksheets("請求書")

    '--- 印刷範囲を A1:F30 に固定 ---
    ws.PageSetup.PrintArea = "A1:F30"

    '--- 印刷範囲だけをPDF出力 ---
    ws.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:="C:PDF請求書.pdf", _
        IgnorePrintAreas:=False
End Sub

IgnorePrintAreas:=False(既定値)にしておくと、PrintArea の設定が反映されます。A1:F30 の範囲外にあるメモやコメント欄はPDFに含まれなくなります。

動的に印刷範囲を決める(最終行まで)

データが日々増えるシートでは、最終行まで自動で印刷範囲にしたいケースがあります。Cells(Rows.Count, 1).End(xlUp).Row で最終行を取得します。

Sub Sample_DynamicPrintArea()
    '--- 動的に印刷範囲を決めてPDF化 ---
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim sArea As String

    Set ws = Worksheets("売上一覧")
    lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
    sArea = "A1:F" & lastRow

    '--- 印刷範囲を動的に設定 ---
    ws.PageSetup.PrintArea = sArea

    ws.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:="C:PDF売上一覧_" & Format(Date, "yyyymmdd") & ".pdf"

    MsgBox "印刷範囲 " & sArea & " をPDF化しました"
End Sub

lastRow の取得方法はExcel VBAでLastRowを取得する方法で詳しく解説しています。データが10行のときも1000行のときも、自動でフィットした範囲のPDFが生成できます。

印刷範囲を無視してシート全体をPDF化する

逆に「シート全体を必ずPDF化したい」場合は、IgnorePrintAreas:=True を指定します。

Sub Sample_IgnorePrintArea()
    '--- 印刷範囲設定を無視してシート全体をPDF化 ---
    ActiveSheet.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:="C:PDF全体.pdf", _
        IgnorePrintAreas:=True
End Sub

既存ブックに古い PrintArea が残っていると、意図せず一部しかPDFにならないトラブルが起きます。事前に True で全体出力するか、PrintArea = "" でリセットするとトラブルを防げます。

実用サンプル: 請求書を取引先別にPDF自動保存

ここまで学んだ要素を組み合わせて、実務で使える請求書PDF自動保存マクロを作ります。

想定シナリオ

「取引先一覧」シートにA列:取引先名、B列:請求金額が入力されています。マクロを実行すると、「請求書ひな形」シートに各取引先の情報を流し込み、取引先名のPDFを C:請求書YYYYMM フォルダに自動保存します。

完成コード

Sub ExportInvoicesPerClient()
    '--- 請求書を取引先別にPDF自動保存 ---
    Dim wsList As Worksheet
    Dim wsTpl As Worksheet
    Dim sFolder As String
    Dim sFile As String
    Dim sClient As String
    Dim sAmount As String
    Dim lastRow As Long
    Dim i As Long

    Set wsList = Worksheets("取引先一覧")
    Set wsTpl = Worksheets("請求書ひな形")

    '--- 保存先フォルダを年月単位で作成 ---
    sFolder = "C:請求書" & Format(Date, "yyyymm")
    If Dir(sFolder, vbDirectory) = "" Then
        MkDir sFolder
    End If

    '--- 取引先一覧の最終行を取得 ---
    lastRow = wsList.Cells(Rows.Count, 1).End(xlUp).Row

    '--- 取引先ごとにループ ---
    For i = 2 To lastRow
        sClient = wsList.Cells(i, 1).Value
        sAmount = wsList.Cells(i, 2).Value

        '--- ひな形に情報を転記 ---
        wsTpl.Range("B2").Value = sClient
        wsTpl.Range("B5").Value = sAmount
        wsTpl.Range("B6").Value = Format(Date, "yyyy年m月d日")

        '--- 取引先名でPDF保存 ---
        sFile = sFolder & "" & sClient & "_請求書_" & _
                Format(Date, "yyyymm") & ".pdf"

        wsTpl.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=sFile, _
            IgnorePrintAreas:=False
    Next i

    MsgBox lastRow - 1 & "社分の請求書PDFを保存しました" & vbCrLf & sFolder
End Sub

このマクロを月初に1回実行するだけで、取引先10社分の請求書が C:請求書202605 フォルダ内に整理されて保存されます。手作業で30分かかっていた作業が、ボタン1つの数秒で終わります。

TIP

請求書テンプレートに通し番号を入れる場合は、wsTpl.Range("B1").Value = "INV-" & Format(Date, "yyyymm") & "-" & Format(i - 1, "000") のように連番も自動生成できます。

よくあるエラーと対処法

ExportAsFixedFormat を使うときに遭遇しやすいエラーを5つ紹介します。

実行時エラー’1004′: ドキュメントが保存されませんでした

最頻出のエラーです。原因は主に3つあります。

原因対処
保存先フォルダが存在しないDir + MkDir でフォルダ存在チェック・作成
同名PDFが他アプリで開かれている該当PDFを閉じてから再実行
保存先パスに使用不可文字(` / : * ? ” < >`)が含まれるファイル名から該当文字を除去

特に取引先名をファイル名に使う場合、株式会社○○/△△ のように / が含まれていると保存に失敗します。事前に Replace 関数でクリーニングしておくのが安全です。

sClient = Replace(sClient, "/", "_")
sClient = Replace(sClient, "", "_")

PDFが空白・1ページ目しか出ない

シート内のデータ範囲は広いのに、PDFが1ページしか生成されない場合は PrintArea が古い状態で残っていることが多いです。

'--- 印刷範囲をリセットしてから出力 ---
ws.PageSetup.PrintArea = ""
ws.ExportAsFixedFormat _
    Type:=xlTypePDF, _
    Filename:="C:PDF全体.pdf", _
    IgnorePrintAreas:=True

PrintArea = "" で範囲をクリアし、IgnorePrintAreas:=True をセットで指定するとシート全体がPDF化されます。

文字が小さすぎてPDFが読めない

シート全体を1ページに収めようとすると、データ量が多い場合に文字が極端に小さくなります。PageSetup.Zoom プロパティと FitToPagesWide / FitToPagesTall を使って調整します。

With ws.PageSetup
    .Zoom = False
    .FitToPagesWide = 1   '横は1ページに収める
    .FitToPagesTall = False  '縦は自動(複数ページ可)
End With

横幅は1ページに収めつつ、縦は必要な分だけページを増やす設定です。長いリストでも文字が読める品質を保てます。

実行時エラー’9′: インデックスが有効範囲にありません

Worksheets("シート名") で指定したシートが存在しないときに発生します。シート名のタイポ・全角半角の混在・不要スペースが主な原因です。

'--- シート存在チェックを入れる ---
Dim ws As Worksheet
On Error Resume Next
Set ws = Worksheets("請求書ひな形")
On Error GoTo 0

If ws Is Nothing Then
    MsgBox "シート「請求書ひな形」が見つかりません"
    Exit Sub
End If

VBAのエラー処理パターン全般はVBAのエラーハンドリング完全ガイドで詳しく解説しています。

PDFの画質を変えたい

既定の xlQualityStandard で問題が出ることはまずありませんが、ファイルサイズを抑えたい場合は xlQualityMinimum を指定できます。

ActiveSheet.ExportAsFixedFormat _
    Type:=xlTypePDF, _
    Filename:="C:PDF軽量版.pdf", _
    Quality:=xlQualityMinimum

xlQualityMinimum だと画像が圧縮され、ファイルサイズが概ね半分程度になります。メール添付向けの軽量PDFを作りたい場合に便利です。

ExportAsFixedFormatと他の保存方法の使い分け

ExcelからPDFを生成する方法は ExportAsFixedFormat だけではありません。用途別の使い分けを整理しておきます。

方法特徴推奨用途
ExportAsFixedFormat高速・高品質・引数が豊富請求書・報告書の自動化(標準)
PrintOut(PrintToFile)印刷ダイアログ経由物理プリンタでの印刷自動化
SaveAs(xlPDF不可)PDF不可xlsx/xlsm保存用
名前を付けて保存 ダイアログ手動操作1回限りの保存

VBAでPDF出力するなら、ExportAsFixedFormat が標準解と覚えておけば十分です。PrintOut はネットワークプリンタ経由の物理印刷が必要なケースだけで使います。

まとめ

VBAの ExportAsFixedFormat メソッドを使うと、ExcelシートのPDF出力作業を完全に自動化できます。

  • 基本構文: 対象.ExportAsFixedFormat Type:=xlTypePDF, Filename:="パス"
  • 日付付きファイル名: Format(Date, "yyyymmdd") でファイル名に日付を組み込む
  • 保存先フォルダ自動作成: Dir + MkDir で年月別フォルダを動的に生成する
  • 複数シート一括処理: For Each で個別PDF、Sheets(Array(...)).Select で結合PDF
  • 印刷範囲指定: PageSetup.PrintArea + IgnorePrintAreas:=False で範囲制御
  • エラー対処: フォルダ不在・同名ファイル開きっぱなし・PrintArea残留が頻出原因

請求書を10社分・月次報告書を5部門分PDF化する作業は、初回1時間の自動化投資で年間60時間以上が浮きます。本記事の請求書テンプレートをそのままコピペして、自社の取引先一覧に合わせて調整するところから始めてください。

VBAの基本構文を学び直したい方は、テーマ別にこちらの記事をご覧ください。

エラーハンドリングを本格的に整備したい方はVBAのエラーハンドリング完全ガイドが役立ちます。VBA全体を体系的に学びたい方は、入門ハブ記事のExcel VBAでマクロ自動化を始めるための完全ガイドも参考にしてください。

タイトルとURLをコピーしました