Contents
この記事でできること
- VBAで一覧表のデータをテンプレートに自動差し込みして印刷できる
- 全件をループで処理するため、件数が多くても手作業不要
- 1件ずつPDFに個別保存もできる(実務版)
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手動コピペ+印刷):
- 一覧表の1行目のデータをテンプレートにコピペ
- 印刷
- テンプレートのデータを消す
- 一覧表の2行目のデータをコピペ
- 印刷…を50件繰り返す(半日コース)
After(VBAで差し込み印刷):
- マクロを実行(またはボタンをクリック)
- 一覧表の全行が1件ずつテンプレートに差し込まれて印刷される
- 完了メッセージで処理件数を確認
自分も毎月50件の請求書を一覧表から1件ずつテンプレートにコピペして印刷していた。半日かかるうえに、金額を1桁間違えて刷り直したこともある。正直しんどかった。VBAで差し込み印刷を自動化してからは、50件が30分で完了。転記ミスもゼロになった。月末の憂鬱がなくなった。同じ「コピペ→印刷」の繰り返しに疲れている人に、この記事で自動化を体験してほしい。
定型帳票の作成は「正確さ」と「スピード」の両方が求められる。VBAなら両方を同時に解決できる。
なお、セルの値を別シートに転記する基本は セルの転記を自動化する方法 を参照。この記事では「一覧表ループ+テンプレート転記+印刷」をセットで解説する。
実行前の準備
シート構成を確認する
このコードは以下の2シート構成を前提としている:
「データ」シート(一覧表):
| A列 | B列 | C列 | D列 |
|---|---|---|---|
| 顧客名 | 件名 | 金額 | 日付 |
| 田中商事 | Webサイト制作 | 500000 | 2026/03/01 |
| 鈴木工業 | システム保守 | 300000 | 2026/03/05 |
| … | … | … | … |
- 1行目はヘッダー(スキップ)
- 2行目以降がデータ
「テンプレート」シート(帳票テンプレート):
- B3: 顧客名
- B5: 件名
- B7: 金額
- D3: 日付
- その他のセルは固定テキスト(「請求書」「合計」など)
テンプレートのセル位置が異なる場合は、コード内のセル指定を書き換える。
バックアップを取る
テンプレートシートのレイアウトが崩れた場合に備えて、ファイルのコピーを保存しておく。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」- 初回は印刷プレビューで確認すること(本番印刷する前にレイアウトを確認)
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
コード(最小版)– 一覧表からテンプレートに差し込み印刷
'============================================================
' ■ 一覧表からテンプレートに差し込み印刷(最小版)
' → データシートの各行をテンプレートに転記し、1件ずつ印刷
'============================================================
Sub MailMergePrintMinimal()
'--- ★書き換えポイント ---
Dim dataSheet As String
dataSheet = "データ" '← 一覧表のシート名
Dim tplSheet As String
tplSheet = "テンプレート" '← テンプレートのシート名
Dim headerRows As Long
headerRows = 1 '← ヘッダー行数(スキップする行数)
'--- ★ここまで ---
Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets(dataSheet)
Dim wsTpl As Worksheet
Set wsTpl = ThisWorkbook.Worksheets(tplSheet)
'--- 一覧表の最終行を取得(A列で判定)
Dim lastRow As Long
lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
'--- データがあるか確認
If lastRow <= headerRows Then
MsgBox "差し込むデータがありません。", vbExclamation
Exit Sub
End If
'--- 1件ずつ差し込み → 印刷
Dim i As Long
Dim count As Long
count = 0
For i = headerRows + 1 To lastRow
'--- ★テンプレートへの差し込み(セル位置を書き換える)---
wsTpl.Range("B3").Value = wsData.Cells(i, 1).Value '← A列 → B3(顧客名)
wsTpl.Range("B5").Value = wsData.Cells(i, 2).Value '← B列 → B5(件名)
wsTpl.Range("B7").Value = wsData.Cells(i, 3).Value '← C列 → B7(金額)
wsTpl.Range("D3").Value = wsData.Cells(i, 4).Value '← D列 → D3(日付)
'--- ★ここまで ---
'--- 印刷(1件分)
wsTpl.PrintOut
'--- テンプレートのデータをクリア(次の差し込みに備える)
wsTpl.Range("B3,B5,B7,D3").ClearContents
count = count + 1
Next i
MsgBox count & " 件の帳票を印刷しました。", vbInformation
End Sub
書き換えポイント
| 変数・箇所 | 説明 | 初期値 |
|---|---|---|
dataSheet |
一覧表のシート名 | "データ" |
tplSheet |
テンプレートのシート名 | "テンプレート" |
headerRows |
ヘッダー行数 | 1 |
wsTpl.Range("B3") 等 |
テンプレートの差し込みセル位置 | B3, B5, B7, D3 |
wsData.Cells(i, 1) 等 |
一覧表の列番号(1=A列, 2=B列…) | 1, 2, 3, 4 |
テンプレートと一覧表の対応表
| 一覧表の列 | 列番号 | テンプレートのセル | 内容 |
|---|---|---|---|
| A列 | 1 | B3 | 顧客名 |
| B列 | 2 | B5 | 件名 |
| C列 | 3 | B7 | 金額 |
| D列 | 4 | D3 | 日付 |
この対応表を自分のシート構成に合わせて書き換える。
コードの流れ
- 一覧表の最終行を取得
- 2行目(ヘッダーの次)から最終行までループ
- 各行のデータをテンプレートの指定セルに転記
PrintOutで1件分を印刷- テンプレートのデータセルをクリア
- 次の行に進む
重要: 初回実行時は wsTpl.PrintOut を wsTpl.PrintPreview に変えてプレビュー確認すること。レイアウトが正しいことを確認してから本番印刷する。
コード(実務版)– 1件ずつPDFに個別保存
実務では印刷だけでなく、PDFファイルとして個別保存するニーズも多い。顧客名や日付をファイル名に入れて保存する。
PDF個別保存を覚えてからは、印刷せずにメール添付で送るパターンにも対応できるようになった。ペーパーレス化にも一歩前進。PDF変換の詳細は ExcelファイルをPDFに一括変換 も参照。
'============================================================
' ■ 一覧表からテンプレートに差し込み → PDF個別保存(実務版)
' → 1件ごとに「顧客名_請求書_20260307.pdf」で保存
'============================================================
Sub MailMergePDFAdvanced()
'--- ★書き換えポイント ---
Dim dataSheet As String
dataSheet = "データ" '← 一覧表のシート名
Dim tplSheet As String
tplSheet = "テンプレート" '← テンプレートのシート名
Dim headerRows As Long
headerRows = 1 '← ヘッダー行数
Dim savePath As String
savePath = "C:\Users\tanaka\Documents\請求書PDF\" '← PDF保存先フォルダ
Dim docType As String
docType = "請求書" '← ファイル名に入れる帳票種類
'--- ★ここまで ---
'--- パスの末尾に \ を付ける
If Right(savePath, 1) <> "\" Then savePath = savePath & "\"
'--- 保存先フォルダの存在確認
If Dir(savePath, vbDirectory) = "" Then
MsgBox "PDF保存先フォルダが見つかりません。" & vbCrLf & _
savePath, vbExclamation
Exit Sub
End If
Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets(dataSheet)
Dim wsTpl As Worksheet
Set wsTpl = ThisWorkbook.Worksheets(tplSheet)
'--- 一覧表の最終行を取得
Dim lastRow As Long
lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
If lastRow <= headerRows Then
MsgBox "差し込むデータがありません。", vbExclamation
Exit Sub
End If
'--- 1件ずつ差し込み → PDF保存
Dim i As Long
Dim count As Long
Dim customerName As String
Dim pdfName As String
count = 0
For i = headerRows + 1 To lastRow
'--- テンプレートへの差し込み
wsTpl.Range("B3").Value = wsData.Cells(i, 1).Value '← 顧客名
wsTpl.Range("B5").Value = wsData.Cells(i, 2).Value '← 件名
wsTpl.Range("B7").Value = wsData.Cells(i, 3).Value '← 金額
wsTpl.Range("D3").Value = wsData.Cells(i, 4).Value '← 日付
'--- PDFファイル名を生成(顧客名_請求書_20260307.pdf)
customerName = wsData.Cells(i, 1).Value
'--- ファイル名に使えない文字を除去
customerName = Replace(customerName, "\", "")
customerName = Replace(customerName, "/", "")
customerName = Replace(customerName, ":", "")
customerName = Replace(customerName, "*", "")
customerName = Replace(customerName, "?", "")
customerName = Replace(customerName, """", "")
customerName = Replace(customerName, "<", "")
customerName = Replace(customerName, ">", "")
customerName = Replace(customerName, "|", "")
pdfName = savePath & customerName & "_" & docType & "_" & _
Format(Date, "yyyyMMdd") & ".pdf"
'--- PDF保存
wsTpl.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=pdfName, _
Quality:=xlQualityStandard, _
OpenAfterPublish:=False
'--- テンプレートのデータをクリア
wsTpl.Range("B3,B5,B7,D3").ClearContents
count = count + 1
Next i
MsgBox count & " 件のPDFを保存しました。" & vbCrLf & _
"保存先: " & savePath, vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
dataSheet |
一覧表のシート名 | "データ" |
tplSheet |
テンプレートのシート名 | "テンプレート" |
headerRows |
ヘッダー行数 | 1 |
savePath |
PDF保存先フォルダ | "C:\Users\tanaka\Documents\請求書PDF\" |
docType |
ファイル名に入れる帳票種類 | "請求書" |
コードの流れ
- 保存先確認: フォルダの存在をチェック
- 最終行取得: 一覧表のデータ件数を把握
- ループ処理: 1行ずつテンプレートに差し込み
- ファイル名生成: 顧客名+帳票種類+日付でPDFファイル名を作成
- 禁止文字除去: ファイル名に使えない文字(\ / : * ? ” < > |)を自動除去
- PDF保存:
ExportAsFixedFormatでPDF出力 - クリア: テンプレートのデータセルをリセット
差し込み印刷マクロをボタン(マクロをボタン1つで実行する方法)に割り当てれば、毎月ボタン1つで帳票作成が完了する。
よくある落とし穴5選
1. テンプレートのセル位置がずれている
原因: コード内の wsTpl.Range("B3") と実際のテンプレートのセル位置が合っていない。行や列を挿入した場合にずれる。
対策: テンプレートを修正したら、コードのセル位置も必ず確認する。対応表を作っておくと管理しやすい。
2. 印刷範囲を設定し忘れて余白まで印刷される
自分もこれでやらかした。印刷範囲を設定し忘れて、テンプレートの余白部分まで印刷されてしまった。紙とインクの無駄遣い。
対策: テンプレートシートの印刷範囲をあらかじめ設定しておく。「ページレイアウト」→「印刷範囲」→「印刷範囲の設定」。または、コードで設定する:
wsTpl.PageSetup.PrintArea = "A1:F30" '← テンプレートの範囲
3. ファイル名に使えない文字でPDF保存エラー
原因: 顧客名に \ / : * ? " < > | が含まれていると、ファイル名として使えずエラーになる。
対策: 実務版コードでは Replace でこれらの文字を自動除去している。
4. PDF保存先フォルダが存在せずエラー
原因: savePath に指定したフォルダが存在しない。
対策: 実務版コードでは Dir でフォルダの存在を確認している。フォルダがない場合は事前に手動で作成するか、MkDir で自動作成する。
5. 大量印刷で紙が足りなくなった
原因: 件数が多いのにプレビュー確認せずに実行。100件×2ページ=200枚が一気に印刷される。
対策: 初回は必ず PrintPreview でプレビュー確認。テスト時は1〜2件だけで動作確認する。
FAQ
Q1: 印刷せずにプレビューだけで確認したい
PrintOut を PrintPreview に変えるだけ:
wsTpl.PrintPreview '← PrintOut の代わり
Q2: 特定の行だけ印刷したい
一覧表に「印刷フラグ」列(例: E列)を追加し、1 が入っている行だけ処理する:
If wsData.Cells(i, 5).Value = 1 Then
'--- 差し込み+印刷処理
End If
Q3: テンプレートに差し込むセルが多い場合
差し込みセルが10個以上ある場合は、配列で管理すると見通しがよい:
'--- 対応表: Array(テンプレートセル, 一覧表の列番号)
Dim mapping As Variant
mapping = Array( _
Array("B3", 1), _
Array("B5", 2), _
Array("B7", 3), _
Array("D3", 4))
Dim m As Variant
For Each m In mapping
wsTpl.Range(m(0)).Value = wsData.Cells(i, m(1)).Value
Next m
Q4: PDF化したファイルをメールで送りたい
PDF保存後にメール作成を連携できる。Excelからメール自動作成(Outlook連携) を参照。
Q5: ボタン1つで差し込み印刷を実行したい
マクロをボタン1つで実行する方法 で MailMergePrintMinimal または MailMergePDFAdvanced をボタンに割り当てる。
まとめ
- 一覧表のデータをテンプレートに自動差し込みして
PrintOutで印刷できる(最小版) ExportAsFixedFormatで1件ずつPDFに個別保存もできる(実務版)- テンプレートのセル位置と一覧表の列番号の「対応表」を作るのが成功の鍵
- 初回は必ず
PrintPreviewでレイアウトを確認してから本番印刷する
関連記事
- セルの転記を自動化する方法 — セル転記の基本に戻りたい場合
- ExcelファイルをPDFに一括変換 — PDF変換の詳細はこちら
- マクロをボタン1つで実行する方法 — 差し込み印刷マクロをボタンに割り当て
次にやりたくなること
- Excelからメール自動作成(Outlook連携): PDF添付でメール送信。請求書の発送まで自動化
- セルの値に応じて行を自動色分け: 一覧表の「印刷済み」行を色分け。未印刷データの管理に便利
もっとカスタマイズしたい場合
「テンプレートのレイアウトが複雑で差し込みセルが多い」「条件に応じて出力先を変えたい」「印刷と同時にメール送信もしたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- テンプレートのレイアウト(セル位置の対応表)
- 一覧表の列数とデータ件数の目安
- 出力形式(印刷 / PDF / 両方)


コメント