1. 導入:なぜVBAで「期間集計」を実装すべきか
実務において「今月の売上件数」や「特定のプロジェクト期間内のタスク数」を抽出する作業は、非常に頻繁に発生します。Excelのワークシート関数であるCOUNTIFを使えば簡単に計算できますが、データ量が増えたり、対象期間を動的に変更してレポートを作成したりする場合には、VBAによる自動化が不可欠です。本記事では、COUNTIF関数の考え方を応用し、VBAから特定の期間内のデータを集計する手法を解説します。
2. 基礎知識:COUNTIF関数による期間指定の考え方
COUNTIF関数は、本来「1つの条件」しか指定できません。しかし、「終了日までの累計」から「開始日より前の累計」を引くという数学的なアプローチをとることで、実質的に「期間内の件数」を算出できます。
・期間終了日までの件数:指定日以下(<=)のデータをカウント ・期間開始日より前の件数:指定日未満(<)のデータをカウント この2つの結果をVBAで算出し、引き算を行うことで、柔軟な集計エンジンを作成することが可能です。
3. 実装/解決策:WorksheetFunctionの活用
VBAでCOUNTIF関数を呼び出すには、Application.WorksheetFunction.CountIf を使用します。これにより、セルに入力する数式と同じロジックをコード内に組み込むことができます。特に、日付を引数に渡す際は、日付型(Date)を正しく文字列として認識させる工夫が必要です。
4. サンプルプログラム:期間集計自動化マクロ
以下のコードは、F列にある日付データから、特定の期間内の件数を取得してメッセージボックスで表示する実用的なサンプルです。
Sub CountByPeriod()
Dim ws As Worksheet
Dim startDate As Date
Dim endDate As Date
Dim countEnd As Long
Dim countStart As Long
Dim totalCount As Long
Set ws = ActiveSheet
‘ 集計期間を設定
startDate = DateSerial(2023, 5, 1)
endDate = DateSerial(2023, 5, 31)
‘ 1. 終了日までの件数を算出
‘ F5からF12の範囲で「endDate以下の日付」をカウント
countEnd = Application.WorksheetFunction.CountIf(ws.Range(“F5:F12”), “<=" & CLng(endDate))
' 2. 開始日より前の件数を算出
' F5からF12の範囲で「startDate未満の日付」をカウント
countStart = Application.WorksheetFunction.CountIf(ws.Range("F5:F12"), "<" & CLng(startDate))
' 3. 引き算で期間内の件数を算出
totalCount = countEnd - countStart
MsgBox "期間 " & startDate & " ~ " & endDate & " の件数は " & totalCount & " 件です。"
End Sub
5. 応用・注意点:現場で陥りやすい罠
・日付の形式: VBAでCOUNTIFを使う際、日付を「”<=2023/5/31"」のように文字列結合すると、Excelの環境設定によって正しく判定されない場合があります。上記サンプルのように、CLng関数を使ってシリアル値に変換してから結合すると、ロケールに左右されず安定して動作します。
・範囲の動的変更: 実際の現場では集計範囲(F5:F12)が日々増減します。その場合は、Range(“F5:F” & Cells(Rows.Count, “F”).End(xlUp).Row) のように最終行を動的に取得する記述に書き換えることで、汎用性が高まります。
・ゼロ除算やエラー回避: 万が一、範囲内に日付以外のデータが含まれている場合は、COUNTIFS関数で「日付型であること」を条件に追加するなどの工夫も検討してください。
