エクセルの便利な機能の一つに、Excelシートからレポート作成することがありますが、その効率的な利用にはVBAマクロの利用です。VBAマクロを活用して集めたデータシートから、担当者別レポートをシートから作成する方法で、あなたのスキル向上と業務効率化をサポートする情報をお届けします。
目次
VBAマクロを使った担当者別レポートを作成|利用シーン
「エクセルVBAマクロで複数Excelシートをひとつに集める方法」で集めたExcelファイルのシートを集計して担当者別売上金額のレポートを作成します。このエクセルVBAマクロで、毎月もしくは毎日の担当者別売上金額レポートの作成が自動化され、時間と手間を大幅に削減できます。
VBAマクロを使った担当者別レポートを作成|サンプルコード
1. ユーザーが年月を入力すると、フォームでその年月を受け取ります。
2. その年月に基づいてSalesDataシートのデータを集計し、担当者ごとの売上金額を計算します。
3. 集計結果をレポートシートに出力し、新しいレポートが生成されます。
サンプルのキャプチャ
対象のExcel
Excelのシート内容(マクロ記述のThisWorkbook)
準備するExcelデータ
シート担当者マスタの内容
集計した結果のシート
コード入力したキャプチャ(フォーム)
コード入力したキャプチャ(標準モジュール)
マクロ実行時のキャプチャ
ユーザーフォームサンプルコード
ユーザーフォームのボタン(CommandButton2)がクリックされたときに実行される処理を定義しています。
Private Sub CommandButton2_Click()
' 入力された年月を変数に格納
Dim inputYearMonth As String
inputYearMonth = TextBox1.Text
' 入力が正しい6桁の年月かどうかを確認
If Len(inputYearMonth) <> 6 Or Not IsNumeric(inputYearMonth) Then
MsgBox "正しい6桁の年月を入力してください (例: 202308)", vbExclamation
Exit Sub
End If
' メインのレポート生成処理を呼び出し
GenerateDailyReport inputYearMonth
' UserFormを閉じる
Unload Me
End Sub
ユーザーフォームサンプルコード解説
1. Private Sub CommandButton2_Click()
・この行は、Excelのユーザーフォームに配置されたボタン(CommandButton2)がクリックされたときに実行される処理を定義しています。
2. 入力された年月を変数に格納
Dim inputYearMonth As String
inputYearMonth = TextBox1.Text
・inputYearMonthという名前の文字列型変数を宣言し、ユーザーフォームにあるテキストボックス(TextBox1)に入力された値をこの変数に格納します。たとえば、ユーザーが「202308」と入力した場合、その値がinputYearMonthに保存されます。
3. 入力が正しい6桁の年月かどうかを確認
If Len(inputYearMonth) <> 6 Or Not IsNumeric(inputYearMonth) Then
MsgBox "正しい6桁の年月を入力してください (例: 202308)", vbExclamation
Exit Sub
End If
・Len(inputYearMonth)は、inputYearMonthの文字数を取得します。年月は6桁であるべきなので、6桁でない場合に次の処理を行います。
・IsNumeric(inputYearMonth)は、inputYearMonthが数値であるかどうかを確認します。年月は数値(例: 202308)でなければならないため、数値でない場合に次の処理を行います。
・条件が満たされない(6桁でない、または数値でない)場合、MsgBox関数でメッセージボックスを表示し、「正しい6桁の年月を入力してください」という警告メッセージを出します。
・Exit Subで処理を終了し、これ以上のコードは実行されません。
4. メインのレポート生成処理を呼び出し
GenerateDailyReport inputYearMonth
・GenerateDailyReportというサブプロシージャ(別のコードとして定義されているはずです)を呼び出します。このとき、inputYearMonthを引数として渡します。
・このプロシージャは、inputYearMonthに基づいて日次レポートを生成する処理を行います。
5. UserFormを閉じる
Unload Me
営業部から「作業時間がかかりすぎる」と相談された係長の佐藤さん。繰り返し作業を効率化するVBAの必要性を感じていましたが、「難しそう」と一歩を踏み出せずにいました。 実際、VBAを実際に使いこなせる人は5割以下。独学で進められる人は3割程度という調査結果もあり、不安が募るばかり。 そんな中、佐藤さんは「Excel VBAエキスパート資格」の学習を開始。初心者向けの基礎から実践的な応用まで体系的に学べる内容に助けられ、資格取得を目指すことでモチベーションを維持しながらスキルを習得しました。 今では営業部の課題を次々と解決し、職場で信頼される存在に成長した佐藤さん。「難しそう」と感じていた不安はいつしか自信に変わり、業務効率化が職場全体の活気を生むきっかけになりました。 Excel VBAで業務を変える佐藤さんの挑戦 基本的な文法やVBAの実践的な応用までを網羅的に学習できる方法は、ExcelVBAエキスパート資格の取得を目指すこと。学習を通して、より効率的に、着実に基礎を身につけることが可能です。資格取得すれば、スキルの証明にもなり、職場での評価アップにも繋がるため、勉強を進めるモチベーションにもなります。
本サイト参考:マクロ知識がないから「何から学べば良いのかわからない」という人におすすめの記事
標準モジュールサンプルコード
Excel VBAを使ってユーザーフォームを表示し、特定の年月のデータをもとに日次レポートを生成するものです。
Option Explicit
Sub GenerateDailyReport(currentDate As String)
Dim wsData As Worksheet
Dim wsReport As Worksheet
Dim wsMaster As Worksheet
Dim lastRowData As Long
Dim lastRowReport As Long
Dim lastRowMaster As Long
Dim r As Range
Dim dict As Object
Dim key As Variant
Dim i As Long
Set wsData = ThisWorkbook.Sheets("SalesData")
Set wsReport = ThisWorkbook.Sheets("Report")
Set wsMaster = ThisWorkbook.Sheets("担当者マスタ")
Set dict = CreateObject("Scripting.Dictionary")
' Reportシートをクリア
wsReport.Cells.Clear
' データシートの最終行を取得
lastRowData = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
' データの集計
For Each r In wsData.Range("A2:A" & lastRowData)
If Format(r.Offset(0, 1).Value, "yyyymm") = currentDate Then
If Not dict.exists(r.Offset(0, 5).Value) Then
dict.Add r.Offset(0, 5).Value, r.Offset(0, 9).Value
Else
dict(r.Offset(0, 5).Value) = dict(r.Offset(0, 5).Value) + r.Offset(0, 9).Value
End If
End If
Next r
' レポートシートの最終行を取得
lastRowReport = wsReport.Cells(wsReport.Rows.Count, "B").End(xlUp).Row + 1
' レポートのヘッダー作成
wsReport.Range("B1:D1").Value = Array("担当者コード", "担当者名", "売上金額")
' 集計結果をレポートシートに出力
For Each key In dict.Keys
' 担当者名を取得
lastRowMaster = wsMaster.Cells(wsMaster.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRowMaster
If wsMaster.Cells(i, 1).Value = key Then
wsReport.Cells(lastRowReport, 2).Value = key
wsReport.Cells(lastRowReport, 3).Value = wsMaster.Cells(i, 2).Value
wsReport.Cells(lastRowReport, 4).Value = dict(key)
lastRowReport = lastRowReport + 1
Exit For
End If
Next i
Next key
End Sub
標準モジュールサンプルコード解説
1. Option Explicit
これは、変数を使用する前に必ず宣言するように強制するものです。これにより、タイプミスなどのミスを防ぐことができます。
2. Sub ShowUserForm()
Sub ShowUserForm()
UserForm1.Show
End Sub
・ShowUserFormというサブルーチンが定義されています。このサブルーチンを呼び出すと、UserForm1が表示されます。
・UserForm1は、ユーザーが情報を入力できるフォームです。
3. Sub GenerateDailyReport(currentDate As String)
' 変数の宣言
Dim wsData As Worksheet
Dim wsReport As Worksheet
Dim wsMaster As Worksheet
Dim lastRowData As Long
Dim lastRowReport As Long
Dim lastRowMaster As Long
Dim r As Range
Dim dict As Object
Dim key As Variant
Dim i As Long
・GenerateDailyReportは、日次レポートを生成するためのサブルーチンです。
・currentDateという文字列のパラメータを受け取ります。これは、ユーザーがフォームに入力した年月(例:202308)です。
- いくつかの変数が宣言されています。これらの変数は、ワークシートやデータの最後の行の位置を管理するために使われます。
4. シートの設定とReportシートのクリア
' ワークシートの設定
Set wsData = ThisWorkbook.Sheets("SalesData")
Set wsReport = ThisWorkbook.Sheets("Report")
Set wsMaster = ThisWorkbook.Sheets("担当者マスタ")
Set dict = CreateObject("Scripting.Dictionary")
' Reportシートをクリア
wsReport.Cells.Clear
・wsData, wsReport, wsMasterの3つのワークシートが、それぞれのシートに関連付けられています。
・dictは、売上データを担当者別に集計するための辞書オブジェクトです。
・wsReport.Cells.Clearは、レポートシートの内容をクリアするためのコマンドです。新しいレポートを生成する前に、古いデータを削除します。
5. データの集計
' データシートの最終行を取得
lastRowData = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
' データの集計
For Each r In wsData.Range("A2:A" & lastRowData)
If Format(r.Offset(0, 1).Value, "yyyymm") = currentDate Then
If Not dict.exists(r.Offset(0, 5).Value) Then
dict.Add r.Offset(0, 5).Value, r.Offset(0, 9).Value
Else
dict(r.Offset(0, 5).Value) = dict(r.Offset(0, 5).Value) + r.Offset(0, 9).Value
End If
End If
Next r
・lastRowDataは、SalesDataシートの最終行の位置を取得します。
・その後、SalesDataシートの各行をループし、currentDateと一致するデータを集計します。
・集計は、担当者別に売上金額を辞書(dict)に追加する形で行われます。
6. レポートシートへの出力
' レポートシートの最終行を取得
lastRowReport = wsReport.Cells(wsReport.Rows.Count, "B").End(xlUp).Row + 1
' レポートのヘッダー作成
wsReport.Range("B1:D1").Value = Array("担当者コード", "担当者名", "売上金額")
' 集計結果をレポートシートに出力
For Each key In dict.Keys
' 担当者名を取得
lastRowMaster = wsMaster.Cells(wsMaster.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRowMaster
If wsMaster.Cells(i, 1).Value = key Then
wsReport.Cells(lastRowReport, 2).Value = key
wsReport.Cells(lastRowReport, 3).Value = wsMaster.Cells(i, 2).Value
wsReport.Cells(lastRowReport, 4).Value = dict(key)
lastRowReport = lastRowReport + 1
Exit For
End If
Next i
Next key
End Sub
・ 集計したデータをレポートシートに出力します。
・wsReportシートのヘッダーに「担当者コード」「担当者名」「売上金額」が表示されます。
・dictに蓄えた担当者ごとの売上データをループで取り出し、担当者マスタシートから担当者名を取得してレポートシートに書き込みます。
Excel VBAで自動化するコードのベースを習得したい方におすすめ!
VBAエキスパート資格は、日常業務でExcelを多用し、手動作業を減らしたいと考えている方には価値あるものです。
ExcelVBAエキスパートベーシック
仕事の効率をあげるためにExcelVBAを利用する人が対象の問題集です。
ExcelVBAエキスパートスタンダード
ExcelVBAの開発を仕事にする人が対象の問題集です。
Excel VBA エキスパート資格について知りたい方は、下記「Excel VBAスキルアップを目指すなら知っておきたいVBAエキスパート」をご確認ください。