【VBA】日付・曜日を判定して月末処理を自動化する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

  • VBAで今日の曜日を判定し、土日ならスキップ・平日なら処理を実行できる
  • 月末最終営業日(土日除外)を自動判定できる
  • 月次処理を「毎回カレンダーで確認→手動実行」から「マクロ1つで自動判定&実行」に変えられる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11

月末になるたびに手作業で締め日を確認して集計していた。祝日や土日がからむと毎回カレンダーとにらめっこ。もっと早く自動化すればよかったと思った。

どんな場面で使う?

  • 月末最終営業日にだけ締め処理や集計マクロを実行したい
  • 土日・祝日を除外した営業日数を自動計算したい
  • 毎月の報告書提出日を曜日判定で自動リマインドしたい
  • 日付ベースの条件分岐で、月初・月末・四半期末の処理を切り替えたい

完成イメージ(Before / After)

Before(手動確認):

  1. カレンダーを開く
  2. 「今日は月末?」「何曜日?」を確認
  3. 月末が土日なら「じゃあ金曜にやるべきだった?」と混乱
  4. 該当日なら手動でマクロを実行

After(自動判定):

  1. マクロを実行(またはファイルを開く)
  2. 今日が月末最終営業日かを自動判定
  3. 該当すれば処理が走る。該当しなければ「今日は対象外です」と表示されて終了

経理の月次処理で毎月末に「今日は最終営業日?」とカレンダーを見ていた。月末が土曜なら金曜にやるべきだし、うっかり忘れて翌月頭にバタバタすることもあった。VBAのWeekdayとDateSerialを使えば月末最終営業日を自動判定できる。この判定をVBAに任せてからは月末処理の漏れがなくなった。同じストレスを抱えている人に、この記事で自動化を試してほしい。

月末最終営業日の確認は、VBAに任せれば一瞬で終わる。

実行前の準備

バックアップを取る

マクロ実行前に、Excelファイルのコピーを別フォルダに保存しておく。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は「【VBA】マクロをボタン1つで実行する方法」を参照。

コード(最小版)– 今日の曜日を判定して処理を分岐


'============================================================
' ■ 曜日判定で処理を分岐(最小版)
'   → 今日が平日(月〜金)なら処理を実行、土日ならスキップ
'============================================================
Sub CheckWeekdayMinimal()

    '--- 今日の曜日番号を取得(vbMonday指定: 月=1, 火=2, ... 土=6, 日=7)
    '    ★重要: vbMonday を省略すると日曜始まりになり、土日の番号がずれる
    Dim wDay As Integer
    wDay = Weekday(Date, vbMonday)

    '--- 土日判定(6=土曜, 7=日曜)
    If wDay >= 6 Then
        MsgBox "今日は " & WeekdayName(Weekday(Date)) & " です。" & vbCrLf & _
               "平日ではないため、処理をスキップします。", vbInformation
        Exit Sub
    End If

    '--- ★ここに平日に実行したい処理を書く ---
    MsgBox "今日は " & WeekdayName(Weekday(Date)) & "(平日)です。" & vbCrLf & _
           "処理を実行します。", vbInformation

End Sub

書き換えポイント

変数・箇所 説明 初期値
wDay >= 6 土日判定の条件。6=土曜, 7=日曜 >= 6
'--- ★ここに〜 平日に実行したい処理をここに書く MsgBox(デモ用)

コードの流れ

  1. Weekday(Date, vbMonday) で今日の曜日番号を取得(月曜=1〜日曜=7)
  2. 番号が6以上(土曜 or 日曜)ならメッセージを出してスキップ
  3. 平日なら処理を実行

重要: Weekday の第2引数に vbMonday を必ず指定する。省略するとデフォルトの日曜始まり(vbSunday)になり、土日の番号がずれる。

コード(実務版)– 月末最終営業日を判定して処理を実行

月次処理で一番ニーズが高いのは「今日が月末最終営業日かどうか」の判定。月末が土日なら前倒しで金曜になる。

この仕組みを入れてからは、月末のカレンダー確認が不要になった。「今日は最終営業日だっけ?」という確認作業が完全に消えたのは想像以上に楽だった。月末処理の結果をそのままPDF出力(「ExcelファイルをPDFに一括変換」)すれば、報告書の自動化まで一気に進められる。


'============================================================
' ■ 月末最終営業日を判定して処理を実行(実務版)
'   → 今日が月末最終営業日なら処理を実行、それ以外はスキップ
'   → 土日を除外(祝日は対象外。祝日も含めたい場合は別途マスタが必要)
'============================================================
Sub RunOnLastBusinessDay()

    '--- 今月の月末日を取得(翌月の0日 = 今月の末日)
    '    ※ 12月でも Month(Date)+1=13 → DateSerial が自動で繰り上げるため正常動作
    Dim lastDay As Date
    lastDay = DateSerial(Year(Date), Month(Date) + 1, 0)

    '--- 月末日が土日なら前にずらして最終営業日を求める
    '    vbMonday指定: 月=1, 火=2, 水=3, 木=4, 金=5, 土=6, 日=7
    Do While Weekday(lastDay, vbMonday) > 5
        lastDay = lastDay - 1
    Loop

    '--- 判定結果を表示
    Dim lastBusinessDayText As String
    lastBusinessDayText = Format(lastDay, "yyyy/mm/dd") & "(" & _
                          WeekdayName(Weekday(lastDay)) & ")"

    '--- 今日が月末最終営業日かどうか判定
    If Date <> lastDay Then
        MsgBox "今月の最終営業日は " & lastBusinessDayText & " です。" & vbCrLf & _
               "今日は対象外のため、処理をスキップします。", vbInformation
        Exit Sub
    End If

    '--- ★ここに月末最終営業日に実行したい処理を書く ---
    MsgBox "今日は月末最終営業日(" & lastBusinessDayText & ")です。" & vbCrLf & _
           "月末処理を実行します。", vbInformation

    '--- 例:月末処理の内容をここに追加 ---
    ' Call MonthlyReport      ' 月次レポート作成
    ' Call ExportToPDF         ' PDF出力
    ' Call SendMailNotification ' メール通知

End Sub

書き換えポイント

変数・箇所 説明 初期値
Month(Date) + 1, 0 月末日取得の計算式。変更不要
Weekday(lastDay, vbMonday) > 5 土日判定。変更不要
'--- ★ここに〜 月末最終営業日に実行したい処理 MsgBox(デモ用)

コードの流れ

  1. 月末日の取得: DateSerial(Year(Date), Month(Date) + 1, 0) で翌月の0日 = 今月の末日を取得
  2. 営業日にずらす: Do While ループで月末日が土日なら1日ずつ前にずらす
  3. 今日と比較: Date <> lastDay なら対象外としてスキップ
  4. 処理の実行: 今日が月末最終営業日なら、★の箇所に書いた処理を実行

DateSerial(年, 月+1, 0) は「翌月の0日目 = 今月の最終日」を意味する。VBAの日付処理では定番のテクニック。初見では分かりにくいが、覚えると月末取得がこの1行で済む。

よくある落とし穴5選

1. Weekday の第2引数を省略して曜日がずれる

原因: Weekday(Date) とだけ書くと、デフォルトで日曜始まり(vbSunday)になる。この場合、土曜=7、日曜=1 になり、>= 6 の判定では土曜しか引っかからない。

自分もこれでハマった。vbMonday を指定し忘れて金曜日に処理が走らなくなった。上司に「金曜の数字が出てない」と指摘されて気づいた。あのときは冷や汗だった。

対策: Weekday(Date, vbMonday) と必ず第2引数を書く。月曜=1〜日曜=7 で統一すれば > 5 で土日判定ができる。

2. DateSerial の「月+1, 0」が理解できない

原因: DateSerial(2026, 4, 0)2026/03/31 になる仕組みが分かりにくい。

対策: 「翌月の0日目 = 今月の最終日」と覚える。VBAが自動的に日付を繰り下げてくれる。12月の場合も DateSerial(2026, 13, 0)2026/12/31 で正常に動く。

3. 祝日を考慮していない

原因: この記事のコードは土日のみ除外。祝日(元日、成人の日、etc.)は営業日として扱われる。

自分も最初、土日だけ除外して安心していたら、1月の月末最終営業日が「成人の日」にあたっていた。祝日なのにマクロが「今日は最終営業日です」と判定して処理が走ってしまい、上司から「祝日にデータ送ってきたけど?」と言われた。

対策: 祝日も除外したい場合は、シートに祝日一覧(マスタ)を用意し、Application.Match で突き合わせる。この記事の範囲では土日除外のみ対応。

4. 月末処理が2回走ってしまう

原因: マクロを同じ日に2回実行すると、当然2回走る。

対策: 処理済みフラグをセルに書き込む方法がある。フラグ用セルはデータと被らない空きセルや別シートに置くことを推奨。


If Range("A1").Value = Format(Date, "yyyy/mm/dd") Then
    MsgBox "本日は処理済みです。", vbInformation
    Exit Sub
End If
' --- 処理 ---
Range("A1").Value = Format(Date, "yyyy/mm/dd")

5. Date と Now を間違えて日付比較がうまくいかない

原因: Now は日付+時刻を返す(例:2026/03/07 14:30:00)。Date は日付のみ(例:2026/03/07)。日付比較に Now を使うと時刻部分のせいで一致しない。

対策: 日付の比較には必ず Date を使う。時刻が不要なら Now は使わない。

VBAで月末日の判定が正しくできないときの対処法

「月末処理が実行されない」という場合、原因は Date ではなく Now を使って日付比較していることが多い。Now は日付+時刻を返すため、日付のみの比較で一致しない。日付比較には必ず Date を使い、DateSerial(Year(Date), Month(Date) + 1, 0) で月末日を取得すれば正確に判定できる。

VBAの曜日判定で土曜・日曜の処理がずれるときの対処法

「土曜のはずなのに平日扱いになる」という場合、原因は Weekday 関数の週の開始曜日設定が想定と違うことだ。Weekday(Date, vbSunday) のように第2引数を明示的に指定すれば、日曜=1、月曜=2…土曜=7として確実に判定できる。

FAQ

Q1: 祝日も除外した営業日判定をしたい

シートに祝日一覧を用意し、月末日から遡りながら祝日にも該当しないか確認する。この記事では土日のみ除外する方法を紹介しているが、祝日テーブルとの組み合わせはカスタマイズの範囲。

Q2: 月初の最初の営業日を取得したい

DateSerial(Year(Date), Month(Date), 1) で月初日を取得し、土日なら+1する:


Dim firstDay As Date
firstDay = DateSerial(Year(Date), Month(Date), 1)
Do While Weekday(firstDay, vbMonday) > 5
    firstDay = firstDay + 1
Loop

Q3: 月末最終営業日に色分けも自動実行したい

月末判定の★部分に色分けマクロを呼び出す行を追加する。色分けの方法は「【VBA】セルの値に応じて行を自動色分けする方法」を参照。


'--- ★ここに月末処理 ---
Call ColorByValue  ' 色分けマクロを呼び出す

Q4: ファイルを開いたら自動で月末判定させたい

ThisWorkbook モジュール(標準モジュールではない)に Workbook_Open イベントを書く:


Private Sub Workbook_Open()
    Call RunOnLastBusinessDay
End Sub

注意: このコードは VBE 左側のプロジェクトエクスプローラーで「ThisWorkbook」をダブルクリックして開くウィンドウに貼る。標準モジュールに貼っても動かない。

これでファイルを開くたびに自動判定される。セルの値が変わったら自動実行する方法(「セルの値が変わったら自動実行」)と同じイベント駆動の考え方。

Q5: 判定結果をセルに書き出したい

MsgBoxの代わりにセルに書く:


Range("A1").Value = "最終営業日: " & Format(lastDay, "yyyy/mm/dd")
Range("A2").Value = IIf(Date = lastDay, "今日は対象日", "今日は対象外")

まとめ

  • Weekday(Date, vbMonday) で曜日番号を取得し、土日を判定できる
  • DateSerial(Year(Date), Month(Date) + 1, 0) で月末日を取得できる
  • 月末日が土日なら前にずらして最終営業日を求める
  • vbMonday の指定忘れが最大の落とし穴。必ず第2引数を書く

関連記事

  • 【VBA】マクロをボタン1つで実行する方法 — 月末判定マクロをボタンに割り当てればワンクリックで済む
  • 【VBA】セルの値に応じて行を自動色分けする方法 — 月末行や期限切れの行を色分けする
  • 【VBA】ExcelファイルをPDFに一括変換する方法 — 月末レポートをPDFにして保存・配布

次にやりたくなること

  • 【VBA】セルの値に応じて行を自動色分けする方法 — 月末処理で期限切れの行を自動でハイライトしたい場合に
  • 【VBA】営業日を計算する方法 — 土日だけでなく祝日も含めた営業日計算をしたい場合に
  • 【VBA】マクロをボタン1つで実行する方法 — 月末判定マクロをボタンに割り当てて、ワンクリックで月末処理を実行したい場合に

コメント

タイトルとURLをコピーしました