Contents
この記事でできること
- 一覧表から請求書テンプレートにデータを自動転記できる
- 全件をループしてPDFファイルとして一括保存できる
- 確認ダイアログ+進捗表示で安全に実行できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業):
- 一覧表を見ながら請求書テンプレートに1件ずつ転記
- 取引先名・金額・日付をコピペ
- PDF保存して次の請求書へ
- 20社分で2時間。転記ミスで再発行のリスクあり
After(マクロ実行):
- 一覧シートにデータを入力
- マクロを実行する
- 確認ダイアログ「20 件の請求書を作成します。実行しますか?」が表示される
- ステータスバーに「請求書作成中… 5/20」と進捗が出る
- 「請求書PDF」フォルダに20件のPDFが保存される
- 5分で完了。転記ミスゼロ
一覧シート(入力するデータ):
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | 請求番号 | 取引先名 | 件名 | 金額 | 請求日 |
| 2 | INV-001 | 株式会社ABC | Webサイト制作 | 500000 | 2026/03/31 |
| 3 | INV-002 | 株式会社DEF | システム保守 | 300000 | 2026/03/31 |
| 4 | INV-003 | 株式会社GHI | コンサルティング | 200000 | 2026/03/31 |
出力されるPDFファイル:
請求書PDF\
├── 請求書_株式会社ABC_20260331.pdf
├── 請求書_株式会社DEF_20260331.pdf
└── 請求書_株式会社GHI_20260331.pdf
毎月20社分の請求書を手作業で作っていた時期がある。一覧表を見ながらテンプレートに1件ずつ転記して、PDF保存して、また次の取引先。金額のコピペミスで再発行になったことが2回ある。正直、月末の請求書作業が怖かった。
VBAで自動化してからはミスゼロになった。作業時間は2時間→5分。一覧シートにデータを入力してマクロを実行するだけで、PDFが全件できあがる。月末の請求書作業が怖くなくなった。
同じように毎月の請求書で消耗している人に、この一括処理を体験してほしい。まずは最小版で1件だけ転記して、動くことを確認するところから始めよう。
一覧表 → テンプレート転記 → PDF保存。この流れをVBAで自動化する。
事前準備
シート構成を用意する
このマクロは2つのシートを使う。
「一覧」シート — 請求データを入力する場所
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 請求番号 | INV-001 |
| B列 | 取引先名 | 株式会社ABC |
| C列 | 件名 | Webサイト制作 |
| D列 | 金額 | 500000 |
| E列 | 請求日 | 2026/03/31 |
- 1行目はヘッダー。データは2行目から入力する
- A列が空の行が最終行として判定される
「請求書」シート — テンプレート(転記先)
| セル | 内容 |
|---|---|
| C3 | 取引先名(宛名) |
| C5 | 件名 |
| C8 | 請求番号 |
| E3 | 請求日 |
| D15 | 金額 |
テンプレートの作り方は本記事の後半で解説する。
バックアップを取る
テンプレートシートにデータを上書きする処理のため、実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
コード(最小版)– 一覧から請求書テンプレートに1件転記
まず1件だけ転記して動作確認する。ループもPDF保存もない最小構成。
セルの転記の基本はセルの転記を自動化する方法を参照。
Sub 請求書を作成する()
Dim wsList As Worksheet
Dim wsTemplate As Worksheet
Dim lastRow As Long
Dim i As Long
Set wsList = Worksheets("一覧")
Set wsTemplate = Worksheets("請求書")
' ★ 最終行を取得(A列で判定)
lastRow = wsList.Cells(wsList.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "一覧にデータがありません。", vbExclamation
Exit Sub
End If
' 1件目のデータを転記(動作確認用)
With wsTemplate
.Range("C3").Value = wsList.Cells(2, 2).Value ' 取引先名
.Range("C5").Value = wsList.Cells(2, 3).Value ' 件名
.Range("E3").Value = wsList.Cells(2, 5).Value ' 請求日
.Range("D15").Value = wsList.Cells(2, 4).Value ' 金額
.Range("C8").Value = wsList.Cells(2, 1).Value ' 請求番号
End With
wsTemplate.Activate
MsgBox "請求書を作成しました。"
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("一覧") |
一覧 | 一覧データのシート名 |
| 2 | Worksheets("請求書") |
請求書 | テンプレートのシート名 |
| 3 | .Range("C3") 等 |
C3, C5, E3, D15, C8 | テンプレート側の転記先セル |
| 4 | wsList.Cells(2, 2) 等 |
列2,3,5,4,1 | 一覧側の列番号(B=2, C=3 …) |
動作確認
- 「一覧」シートの2行目にテスト用データを1件入力する
- マクロを実行する
- 「請求書」シートに切り替わり、データが転記されていることを確認する
最小版で転記が確認できたら、次の実務版に進む。
コード(実務版)– 全件ループ+PDF保存+確認ダイアログ+進捗表示
自分はこの方法で毎月20社分の請求書を処理している。2時間かかっていた作業が5分で終わるようになった。
一覧の全件をループしてテンプレートに転記し、1件ずつPDF保存する。PDF保存の基本はExcelファイルをPDFに一括変換する方法を参照。
Sub 請求書を一括作成してPDF保存()
Dim wsList As Worksheet
Dim wsTemplate As Worksheet
Dim lastRow As Long
Dim i As Long
Dim savePath As String
Dim fileName As String
Dim cnt As Long
Dim clientName As String
Set wsList = Worksheets("一覧")
Set wsTemplate = Worksheets("請求書")
' ★ 最終行を取得(A列で判定)
lastRow = wsList.Cells(wsList.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "一覧にデータがありません。", vbExclamation
Exit Sub
End If
' ★ 保存先フォルダ(ブックと同じ場所に「請求書PDF」フォルダ)
savePath = ThisWorkbook.Path & "\請求書PDF\"
If Dir(savePath, vbDirectory) = "" Then
MkDir savePath
End If
' 確認ダイアログ(件数+保存先を表示)
If MsgBox((lastRow - 1) & " 件の請求書を作成します。" & vbCrLf & _
"保存先: " & savePath & vbCrLf & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
Application.ScreenUpdating = False
For i = 2 To lastRow
' ステータスバーに進捗表示
Application.StatusBar = "請求書作成中... " & (i - 1) & "/" & (lastRow - 1)
' テンプレートに転記
With wsTemplate
.Range("C3").Value = wsList.Cells(i, 2).Value ' 取引先名
.Range("C5").Value = wsList.Cells(i, 3).Value ' 件名
.Range("E3").Value = wsList.Cells(i, 5).Value ' 請求日
.Range("D15").Value = wsList.Cells(i, 4).Value ' 金額
.Range("C8").Value = wsList.Cells(i, 1).Value ' 請求番号
End With
' ファイル名の禁止文字を置換
clientName = Replace(wsList.Cells(i, 2).Value, "/", "/")
clientName = Replace(clientName, "\", "\")
clientName = Replace(clientName, ":", ":")
clientName = Replace(clientName, "*", "*")
clientName = Replace(clientName, "?", "?")
clientName = Replace(clientName, """", """)
clientName = Replace(clientName, "<", "<")
clientName = Replace(clientName, ">", ">")
clientName = Replace(clientName, "|", "|")
' ★ PDFファイル名: 請求書_取引先名_日付.pdf
fileName = "請求書_" & clientName & "_" & _
Format(wsList.Cells(i, 5).Value, "yyyymmdd") & ".pdf"
' PDF保存
wsTemplate.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=savePath & fileName, _
Quality:=xlQualityStandard
cnt = cnt + 1
Next i
' テンプレートをクリア(前回データの残留防止)
With wsTemplate
.Range("C3").ClearContents
.Range("C5").ClearContents
.Range("E3").ClearContents
.Range("D15").ClearContents
.Range("C8").ClearContents
End With
Application.StatusBar = False
Application.ScreenUpdating = True
MsgBox cnt & " 件の請求書PDFを保存しました。" & vbCrLf & _
"保存先: " & savePath, vbInformation
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | "\請求書PDF\" |
請求書PDF | PDF保存先フォルダ名 |
| 2 | .Range("C3") 等 |
C3, C5, E3, D15, C8 | テンプレート側の転記先セル |
| 3 | wsList.Cells(i, 2) 等 |
列2,3,5,4,1 | 一覧側の列番号 |
| 4 | "請求書_" |
請求書_ | PDFファイル名のプレフィックス |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| 確認ダイアログ | 件数+保存先を表示してYes/Noで確認 | — |
| 進捗表示 | ステータスバーに「5/20」形式で進捗を表示 | 進捗表示の方法 |
| PDF一括保存 | ExportAsFixedFormatで1件ずつPDF化 | PDF一括変換 |
| フォルダ自動作成 | MkDirで保存先フォルダを自動作成 | — |
| 禁止文字置換 | ファイル名に使えない文字を全角に変換 | — |
| テンプレートクリア | ループ完了後にClearContentsで前回データを消去 | — |
テンプレートの作り方
「請求書」シートのレイアウト例を示す。実際のデザインは自由に変更してよい。重要なのは転記先のセル位置を合わせること。
レイアウト例
行1 : [空白]
行2 : [空白] [空白] 請 求 書
行3 : [空白] C3:取引先名 御中 E3:請求日
行4 : [空白]
行5 : [空白] C5:件名
行6 : [空白]
行7 : [空白] 下記の通りご請求申し上げます。
行8 : [空白] C8:請求番号
行9 : [空白]
行10 : [空白] ─────────────────
行11 : [空白] 項目 数量 単価 金額
行12 : [空白] ─────────────────
行13 : [空白] (明細行)
行14 : [空白] ─────────────────
行15 : [空白] [空白] [空白] 小計 D15:金額
行16 : [空白] [空白] [空白] 消費税 (数式: =D15*0.1)
行17 : [空白] [空白] [空白] 合計 (数式: =D15+D16)
行18 : [空白]
行19 : [空白] 振込先: ○○銀行 ○○支店 普通 1234567
行20 : [空白] 支払期限: 翌月末日
ポイント
- 消費税(D16)と合計(D17)はExcelの数式で計算する。VBA側で転記するのは小計(D15)だけでよい
- テンプレートの書式(フォント、罫線、列幅)は事前に整えておく
- 印刷範囲を設定しておくとPDFのレイアウトが安定する(「ページレイアウト」→「印刷範囲の設定」)
- 金額セル(D15)の表示形式は
#,##0に設定しておく。書式設定の詳細はセルの書式を一括変更する方法を参照
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | 「パスが見つかりません」エラー | PDF保存先フォルダが存在しない | MkDir で自動作成する。実務版コードでは Dir(savePath, vbDirectory) で存在チェック後に作成している |
| 2 | PDF保存時に「実行時エラー 1004」 | 取引先名に / \ : などファイル名に使えない文字が含まれている |
Replace 関数で禁止文字を全角に置換する。実務版コードでは9種類の禁止文字を置換済み |
| 3 | 金額が「500000」と表示される(カンマなし) | テンプレートのセル書式が「標準」になっている | テンプレートのD15セルの表示形式を #,##0 に設定する。または wsTemplate.Range("D15").NumberFormat = "#,##0" をコードに追加 |
| 4 | 2回目の実行でテンプレートに前回データが残る | ループ終了後にClearContentsしていない | 実務版コードではループ完了後に全転記セルをClearContentsしている。最小版で試す場合も手動でクリアすること |
| 5 | 一覧の列を追加したらデータがズレた | Cells(i, 2) のように列番号をハードコーディングしている |
列番号を Const で定数化する(例: Const COL_CLIENT As Long = 2)。列を変更したら定数だけ直せばよい |
取引先名に「/」が入っていてPDF保存でエラーになったことがある。「株式会社A/B」のような社名で、ファイル名に使えない文字だと気づかずに30分溶かした。実務版コードでは最初からReplace処理を入れているので同じ失敗は起きない。
FAQ
Q1. 請求書に明細行(複数行の品目)を入れたい
一覧シートの構成を変更する。1つの請求番号に対して複数行を持たせ、ループ処理で請求番号が変わるタイミングでPDF保存する。本記事の構成は「1行=1請求書」の最もシンプルなパターン。明細対応は別記事で解説予定。
Q2. 既存のPDFが上書きされるのを防ぎたい
Dir() で同名ファイルの存在をチェックしてスキップする。
If Dir(savePath & fileName) <> "" Then
' 既に存在する場合はスキップ
GoTo NextRecord
End If
Q3. 請求日を今日の日付で自動設定したい
一覧シートのE列に Date 関数の値を入れるか、コード内で直接設定する。
wsTemplate.Range("E3").Value = Date
Q4. 消費税を自動計算してテンプレートに反映したい
テンプレートのD16セルにExcelの数式 =D15*0.1 を入れておく。VBAで小計(D15)を転記すると消費税は数式で自動計算される。コード側で計算する必要はない。
Q5. ボタンからマクロを実行したい
マクロをボタン1つで実行する方法を参照。シート上にボタンを設置して OnAction にマクロ名「請求書を一括作成してPDF保存」を割り当てる。経理以外の人にも使ってもらう場合はボタン化が便利。
まとめ
この記事では、VBAで一覧表から請求書テンプレートにデータを自動転記し、PDFファイルとして一括保存する方法を解説した。
- 最小版: 1件だけ転記して動作確認
- 実務版: 全件ループ + PDF保存 + 確認ダイアログ + 進捗表示
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- ExcelファイルをPDFに一括変換する方法 — PDF変換の基本。ExportAsFixedFormatの詳細はこちら
- セルの転記を自動化する方法 — 別シートへのデータ転記の基本パターン
- 一覧表からExcelテンプレートに差し込み印刷する方法 — 印刷まで含めた差し込み処理
- セルの書式を一括変更する方法 — 金額の表示形式や日付書式の設定
- マクロをボタン1つで実行する方法 — 請求書作成マクロをボタン化する
次にやりたくなること
- 請求番号を連番で自動採番したい → 連番で請求番号を自動採番する方法で、INV-001, INV-002… を自動生成できる
- 支払期限を営業日で計算したい → 営業日で支払期限を計算する方法で、土日祝を除いた期限日を自動設定できる

コメント