この記事でできること
ExcelのデータをWordテンプレートに自動差し込み+印刷(PDF出力)するVBAマクロを作れる。コピペ → 実行まで10分。
対象読者:Excelの一覧データからWordの書類(案内状・通知書・契約書など)を大量に作りたい人。VBAは初心者でOK。
—
導入
案内状を100人分作る仕事があったとき、自分はExcelの名簿をWordに1人ずつコピペして印刷していた。名前と住所を間違えるのが怖くて、1枚ずつ確認しながら進めるので半日かかっていた。正直しんどかった。
VBAでExcel → Word の差し込みを自動化してからは、100人分でも5分で完了するようになった。転記ミスもゼロ。
この記事で、同じ作業で時間を奪われている人が一気に自動化できるようになればうれしい。
前提条件
– Excel 2016以降 / Microsoft 365
– Word 2016以降 / Microsoft 365
– Windows 10/11
– ファイル保存形式:.xlsm(マクロ有効ブック)
– コードの貼り付け場所:標準モジュール(Excel側)
– 実行方法:マクロ実行(Alt + F8)またはボタン割り当て
– Wordテンプレートファイル(.docx)を事前に用意
—
どんな場面で使う?
- 案内状・通知書・契約書などの定型文書をExcelの名簿データから100枚単位で一括作成したいとき
- 宛名・金額・日付などを1人ずつWordにコピペする手作業をなくしたいとき
- 差し込み済みの文書を1人1ファイルのPDFとして個別保存したいとき
- Wordの標準メールマージ機能では対応できない条件分岐やファイル名制御が必要なとき
完成イメージ(Before / After)
Before(手作業)
Excelの名簿 → Wordの案内状テンプレートに1人ずつコピペ → 印刷 or PDF保存 → 100人分繰り返し
After(VBA実行後)
Excelの一覧データを読み取り → Wordテンプレートの {氏名} {住所} などのフィールドに自動挿入 → 全員分のPDFが個別に保存される
【Excelデータ(一覧シート)】
A列 B列 C列 D列
1 氏名 住所 電話番号 会員番号
2 山田太郎 東京都新宿区 03-1234-5678 A001
3 佐藤花子 大阪府大阪市 06-8765-4321 A002
...
↓ VBA実行 ↓
【Wordテンプレート内の {氏名} → 山田太郎 に自動置換】
【Wordテンプレート内の {住所} → 東京都新宿区 に自動置換】
→ PDF保存:案内状_山田太郎.pdf
→ PDF保存:案内状_佐藤花子.pdf
...(全員分自動生成)
—
事前準備
1. Excelデータ(一覧シート)
シート名「データ」に以下の形式でデータを入力する。
| セル | 内容 |
|---|---|
| A1 | 氏名 |
| B1 | 住所 |
| C1 | 電話番号 |
| D1 | 会員番号 |
| A2以降 | 実データを入力 |
1行目のヘッダー名がWordテンプレートの差し込みフィールド名と一致する必要がある。
2. Wordテンプレート(.docx)
Wordファイルを作成し、差し込みたい箇所に {ヘッダー名} を記入する。
ご案内
{氏名} 様
拝啓 時下ますますご清栄のこととお慶び申し上げます。
会員番号:{会員番号}
ご住所:{住所}
お電話:{電話番号}
下記の通りご案内申し上げます。
...
テンプレートファイルはExcelファイルと同じフォルダに保存する。
—
手順
- Excelのデータシートを作成する(1行目がヘッダー、2行目以降がデータ)
- Wordテンプレートを作成し、差し込み箇所に
{ヘッダー名}を記入して保存 - Excel側で Alt + F11 を押してVBE(コードを書く画面)を開く
- 左側のプロジェクトエクスプローラで 「挿入」→「標準モジュール」 を選択
- 下のコードをコピペして貼り付ける
- コード内の
templatePathをWordテンプレートのファイルパスに修正する - Alt + F8 で「MailMergeToWord」を選んで実行
- Wordが自動で開き、差し込み結果が表示されることを確認
- Ctrl + S で .xlsm形式 で保存
ExcelからWordへの転記の基本はExcelの表をWordに自動転記する方法で解説している。まだ読んでいない場合は先にそちらを確認すると理解が早い。
—
基本コード(単一レコード差し込み)
まずはこれで動く、最小限のコード。Excelの1行目のデータをWordテンプレートに差し込む。
Sub MailMergeToWord()
Dim wordApp As Object
Dim wordDoc As Object
Dim wsData As Worksheet
Dim templatePath As String
Dim lastCol As Long
Dim j As Long
Dim fieldName As String
Dim fieldValue As String
' テンプレートのパスを設定(★ここを自分の環境に合わせて変更★)
templatePath = ThisWorkbook.Path & "\テンプレート.docx"
' テンプレートファイルの存在確認
If Dir(templatePath) = "" Then
MsgBox "テンプレートファイルが見つかりません。" & vbCrLf & _
templatePath, vbExclamation
Exit Sub
End If
' データシートを設定
Set wsData = ThisWorkbook.Sheets("データ")
' 最終列を取得
lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column
' Wordを起動してテンプレートを開く
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = True
Set wordDoc = wordApp.Documents.Open(templatePath)
' 1行目のヘッダーをフィールド名として、2行目のデータを差し込み
For j = 1 To lastCol
fieldName = "{" & wsData.Cells(1, j).Value & "}"
fieldValue = CStr(wsData.Cells(2, j).Value)
' Word文書内のフィールドを置換
With wordDoc.Content.Find
.Text = fieldName
.Replacement.Text = fieldValue
.Forward = True
.Wrap = 1 ' wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.Execute Replace:=2 ' wdReplaceAll
End With
Next j
MsgBox "差し込みが完了しました。Word文書を確認してください。", vbInformation
' 後片付け(Wordは開いたまま)
Set wordDoc = Nothing
Set wordApp = Nothing
End Sub
ポイントは、Excelの1行目(ヘッダー)を {ヘッダー名} 形式でWordテンプレート内を検索・置換しているところ。Find.Execute Replace:=2 で文書全体を一括置換できる。
—
実務版コード(全レコードループ+個別PDF保存+差し込みフィールド自動検出)
自分はこの実務版で案内状200通を15分で全部PDFにできた。手作業だったら丸一日かかっていたはず。もっと早く知りたかった。
Sub MailMergeToWordFull()
'=== 実務版:全レコードループ+個別PDF保存+フィールド自動検出 ===
Dim wordApp As Object
Dim wordDoc As Object
Dim wsData As Worksheet
Dim templatePath As String
Dim outputFolder As String
Dim lastRow As Long
Dim lastCol As Long
Dim i As Long
Dim j As Long
Dim fieldName As String
Dim fieldValue As String
Dim pdfFileName As String
Dim successCount As Long
Dim errorCount As Long
' テンプレートのパスを設定(★ここを自分の環境に合わせて変更★)
templatePath = ThisWorkbook.Path & "\テンプレート.docx"
' テンプレートファイルの存在確認
If Dir(templatePath) = "" Then
MsgBox "テンプレートファイルが見つかりません。" & vbCrLf & _
templatePath, vbExclamation
Exit Sub
End If
' ---- ここが追加:PDF出力先フォルダの作成 ----
outputFolder = ThisWorkbook.Path & "\差し込み結果"
If Dir(outputFolder, vbDirectory) = "" Then
MkDir outputFolder
End If
' データシートを設定
Set wsData = ThisWorkbook.Sheets("データ")
' 最終行・最終列を取得
lastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column
If lastRow < 2 Then
MsgBox "データシートにデータがありません。", vbExclamation
Exit Sub
End If
' ---- ここが追加:差し込みフィールドの自動検出 ----
' テンプレートを一度開いてフィールドを確認
Dim fieldNames() As String
Dim fieldCount As Long
fieldCount = 0
ReDim fieldNames(1 To lastCol)
For j = 1 To lastCol
If wsData.Cells(1, j).Value <> "" Then
fieldCount = fieldCount + 1
fieldNames(fieldCount) = wsData.Cells(1, j).Value
End If
Next j
If fieldCount = 0 Then
MsgBox "ヘッダー行(1行目)が空です。", vbExclamation
Exit Sub
End If
' 確認ダイアログ
Dim msg As String
msg = "以下の設定で差し込み印刷を実行します。" & vbCrLf & vbCrLf & _
"データ件数:" & (lastRow - 1) & "件" & vbCrLf & _
"差し込みフィールド:" & fieldCount & "個" & vbCrLf
For j = 1 To fieldCount
msg = msg & " {" & fieldNames(j) & "}" & vbCrLf
Next j
msg = msg & vbCrLf & "PDF出力先:" & outputFolder
If MsgBox(msg, vbOKCancel + vbQuestion, "実行確認") = vbCancel Then
Exit Sub
End If
' ---- ここが追加:画面更新を停止 ----
Application.ScreenUpdating = False
Application.StatusBar = "差し込み印刷を準備しています..."
' Wordを起動(非表示で処理して高速化)
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = False
successCount = 0
errorCount = 0
' ---- ここが追加:全レコードループ ----
For i = 2 To lastRow
On Error Resume Next
' テンプレートを毎回新しく開く(前のレコードの置換が残らないように)
Set wordDoc = wordApp.Documents.Open(templatePath, ReadOnly:=True)
If Err.Number <> 0 Then
errorCount = errorCount + 1
Err.Clear
GoTo NextRecord
End If
On Error GoTo 0
' 各フィールドを差し込み
For j = 1 To fieldCount
fieldName = "{" & fieldNames(j) & "}"
fieldValue = CStr(wsData.Cells(i, j).Value)
' 日付型の場合はフォーマットを適用
If IsDate(wsData.Cells(i, j).Value) And _
Not IsEmpty(wsData.Cells(i, j).Value) Then
fieldValue = Format(wsData.Cells(i, j).Value, "yyyy年mm月dd日")
End If
With wordDoc.Content.Find
.Text = fieldName
.Replacement.Text = fieldValue
.Forward = True
.Wrap = 1 ' wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.Execute Replace:=2 ' wdReplaceAll
End With
Next j
' ---- ここが追加:個別PDF保存 ----
' A列の値をファイル名に使用(A列=氏名の想定)
pdfFileName = wsData.Cells(i, 1).Value
' ファイル名に使えない文字を除去
pdfFileName = Replace(pdfFileName, "\", "")
pdfFileName = Replace(pdfFileName, "/", "")
pdfFileName = Replace(pdfFileName, ":", "")
pdfFileName = Replace(pdfFileName, "*", "")
pdfFileName = Replace(pdfFileName, "?", "")
pdfFileName = Replace(pdfFileName, """", "")
pdfFileName = Replace(pdfFileName, "<", "")
pdfFileName = Replace(pdfFileName, ">", "")
pdfFileName = Replace(pdfFileName, "|", "")
On Error Resume Next
wordDoc.ExportAsFixedFormat _
OutputFileName:=outputFolder & "\" & pdfFileName & ".pdf", _
ExportFormat:=17 ' wdExportFormatPDF = 17
If Err.Number = 0 Then
successCount = successCount + 1
Else
errorCount = errorCount + 1
Err.Clear
End If
On Error GoTo 0
' Word文書を保存せずに閉じる
wordDoc.Close SaveChanges:=False
Set wordDoc = Nothing
NextRecord:
' 進捗表示
Application.StatusBar = "差し込み中... " & (i - 1) & "/" & (lastRow - 1) & "件完了"
DoEvents
Next i
' Wordを終了
wordApp.Quit
Set wordApp = Nothing
' 画面更新を復帰
Application.ScreenUpdating = True
Application.StatusBar = False
MsgBox "差し込み印刷が完了しました。" & vbCrLf & vbCrLf & _
"成功:" & successCount & "件" & vbCrLf & _
"エラー:" & errorCount & "件" & vbCrLf & _
"出力先:" & outputFolder, vbInformation
End Sub
大量のレコードを処理するときは、進捗表示があると安心感が違う。ステータスバーの使い方は処理の進捗をステータスバーに表示する方法で詳しく解説している。
ファイルの存在確認(Dir(templatePath) = "")のパターンはファイルやフォルダの存在を確認してから処理する方法と同じ。外部ファイルを扱うマクロでは必須のチェック。
注意:実行前にWordテンプレートの原本をバックアップしてください。基本コードではテンプレートを直接編集するため、保存すると元に戻せません。実務版はReadOnlyで開くので安全です。
—
落とし穴
| # | 症状 | 原因 | 対策 | |
|---|---|---|---|---|
| 1 | 「ファイルが見つかりません」エラー | templatePath のパスが間違っている、またはファイル名に全角スペースが入っている |
Dir(templatePath) で事前に存在確認する。パスはコピペが確実 |
|
| 2 | 差し込みフィールドが置換されない | Excelのヘッダー名とWordテンプレートの {フィールド名} が一致していない(全角/半角、スペースの有無) |
ヘッダー名を完全一致させる。自分もこれで30分溶かしたことがある。{氏名} と { 氏名 } は別物 |
|
| 3 | Wordが裏で大量に起動してPCが固まる | エラー発生時に wordApp.Quit が実行されず、Wordプロセスが残る |
実務版では On Error Resume Next でエラーを回避しつつ、最後に必ず wordApp.Quit を実行。タスクマネージャーで残ったWordプロセスを手動で終了する場合もある |
|
| 4 | PDFのファイル名に使えない文字でエラーになる | 氏名に \ / : * ? " < > ` |
` が含まれている | 実務版では Replace で禁止文字を除去済み |
| 5 | 日付が「45000」のようなシリアル値で差し込まれる | Excelの日付型がそのまま文字列化されている | 実務版では IsDate() で判定し、Format() で変換してから差し込む |
|
| 6 | Wordテンプレートの書式(フォント・サイズ)が崩れる | Find.Execute Replace で置換すると、置換後のテキストにフィールド部分の書式が引き継がれないことがある |
テンプレート内の {フィールド名} に適用した書式は、置換後も基本的に維持される。ただし複数の書式が混在するフィールドは崩れることがあるので、フィールド全体を同じ書式に統一しておく |
VBAでWordの差し込みフィールドが置換されないときの対処法
「マクロを実行したのにWordのテンプレートがそのまま」という場合、原因はExcelのヘッダー名とWordテンプレート内の{フィールド名}が一致していないことだ。全角・半角、スペースの有無を含めて完全一致させる必要がある。{氏名}と{ 氏名 }は別物なので、コピペでヘッダー名を揃えるのが確実だ。
VBAでWord操作後にWordプロセスが残るときの対処法
「マクロ実行後にPCが重くなる」場合、エラー発生時にwordApp.Quitが呼ばれずWordプロセスがバックグラウンドに残っている可能性がある。On Error GoToでエラーハンドラを用意し、必ずwordApp.QuitとSet wordApp = Nothingを実行する終了処理を入れよう。既に残っているプロセスはタスクマネージャーで手動終了する。
---
FAQ
Q1. Word側でブックマーク(Bookmarks)を使う方法との違いは?
A. ブックマーク方式はExcelの表をWordに自動転記する方法で解説している。{フィールド名} 置換方式は設定が簡単だが、同じフィールドを文書内の複数箇所に置けるのが利点。ブックマーク方式は位置が正確だが、Word側の設定がやや手間。用途に応じて使い分ける。
Q2. Wordの差し込み印刷機能(メールマージ)とVBAの違いは?
A. Wordの標準機能でもExcelデータの差し込み印刷はできる。ただしVBAを使うと、個別PDF保存・ファイル名の自動設定・条件分岐など、標準機能ではできない柔軟な処理が可能になる。定期的に同じ処理を繰り返すならVBAが効率的。
Q3. Excelのデータにフィルタをかけて、特定の人だけ差し込みたい
A. ループ内に If 文で条件を追加する。たとえば「D列が"対象"の行だけ処理する」場合:
If wsData.Cells(i, "D").Value = "対象" Then
' 差し込み処理
End If
条件が複雑な場合は、複数条件でデータを抽出して別シートにまとめる方法で事前にデータを絞り込んでから差し込む方法もある。
Q4. 差し込み結果をPDFではなくWordファイルで個別保存したい
A. ExportAsFixedFormat の代わりに SaveAs2 を使う。
wordDoc.SaveAs2 outputFolder & "\" & pdfFileName & ".docx", _
FileFormat:=12 ' wdFormatXMLDocument = 12
Q5. テンプレートに画像(社印など)を入れておいても大丈夫?
A. 大丈夫。テンプレートの画像は差し込み処理では影響を受けない。ただし、フィールド置換によるテキスト量の増減でレイアウトがずれることがあるので、テンプレート設計時にテスト印刷で確認しておくのが安全。自分は最初のテストで社印が2ページ目にずれて焦ったことがある。
---
まとめ
この記事では、ExcelのデータをWordテンプレートの差し込みフィールドに自動挿入して印刷(PDF出力)するVBAマクロを作成した。
- 基本コード:単一レコードの差し込み(1人分)
- 実務版:全レコードループ+個別PDF保存+フィールド自動検出+進捗表示
Excel → Word の連携パターンを覚えると、案内状・通知書・契約書・証明書など、あらゆる定型文書の大量作成を自動化できる。
Excelファイル同士の操作で完結する場合はExcelファイルを自動で開いて処理して閉じる方法が参考になる。
---
次にやりたくなること
- Excel内だけでテンプレート差し込み印刷を完結させたい → 一覧表からExcelテンプレートに差し込み印刷で、Wordを使わずにExcel内で差し込み印刷する方法を解説している
- 差し込んだPDFをメールに自動添付して送りたい → Excelからメール自動作成(Outlook連携)で、PDFを添付したメールの下書きを自動作成する方法を解説している
- 請求書もExcelデータから自動作成したい → Excelで請求書を自動作成する方法で、顧客一覧から請求書テンプレートに転記する方法を解説している
- 差し込みデータのExcelファイルを事前に自動整形したい → Excelファイルを自動で開いて処理して閉じる方法で、差し込み前のデータ準備を自動化できる
- エラーで止まらないマクロにしたい → On Error GoToでエラーが起きても止まらないVBAを書く方法で、Word操作時のエラー処理を堅牢にできる
---
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "VBAでExcelからWordに差し込み印刷するとき、ブックマーク方式とフィールド置換方式の違いは?",
"acceptedAnswer": {
"@type": "Answer",
"text": "フィールド置換方式({フィールド名}を検索置換)は設定が簡単で、同じフィールドを文書内の複数箇所に置けるのが利点です。ブックマーク方式は位置が正確ですが、Word側でブックマークを事前設定する手間がかかります。"
}
},
{
"@type": "Question",
"name": "VBAの差し込み印刷とWordの標準メールマージ機能の違いは?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Wordの標準機能でもExcelデータの差し込み印刷はできますが、VBAを使うと個別PDF保存・ファイル名の自動設定・条件分岐など柔軟な処理が可能です。定期的に同じ処理を繰り返すならVBAが効率的です。"
}
},
{
"@type": "Question",
"name": "VBAでExcelの特定のデータだけWordに差し込むには?",
"acceptedAnswer": {
"@type": "Answer",
"text": "ループ内にIf文で条件を追加します。例えば特定の列の値が「対象」の行だけ処理するようにIf wsData.Cells(i, \"D\").Value = \"対象\" Thenで条件分岐します。"
}
},
{
"@type": "Question",
"name": "VBAで差し込み結果をWordファイルで個別保存するには?",
"acceptedAnswer": {
"@type": "Answer",
"text": "ExportAsFixedFormatの代わりにSaveAs2を使います。wordDoc.SaveAs2でFileFormat:=12(wdFormatXMLDocument)を指定すると.docx形式で保存できます。"
}
},
{
"@type": "Question",
"name": "VBAの差し込み印刷でWordテンプレートに画像を入れても大丈夫?",
"acceptedAnswer": {
"@type": "Answer",
"text": "大丈夫です。テンプレートの画像は差し込み処理では影響を受けません。ただしテキスト量の増減でレイアウトがずれることがあるので、テスト印刷で確認しておくのが安全です。"
}
}
]
}


コメント