この記事でできること
- VBAで今日の曜日を判定し、土日ならスキップ・平日なら処理を実行できる
- 月末最終営業日(土日除外)を自動判定できる
- 月次処理を「毎回カレンダーで確認→手動実行」から「マクロ1つで自動判定&実行」に変えられる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
月末になるたびに手作業で締め日を確認して集計していた。祝日や土日がからむと毎回カレンダーとにらめっこ。もっと早く自動化すればよかったと思った。
—
どんな場面で使う?
- 月末最終営業日にだけ締め処理や集計マクロを実行したい
- 土日・祝日を除外した営業日数を自動計算したい
- 毎月の報告書提出日を曜日判定で自動リマインドしたい
- 日付ベースの条件分岐で、月初・月末・四半期末の処理を切り替えたい
—
完成イメージ(Before / After)
Before(手動確認):
- カレンダーを開く
- 「今日は月末?」「何曜日?」を確認
- 月末が土日なら「じゃあ金曜にやるべきだった?」と混乱
- 該当日なら手動でマクロを実行
After(自動判定):
- マクロを実行(またはファイルを開く)
- 今日が月末最終営業日かを自動判定
- 該当すれば処理が走る。該当しなければ「今日は対象外です」と表示されて終了
—
経理の月次処理で毎月末に「今日は最終営業日?」とカレンダーを見ていた。月末が土曜なら金曜にやるべきだし、うっかり忘れて翌月頭にバタバタすることもあった。VBAのWeekdayとDateSerialを使えば月末最終営業日を自動判定できる。この判定をVBAに任せてからは月末処理の漏れがなくなった。同じストレスを抱えている人に、この記事で自動化を試してほしい。
月末最終営業日の確認は、VBAに任せれば一瞬で終わる。
—
実行前の準備
バックアップを取る
マクロ実行前に、Excelファイルのコピーを別フォルダに保存しておく。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
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(デモ用) |
コードの流れ
Weekday(Date, vbMonday)で今日の曜日番号を取得(月曜=1〜日曜=7)- 番号が6以上(土曜 or 日曜)ならメッセージを出してスキップ
- 平日なら処理を実行
重要: 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(デモ用) |
コードの流れ
- 月末日の取得:
DateSerial(Year(Date), Month(Date) + 1, 0)で翌月の0日 = 今月の末日を取得 - 営業日にずらす:
Do Whileループで月末日が土日なら1日ずつ前にずらす - 今日と比較:
Date <> lastDayなら対象外としてスキップ - 処理の実行: 今日が月末最終営業日なら、★の箇所に書いた処理を実行
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つで実行する方法 — 月末判定マクロをボタンに割り当てて、ワンクリックで月末処理を実行したい場合に
—


コメント