TL;DR — VBA に「PDF として SaveAs」という手段はありません。シート・範囲・ブックに対して
ExportAsFixedFormatを呼び、Type:=xlTypePDFと .pdf で終わる完全なパス を渡すと、Excel は印刷するときとまったく同じページを描き出します。考え方はこれに尽きます。PDF とは、ファイルに送られた印刷ジョブです。ですから、印刷範囲・印刷の向き・拡大縮小の設定が PDF の中身を決めます — 先にページを整え、それから書き出しましょう。
Sub SaveReportAsPdf()
Dim pdfPath As String
pdfPath = ThisWorkbook.Path & "\Report_" & Format(Date, "yyyy-mm-dd") & ".pdf"
ThisWorkbook.Worksheets("Report").ExportAsFixedFormat _
Type:=xlTypePDF, Filename:=pdfPath, Quality:=xlQualityStandard, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
End Sub
ここにたどり着く人の多くは、.pdf という名前で SaveAs を試したか、ファイル → エクスポート をマクロ記録して意味のわからない一行を手にしたかのどちらかです。この記事は、Excel から出力を取り出すための三部作の筆頭です。三つの記事は一本のパイプラインを共有しています。ページ設定 がページとは何か —
印刷範囲・印刷の向き・拡大縮小 — を決めます。PrintOut はそのページをプリンターへ送ります。そしてこの記事で扱う ExportAsFixedFormat は、同じ ページを PDF ファイルへ送ります。ページを一度正しく作れば、どちらの出力も正しく出てきます。ページが間違っていれば、どんな書き出しオプションも救ってはくれません。
この記事で学べること
- Excel の PDF がなぜ印刷ジョブなのか、そしてそれがコードにとって何を意味するか
ExportAsFixedFormatの呼び出し方と、本当に効いてくる引数- シート一枚、範囲一つ、ブック全体を書き出す方法
- 選んだ複数のシートを一つの PDF にまとめる方法
- 安全なファイルパスの組み立て方と、不正なパスが招く実行時エラー 1004
- 判断の分かれ目:
ExportAsFixedFormatか、「PDF に印刷」か
考え方の軸:PDF とはファイルに送られた印刷である
Excel には PDF 専用のレイアウトはありません。書き出すとき、Excel は紙に印刷するときとまったく同じようにシートをページに分けます — 同じ印刷範囲、同じ改ページ、同じ余白、同じヘッダーとフッター — そして、そのページをプリンターに流す代わりにファイルへ書き込みます。この一つの事実で、「PDF がなぜこんな見た目になるのか」という疑問のほとんどが説明できます。
- 幅の広い表が二ページに分かれてしまうのは、ページ が縦向き・100% の倍率だからです。
- データのはるか下にある余計なセルの塊まで入ってしまうのは、使用範囲がそこまで広がっているからです。
- シートの一部しか出てこないのは、何か月も前に設定された印刷範囲がクリアされずに残っているからです。
どれも書き出しの問題ではありません。ページの問題であり、直す場所は書き出しの行が走る前の ページ設定 です。
ExportAsFixedFormat の呼び出し方
ExportAsFixedFormat は Worksheet・Range・Workbook・Chart に用意されています。実際に使う引数は次のとおりです。
| 引数 | 役割 |
|---|---|
Type |
xlTypePDF(または xlTypeXPS)。必須です。 |
Filename |
作成するファイルの完全なパス。フォルダーと .pdf まで含めます。 |
Quality |
印刷品質なら xlQualityStandard、ファイルを小さくするなら xlQualityMinimum。 |
IgnorePrintAreas |
False(既定)は印刷範囲に従い、True はすべてを書き出します。 |
From、To |
ページの範囲。たとえば 1 ページ目から 3 ページ目まで。 |
OpenAfterPublish |
True にすると、書き出し後に既定のビューアーで PDF を開きます。 |
名前付き引数を使いましょう。位置引数でも動きますが、ExportAsFixedFormat xlTypePDF, p, , , True は一週間後には読めませんし、順番も間違えやすいのです。
シート一枚、範囲一つ、ブック全体
どのオブジェクトに対して呼ぶかで、書き出す範囲が決まります。
' シート一枚(そのシートの印刷範囲に従う)
Worksheets("Report").ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath
' 範囲一つ(印刷範囲に関係なく)
Worksheets("Report").Range("A1:H40").ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath
' ブック内の表示されているすべてのシートを、シート見出しの順に
ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath
範囲の形は、シートの印刷範囲に手を触れずに「このブロックだけ」を出す最短の方法です。ブックの形は非表示のシートを除外します。補助シートや参照用の表については、たいていそれが望みどおりの動きです。
選んだ複数のシートを一つの PDF に
特定のシートの組み合わせ — たとえば集計シートと二枚の明細シート — をまとめるには、それらをグループとして選択してから、アクティブシートを書き出します。グループ化された選択は一つの文書として書き出されます。
Sub ExportChosenSheets(pdfPath As String)
ThisWorkbook.Worksheets(Array("Summary", "North", "South")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath
ThisWorkbook.Worksheets("Summary").Select ' グループ化を解除する
End Sub
ここは Select が本当に必要になる数少ない場面の一つです。ほかの場面でなぜ避けるのかは
Select と Activate をご覧ください。終わったら必ずグループを解除します。グループ化されたシートに入力すると、すべてのシートに同時に書き込まれてしまうからです。
シート ごとに PDF を一つずつ作るなら、ループを回して各シートから名前を組み立てます。
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Visible = xlSheetVisible Then
ws.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\" & ws.Name & ".pdf"
End If
Next ws
安全なファイルパスと、それで防げるエラー 1004
誰もが一度はぶつかるのが 実行時エラー 1004「Document not saved. The document may be open, or an error may have been encountered when saving.」 です。このメッセージは、見た目どおりの意味であることがほとんどありません。よくある原因は次のとおりです。
- フォルダーが存在しない — Excel はフォルダーを作ってくれません。先に MkDir で作ります。
- PDF がすでにビューアーで開かれている — ファイルがロックされています。
- ファイル名に Windows で使えない文字が含まれている — 日付の
/や時刻の:など。 - 印刷するものが何もない — シートや印刷範囲が空です。
フォルダーのない裸のファイル名はエラーになりません。そのほうがかえって厄介です。PDF は Excel のカレントフォルダー(CurDir を参照)に保存され、ユーザーは二度と見つけられません。ですから、完全なパスを必ず組み立て、データから来る部分はきれいにしておきましょう。
Function SafePdfPath(folder As String, baseName As String) As String
Dim bad As Variant
For Each bad In Array("/", "\", ":", "*", "?", """", "<", ">", "|")
baseName = Replace(baseName, bad, "-")
Next bad
If Dir(folder, vbDirectory) = "" Then MkDir folder
SafePdfPath = folder & "\" & baseName & ".pdf"
End Function
保存場所をユーザーに選んでもらうなら、GetSaveAsFilename でたずね、その戻り値を Filename に渡します — そして、キャンセルを意味する False を確かめるのを忘れないでください。
判断の分かれ目:PDF に印刷せず、書き出す
アクティブプリンターを Microsoft Print to PDF に切り替え、ファイル名を付けて PrintOut を呼ぶコードを見かけることがあるでしょう。真似をしてはいけません。プリンター名はパソコンや言語によって変わりますし、保存ダイアログが開いて無人で走るはずのマクロが止まることがあり、副作用としてユーザーのアクティブプリンターまで変えてしまいます。ExportAsFixedFormat は Excel に組み込まれていて、プリンターをまったく必要とせず、パスを引数として受け取ります。ルールは単純です。紙は PrintOut で、ファイルは ExportAsFixedFormat
で。 そして、どちらを呼ぶにしても、描き出されるページを決めたのは ページ設定 です — 見た目のおかしい PDF を直す場所はそこです。
ExcelMaster の活用
PDF のマクロは、地味で具体的な形で失敗します。まだ存在しないフォルダー、ファイル名に入り込んだ日付のスラッシュ、前の四半期から残っている印刷範囲、二ページ目にはみ出す表。どれも同じ不親切なエラー 1004 として、あるいはどこか微妙におかしい PDF として現れます。
ExcelMaster には、望む結果をそのまま伝えられます — 「集計シートと二つの地域シートを、今月の名前を付けた一つの PDF に、横向きで、横 1 ページに収めて書き出して」 — すると、ページ設定・安全なパス・書き出しをまとめて書き、結果まで確かめてくれます。マクロはあなたの手元に残り、当て推量は要らなくなります。
よくある質問
VBA で Excel のシートを PDF として保存するには?
シートに対して ExportAsFixedFormat を呼び、Type:=xlTypePDF と、.pdf で終わる完全な Filename を渡します。たとえば Worksheets("Report").ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Out\Report.pdf" です。
SaveAs には PDF のオプションがなく、この書き出しメソッドが正式な方法です。
範囲だけを PDF として保存するには?
範囲そのものに対してメソッドを呼びます。Range("A1:H40").ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath です。これはシートの印刷範囲に関係なくそのブロックを書き出すので、書き出しの前後で印刷範囲を変えたり戻したりする必要はありません。
複数のシートを一つの PDF に書き出すには?
Worksheets(Array("Summary", "North")).Select でシートをグループとして選択し、それから
ActiveSheet.ExportAsFixedFormat を呼びます。グループ化された選択は一つの文書として書き出されます。そのあとシートを一枚だけ選択してグループを解除し、以後の入力がすべてのシートに入ってしまわないようにします。
ExportAsFixedFormat で実行時エラー 1004 が出るのはなぜですか?
たいていは、パスのフォルダーが存在しない、PDF がすでにビューアーで開かれている、ファイル名に / や : のような使えない文字が含まれている、あるいは印刷するものが何もない、のいずれかです。完全なパスを組み立て、先にフォルダーを作り、データから来る部分から使えない文字を取り除きましょう。
PDF で表がページをまたいで切れたり、余計なセルが入ったりするのはなぜですか?
PDF はシートのページ設定を使うからです。縦向き・100% の倍率の幅広い表はページをまたいで分かれ、データのはるか下まで広がった使用範囲は空白のページを増やします。書き出す前に PageSetup で直しましょう — 印刷の向き、印刷範囲、そして横 1 ページに収める設定です。
検証環境
検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-09-29。
関連ガイド: VBA PrintOut · VBA Page Setup · VBA GetSaveAsFilename · VBA MkDir · VBA CurDir · VBA Outlook · VBA On Error
