VBAで日付を操作する方法|今日の日付・○日前・月末・日数差を自動計算

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

年・月・日・曜日などを取り出す

YearMonthDayWeekday などを使えば、日付の一部だけを取り出せます。

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

処理の流れは下記の通りです。

  1. DateSerial(年, 月, 1) で「当月の1日」を作成
  2. DateAdd("m",1,...) で「翌月の1日」を求める
  3.  そこから「-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
  • 月末日を求めるDateSerialDateAdd("m",1,...) - 1

これらを覚えるだけで、「今日から30日後の納期」「入社日からの在籍年数」「月末締め」など、ほとんどの日付処理を自動化できます。VBAで日付を思い通りに扱えるようになると、手作業だったスケジュール処理やレポート作成が驚くほど効率化します。

この記事を書いた人

うつ病により二度の休職を経験。
現在は自動車メーカー勤務で、開発業務改善に従事。
自身の経験を基にしたメンタル改善のための情報や、仕事を楽にするためのVBAのノウハウ発信をしています。

目次