毎月の月次レポート作成、まだ手作業で消耗していませんか? VBAマクロを使えば「ボタン1クリック」で完了します。本記事では、現場でそのまま使える実例コード10本を、コピペで動く形でご紹介します。導入企業では 月18時間 → 0.5時間(96%削減) を達成した実績もあります。
はじめに – なぜVBA自動化なのか
中小企業の経理・営業企画担当者にヒアリングすると、月次レポート作成に 毎月8〜20時間 を費やしているケースが珍しくありません。同じ操作を毎月繰り返しているなら、それは VBAで自動化すべきサイン です。
本記事では、実際の案件で繰り返し使ってきた、月次レポート自動化に役立つVBAコード10本を厳選してご紹介します。すべて動作確認済みです。
①ボタン1クリックで全シート再計算
複数シートにまたがる集計を行う際、計算順序のミスや循環参照で結果がズレる事故を防ぎます。レポート生成の最初の1ステップとして組み込みましょう。
Sub RecalcAll()
Application.CalculateFullRebuild
MsgBox "全シートの再計算が完了しました", vbInformation
End Sub
使いどころ
SUMIFS/INDEX-MATCH/LAMBDA等の重い式が散在するブックで、データ取り込み後に呼び出します。CalculateFullRebuild はキャッシュも含めて完全再構築するため、軽いCalculateより確実です。
②指定日のシートをコピー&リネーム
「YYYY-MM」形式のシートを毎月作るために、テンプレートシートを複製して月名でリネームします。手作業の「右クリック→コピーを作成→名前を変更」を撲滅できます。
Sub CreateMonthlySheet()
Dim newName As String
newName = Format(DateAdd("m", -1, Date), "yyyy-mm")
On Error Resume Next
If Not Worksheets(newName) Is Nothing Then
MsgBox "シート " & newName & " はすでに存在します"
Exit Sub
End If
On Error GoTo 0
Worksheets("テンプレート").Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = newName
End Sub
③CSVを一括取り込みして整形
基幹システムから出力された複数CSVを、フォルダ指定で一気に取り込み、決まった列順に整形して1枚のシートにまとめます。
Sub ImportCsvBatch()
Dim folderPath As String, fileName As String
Dim ws As Worksheet
folderPath = "C:\Reports\Input\"
fileName = Dir(folderPath & "*.csv")
Set ws = ThisWorkbook.Sheets("取込")
ws.Cells.Clear
ws.Range("A1:E1").Value = Array("日付", "拠点", "商品", "数量", "金額")
Do While fileName <> ""
With ws.QueryTables.Add( _
Connection:="TEXT;" & folderPath & fileName, _
Destination:=ws.Cells(ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFilePlatform = 65001 ' UTF-8
.Refresh BackgroundQuery:=False
End With
fileName = Dir
Loop
End Sub
⚠ 注意:
QueryTablesは将来的に廃止予定とアナウンスされていますが2026年時点でまだ動作します。長期的にはWorkbooks.OpenTextまたはPower Query (M言語)への移行を検討してください。
④ピボットテーブルを自動更新+書式リセット
データソース変更後にピボットが自動更新されない問題と、フィールド追加で書式が崩れる問題を一気に解決します。
Sub RefreshAllPivots()
Dim ws As Worksheet, pt As PivotTable
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
pt.NullString = "0"
pt.TableStyle2 = "PivotStyleMedium9"
Next pt
Next ws
End Sub
⑤PDFで月次フォルダに自動保存
完成したレポートを C:\Reports\Output\YYYY\YYYY-MM\ 形式でフォルダ階層を作りながらPDF保存します。ファイル名にもタイムスタンプを付けて履歴管理を楽にします。
Sub ExportPDFToMonthlyFolder()
Dim baseDir As String, fullPath As String
Dim yyyy As String, yyyymm As String
yyyy = Format(Date, "yyyy")
yyyymm = Format(Date, "yyyy-mm")
baseDir = "C:\Reports\Output\" & yyyy & "\" & yyyymm & "\"
If Dir(baseDir, vbDirectory) = "" Then
MkDir "C:\Reports\Output\" & yyyy
MkDir baseDir
End If
fullPath = baseDir & "月次レポート_" & Format(Now, "yyyymmdd_hhnnss") & ".pdf"
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
fileName:=fullPath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
OpenAfterPublish:=False
End Sub
⑥Outlookで関係者全員に自動配信
PDF添付付きで、CC・BCC含め指定したアドレス全員にメール下書きを生成します。自動送信ではなく下書き作成にすることで誤送信リスクを抑えるのがコツです。
Sub CreateOutlookDraft(attachmentPath As String)
Dim olApp As Object, olMail As Object
Set olApp = CreateObject("Outlook.Application")
Set olMail = olApp.CreateItem(0)
With olMail
.To = "kanrisha@example.com; tantosha@example.com"
.CC = "leader@example.com"
.Subject = Format(DateAdd("m", -1, Date), "yyyy年m月") & " 月次レポート"
.Body = "お疲れさまです。" & vbCrLf & vbCrLf & _
Format(DateAdd("m", -1, Date), "yyyy年m月") & "の月次レポートを送付いたします。"
.Attachments.Add attachmentPath
.Display ' .Send にすれば即送信(非推奨)
End With
End Sub
⑦エラー時は管理者にメール通知
定時バッチ実行中のエラーを見落とさないように、On Error句で例外を捕まえて管理者に通知します。
Sub NotifyAdmin(errNo As Long, errDesc As String)
Dim olApp As Object, olMail As Object
Set olApp = CreateObject("Outlook.Application")
Set olMail = olApp.CreateItem(0)
With olMail
.To = "admin@example.com"
.Subject = "[ERR] 月次レポート処理失敗 " & Format(Now, "yyyy/mm/dd hh:nn")
.Body = "エラー番号: " & errNo & vbCrLf & "詳細: " & errDesc
.Send
End With
End Sub
⑧前月比・前年比を自動算出
当月実績シートと前月・前年同月シートの値を突合し、差額と比率を算出します。手計算でやると桁数ミスが起きやすい箇所です。
Function GetVariance(currentVal As Double, previousVal As Double) As String
If previousVal = 0 Then
GetVariance = "—"
Exit Function
End If
Dim ratio As Double
ratio = (currentVal - previousVal) / previousVal
GetVariance = Format(ratio, "+0.0%;-0.0%;0.0%")
End Function
シート上の式から =GetVariance(B5, B4) のように呼び出せます。負の値が赤・正の値が青で表示されるので、ひと目で増減傾向が掴めます。
⑨処理ログを自動記録
「いつ・誰が・何を・どれくらいの時間で実行したか」をログシートに自動追記。後から問題が起きた時の調査時間が大幅に減ります。
Sub WriteLog(actionName As String, startTime As Date)
Dim ws As Worksheet, row As Long, duration As Double
Set ws = ThisWorkbook.Sheets("ログ")
row = ws.Cells(Rows.Count, 1).End(xlUp).row + 1
duration = (Now - startTime) * 86400 ' 秒に変換
ws.Cells(row, 1).Value = Now
ws.Cells(row, 2).Value = Environ("USERNAME")
ws.Cells(row, 3).Value = actionName
ws.Cells(row, 4).Value = Format(duration, "0.00") & "秒"
End Sub
⑩全部まとめて1ボタン化
①〜⑨を統合した「月次レポート完全自動化マクロ」です。シートの先頭にボタンを配置して、月初に1クリック実行すれば全工程が完了します。
Sub RunMonthlyReport()
Dim t As Date: t = Now
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error GoTo ErrHandler
Call WriteLog("月次レポート開始", t)
Call RecalcAll
Call CreateMonthlySheet
Call ImportCsvBatch
Call RefreshAllPivots
Call ExportPDFToMonthlyFolder
Call CreateOutlookDraft("C:\Reports\Output\latest.pdf")
Call WriteLog("月次レポート完了", t)
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "月次レポート処理が完了しました", vbInformation
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Call NotifyAdmin(Err.Number, Err.Description)
End Sub
🎯 期待される効果: 実際の導入事例では、月次レポート作成時間が 18時間 → 0.5時間(96%削減) となりました。空いた工数は、レポート結果の分析・施策立案に振り向けるのが正解です。「作る」より「使う」に時間を使いましょう。
まとめ
VBA自動化の本質は「同じ操作を二度とやらない」ことです。最初の構築には数時間〜数日かかりますが、月8〜20時間の手作業を恒久的に消せます。
本記事のコードをベースに、自社の月次レポートに合わせてカスタマイズしてください。コード調整や本格的な業務改善のご相談は、お問い合わせからお気軽にどうぞ。
