wanna.jp VBAリファレンス
Top > VBA関数リファレンス > VBA Dayの使い方

【経理向けVBA】請求締め日の判定処理を自動化!Day関数で売上集計ミスを防ぐ実務テクニック

経理担当者の皆さん、日々の業務お疲れ様です。月次の売上集計や請求書作成において、最も神経を使う作業の一つが「締め日の判定」ではないでしょうか?
「この請求データは今月分?それとも来月分?」わずかな判定ミスが、月次の売上着地見込みを大きく狂わせ、経営判断にまで影響を及ぼす可能性があります。特に、締め日を過ぎた日付のデータ処理には細心の注意が必要ですよね。
今回は、そんな経理業務の落とし穴を回避し、VBAのDay関数を使って締め日判定を正確かつ自動化する方法を、実務に即したコードとともにご紹介します。もう手作業での確認ミスに悩む必要はありません!

コピペで即解決!締め日判定の実務VBAコード

まずは、特定の日付が「どの締め月に属するか」を判別するためのVBA関数です。例えば「20日締め」の場合、21日以降の日付は翌月として扱います。このロジックをDay関数でシンプルに実装します。


'=====================================================================================
' 関数名: GetClosingTargetMonth
' 概要  : 指定された日付が、特定の締め日に基づいてどの締め月に属するかを返します。
'         (例: 20日締めの場合、21日以降は翌月として扱う)
' 引数  : targetDate As Date  - 判定対象の日付
'         closeDay As Integer - 締め日(例: 20日締めの場合は 20)
' 戻り値: Date                - 締め月(常に月の1日を返します。例: 2026/02/01, 2026/03/01)
'=====================================================================================
Function GetClosingTargetMonth(targetDate As Date, closeDay As Integer) As Date
    Dim year As Integer
    Dim month As Integer
    
    ' 年と月を取得
    year = VBA.Year(targetDate)
    month = VBA.Month(targetDate)
    
    ' 日付の「日」を取得し、締め日と比較
    If VBA.Day(targetDate) > closeDay Then
        ' ターゲット日付が締め日よりも後の場合、対象月を翌月とする
        ' 例: 2月21日で20日締めの場合、3月1日を返す
        GetClosingTargetMonth = DateSerial(year, month + 1, 1)
    Else
        ' ターゲット日付が締め日以前の場合、対象月を当月とする
        ' 例: 2月20日で20日締めの場合、2月1日を返す
        GetClosingTargetMonth = DateSerial(year, month, 1)
    End If
End Function

'=====================================================================================
' 使用例: 締め日判定の結果をイミディエイトウィンドウに出力します。
'         VBEでF5キーを押して実行してください。
'=====================================================================================
Sub TestClosingMonthDetection()
    Dim inputDate As Date
    Dim closingDay As Integer
    Dim resultMonth As Date
    
    ' --- 設定ここから ---
    closingDay = 20 ' ★★★ ここに貴社の締め日を設定してください(例: 20日締め = 20) ★★★
    ' --- 設定ここまで ---
    
    Debug.Print "--- 締め日判定テスト開始 (締め日: " & closingDay & "日) ---"
    
    ' ケース1: 締め日当日の入力例
    inputDate = #2/20/2026# ' 入力例: 2026年2月20日
    resultMonth = GetClosingTargetMonth(inputDate, closingDay)
    Debug.Print "入力日: " & Format(inputDate, "yyyy/mm/dd") & _
                " -> 対象締め月: " & Format(resultMonth, "yyyy年mm月") & _
                " (期待: 2026年02月)"
    
    ' ケース2: 締め日の翌日の入力例 (翌月扱いになるケース)
    inputDate = #2/21/2026# ' 入力例: 2026年2月21日
    resultMonth = GetClosingTargetMonth(inputDate, closingDay)
    Debug.Print "入力日: " & Format(inputDate, "yyyy/mm/dd") & _
                " -> 対象締め月: " & Format(resultMonth, "yyyy年mm月") & _
                " (期待: 2026年03月)" ' ← ここがポイント!
                
    ' ケース3: 翌月の締め日以前の入力例
    inputDate = #3/15/2026# ' 入力例: 2026年3月15日
    resultMonth = GetClosingTargetMonth(inputDate, closingDay)
    Debug.Print "入力日: " & Format(inputDate, "yyyy/mm/dd") & _
                " -> 対象締め月: " & Format(resultMonth, "yyyy年mm月") & _
                " (期待: 2026年03月)"
                
    ' ケース4: 年をまたぐ締め日判定の例 (12月25日締め、12月26日データの場合)
    closingDay = 25 ' 例として25日締めに変更
    inputDate = #12/26/2026# ' 入力例: 2026年12月26日
    resultMonth = GetClosingTargetMonth(inputDate, closingDay)
    Debug.Print "入力日: " & Format(inputDate, "yyyy/mm/dd") & _
                " -> 対象締め月: " & Format(resultMonth, "yyyy年mm月") & _
                " (期待: 2027年01月)" ' ← ここもポイント!
    
    Debug.Print "--- 締め日判定テスト終了 ---"
End Sub

落とし穴回避!「20日締め、21日以降は翌月扱い」ロジックの解説

ご紹介したコードの核心は、以下の条件分岐にあります。


If VBA.Day(targetDate) > closeDay Then
    ' ターゲット日付が締め日よりも後の場合、対象月を翌月とする
    GetClosingTargetMonth = DateSerial(year, month + 1, 1)
Else
    ' ターゲット日付が締め日以前の場合、対象月を当月とする
    GetClosingTargetMonth = DateSerial(year, month, 1)
End If

ここでVBA.Day(targetDate)関数が、指定された日付(targetDate)の「日」の部分だけを取り出しています。例えば、#2026/02/20#であれば「20」、#2026/02/21#であれば「21」を返します。
この「日」を貴社の締め日(closeDay)と比較することで、「当月締め」と「翌月締め」を厳密に区別しています。

  • VBA.Day(targetDate) > closeDay の場合:
    例えば、20日締め(closeDay = 20)で、targetDateが2月21日(VBA.Day(targetDate) = 21)の場合、21 > 20が真となります。このとき、DateSerial(year, month + 1, 1)を使って「翌月の1日」を計算しています。これにより、2月21日のデータは3月締めの請求として正しく処理されます。
  • それ以外の場合 (VBA.Day(targetDate) <= closeDay):
    例えば、20日締め(closeDay = 20)で、targetDateが2月15日または2月20日の場合、VBA.Day(targetDate)closeDay以下となります。このとき、DateSerial(year, month, 1)で「当月の1日」を返し、2月締めの請求として処理されます。

DateSerial関数は、年、月、日を数値で指定して日付を生成するVBA関数です。特に、月の部分にmonth + 1と指定することで、翌月の正しい日付(例:12月の翌月は自動的に翌年の1月として扱われる)を正確に取得できるため、年をまたぐ処理もスムーズに対応できます。

まとめ

VBAのDay関数を核とした締め日判定ロジックは、経理業務における請求データ集計の正確性と効率性を飛躍的に向上させます。手作業で日付を一つ一つ確認する手間を省き、誤りのリスクを大幅に削減できるでしょう。
この関数を応用すれば、請求書の一括作成、会計システムへのデータ連携、売上予測レポートの自動生成など、さらなる業務自動化の可能性が広がります。ぜひ、本記事のコードをコピー&ペーストして、皆さんの日々の経理業務に役立ててください。正確な締め日判定で、健全な月次決算と経営判断をサポートしましょう!

VBAでの業務効率化、悩み解決します

「このマクロ、もっと速くならないかな?」「エラーが消えない…」
Access/VBA専門のwanna.jpにご相談ください。

無料相談はこちら