【VBA】ExcelファイルをPDFに一括変換する方法|フォルダ指定でまとめて保存(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

どんな場面で使う?

  • 月次報告書を20件以上PDF化して上司や取引先に提出する
  • 請求書や見積書をExcelで作成し、PDF添付でメール送信する
  • 年度末に大量のExcelファイルをアーカイブ用PDFにまとめて変換したい
  • 社内規定で「提出書類はPDF」と決まっており、毎回手動で変換している

完成イメージ(Before / After)

Before(手動でPDF変換)

Before(実行前)のExcel画面
A B
1 ファイル名 状態
2 2026年01月_売上報告.xlsx 未変換
3 2026年02月_売上報告.xlsx 未変換
4 2026年03月_売上報告.xlsx 未変換

1つずつ「名前を付けて保存→PDF」を10回繰り返す。20分かかる。

After(VBAで一括変換)

After(実行後)のExcel画面
A B
1 ファイル名 状態
2 2026年01月_売上報告.pdf 変換完了
3 2026年02月_売上報告.pdf 変換完了
4 2026年03月_売上報告.pdf 変換完了

ボタン1つで全ファイルがPDFに。30秒で完了。

同じフォルダにPDFファイルが自動生成される。


C:\報告書\
  ├── 2026年01月_売上報告.xlsx
  ├── 2026年01月_売上報告.pdf  ← 自動生成
  ├── 2026年02月_売上報告.xlsx
  ├── 2026年02月_売上報告.pdf  ← 自動生成
  ├── 2026年03月_売上報告.xlsx
  └── 2026年03月_売上報告.pdf  ← 自動生成

実行前の準備

バックアップを取る

対象フォルダ内のExcelファイルをフォルダごとコピーしてバックアップを取ること。VBAからファイルを開いて処理するため、万が一に備える。

Excelをマクロ有効ブック(.xlsm)で保存する

  1. 新しいExcelブックを開く(VBAを書く用のファイル)
  2. 「ファイル」→「名前を付けて保存」
  3. ファイルの種類を 「Excel マクロ有効ブック (*.xlsm)」 に変更して保存

.xlsx のままだとマクロが保存されない。必ず .xlsm にすること。

注意: VBAを書くExcelファイルと、PDF化したいExcelファイルは別。PDF化したいファイルは .xlsx のままでOK。

対象フォルダのパスを確認する

PDF化したいExcelファイルが入っているフォルダのパスを確認しておく。パスの調べ方:エクスプローラーでフォルダを開き、アドレスバーをクリックするとパスが表示される。

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

Alt + F11 キーを押すとVBE(Visual Basic Editor)が開く。

一般的にはAlt + F11で開けるが、企業のセキュリティ設定でVBAが無効化されている場合は、IT部門に確認すること。

標準モジュールを挿入する

  1. VBEのメニュー「挿入」→「標準モジュール」をクリック
  2. 右側に白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. 下の「コード(最小版)」をコピーして、コードウィンドウに貼り付ける
  2. コード内の folderPath を自分のフォルダパスに書き換える
  3. Alt + F8 を押す(または VBE上で F5
  4. 「ExcelToPDF」を選択して「実行」
  5. 処理が完了すると、件数がメッセージボックスに表示される

コード(最小版)– 同じフォルダにPDFを保存

まずはこれだけで動く。指定フォルダ内の .xlsx ファイルを、同じフォルダに .pdf として保存する。


Sub ExcelToPDF()

    Dim folderPath As String
    Dim fileName As String
    Dim pdfName As String
    Dim wb As Workbook
    Dim fileCount As Long

    ' --- ★ ここを自分のフォルダパスに書き換える ---
    folderPath = "C:\報告書\"

    ' フォルダパスの末尾に \ がなければ追加
    If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"

    ' 画面更新を停止(高速化)
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    fileCount = 0

    ' フォルダ内の .xlsx ファイルを順番に処理
    fileName = Dir(folderPath & "*.xlsx")

    Do While fileName <> ""

        ' Excelファイルを読み取り専用で開く
        Set wb = Workbooks.Open(folderPath & fileName, ReadOnly:=True, UpdateLinks:=0)

        ' PDFファイル名を生成(拡張子を .pdf に変換)
        pdfName = Left(fileName, InStrRev(fileName, ".") - 1) & ".pdf"

        ' PDF として保存
        wb.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=folderPath & pdfName, _
            Quality:=xlQualityStandard, _
            IncludeDocProperties:=False, _
            IgnorePrintAreas:=False, _
            OpenAfterPublish:=False

        ' ファイルを閉じる(保存しない)
        wb.Close SaveChanges:=False

        fileCount = fileCount + 1

        ' 次のファイルへ
        fileName = Dir()

    Loop

    ' 画面更新を再開
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    MsgBox fileCount & " 件のExcelファイルをPDFに変換しました。", vbInformation

End Sub

コードの動作:

  1. 指定フォルダ内の .xlsx ファイルを Dir で順番に取得
  2. 各ファイルを読み取り専用で開く(元ファイルは変更されない)
  3. ExportAsFixedFormat でPDFとして保存(同じフォルダに同名 .pdf)
  4. ファイルを閉じて次のファイルへ
  5. 全ファイルの処理が終わったら件数を表示

フォルダパスについて: folderPath = "C:\報告書\" の部分を自分のフォルダパスに書き換える。パスの末尾には \ を付ける。

自分はこの最小版で十分だった。月次報告20ファイルが1分もかからず全部PDFになったときは感動した。

ネットワークドライブ(\\server\share\ のようなパス)で使う場合は、Dirの動作が不安定になることがある。その場合は下の実務版コードを使うこと。

コード(実務版)– 出力先フォルダ指定+ログ+エラースキップ

業務で使うなら、出力先フォルダを分けたい、.xlsm にも対応したい、エラーで止まらないようにしたい、という要望がある。処理ログをシートに記録する機能付き。

ファイル名を先に配列に格納してからループする方式は、/001 で紹介した Dir関数の応用。Dirの内部状態がリセットされるリスクを回避できる。

ログシートのレイアウト:

A B C
1 ファイル名 結果 詳細
2 2026年01月_売上報告.xlsx OK 2026年01月_売上報告.pdf
3 破損ファイル.xlsx エラー ファイルを開けませんでした

Sub ExcelToPDFEx()

    Dim folderPath As String
    Dim outputPath As String
    Dim fileName As String
    Dim pdfName As String
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim fso As Object
    Dim fileCount As Long
    Dim errCount As Long
    Dim logRow As Long
    Dim fileList() As String
    Dim i As Long
    Dim n As Long

    ' --- ★ ここを自分のフォルダパスに書き換える ---
    folderPath = "C:\報告書\"
    outputPath = "C:\報告書\PDF出力\"  ' 出力先フォルダ(なければ自動作成)

    ' フォルダパスの末尾に \ がなければ追加
    If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\"
    If Right(outputPath, 1) <> "\" Then outputPath = outputPath & "\"

    ' 出力先フォルダがなければ作成(FSO で安全にチェック)
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FolderExists(outputPath) Then
        fso.CreateFolder outputPath
    End If
    Set fso = Nothing

    ' --- ファイル名を先に配列に格納(Dir の安全対策) ---
    n = 0
    fileName = Dir(folderPath & "*.xls*")  ' .xlsx と .xlsm の両方に対応
    Do While fileName <> ""
        n = n + 1
        ReDim Preserve fileList(1 To n)
        fileList(n) = fileName
        fileName = Dir()
    Loop

    If n = 0 Then
        MsgBox "対象フォルダにExcelファイルが見つかりませんでした。" & vbCrLf & _
               folderPath, vbExclamation
        Exit Sub
    End If

    ' --- ログ用シートを準備 ---
    Set ws = ThisWorkbook.Worksheets(1)
    ws.Cells.Clear
    ws.Cells(1, 1).Value = "ファイル名"
    ws.Cells(1, 2).Value = "結果"
    ws.Cells(1, 3).Value = "詳細"
    logRow = 2

    ' 画面更新を停止(高速化)
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    fileCount = 0
    errCount = 0

    ' --- ファイルを順番に処理 ---
    For i = 1 To n

        fileName = fileList(i)

        ' ログにファイル名を記録
        ws.Cells(logRow, 1).Value = fileName

        On Error GoTo ErrHandler

        ' Excelファイルを読み取り専用で開く
        Set wb = Workbooks.Open(folderPath & fileName, ReadOnly:=True, UpdateLinks:=0)

        ' PDFファイル名を生成(拡張子を .pdf に変換)
        pdfName = Left(fileName, InStrRev(fileName, ".") - 1) & ".pdf"

        ' PDF として保存
        wb.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=outputPath & pdfName, _
            Quality:=xlQualityStandard, _
            IncludeDocProperties:=False, _
            IgnorePrintAreas:=False, _
            OpenAfterPublish:=False

        ' ファイルを閉じる(保存しない)
        wb.Close SaveChanges:=False
        Set wb = Nothing

        ' ログに成功を記録
        ws.Cells(logRow, 2).Value = "OK"
        ws.Cells(logRow, 3).Value = pdfName

        fileCount = fileCount + 1
        On Error GoTo 0

NextFile:
        logRow = logRow + 1

    Next i

    ' 画面更新を再開
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    MsgBox "完了" & vbCrLf & _
           "成功:" & fileCount & " 件" & vbCrLf & _
           "エラー:" & errCount & " 件" & vbCrLf & _
           "ログはシートに記録しました。", vbInformation

    Exit Sub

ErrHandler:
    ' エラーが出たファイルはスキップしてログに記録
    ws.Cells(logRow, 2).Value = "エラー"
    ws.Cells(logRow, 3).Value = Err.Description
    errCount = errCount + 1

    ' 開いたブックがあれば閉じる
    If Not wb Is Nothing Then
        wb.Close SaveChanges:=False
        Set wb = Nothing
    End If

    ' Application 設定を確実に復帰
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    On Error GoTo 0
    Resume NextFile

End Sub

自分はこの実務版に切り替えてから、エラーで止まる心配がなくなった。破損ファイルが混ざっていてもスキップして次に進むし、ログを見れば何が失敗したか一目でわかる。上司への報告書20件のPDF化が、安心して放置できる作業になった。

フォルダ指定ダイアログとの連携

実務版コードの outputPath をハードコードせず、実行のたびにダイアログで出力先を選びたい場合は、以下のコードを outputPath = "C:\報告書\PDF出力\" の代わりに使う。フォルダ選択ダイアログの詳しい使い方は /137 を参照。


' --- 出力先フォルダをダイアログで選択 ---
With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "PDF出力先フォルダを選択してください"
    If .Show = -1 Then
        outputPath = .SelectedItems(1) & "\"
    Else
        MsgBox "キャンセルされました。", vbExclamation
        Exit Sub
    End If
End With

キャンセルボタンを押した場合は処理を中断するので、誤実行の防止にもなる。

追加ポイント:

  • 出力先フォルダを別途指定(FileSystemObject.FolderExists で安全にチェック、なければ自動作成)
  • .xls* パターンで .xlsx と .xlsm の両方に対応
  • ファイル名を先に配列に格納してからループ(Dir の内部状態リセット問題を回避)
  • エラーが出たファイルはスキップして次のファイルへ進む
  • シートの A〜C 列に処理ログ(ファイル名・結果・詳細)を記録
  • エラーハンドラで Application.ScreenUpdating / DisplayAlerts を確実に復帰

よくある落とし穴5選

自分が初めてPDF一括変換を試したとき、印刷範囲を設定し忘れていた。上司に提出したら「全部白紙なんだけど?」と言われて血の気が引いた。原因はExcel側の印刷範囲が未設定で、空白ページだけがPDFに出力されていたこと。以来、PDF化の前に印刷プレビューを確認するのが習慣になった。

# 症状 原因 対策
1 PDFに空白ページが大量に含まれる Excelファイルに印刷範囲が設定されていない。または印刷範囲外のセルにデータが残っている PDF化する前に、各Excelファイルの印刷範囲を確認する。不要なセルのデータを削除しておく
2 「実行時エラー ‘1004’」でファイルが開けない ファイルが他のユーザーに開かれている、またはパスワードで保護されている 実務版コードを使えばエラーをスキップできる。共有フォルダのファイルは他の人が閉じてから実行する
3 一部のファイルがPDF化されない フォルダに .xlsm ファイルが混在しているが、最小版コードは .xlsx しか対象にしていない 実務版コードを使う(.xls* で .xlsx と .xlsm の両方に対応)
4 同名のPDFが上書きされる 同じフォルダに既にPDFがある状態で再実行した DisplayAlerts = False のため確認なしで上書きされる。上書きしたくない場合は、出力先フォルダを変えるか、ファイル名に日時を追加する
5 PDFのレイアウトがおかしい(列が切れる、文字が小さい) Excelの印刷設定(用紙サイズ、余白、倍率)が適切でない PDF化する前に、各Excelファイルで「印刷プレビュー」を確認して印刷設定を調整しておく

VBAでPDF変換したら白紙になるときの対処法

「PDFを開いたら中身が空白だった」という場合、原因はExcelファイルの印刷範囲が設定されていないか、印刷範囲外のセルにデータが残っていることだ。PDF化の前に各Excelファイルで「ファイル」→「印刷」→「印刷プレビュー」を確認し、印刷範囲を正しく設定すれば解決する。

VBAでPDF一括変換中にエラーで止まるときの対処法

「途中でエラーが出て残りのファイルが変換されない」という場合、原因はパスワード保護されたファイルや破損ファイルが混在していることだ。実務版コードに切り替えればエラーが発生したファイルをスキップして次に進むため、止まらずに全ファイルの処理が完了する。

FAQ

Q1: 特定のシートだけPDF化したい

wb.ExportAsFixedFormatwb.Worksheets("Sheet1").ExportAsFixedFormat に変えれば、指定シートだけPDF化できる。シート名を自分の環境に合わせて書き換えること。

Q2: 複数シートを1つのPDFにまとめたい

ブック全体を ExportAsFixedFormat すれば、全シートが1つのPDFになる(最小版・実務版ともにこの動作)。自分も最初「シートごとに別PDFになるのでは?」と心配したが、デフォルトでブック全体が1PDFにまとまる。

Q3: PDF化した後にメールで送りたい

/007 を参照。.Attachments.Add でPDFファイルのパスを指定すれば添付できる。宛先リストと組み合わせれば、PDF添付メールの一括送信も可能。

Q4: PDF化と同時にファイル名を変えたい

pdfName の生成部分を変更すればよい。例:日付を先頭に付ける場合は pdfName = Format(Now, "yyyymmdd_HHmmss") & "_" & 元のファイル名 & ".pdf" とする。ファイル名の一括変更については /005 も参考になる。

Q5: サブフォルダ内のファイルも対象にしたい

Q6: 特定のシートだけPDFにできますか?

できる。wb.ExportAsFixedFormat の部分を Sheets("シート名").ExportAsFixedFormat に変えるだけでよい。例えば「売上集計」シートだけをPDF化したい場合は以下のように書く。


wb.Sheets("売上集計").ExportAsFixedFormat _
    Type:=xlTypePDF, _
    Filename:=outputPath & pdfName

シート名は自分の環境に合わせて書き換えること。存在しないシート名を指定するとエラーになるので注意。

Q7: PDFのファイル名を元のExcelファイル名と同じにするには?

本記事のコードはデフォルトで元のExcelファイル名と同じ名前(拡張子だけ .pdf に変換)で保存される。仕組みとしては Replace(wb.Name, ".xlsx", ".pdf") と同じ考え方。もし .xlsm ファイルにも対応したい場合は、実務版コードのように Left(fileName, InStrRev(fileName, ".") - 1) & ".pdf" を使えば、どの拡張子でも対応できる。

まとめ

この記事で、フォルダ内のExcelファイルを一括でPDFに変換できるようになった。

  • 最小版:指定フォルダ内の .xlsx → 同じフォルダに .pdf を保存
  • 実務版:出力先フォルダ指定+.xlsm対応+エラースキップ+処理ログ

重要なのは、PDF化する前に各Excelファイルの印刷設定を確認しておくこと。印刷範囲・用紙サイズ・余白がPDFのレイアウトにそのまま反映される。まず1ファイルだけテスト変換してから本番実行するのがおすすめ。

関連記事

  • Dir関数の基本を学びたいなら /001 を参照 — 本記事のコードの土台になっている
  • PDF化したファイルを別フォルダに整理したいなら /003 を参照
  • PDF化した報告書をメールに添付して送信したいなら /007 を参照
  • ファイル名を業務ルールに合わせてリネームしたいなら /005 を参照
  • 古いファイルを自動削除して整理したいなら /051 を参照

次にやりたくなること

コメント

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