Contents
この記事でできること
- VBAで2つの日付の差分(経過日数・経過月数・経過年数)を計算できる
- DateAddで日付に日数・月数を加算・減算できる
- 一覧表の期限日と今日を比較して、期限切れ行を色分け+残日数を自動入力できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業):
- 一覧表の期限日を目視で1件ずつ確認
- 「あと何日?」を電卓やExcel数式で手計算
- 期限切れの行を手動で赤く塗る
- 100件あると確認漏れ・計算ミスが起きる
After(マクロ実行):
- 「管理一覧」シートに期限日を入力
- マクロを実行する
- 期限切れ行が赤色、7日以内が黄色に自動色分け
- 残日数列に「あと○日」「○日超過」が自動入力される
- 100件が数秒で完了。見落としゼロ
管理一覧シート(処理前):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 案件名 | 期限日 | 残日数 | 状態 |
| 2 | 契約A | 2026/03/10 | ||
| 3 | 契約B | 2026/03/15 | ||
| 4 | 契約C | 2026/03/20 | ||
| 5 | 契約D | 2026/04/30 |
管理一覧シート(処理後 — 2026/03/13に実行した場合):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 案件名 | 期限日 | 残日数 | 状態 |
| 2 | 契約A | 2026/03/10 | 3日超過 | 期限切れ(赤色) |
| 3 | 契約B | 2026/03/15 | あと2日 | 期限間近(黄色) |
| 4 | 契約C | 2026/03/20 | あと7日 | 期限間近(黄色) |
| 5 | 契約D | 2026/04/30 | あと48日 | 期限内 |
契約更新の管理表を毎週チェックしていたとき、100件以上の期限日を目視で確認していた。「あと何日?」を毎回手計算して、期限切れを見落として上司に指摘されたことがある。
DateDiffで残日数を自動計算し、期限切れ行を赤く色分けするマクロを作ってからは、ボタン1つで全件チェックできるようになった。見落としゼロになって、週1回のチェック作業が5分で終わるようになった。
期限管理は多くの職場で必要なのに、日付の計算方法を知らないと手作業に頼るしかない。DateDiff / DateAdd / 日付比較の3つを覚えれば、期限管理の自動化は簡単にできる。日付・曜日の判定で月末処理を自動化と組み合わせれば、月末期限の処理もカバーできる。
DateDiff / DateAdd / 日付比較の3つを覚えれば、日付まわりの計算は一通りできる。
事前準備
シート構成を用意する
実務版コードでは以下の構成を使う。最小版はシート構成不要(イミディエイトウィンドウで結果を確認する)。
「管理一覧」シート — 期限日を入力する場所
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 案件名 | 契約A |
| B列 | 期限日 | 2026/03/31 |
| C列 | 残日数 | (マクロで自動入力) |
| D列 | 状態 | (マクロで自動入力) |
- 1行目はヘッダー。データは2行目から入力する
- B列の期限日は日付型で入力すること(文字列は不可)
- A列が空の行が最終行として判定される
バックアップを取る
セルの背景色と値を上書きする処理のため、実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
コード(最小版)– 2つの日付の差分・加算・比較を確認する
まずDateDiff / DateAdd / 日付比較の動作を確認する。イミディエイトウィンドウ(Ctrl + Gで表示)に結果が出力される。
Sub 日付計算の動作確認()
Dim startDate As Date
Dim endDate As Date
startDate = DateValue("2026/01/01")
endDate = DateValue("2026/03/13")
' ★ DateDiff: 2つの日付の差分を計算
Debug.Print "=== DateDiff(日付の差分) ==="
Debug.Print "経過日数: " & DateDiff("d", startDate, endDate) & " 日"
Debug.Print "経過月数: " & DateDiff("m", startDate, endDate) & " ヶ月"
Debug.Print "経過年数: " & DateDiff("yyyy", startDate, endDate) & " 年"
Debug.Print "経過週数: " & DateDiff("ww", startDate, endDate) & " 週"
' ★ DateAdd: 日付の加算・減算
Debug.Print "=== DateAdd(日付の加算・減算) ==="
Debug.Print "30日後: " & Format(DateAdd("d", 30, endDate), "yyyy/mm/dd")
Debug.Print "7日前: " & Format(DateAdd("d", -7, endDate), "yyyy/mm/dd")
Debug.Print "3ヶ月後: " & Format(DateAdd("m", 3, endDate), "yyyy/mm/dd")
Debug.Print "1年後: " & Format(DateAdd("yyyy", 1, endDate), "yyyy/mm/dd")
' ★ 日付の比較演算
Debug.Print "=== 日付の比較 ==="
Dim deadline As Date
deadline = DateValue("2026/03/31")
Debug.Print "期限日: " & Format(deadline, "yyyy/mm/dd")
Debug.Print "今日: " & Format(Date, "yyyy/mm/dd")
If deadline < Date Then
Debug.Print "→ 期限切れ"
ElseIf deadline = Date Then
Debug.Print "→ 今日が期限"
Else
Debug.Print "→ 期限内(あと " & DateDiff("d", Date, deadline) & " 日)"
End If
' ★ DateSerial / DateValue: 日付の生成
Debug.Print "=== DateSerial / DateValue ==="
Debug.Print "DateSerial(2026, 3, 13) = " & DateSerial(2026, 3, 13)
Debug.Print "DateValue(""2026/03/13"") = " & DateValue("2026/03/13")
Debug.Print "3月の末日: " & DateSerial(2026, 4, 0) ' 翌月の0日=当月末日
MsgBox "イミディエイトウィンドウ(Ctrl+G)に結果を出力しました。"
End Sub
実行結果(イミディエイトウィンドウ)
=== DateDiff(日付の差分) ===
経過日数: 71 日
経過月数: 2 ヶ月
経過年数: 0 年
経過週数: 10 週
=== DateAdd(日付の加算・減算) ===
30日後: 2026/04/12
7日前: 2026/03/06
3ヶ月後: 2026/06/13
1年後: 2027/03/13
=== 日付の比較 ===
期限日: 2026/03/31
今日: 2026/03/13
→ 期限内(あと 18 日)
=== DateSerial / DateValue ===
DateSerial(2026, 3, 13) = 2026/03/13
DateValue("2026/03/13") = 2026/03/13
3月の末日: 2026/03/31
DateDiffの第1引数(interval)で「日・月・年・週」を切り替えられる点に注目。DateAddは負の値を指定すると減算になる。
動作確認
- マクロを実行する
- 「イミディエイトウィンドウに結果を出力しました」のメッセージが出る
Ctrl + Gでイミディエイトウィンドウを表示して結果を確認する
最小版でDateDiff / DateAdd / 日付比較の動作が確認できたら、次の実務版に進む。
コード(実務版)– 期限日と今日を比較→期限切れ行を色分け+残日数を自動入力
自分はこの方法で毎週の契約更新チェックを処理している。100件以上の期限日を数秒でチェックできるようになり、見落としがゼロになった。
管理一覧の期限日と今日を比較し、期限切れ行を赤色に色分け、期限7日以内を黄色で警告、残日数を自動入力する。色分けの詳細はセルの値に応じて行を自動色分けを参照。
Sub 期限チェックと残日数計算()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim deadline As Date
Dim remainDays As Long
Dim cntExpired As Long
Dim cntWarning As Long
Dim cntOK As Long
Dim warningDays As Long
' ★ シート名を指定
Set ws = Worksheets("管理一覧")
' ★ 警告の日数を指定(期限の○日前から黄色にする)
warningDays = 7
' ★ 最終行を取得(A列=案件名で判定)
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
' 確認ダイアログ
If MsgBox((lastRow - 1) & " 件の期限チェックを実行します。" & vbCrLf & _
"基準日: " & Format(Date, "yyyy/mm/dd") & "(今日)" & vbCrLf & _
"警告: 期限 " & warningDays & " 日以内を黄色表示" & vbCrLf & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
On Error GoTo ErrHandler
Application.ScreenUpdating = False
For i = 2 To lastRow
' 期限日が空または日付でない場合はスキップ
If ws.Cells(i, 2).Value = "" Then GoTo NextRow
If Not IsDate(ws.Cells(i, 2).Value) Then GoTo NextRow
deadline = CDate(ws.Cells(i, 2).Value)
' ★ 残日数を計算(期限日 - 今日)
remainDays = DateDiff("d", Date, deadline)
' 背景色をリセット(前回の実行結果をクリア)
ws.Range("A" & i & ":D" & i).Interior.ColorIndex = xlNone
If remainDays < 0 Then
' ★ 期限切れ: 赤色に色分け
ws.Cells(i, 3).Value = Abs(remainDays) & "日超過"
ws.Cells(i, 4).Value = "期限切れ"
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(255, 200, 200)
cntExpired = cntExpired + 1
ElseIf remainDays = 0 Then
' ★ 本日期限: 赤色に色分け
ws.Cells(i, 3).Value = "本日期限"
ws.Cells(i, 4).Value = "本日期限"
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(255, 200, 200)
cntExpired = cntExpired + 1
ElseIf remainDays <= warningDays Then
' ★ 期限間近: 黄色で警告
ws.Cells(i, 3).Value = "あと" & remainDays & "日"
ws.Cells(i, 4).Value = "期限間近"
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(255, 255, 200)
cntWarning = cntWarning + 1
Else
' ★ 期限内: 色なし
ws.Cells(i, 3).Value = "あと" & remainDays & "日"
ws.Cells(i, 4).Value = "期限内"
cntOK = cntOK + 1
End If
NextRow:
Next i
' 列幅を自動調整
ws.Columns("C:D").AutoFit
Application.ScreenUpdating = True
MsgBox "期限チェック完了" & vbCrLf & vbCrLf & _
"期限切れ: " & cntExpired & " 件" & vbCrLf & _
"期限間近(" & warningDays & "日以内): " & cntWarning & " 件" & vbCrLf & _
"期限内: " & cntOK & " 件", vbInformation
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました。" & vbCrLf & _
"行番号: " & i & vbCrLf & _
Err.Description, vbCritical
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("管理一覧") |
管理一覧 | データのシート名 |
| 2 | warningDays = 7 |
7 | 期限の何日前から黄色にするか |
| 3 | ws.Cells(i, 2) |
列2(B列) | 期限日の列番号 |
| 4 | ws.Cells(i, 3) |
列3(C列) | 残日数の出力先列 |
| 5 | ws.Cells(i, 4) |
列4(D列) | 状態の出力先列 |
| 6 | RGB(255, 200, 200) |
薄い赤 | 期限切れの色。変更する場合はRGB値を指定 |
| 7 | RGB(255, 255, 200) |
薄い黄 | 期限間近の色。変更する場合はRGB値を指定 |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| 期限切れ色分け | 期限切れ行を薄い赤色に色分け | セルの値に応じて行を自動色分け |
| 期限間近の警告 | 期限7日以内を薄い黄色で警告 | セルの値に応じて行を自動色分け |
| 残日数の自動入力 | 「あと○日」「○日超過」「本日期限」を自動入力 | — |
| 日付チェック | IsDateで日付でないセルをスキップ | — |
| 確認ダイアログ | 件数+基準日+警告日数を表示してYes/No確認 | — |
| 色のリセット | 前回の実行結果をクリアしてから再判定 | — |
| 高速化 | ScreenUpdating = Falseで画面更新を停止 | — |
| エラー復帰 | On Error GoTo ErrHandlerでScreenUpdating復帰 | — |
DateDiff / DateAdd / 日付比較の使い分け
DateDiff の interval引数一覧
| interval | 意味 | 例(2026/01/01 → 2026/03/13) |
|---|---|---|
| “yyyy” | 年 | 0 |
| “q” | 四半期 | 1 |
| “m” | 月 | 2 |
| “ww” | 週 | 10 |
| “d” | 日 | 71 |
| “h” | 時間 | 1704 |
| “n” | 分 | 102240 |
| “s” | 秒 | 6134400 |
重要: “m” は月、”n” は分。混同しやすいので注意。VBAでは「minute」の2文字目 “n” を使う(”m” は month に使われているため)。
DateAdd の使い方
| やりたいこと | コード | 結果 |
|---|---|---|
| 30日後 | DateAdd("d", 30, Date) |
今日の30日後 |
| 7日前 | DateAdd("d", -7, Date) |
今日の7日前 |
| 3ヶ月後 | DateAdd("m", 3, Date) |
今日の3ヶ月後 |
| 1年前 | DateAdd("yyyy", -1, Date) |
今日の1年前 |
| 翌月末日 | DateSerial(Year(Date), Month(Date) + 2, 0) |
翌月の末日 |
DateAddで月を加算するとき、存在しない日付は自動で月末に調整される。例: DateAdd("m", 1, #1/31/2026#) → 2026/02/28。月末処理の詳細は日付・曜日の判定で月末処理を自動化を参照。
日付の比較演算
| 比較 | 意味 | 使用例 |
|---|---|---|
date1 > date2 |
date1がdate2より後 | If deadline > Date Then(期限が今日より後) |
date1 < date2 |
date1がdate2より前 | If deadline < Date Then(期限切れ) |
date1 = date2 |
date1とdate2が同じ日 | If deadline = Date Then(今日が期限) |
date1 >= date2 |
date1がdate2以降 | 範囲判定に使用 |
date1 <= date2 |
date1がdate2以前 | 範囲判定に使用 |
date1 <> date2 |
date1とdate2が異なる日 | 除外条件に使用 |
日付型の変数同士なら直接比較できる。セルの値を比較する場合は、CDateで日付型に変換してから比較すること。
DateSerial / DateValue の使い分け
| 関数 | 入力 | 用途 |
|---|---|---|
DateSerial(年, 月, 日) |
3つの数値 | 計算で日付を作るとき(月末日の取得など) |
DateValue("文字列") |
日付文字列 | 文字列を日付型に変換するとき |
CDate(値) |
日付に変換可能な値 | セルの値を日付型に変換するとき |
' DateSerial の便利な使い方
Debug.Print DateSerial(2026, 4, 0) ' → 2026/03/31(3月の末日)
Debug.Print DateSerial(2026, 1, 0) ' → 2025/12/31(前年の12月末日)
Debug.Print DateSerial(2026, 13, 1) ' → 2027/01/01(年の繰り上がり)
日付の表示形式を変えたい場合は日付や数値の表示形式をFormatで自由に変換する方法を参照。セルの書式設定で見た目を変える方法はセルの書式を一括変更する方法を参照。
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | DateDiffで月数を求めたら巨大な数値が返る | interval引数を "m"(月)のつもりで "n"(分)と間違えている。VBAでは分は "n" を使う | interval引数の一覧表を確認。"m"=月、"n"=分。VBAでは minute の "n" を使う |
| 2 | DateDiffで経過月数を求めたら想定より1ヶ月多い/少ない | DateDiffの "m" は「年月の差」のみで計算し日は無視する。1/31→2/1 は1ヶ月、1/1→1/31 は0ヶ月 | 日付の「日」まで考慮した厳密な月数が必要なら、日数ベースで計算する |
| 3 | 文字列の日付を比較したら結果がおかしい | "2026/3/1" > "2026/12/1" は文字列比較になり True になる("3" > "1"の辞書順) | CDate または DateValue で日付型に変換してから比較する |
| 4 | DateAddで月末日に1ヶ月足したら日がズレた | DateAdd("m", 1, #1/31/2026#) は 2/28 になる。存在しない日は月末に自動調整される仕様 | 月末日が必要なら DateSerial(Year(d), Month(d)+2, 0) で翌月末日を取得 |
| 5 | セルの日付をDateDiffに渡したらエラーになる | セルの値が日付に見えるが文字列として格納されている。書式が「文字列」のセルに入力された日付は日付型ではない | IsDate で判定してからCDateで変換する。セルの書式を「日付」に変更して再入力 |
DateDiffの interval引数を "m" にしたつもりが "n"(分)と間違えて、経過月数のはずが経過分数が返ってきたことがある。結果が何百万という数字になって、最初はバグかと思った。interval引数は一覧表を見て指定するのが確実。
FAQ
Q1. DateDiffの "m" で求めた月数は何を基準にしている?
年月の差のみで計算する。日は無視される。
Debug.Print DateDiff("m", #1/31/2026#, #2/1/2026#) ' → 1(1日しか経っていないが1ヶ月)
Debug.Print DateDiff("m", #1/1/2026#, #1/31/2026#) ' → 0(同じ月なので0ヶ月)
Debug.Print DateDiff("m", #1/15/2026#, #3/14/2026#) ' → 2(1ヶ月29日だが2ヶ月)
厳密に「30日で1ヶ月」としたい場合は DateDiff("d", date1, date2) \ 30 で日数を30で割る。
Q2. 日付に「30日後」を足したいが営業日で計算したい場合は?
DateAddは暦日(カレンダー日数)ベースの計算。営業日(土日祝日を除く)で計算したい場合は WorksheetFunction.WorkDay を使う。詳しくは祝日・土日を除いた営業日を自動計算する方法を参照。
' 暦日ベース: DateAdd
Debug.Print DateAdd("d", 30, Date) ' → 30暦日後
' 営業日ベース: WorksheetFunction.WorkDay
Debug.Print WorksheetFunction.WorkDay(Date, 30) ' → 30営業日後
Q3. DateSerialの月や日に0や負の値を入れたらどうなる?
自動で繰り上げ・繰り下げされる。月末日の取得に便利。
Debug.Print DateSerial(2026, 4, 0) ' → 2026/03/31(4月0日=3月末日)
Debug.Print DateSerial(2026, 0, 1) ' → 2025/12/01(0月=前年12月)
Debug.Print DateSerial(2026, 13, 1) ' → 2027/01/01(13月=翌年1月)
Debug.Print DateSerial(2026, 3, -1) ' → 2026/02/27(3月-1日=2月末日の前日)
Q4. 日付の表示形式を「2026年3月13日」にしたい
Format関数で書式文字列を指定する。詳しくは日付や数値の表示形式をFormatで自由に変換する方法を参照。
Debug.Print Format(Date, "yyyy年m月d日") ' → 2026年3月13日
Debug.Print Format(Date, "yyyy/mm/dd") ' → 2026/03/13
Debug.Print Format(Date, "ggge年m月d日") ' → 令和8年3月13日
Debug.Print Format(Date, "yyyy年mm月dd日(aaa)") ' → 2026年03月13日(金)
Q5. 期限の7日前に色を変えたい(警告日数を変えたい)場合は?
実務版コードの warningDays = 7 の値を変更する。14日前から警告にしたい場合は warningDays = 14 に変更するだけで動作する。複数段階の警告(30日前=緑、7日前=黄色、期限切れ=赤)にしたい場合は、ElseIfの条件を追加する。
' 例: 3段階の警告
If remainDays < 0 Then
' 期限切れ: 赤
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(255, 200, 200)
ElseIf remainDays <= 7 Then
' 7日以内: 黄色
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(255, 255, 200)
ElseIf remainDays <= 30 Then
' 30日以内: 薄い緑
ws.Range("A" & i & ":D" & i).Interior.Color = RGB(200, 255, 200)
Else
' 期限内: 色なし
ws.Range("A" & i & ":D" & i).Interior.ColorIndex = xlNone
End If
まとめ
この記事では、VBAで2つの日付の差分・加算・比較を計算する方法を解説した。
- 最小版: DateDiff / DateAdd / 日付比較の動作をイミディエイトウィンドウで確認
- 実務版: 一覧表の期限日と今日を比較して、期限切れ行を色分け+残日数を自動入力
最も重要なポイントは DateDiffの interval引数の指定を間違えないこと。特に "m"(月)と "n"(分)の混同に注意する。
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- 日付・曜日の判定で月末処理を自動化 -- DateSerialでの月末日取得や曜日判定との組み合わせ
- 祝日・土日を除いた営業日を自動計算する方法 -- 営業日ベースの日数計算が必要な場合
- 日付や数値の表示形式をFormatで自由に変換する方法 -- 日付の表示形式(和暦・曜日付きなど)
- セルの値に応じて行を自動色分け -- 条件に応じた色分けの詳細な方法
- セルの書式を一括変更する方法 -- セルの日付書式やNumberFormatの設定
次にやりたくなること
- 月末や曜日で条件分岐したい → 日付・曜日の判定で月末処理を自動化で、月末日の自動取得や曜日による処理分岐ができる
- 営業日で期限を計算したい → 祝日・土日を除いた営業日を自動計算する方法で、土日祝日を除いた営業日ベースの計算ができる

コメント