【VBA】一覧表からExcelテンプレートに差し込み印刷する方法(コピペOK)

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

この記事でできること

  • VBAで一覧表のデータをテンプレートに自動差し込みして印刷できる
  • 全件をループで処理するため、件数が多くても手作業不要
  • 1件ずつPDFに個別保存もできる(実務版)

対象: Excel 2016以降 / Microsoft 365、Windows 10/11


完成イメージ(Before / After)

Before(手動コピペ+印刷):

  1. 一覧表の1行目のデータをテンプレートにコピペ
  2. 印刷
  3. テンプレートのデータを消す
  4. 一覧表の2行目のデータをコピペ
  5. 印刷…を50件繰り返す(半日コース)

After(VBAで差し込み印刷):

  1. マクロを実行(またはボタンをクリック)
  2. 一覧表の全行が1件ずつテンプレートに差し込まれて印刷される
  3. 完了メッセージで処理件数を確認

自分も毎月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 のままだとマクロが保存できない。

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

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

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

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

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

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

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

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」
  3. 初回は印刷プレビューで確認すること(本番印刷する前にレイアウトを確認)

ボタンに割り当てれば毎回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 日付

この対応表を自分のシート構成に合わせて書き換える。

コードの流れ

  1. 一覧表の最終行を取得
  2. 2行目(ヘッダーの次)から最終行までループ
  3. 各行のデータをテンプレートの指定セルに転記
  4. PrintOut で1件分を印刷
  5. テンプレートのデータセルをクリア
  6. 次の行に進む

重要: 初回実行時は wsTpl.PrintOutwsTpl.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. 保存先確認: フォルダの存在をチェック
  2. 最終行取得: 一覧表のデータ件数を把握
  3. ループ処理: 1行ずつテンプレートに差し込み
  4. ファイル名生成: 顧客名+帳票種類+日付でPDFファイル名を作成
  5. 禁止文字除去: ファイル名に使えない文字(\ / : * ? ” < > |)を自動除去
  6. PDF保存: ExportAsFixedFormat でPDF出力
  7. クリア: テンプレートのデータセルをリセット

差し込み印刷マクロをボタン(マクロをボタン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: 印刷せずにプレビューだけで確認したい

PrintOutPrintPreview に変えるだけ:


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 のバージョン / OS
  • テンプレートのレイアウト(セル位置の対応表)
  • 一覧表の列数とデータ件数の目安
  • 出力形式(印刷 / PDF / 両方)

あわせて読みたい

コメント

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