【VBAマクロ】Excelシートから担当者別レポートを自動作成する方法

 

エクセルの便利な機能の一つに、Excelシートからレポート作成することがありますが、その効率的な利用にはVBAマクロの利用です。

 

VBAマクロを活用して集めたデータシートから、担当者別レポートをシートから作成する方法で、あなたのスキル向上と業務効率化をサポートする情報をお届けします。

 

📌 「これ、自動化できたらラクなのに…」と思ったこと、ありませんか?
実はその作業、Excelマクロで簡単に自動化できるかもしれません。
「でもマクロって難しそう…」という方のために、完全初心者向けの入門記事をご用意しました!

👇実務で“そのまま使える”テンプレ付きで、コピペするだけ
初心者向けエクセルマクロの作り方を解説|コピペOK実務テンプレ付き

 

 

Excel VBAで担当者別レポートを自動作成|どんな場面で使える?

 

データシートから担当者別売上金額レポートシートを作成する

「エクセルVBAマクロで複数Excelシートをひとつに集める方法」で集めたExcelファイルのシートを集計して担当者別売上金額のレポートを作成します。このエクセルVBAマクロで、毎月もしくは毎日の担当者別売上金額レポートの作成が自動化され、時間と手間を大幅に削減できます。

 

担当者別レポートを作成するVBAマクロ|実用サンプルコード

 

自分の実力を客観的にチェックしたい…。そんな方のために、自分に合ったスタート地点がわかる無料のExcelVBAベーシック選択問題集をご用意しました。

👉無料ExcelVBAベーシック選択問題138問

 

全体の流れ

1. ユーザーが年月を入力すると、フォームでその年月を受け取ります。

2. その年月に基づいてSalesDataシートのデータを集計し、担当者ごとの売上金額を計算します。

3. 集計結果をレポートシートに出力し、新しいレポートが生成されます。

 

完成イメージ|レポート作成のサンプル画面

対象のExcel

 

Excelのシート内容(マクロ記述のThisWorkbook)

準備するExcelデータ

シート担当者マスタの内容

 

集計した結果のシート

コード入力したキャプチャ(フォーム)

コード入力したキャプチャ(標準モジュール)

マクロ実行時のキャプチャ

ユーザーフォームのコード

 

ユーザーフォームのボタン(CommandButton2)がクリックされたときに実行される処理を定義しています。

 

  1. Private Sub CommandButton2_Click()
  2.     ' 入力された年月を変数に格納
  3.     Dim inputYearMonth As String
  4.     inputYearMonth = TextBox1.Text
  5.     
  6.     ' 入力が正しい6桁の年月かどうかを確認
  7.     If Len(inputYearMonth) <> 6 Or Not IsNumeric(inputYearMonth) Then
  8.         MsgBox "正しい6桁の年月を入力してください (例: 202308)", vbExclamation
  9.         Exit Sub
  10.     End If
  11.     
  12.     ' メインのレポート生成処理を呼び出し
  13.     GenerateDailyReport inputYearMonth
  14.     
  15.     ' UserFormを閉じる
  16.     Unload Me
  17. 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

 

標準モジュールのマクロコード(レポート作成処理)

 

Excel VBAを使ってユーザーフォームを表示し、特定の年月のデータをもとに日次レポートを生成するものです。

 

  1. Option Explicit
  2. Sub GenerateDailyReport(currentDate As String)
  3.     Dim wsData As Worksheet
  4.     Dim wsReport As Worksheet
  5.     Dim wsMaster As Worksheet
  6.     Dim lastRowData As Long
  7.     Dim lastRowReport As Long
  8.     Dim lastRowMaster As Long
  9.     Dim r As Range
  10.     Dim dict As Object
  11.     Dim key As Variant
  12.     Dim i As Long
  13.     
  14.     Set wsData = ThisWorkbook.Sheets("SalesData")
  15.     Set wsReport = ThisWorkbook.Sheets("Report")
  16.     Set wsMaster = ThisWorkbook.Sheets("担当者マスタ")
  17.     Set dict = CreateObject("Scripting.Dictionary")
  18.     
  19.     ' Reportシートをクリア
  20.     wsReport.Cells.Clear
  21.     
  22.     ' データシートの最終行を取得
  23.     lastRowData = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
  24.     
  25.     ' データの集計
  26.     For Each r In wsData.Range("A2:A" & lastRowData)
  27.         If Format(r.Offset(0, 1).Value, "yyyymm") = currentDate Then
  28.             If Not dict.exists(r.Offset(0, 5).Value) Then
  29.                 dict.Add r.Offset(0, 5).Value, r.Offset(0, 9).Value
  30.             Else
  31.                 dict(r.Offset(0, 5).Value) = dict(r.Offset(0, 5).Value) + r.Offset(0, 9).Value
  32.             End If
  33.         End If
  34.     Next r
  35.     
  36.     ' レポートシートの最終行を取得
  37.     lastRowReport = wsReport.Cells(wsReport.Rows.Count, "B").End(xlUp).Row + 1
  38.     
  39.     ' レポートのヘッダー作成
  40.     wsReport.Range("B1:D1").Value = Array("担当者コード", "担当者名", "売上金額")
  41.     
  42.     ' 集計結果をレポートシートに出力
  43.     For Each key In dict.Keys
  44.         ' 担当者名を取得
  45.         lastRowMaster = wsMaster.Cells(wsMaster.Rows.Count, "A").End(xlUp).Row
  46.         For i = 2 To lastRowMaster
  47.             If wsMaster.Cells(i, 1).Value = key Then
  48.                 wsReport.Cells(lastRowReport, 2).Value = key
  49.                 wsReport.Cells(lastRowReport, 3).Value = wsMaster.Cells(i, 2).Value
  50.                 wsReport.Cells(lastRowReport, 4).Value = dict(key)
  51.                 lastRowReport = lastRowReport + 1
  52.                 Exit For
  53.             End If
  54.         Next i
  55.     Next key
  56. End Sub

 

自分の実力を客観的にチェックしたい…。そんな方のために、自分に合ったスタート地点がわかる無料のExcelVBAベーシック選択問題集をご用意しました。

👉無料ExcelVBAベーシック選択問題138問

 

標準モジュールのマクロ解説と動作の流れ

 

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に蓄えた担当者ごとの売上データをループで取り出し、担当者マスタシートから担当者名を取得してレポートシートに書き込みます。

 

以下、業務に役立つマクロ10選を選びました。※ここをクリックで一覧表示します

 

Excel VBAエキスパートベーシックとスタンダード、どちらを選べばいいか判断が難しい…。そんな方のために、自分に合ったスタート地点がわかる無料のExcelVBAベーシック選択問題集を用意しました。

👉無料ExcelVBAベーシック選択問題138問