VBAで業務マクロを作るとき、「今日から○日後・○か月後」「2つの日付の差を出す」「年齢を出す」「月末日を取得する」「特定の週の何日目かを知る」といった 日付を柔軟に扱いたい場面が多くあります。
しかし、日付・時刻を扱うには「Date型」「文字列型」「シリアル値」「うるう年」「月末」など細かなポイントもあり、思わぬバグにつながることもあります。
この記事では、以下のテーマを網羅的に解説します。
- 日付・時刻の取得・判定
- 日付の比較・条件判定
- 加算・減算(未来・過去の日付を算出)
- 日付の差(期間/月数/年数など)を求める
- 年・月・日・時・分・秒などの部分取得
- 実務的な応用例・注意点
- 「月末」「営業日」「文字列から日付へ変換」などの追加トピック
現在の日付・時刻を取得する
日付操作の第一歩は「現在の日付・時刻を取得する」ことです。
VBAでは以下の2つの関数が基本になります。
Dim dtNow As Date
dtNow = Now ' 現在の日付+時刻
Dim dtToday As Date
dtToday = Date ' 現在の日付(時刻部分は 0:00:00)
Now は「年/月/日 + 時刻」を返し、Date は「今日の日付のみ」を返します。
日付として有効か判定・変換する
文字列を扱う場面では、「それが正しい日付かどうか」を確認してから処理するのが安全です。
Sub CheckDate()
Dim strValue As String
Dim dt As Date
strValue = "2025/11/01"
If IsDate(strValue) Then
dt = CDate(strValue) ' 文字列 → 日付型に変換
MsgBox "有効な日付です:" & dt
Else
MsgBox "これは日付として認識できません。"
End If
End Sub
IsDate():文字列が日付かどうかを判定します。CDate():文字列をDate型に変換します。
Excelから取り込んだCSVなどでは、「文字列の日付」を CDate で変換してから処理するのが確実です。
日付を比較する
2つの日付を比較して、「期限を過ぎているか」や「今日以前か」を判定できます。
Sub CompareDate()
Dim dtLimit As Date
dtLimit = #2025/11/05#
If dtLimit < Date Then
MsgBox "期限を過ぎています。"
Else
MsgBox "まだ期限内です。"
End If
End Sub
ポイントとして、Now で取得した時刻付きの日付を比較する場合、「日付は同じでも時刻が早いか遅いか」で結果が変わることがあります。
単純に日付で比較したい場合は Date を使うようにしましょう。
日付を加算・減算する(DateAdd関数)
DateAdd関数の構文
日付を進めたり戻したりするには、DateAdd 関数を使います。
DateAdd(間隔, 数値, 基準日)
DateAdd関数の間隔(interval)とは
DateAdd 関数の第一引数である間隔(interval)とは、時間間隔を表す文字列を指します。
間隔の具体的な値とそれに対応する意味は下の表を参照ください。
| 値 | 意味 |
|---|---|
"yyyy" | 年を加算・減算 |
"m" | 月を加算・減算 |
"d" | 日を加算・減算 |
"ww" | 週を加算・減算 |
"h" | 時間を加算・減算 |
"n" | 分を加算・減算 |
"s" | 秒を加算・減算 |
DateAdd関数の使用例
Sub AddDateSample()
MsgBox DateAdd("d", 7, Date) ' 今日から7日後
MsgBox DateAdd("m", -1, Date) ' 1か月前
MsgBox DateAdd("yyyy", 2, Date) ' 2年後
MsgBox DateAdd("h", 2, Now) ' 現在から3時間後
End Sub
DateAdd 関数を使用する上での注意点は下記の通りです。
- 1月31日など「月末」に対して
+1か月すると、翌月の月末(2月28日など)になります。 - 営業日を考慮した加算(休日を除くなど)は別途ロジックが必要です。
2つの日付の差を求める(DateDiff関数)
DateDiff関数の構文
2つの日付の差を求めたいときは、DateDiff 関数を使います。
DateDiff(間隔, 開始日, 終了日)
第一引数の間隔についてはDateAdd 関数とほぼ同じですが再掲します。異なる点はDateDiff 関数には「週」は指定できないということです。
| 値 | 意味 |
|---|---|
"yyyy" | 年数の差 |
"m" | 月数の差 |
"d" | 日数の差 |
"h" | 時間の差 |
"n" | 分の差 |
"s" | 秒の差 |
DateDiff関数の使用例
下記コードでは、2つの日付から日数の差をDateDiff 関数により取得して、メッセージ表示しています。
Sub DiffDateSample()
Dim diff As Long
diff = DateDiff("d", #2025/01/01#, #2025/03/01#)
MsgBox "日数差:" & diff & "日" ' → 59日
End Sub
下記のコードでは、生年月日を指定して、現在の年齢を取得しています。
Sub CalcAge()
Dim birth As Date
birth = #1995/5/10#
Dim age As Long
age = DateDiff("yyyy", birth, Date)
If Date < DateAdd("yyyy", age, birth) Then
age = age - 1
End If
MsgBox "年齢は " & age & " 歳です"
End Sub
年・月・日・曜日などを取り出す
Year・Month・Day・Weekday などを使えば、日付の一部だけを取り出せます。
Sub GetParts()
Dim dt As Date
dt = #2025/11/01#
MsgBox "年:" & Year(dt)
MsgBox "月:" & Month(dt)
MsgBox "日:" & Day(dt)
MsgBox "曜日番号:" & Weekday(dt)
MsgBox "曜日名:" & WeekdayName(Weekday(dt))
End Sub
たとえば Weekday(dt) の結果が 1 のときは「日曜日」、2 のときは「月曜日」です。
月末・翌月初日を求める
実務では「月末締め」「翌月の処理開始日」などを求めたいケースがよくあります。
Sub GetMonthEnd()
Dim dt As Date
dt = Date
Dim monthEnd As Date
monthEnd = DateAdd("m", 1, DateSerial(Year(dt), Month(dt), 1)) - 1
MsgBox "今月の月末は " & Format(monthEnd, "yyyy/mm/dd")
End Sub
処理の流れは下記の通りです。
DateSerial(年, 月, 1)で「当月の1日」を作成DateAdd("m",1,...)で「翌月の1日」を求める- そこから「-1日」することで月末日を算出します。
実務で使える日付マクロ例
30日後の納期を自動計算
Sub Deadline()
Dim dtLimit As Date
dtLimit = DateAdd("d", 30, Date)
Range("B1").Value = Format(dtLimit, "yyyy/mm/dd")
End Sub
入社日からの在籍年数を求める
Sub CalcYears()
Dim joinDate As Date
joinDate = Range("A1").Value
Dim years As Long
years = DateDiff("yyyy", joinDate, Date)
If Date < DateAdd("yyyy", years, joinDate) Then
years = years - 1
End If
Range("B1").Value = years & "年"
End Sub
よくある困りごとと注意点
| トラブル | 原因 | 対処法 |
|---|---|---|
DateAdd("m",1,#2025/01/31#) の結果が 2/28 になる | 月末補正 | 仕様です。翌月に同じ日がない場合、月末に補正されます。 |
| 文字列を日付として認識できない | ロケール(コンピュータの言語や地域の設定)の違い | CDate を使うか、DateSerial で安全に作成します。 |
Now を比較したら思った結果にならない | 時刻を含む | 比較用には Date を使うと安全です。 |
| 営業日(休日除外)を加算できない | DateAdd は休日を考慮しない | 祝日リストを参照するロジックを作る必要あり。 |
まとめ
- 今日の日付 →
Date - 現在時刻付き →
Now - 日付の加算・減算 →
DateAdd - 日付の差分(日数・月数・年数) →
DateDiff - 年・月・日・曜日の取得 →
Year/Month/Day/Weekday - 月末日を求める →
DateSerial+DateAdd("m",1,...) - 1
これらを覚えるだけで、「今日から30日後の納期」「入社日からの在籍年数」「月末締め」など、ほとんどの日付処理を自動化できます。VBAで日付を思い通りに扱えるようになると、手作業だったスケジュール処理やレポート作成が驚くほど効率化します。