Contents
この記事でできること
VBAで祝日・土日を除いた営業日を自動計算できるようになる。N営業日後の日付を出したり、2つの日付間の営業日数を数えたり、一覧表の支払期限を一括計算できる。
- 対象:納期・支払期限の計算で毎回カレンダーを手で数えている人
- 所要時間:コピペ → 動作確認まで約5分(目安)
自分も以前、支払期限を「月末締め翌月末払い」で計算していたが、年末年始を考慮し忘れて先方から催促メールが来たことがある。正直あれは焦った。営業日計算をVBAで自動化してからは、どの取引先にも正確な期限を出せるようになり、催促が来ることはなくなった。
日付や曜日の基本的な判定方法は日付・曜日の判定で月末処理を自動化する方法で解説しているので、あわせて確認すると理解が深まる。
この記事で、同じように営業日計算で困っている方がサクッと自動化できるようになればうれしい。
完成イメージ(Before / After)
Before(実行前)
請求日から支払期限を手計算。カレンダーを見ながら土日祝を除外して数える。
| A(取引先) | B(案件名) | C(請求日) | D(支払期限) | |
|---|---|---|---|---|
| 1 | 取引先 | 案件名 | 請求日 | 支払期限 |
| 2 | A商事 | 部品納入 | 2026/01/06 | (手計算…) |
| 3 | B工業 | 設備保守 | 2026/01/15 | (手計算…) |
| 4 | C物産 | 原材料 | 2026/02/03 | (手計算…) |
After(実行後)
マクロを実行すると、C列の請求日から30営業日後(祝日・土日除外)がD列に自動出力される。
| A(取引先) | B(案件名) | C(請求日) | D(支払期限) | |
|---|---|---|---|---|
| 1 | 取引先 | 案件名 | 請求日 | 支払期限 |
| 2 | A商事 | 部品納入 | 2026/01/06 | 2026/02/17 |
| 3 | B工業 | 設備保守 | 2026/01/15 | 2026/02/26 |
| 4 | C物産 | 原材料 | 2026/02/03 | 2026/03/17 |
事前準備
バックアップを取る
既存のデータが入っているExcelファイルで試す場合は、先にファイルをコピーしてバックアップを取ること。
Excelをマクロ有効ブック(.xlsm)で保存する
- Excelを開く(新規でも既存でもOK)
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を 「Excel マクロ有効ブック (*.xlsm)」 に変更して保存
.xlsx のままだとマクロが保存されない。必ず .xlsm にすること。
「祝日」シートを作る
実務版・一括計算で使う祝日リストを準備する。シート名は 「祝日」 にすること。
| A(日付) | B(祝日名) | |
|---|---|---|
| 1 | 日付 | 祝日名 |
| 2 | 2026/01/01 | 元日 |
| 3 | 2026/01/12 | 成人の日 |
| 4 | 2026/02/11 | 建国記念の日 |
| 5 | 2026/02/23 | 天皇誕生日 |
| 6 | 2026/03/20 | 春分の日 |
| 7 | 2026/04/29 | 昭和の日 |
| 8 | 2026/05/03 | 憲法記念日 |
| 9 | 2026/05/04 | みどりの日 |
| 10 | 2026/05/05 | こどもの日 |
| 11 | 2026/05/06 | 振替休日 |
| 12 | 2026/07/20 | 海の日 |
| 13 | 2026/08/11 | 山の日 |
| 14 | 2026/09/21 | 敬老の日 |
| 15 | 2026/09/23 | 秋分の日 |
| 16 | 2026/10/12 | スポーツの日 |
| 17 | 2026/11/03 | 文化の日 |
| 18 | 2026/11/23 | 勤労感謝の日 |
ポイント:
- A列は日付型で入力する(文字列ではない)
- 振替休日も忘れずに入れる(内閣府の「国民の祝日について」ページで確認)
- 会社独自の休業日(年末年始の12/29〜1/3、お盆など)があれば追加する
- 毎年1月に翌年分の祝日を追加するのがおすすめ
注意: 上記の祝日リストは参考例です。実際に使用する際は、内閣府の公式情報で正確な日付を確認してください。
コード(最小版)– WorkDayで簡単にN営業日後を計算
まずはこれだけで動く。祝日リストなしで、土日のみ除外した5営業日後を計算する。
Sub N営業日後を計算する()
Dim startDate As Date
Dim resultDate As Date
startDate = Date ' 今日の日付
' 5営業日後を計算(土日のみ除外)
resultDate = WorksheetFunction.WorkDay(startDate, 5)
MsgBox "今日: " & Format(startDate, "yyyy/mm/dd") & vbCrLf & _
"5営業日後: " & Format(resultDate, "yyyy/mm/dd")
End Sub
コードの動作:
Dateで今日の日付を取得WorksheetFunction.WorkDayで5営業日後の日付を計算(土日を自動で飛ばす)MsgBoxで結果を表示
重要:WorkDayの数え方
WorkDay関数は開始日の翌日からカウントする。つまり WorkDay(1月5日, 5) は 1月6日を1日目として数え始める。当日を含めたい場合は nDays - 1 にするか、開始日を1日前にする。
MsgBoxの使い方の詳細はMsgBoxの使い方と実務パターンを参照。
コード(実務版)– 祝日リスト対応のN営業日後
業務で使うなら祝日の除外が必須。「祝日」シートのリストを参照して、土日+祝日を除外したN営業日後を計算する。
自分はこの方法を使うようになってから、年末年始やGWを跨ぐ期限計算でミスがなくなった。特に12月〜1月は祝日+年末年始休業が重なるので、手計算だとまず間違える。
Sub N営業日後を計算する_祝日対応()
Dim ws As Worksheet
Dim startDate As Date
Dim nDays As Long
Dim holidays As Variant
Dim resultDate As Date
Dim lastRow As Long
Set ws = Worksheets("祝日")
startDate = Date
nDays = 5
' 祝日リストを配列に読み込み
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow >= 2 Then
holidays = ws.Range("A2:A" & lastRow).Value
End If
' WorkDay関数に祝日リストを渡す
If IsArray(holidays) Then
resultDate = WorksheetFunction.WorkDay(startDate, nDays, _
ws.Range("A2:A" & lastRow))
Else
resultDate = WorksheetFunction.WorkDay(startDate, nDays)
End If
MsgBox nDays & "営業日後: " & Format(resultDate, "yyyy/mm/dd(aaa)")
End Sub
コードの動作:
- 「祝日」シートからA列の最終行を取得して祝日リストを読み込む
WorksheetFunction.WorkDayに祝日範囲を渡してN営業日後を計算- 結果を曜日付きで表示(
aaaは「月」「火」などの曜日表記)
2つの日付間の営業日数を計算する
「1月6日〜1月31日の間に何営業日あるか?」を計算する。稼働日数やリードタイムの算出に使える。
Sub 営業日数を計算する()
Dim ws As Worksheet
Dim startDate As Date
Dim endDate As Date
Dim bizDays As Long
Dim lastRow As Long
Set ws = Worksheets("祝日")
startDate = #1/6/2026#
endDate = #1/31/2026#
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow >= 2 Then
bizDays = WorksheetFunction.NetworkDays(startDate, endDate, _
ws.Range("A2:A" & lastRow))
Else
bizDays = WorksheetFunction.NetworkDays(startDate, endDate)
End If
MsgBox Format(startDate, "yyyy/mm/dd") & " ~ " & _
Format(endDate, "yyyy/mm/dd") & vbCrLf & _
"営業日数: " & bizDays & " 日"
End Sub
WorkDay と NetworkDays の使い分け:
| 関数 | 用途 | 戻り値 |
|---|---|---|
| WorkDay | N営業日後の日付を知りたい | 日付 |
| NetworkDays | 2日付間の営業日数を知りたい | 数値 |
実務で使う:支払期限を一括計算する
一覧表の請求日から支払期限を一括で計算するコード。実務ではこのパターンが最も使える。
「一覧」シートのレイアウト:
| A(取引先) | B(案件名) | C(請求日) | D(支払期限) | |
|---|---|---|---|---|
| 1 | 取引先 | 案件名 | 請求日 | 支払期限 |
| 2 | A商事 | 部品納入 | 2026/01/06 | (自動で入る) |
Sub 支払期限を一括計算する()
Dim wsData As Worksheet
Dim wsHoliday As Worksheet
Dim lastRow As Long
Dim lastRowH As Long
Dim i As Long
Dim cnt As Long
' --- 祝日シートの存在チェック ---
Dim sheetExists As Boolean
Dim tmpSheet As Worksheet
sheetExists = False
For Each tmpSheet In ThisWorkbook.Worksheets
If tmpSheet.Name = "祝日" Then
sheetExists = True
Exit For
End If
Next tmpSheet
If Not sheetExists Then
MsgBox "「祝日」シートが見つかりません。" & vbCrLf & _
"シート名を確認してください。", vbExclamation
Exit Sub
End If
Set wsData = Worksheets("一覧")
Set wsHoliday = Worksheets("祝日")
lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
lastRowH = wsHoliday.Cells(wsHoliday.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
On Error GoTo ErrHandler
Application.ScreenUpdating = False
For i = 2 To lastRow
If IsDate(wsData.Cells(i, 3).Value) Then
' C列の請求日から30営業日後をD列に出力
If lastRowH >= 2 Then
wsData.Cells(i, 4).Value = _
WorksheetFunction.WorkDay( _
wsData.Cells(i, 3).Value, 30, _
wsHoliday.Range("A2:A" & lastRowH))
Else
wsData.Cells(i, 4).Value = _
WorksheetFunction.WorkDay(wsData.Cells(i, 3).Value, 30)
End If
wsData.Cells(i, 4).NumberFormat = "yyyy/mm/dd"
cnt = cnt + 1
End If
Next i
Application.ScreenUpdating = True
MsgBox cnt & " 件の支払期限を計算しました。"
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました(行 " & i & "): " & Err.Description, vbExclamation
End Sub
コードの動作:
- 「祝日」シートの存在を確認(見つからなければエラーメッセージを表示して終了)
- 「一覧」シートのA列で最終行を取得
- 2行目から最終行までループ
- C列が日付型の行だけ処理(IsDateチェック)
- C列の請求日から30営業日後を計算してD列に出力
- D列の書式を
yyyy/mm/ddに設定 - 処理件数をMsgBoxで報告
- エラー発生時も
Application.ScreenUpdating = Trueに戻してからエラー内容を表示
営業日数の変更: 30 の部分を変えれば、任意のN営業日後に変更できる。
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | 期限日が1日ズレる | WorkDay関数は開始日の翌日からカウントする | 当日を含めるなら nDays - 1 にする |
| 2 | 祝日が除外されていない | 祝日リストの年度が古い(去年のまま) | 毎年1月に祝日リストを更新する。内閣府の祝日一覧を参照 |
| 3 | 実行時にエラーが出る | 祝日シートのA列に文字列(日付型でないデータ)が混ざっている | IsDate で事前チェック。セルの表示形式を「日付」に設定してから入力する |
| 4 | 振替休日が営業日扱いになる | 祝日リストに振替休日が入っていない | 内閣府の祝日一覧で振替休日・国民の休日を確認して追加する |
| 5 | 会社の休業日が考慮されない | 年末年始(12/29〜1/3)やお盆は祝日ではないが休業日 | 祝日リストに会社独自の休業日も追加する |
自分も2番でやらかしたことがある。年明けに祝日リストを更新し忘れて、1月4日(仕事始め)を休日扱いにしてしまい、取引先への支払期限がズレた。それ以来、毎年1月の最初の出勤日に「祝日シート更新」をルーティンにしている。
FAQ
Q1: 当日を含めて営業日を計算したい場合は?
WorkDay関数は翌日からカウントするため、当日を含めたい場合は営業日数を1つ減らす。例:「今日を含めて5営業日以内」なら WorkDay(startDate, 4) にする。
Q2: 土曜日も営業日に含めたい場合は?
WorksheetFunction.WorkDay_Intl を使う。第3引数に曜日パターンを指定できる。よく使うパターンは以下のとおり。
| パターン値 | 休日の曜日 |
|---|---|
| 1(既定) | 土曜・日曜 |
| 11 | 日曜のみ |
| 12 | 月曜のみ |
| 17 | なし(祝日リストのみで制御) |
例:WorkDay_Intl(startDate, nDays, 11, 祝日範囲) で土曜を営業日に含める。
Q3: 祝日リストを自動で作成できる?
VBAだけで祝日リストを自動生成するのは困難。内閣府の「国民の祝日について」ページから一覧をコピーして祝日シートに貼り付けるのが現実的。
Q4: マイナスの日数を指定したらどうなる?
N営業日前の日付が返る。WorkDay(Date, -5) で5営業日前を計算できる。支払いの起算日を遡る場合に使える。
Q5: 結果がシリアル値(数値)で表示される
D列のセルにNumberFormatが設定されていない場合、日付がシリアル値(例:46044)で表示される。コード内で wsData.Cells(i, 4).NumberFormat = "yyyy/mm/dd" を設定するか、事前にD列の書式を「日付」に設定しておく。
Q6: 「祝日」シートが見つからないとエラーになる
シート名が全角・半角で異なっていたり、前後にスペースが入っているとシートが見つからずエラーになる。シート名は正確に 「祝日」(全角2文字)にすること。一括計算コードでは存在チェックを入れているが、実務版コードで同じエラーが出る場合はシート名を再確認する。
まとめ
この記事で、VBAを使って祝日・土日を除いた営業日を自動計算できるようになった。
- 最小版:WorkDayでN営業日後を簡単計算(土日のみ除外)
- 実務版:祝日リスト対応のN営業日後
- 営業日数計算:NetworkDaysで2日付間の営業日数を取得
- 一括計算:一覧表の支払期限を一括で自動出力
重要なのは以下の2点:
- WorkDayは翌日からカウントする(当日含むなら-1)
- 祝日リストは毎年更新する(振替休日・会社休業日も忘れずに)
関連記事
- 日付・曜日の判定で月末処理を自動化する方法 — Weekday関数やDateSerial関数で月末日付を判定する方法
- セルの書式を一括変更する方法 — 日付の表示形式をまとめて変更したい場合
- データの最終行・最終列を正確に取得する方法 — 一覧表のFor文ループで必須の最終行取得
- MsgBoxの使い方と実務パターン — 結果表示やユーザー確認のMsgBox活用法
- 請求書を自動作成する方法 — 営業日計算と組み合わせて支払期限付きの請求書を自動作成
次にやりたくなること
- 請求書を自動作成する方法 — 営業日で計算した支払期限を請求書テンプレートに自動差し込みしたい場合に
- 日付・曜日の判定で月末処理を自動化する方法 — 月末判定や締日計算で「月末が土日なら前営業日にする」処理を組み合わせたい場合に


コメント