この記事でできること
VBAでデータシートから月次報告書テンプレートに自動転記し、PDF出力できるようになる。
- 対象:毎月の報告書をコピペで作っている人
- 所要時間:コピペ → 実行まで5分
—
どんな場面で使う?
- 毎月の売上データを集計してテンプレートに転記し、上長に提出する月次報告書を自動化したいとき
- 部門別・拠点別の実績をまとめたPDF報告書を一括で出力したいとき
- 前月比や達成率などの計算をVBAで自動化してヒューマンエラーをなくしたいとき
- 報告書にグラフを自動挿入して、見栄えの良い資料をワンクリックで作りたいとき
完成イメージ(Before / After)
Before(手作業)
| 操作 | 時間 |
|---|---|
| データシートから対象月の数値を目視で拾う | 15分 |
| テンプレートに1項目ずつ転記 | 20分 |
| グラフのデータ範囲を手動で更新 | 10分 |
| PDF保存して上長に提出 | 5分 |
合計50分。転記ミスで差し戻されると、さらに30分ロス。
After(VBA実行後)
- 対象月を選んでマクロを実行する
- データが自動で抽出・集計・転記される
- グラフが自動更新される
- PDFが保存される
- 3分で完了。転記ミスゼロ
データシート(入力するデータ):
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | 年月 | 売上 | 原価 | 経費 | 利益 |
| 2 | 2026/01 | 5000000 | 3000000 | 800000 | 1200000 |
| 3 | 2026/02 | 5500000 | 3200000 | 850000 | 1450000 |
| 4 | 2026/03 | 6000000 | 3500000 | 900000 | 1600000 |
出力されるPDF:
月次報告書PDF\
└── 月次報告書_2026年03月.pdf
—
毎月の報告書を手で作っていた時期がある。データシートから数値を拾って、テンプレートに1セルずつコピペして、グラフの範囲を直して、PDFに変換。正直、月初の報告書作成が憂鬱だった。しかも一度、前月のデータを転記してしまい上長に指摘されたことがある。
VBAで自動化してからは、月を選んで実行するだけ。50分→3分になった。転記ミスもゼロ。月初のストレスがなくなった。
同じように毎月の報告書で時間を取られている人に、この自動化を試してほしい。まずは固定データの転記から始めよう。
データシート → テンプレート転記 → PDF出力。この流れをVBAで自動化する。
—
事前準備
シート構成を用意する
このマクロは2つのシートを使う。
「データ」シート — 月別の実績データ
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 年月 | 2026/03 |
| B列 | 売上 | 6000000 |
| C列 | 原価 | 3500000 |
| D列 | 経費 | 900000 |
| E列 | 利益 | 1600000 |
- 1行目はヘッダー。データは2行目から入力する
- A列は日付型で入力する(年月の1日を入力:2026/03/01)
「報告書」シート — テンプレート(転記先)
| セル | 内容 |
|---|---|
| C3 | 報告書タイトル(例:2026年03月 月次報告書) |
| C6 | 売上 |
| C7 | 原価 |
| C8 | 経費 |
| C9 | 利益 |
| C10 | 利益率 |
テンプレートのレイアウトは自由に変更してよい。重要なのは転記先のセル位置を合わせること。
バックアップを取る
テンプレートシートにデータを上書きする処理のため、実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
—
コード(最小版)– データシートからテンプレートに転記
まず最新月のデータを1件だけ転記して動作確認する。月選択もPDF保存もないシンプルな構成。
セルの転記の基本はセルの転記を自動化する方法を参照。テンプレートの考え方はExcelで請求書を自動作成する方法と同じパターン。
Sub 月次報告書を作成する()
Dim wsData As Worksheet
Dim wsReport As Worksheet
Dim lastRow As Long
Set wsData = Worksheets("データ")
Set wsReport = Worksheets("報告書")
' ★ 最終行を取得(A列で判定)
lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データシートにデータがありません。", vbExclamation
Exit Sub
End If
' 最終行(最新月)のデータを転記
Dim sales As Double
Dim cost As Double
Dim expense As Double
Dim profit As Double
sales = wsData.Cells(lastRow, 2).Value ' 売上
cost = wsData.Cells(lastRow, 3).Value ' 原価
expense = wsData.Cells(lastRow, 4).Value ' 経費
profit = wsData.Cells(lastRow, 5).Value ' 利益
With wsReport
' ★ タイトル
.Range("C3").Value = Format(wsData.Cells(lastRow, 1).Value, "yyyy年mm月") & " 月次報告書"
' ★ 各項目を転記
.Range("C6").Value = sales
.Range("C7").Value = cost
.Range("C8").Value = expense
.Range("C9").Value = profit
' 利益率(売上がゼロの場合はゼロ)
If sales <> 0 Then
.Range("C10").Value = profit / sales
Else
.Range("C10").Value = 0
End If
End With
wsReport.Activate
MsgBox "月次報告書を作成しました。"
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("データ") |
データ | 実績データのシート名 |
| 2 | Worksheets("報告書") |
報告書 | テンプレートのシート名 |
| 3 | .Range("C3") 等 |
C3, C6〜C10 | テンプレート側の転記先セル |
| 4 | wsData.Cells(lastRow, 2) 等 |
列2〜5 | データ側の列番号 |
動作確認
- 「データ」シートに最低1行のテストデータを入力する
- マクロを実行する
- 「報告書」シートに切り替わり、データが転記されていることを確認する
最小版で転記が確認できたら、次の実務版に進む。
—
コード(実務版)– 月選択 → データ抽出 → グラフ付き報告書PDF出力
自分はこの方法で毎月の報告書を処理している。月初の作業が50分→3分になった。InputBoxで対象月を選べるので、過去月の再出力にも対応できる。
InputBoxの使い方はInputBoxで条件を入力させて処理を動的に変える方法を参照。グラフ作成の基本はデータ範囲からグラフを自動作成する方法を参照。
Sub 月次報告書を自動生成()
Dim wsData As Worksheet
Dim wsReport As Worksheet
Dim lastRow As Long
Dim targetMonth As String
Dim targetDate As Date
Dim i As Long
Dim savePath As String
Dim fileName As String
Set wsData = Worksheets("データ")
Set wsReport = Worksheets("報告書")
' ★ 対象月を入力(yyyy/mm形式)
targetMonth = InputBox("対象月を入力してください(例: 2026/03)", _
"月次報告書の生成", Format(Date, "yyyy/mm"))
If targetMonth = "" Then Exit Sub
' 入力値の検証
On Error Resume Next
targetDate = CDate(targetMonth & "/01")
On Error GoTo 0
If targetDate = 0 Then
MsgBox "日付の形式が正しくありません。" & vbCrLf & _
"yyyy/mm 形式で入力してください。", vbExclamation
Exit Sub
End If
' 最終行を取得
lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データシートにデータがありません。", vbExclamation
Exit Sub
End If
' 対象月のデータを検索
Dim found As Boolean
Dim sales As Double
Dim cost As Double
Dim expense As Double
Dim profit As Double
found = False
For i = 2 To lastRow
If Format(wsData.Cells(i, 1).Value, "yyyy/mm") = Format(targetDate, "yyyy/mm") Then
sales = wsData.Cells(i, 2).Value
cost = wsData.Cells(i, 3).Value
expense = wsData.Cells(i, 4).Value
profit = wsData.Cells(i, 5).Value
found = True
Exit For
End If
Next i
If Not found Then
MsgBox Format(targetDate, "yyyy年mm月") & " のデータが見つかりません。", vbExclamation
Exit Sub
End If
' 確認ダイアログ
If MsgBox(Format(targetDate, "yyyy年mm月") & " の月次報告書を作成します。" & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
Application.ScreenUpdating = False
' --- テンプレートに転記 ---
With wsReport
.Range("C3").Value = Format(targetDate, "yyyy年mm月") & " 月次報告書"
.Range("C6").Value = sales
.Range("C7").Value = cost
.Range("C8").Value = expense
.Range("C9").Value = profit
If sales <> 0 Then
.Range("C10").Value = profit / sales
Else
.Range("C10").Value = 0
End If
' --- 前月比を計算して転記(ここが追加) ---
Dim prevDate As Date
Dim prevSales As Double
Dim prevProfit As Double
Dim prevFound As Boolean
prevDate = DateAdd("m", -1, targetDate)
prevFound = False
For i = 2 To lastRow
If Format(wsData.Cells(i, 1).Value, "yyyy/mm") = Format(prevDate, "yyyy/mm") Then
prevSales = wsData.Cells(i, 2).Value
prevProfit = wsData.Cells(i, 5).Value
prevFound = True
Exit For
End If
Next i
' ★ 前月比(D列に出力)
If prevFound And prevSales <> 0 Then
.Range("D6").Value = (sales - prevSales) / prevSales ' 売上前月比
Else
.Range("D6").Value = "---"
End If
If prevFound And prevProfit <> 0 Then
.Range("D9").Value = (profit - prevProfit) / prevProfit ' 利益前月比
Else
.Range("D9").Value = "---"
End If
' --- グラフを更新(ここが追加) ---
' 直近6ヶ月のデータでグラフを作成
Dim chartObj As ChartObject
Dim startRow As Long
Dim endRow As Long
' 対象月を含む直近6ヶ月の範囲を決定
endRow = 0
For i = 2 To lastRow
If Format(wsData.Cells(i, 1).Value, "yyyy/mm") = Format(targetDate, "yyyy/mm") Then
endRow = i
Exit For
End If
Next i
startRow = endRow - 5
If startRow < 2 Then startRow = 2
' 既存のグラフを削除
For Each chartObj In .ChartObjects
chartObj.Delete
Next chartObj
' ★ グラフを作成(売上・利益の推移)
Set chartObj = .ChartObjects.Add( _
Left:=.Range("B13").Left, _
Top:=.Range("B13").Top, _
Width:=400, _
Height:=250)
With chartObj.Chart
.ChartType = xlColumnClustered
' 売上系列
.SeriesCollection.NewSeries
.SeriesCollection(1).Values = wsData.Range(wsData.Cells(startRow, 2), wsData.Cells(endRow, 2))
.SeriesCollection(1).XValues = wsData.Range(wsData.Cells(startRow, 1), wsData.Cells(endRow, 1))
.SeriesCollection(1).Name = "売上"
' 利益系列
.SeriesCollection.NewSeries
.SeriesCollection(2).Values = wsData.Range(wsData.Cells(startRow, 5), wsData.Cells(endRow, 5))
.SeriesCollection(2).Name = "利益"
.HasTitle = True
.ChartTitle.Text = "売上・利益推移(直近" & (endRow - startRow + 1) & "ヶ月)"
.HasLegend = True
.Legend.Position = xlLegendPositionBottom
End With
End With
' --- PDF保存(ここが追加) ---
savePath = ThisWorkbook.Path & "\月次報告書PDF\"
If Dir(savePath, vbDirectory) = "" Then
MkDir savePath
End If
fileName = "月次報告書_" & Format(targetDate, "yyyy年mm月") & ".pdf"
wsReport.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=savePath & fileName, _
Quality:=xlQualityStandard
Application.ScreenUpdating = True
MsgBox "月次報告書を作成しました。" & vbCrLf & _
"保存先: " & savePath & fileName, vbInformation
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | "\月次報告書PDF\" |
月次報告書PDF | PDF保存先フォルダ名 |
| 2 | .Range("C3") 等 |
C3, C6〜C10 | テンプレート側の転記先セル |
| 3 | .Range("D6"), .Range("D9") |
D6, D9 | 前月比の出力先セル |
| 4 | Left:=.Range("B13").Left |
B13 | グラフの配置位置(左上セル) |
| 5 | Width:=400, Height:=250 |
400, 250 | グラフのサイズ(ピクセル) |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| 月選択(InputBox) | 対象月をyyyy/mm形式で入力。過去月の再出力にも対応 | InputBoxの使い方 |
| 入力値検証 | 不正な日付形式をチェックしてエラー表示 | — |
| 前月比の自動計算 | 売上・利益の前月比を算出してD列に出力 | — |
| グラフ自動生成 | 直近6ヶ月の売上・利益推移を棒グラフで表示 | グラフ自動作成 |
| PDF保存 | 報告書シートをPDFとして保存 | PDF一括変換 |
| 確認ダイアログ | 対象月を表示してYes/Noで確認 | — |
—
テンプレートの作り方
「報告書」シートのレイアウト例を示す。実際のデザインは自由に変更してよい。重要なのは転記先のセル位置を合わせること。
レイアウト例
行1 : [空白]
行2 : [空白]
行3 : [空白] C3: 2026年03月 月次報告書
行4 : [空白]
行5 : [空白] B列:項目名 C列:今月 D列:前月比
行6 : [空白] 売上 C6:5000000 D6:+10.0%
行7 : [空白] 原価 C7:3000000
行8 : [空白] 経費 C8:800000
行9 : [空白] 利益 C9:1200000 D9:+13.0%
行10 : [空白] 利益率 C10:24.0%
行11 : [空白] ─────────────────
行12 : [空白]
行13 : [空白] ← ここにグラフが自動配置される
ポイント
- 金額セル(C6〜C9)の表示形式は
#,##0に設定しておく。書式設定の詳細はセルの書式を一括変更する方法を参照 - 利益率(C10)の表示形式は
0.0%に設定する - 前月比(D6, D9)の表示形式は
+0.0%;-0.0%にすると見やすい - 印刷範囲を設定しておくとPDFのレイアウトが安定する
- テンプレートに罫線・タイトル書式・会社ロゴなどを事前に設定しておくと、出力されるPDFの見栄えが良くなる
—
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | 「データが見つかりません」と表示される | A列の年月がテキスト形式になっている | セルを選択 →「データ」→「区切り位置」→「完了」で日付型に変換。または CDate() でコード側で変換 |
| 2 | グラフのデータが表示されない | データシートの行数が6行未満で startRow がデータ範囲外になる |
If startRow < 2 Then startRow = 2 で最小行を保証している。データが1ヶ月分でも動作する |
| 3 | PDFにグラフが含まれない | グラフの配置が印刷範囲の外にある | 「ページレイアウト」→「印刷範囲の設定」でグラフを含む範囲を指定する |
| 4 | 前月比が「---」になる | 前月のデータがデータシートに存在しない | 前月データがない場合は「---」を表示する仕様。データを追加するか、表示テキストを変更する |
| 5 | 2回実行すると前回のグラフが残る | 既存グラフの削除処理が抜けている | 実務版コードでは ChartObjects をループして既存グラフを削除してから新規作成している |
| 6 | 利益率が「0」になる | 売上がゼロのデータ行を転記した | ゼロ除算チェック If sales <> 0 Then を入れている。テストデータにゼロを入れないこと |
A列の年月がテキスト形式で格納されていて、Format() で比較しても一致しないパターンにハマったことがある。見た目は「2026/03」なのに中身は文字列。これで20分溶かした。日付型で入力しているかどうかは、セルの表示形式を「標準」にしてシリアル値(例:46143)が表示されるか確認すれば分かる。
VBAで月次報告書のデータが転記されないときの対処法
「マクロを実行したのにテンプレートが空のまま」という場合、原因はA列の年月データがテキスト形式で格納されており、日付比較が一致しないことだ。セルの表示形式を「標準」にしてシリアル値が表示されるか確認し、テキスト形式なら「データ」→「区切り位置」→「完了」で日付型に変換しよう。
VBAで月次報告書のPDF出力が白紙になるときの対処法
「PDFを出力したのに中身が白紙」という場合、印刷範囲がデータやグラフのある領域をカバーしていない可能性が高い。「ページレイアウト」→「印刷範囲の設定」でテンプレート全体を含む範囲を指定し、改ページプレビューでグラフが範囲内に収まっているか確認しよう。
---
FAQ
Q1. データシートに複数の項目列(部門別売上など)を追加したい
列を追加して、転記コードの wsData.Cells(i, 列番号) と wsReport.Range("転記先") のペアを増やせばよい。列番号を Const で定数化しておくと管理が楽になる。
Const COL_SALES As Long = 2
Const COL_COST As Long = 3
' 追加列
Const COL_DEPT_A As Long = 6
Const COL_DEPT_B As Long = 7
Q2. グラフの種類を折れ線グラフに変えたい
.ChartType = xlColumnClustered を .ChartType = xlLine に変更する。グラフの種類一覧はデータ範囲からグラフを自動作成する方法を参照。
Q3. 複数月分の報告書をまとめてPDF出力したい
InputBoxの代わりにループ処理で対象月を回す。見積書・納品書をテンプレートから自動作成する方法の一括出力パターンが参考になる。
' 例:4月〜3月の12ヶ月分を一括出力
Dim m As Long
For m = 4 To 15
targetDate = DateSerial(2025, m, 1)
' ... 転記・PDF保存処理 ...
Next m
Q4. 報告書に前年同月のデータも載せたい
前月比と同じ要領で、DateAdd("yyyy", -1, targetDate) で前年同月のデータを検索し、別のセルに転記する。
Q5. ボタンから実行したい
マクロをボタン1つで実行する方法を参照。シート上にボタンを設置して OnAction にマクロ名「月次報告書を自動生成」を割り当てる。
---
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "データシートに複数の項目列(部門別売上など)を追加したい",
"acceptedAnswer": {
"@type": "Answer",
"text": "列を追加して、転記コードの wsData.Cells(i, 列番号) と wsReport.Range(\"転記先\") のペアを増やせばOKです。列番号をConstで定数化しておくと管理が楽になります。"
}
},
{
"@type": "Question",
"name": "グラフの種類を折れ線グラフに変えたい",
"acceptedAnswer": {
"@type": "Answer",
"text": ".ChartType = xlColumnClustered を .ChartType = xlLine に変更するだけでOKです。グラフ種類の一覧はデータ範囲からグラフを自動作成する方法の記事を参照してください。"
}
},
{
"@type": "Question",
"name": "複数月分の報告書をまとめてPDF出力したい",
"acceptedAnswer": {
"@type": "Answer",
"text": "InputBoxの代わりにループ処理で対象月を回します。Forループで4月〜翌3月を処理し、各月ごとに転記→PDF保存を実行すれば一括出力できます。"
}
},
{
"@type": "Question",
"name": "報告書に前年同月のデータも載せたい",
"acceptedAnswer": {
"@type": "Answer",
"text": "前月比と同じ要領で、DateAdd(\"yyyy\", -1, targetDate) で前年同月のデータを検索し、別のセルに転記します。"
}
},
{
"@type": "Question",
"name": "ボタンから実行したい",
"acceptedAnswer": {
"@type": "Answer",
"text": "シート上にボタンを設置してOnActionにマクロ名を割り当てます。マクロをボタン1つで実行する方法の記事でボタン設置の手順を紹介しています。"
}
}
]
}
---
まとめ
この記事では、VBAでデータシートから月次報告書テンプレートにデータを自動転記し、グラフ付きPDFとして出力する方法を解説した。
- 最小版: 最新月のデータをテンプレートに転記して動作確認
- 実務版: 月選択 + 前月比計算 + グラフ自動生成 + PDF保存
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- Excelで請求書を自動作成する方法 -- テンプレート転記の基本パターン。本記事と同じ考え方で帳票を作れる
- 見積書・納品書をテンプレートから自動作成する方法 -- 一覧データからの一括出力パターン
- テンプレートシートをコピーして月別・担当者別に量産する方法 -- 月別シートの自動生成
- データ範囲からグラフを自動作成する方法 -- グラフ作成のChartType一覧・書式設定の詳細
- ExcelファイルをPDFに一括変換する方法 -- ExportAsFixedFormatの詳細
---
次にやりたくなること
月次報告書の自動生成ができたら、次はこのあたりが気になるはず。
- 報告書のテンプレートを月ごとにシート分けして管理したい → テンプレートシートをコピーして月別・担当者別に量産する方法で、月別シートの一括生成ができる
- 報告書のグラフをもっと凝った見た目にしたい → データ範囲からグラフを自動作成する方法で、グラフの種類・色・凡例の詳細設定ができる
- 作成した報告書PDFをメールで自動送信したい → Excelファイルをメールに自動添付して送信する方法で、PDF添付メールの自動化ができる
- 報告書作成を毎月決まった日に自動実行したい → Excelを閉じていてもマクロを定時実行する方法で、タスクスケジューラによる完全自動化ができる
- 報告書のデータ元になる売上集計を自動化したい → 売上データを月別・担当者別に自動集計する方法で、集計作業もセットで自動化できる


コメント