【Excel VBA】日付の扱い方!取得/加減算/書式変換/比較/エラー回避まで!

Excel VBAで日付の取得や計算をしたいときはないでしょうか。

そんな時に悩むことは、

・Excel VBAで日付の取得や計算をしたいが方法がわからない
・Excel VBAで日付の計算方法をざっと把握したいがまとまっているところがない
・日付型に変換できるか判定し、エラーを回避する方法がわからない

ですね。

今回は

Excel VBAで日付データの取得/加減算/書式変換/比較/エラー回避する方法

についてまとめます!

Excel VBAで扱う日付のデータ形式について

Excel VBAで扱う日付のデータ形式について説明をします。

Excel VBAで扱う日付のデータ形式は、文字列ではなく、日付と時間を数値で識別するシリアル値となっています。

シリアル値とはエクセルシートでは「1900/1/1 0:00:00」をVBAでは「1899/12/31 0:00:00」「1.0」として保持する数値で、整数部分が日付、小数点以下が時刻として扱われています。

タカヒロ
タカヒロ
シリアル値を扱う上でエクセルシートとVBAでは1日のずれがありますが、これは「1900/2/29」の存在しない日付を加算してしまっていることが原因のようです。なお「1900/3/1」から両方のシリアル値は一致する形になります。

例えば、A1セルにシリアル値「1」を入力し、Excel側の書式設定を日付にすると、

Sub test()
     Range("A1").Value2 = 1
End Sub

Excelシート側でシリアル値が日付表記に変換されます。

タカヒロ
タカヒロ
Excel側へ明示的にシリアル値を設定/取得したい場合はValue2プロパティを使用します。
なお、Valueプロパティは表示されている日付の形式の値を扱います。

次にValue2プロパティで、A1に入力された日付のシリアル値を取得してみます。

Sub test()
     Debug.Print Range("A1").Value2
End Sub

実行すると結果は「1」となります。

日付の加減算や比較をするときは表面上は人が理解できる日付の形式で表示されますが、バックグラウンドでは数値であるシリアル値で処理される形となっていることがわかるかと思います。

VBA上で日付データを設定する上でさまざまな関数を使用しますが、
VBAが理解できるシリアル値へ変換しなければならない仕様であることが背景となっているわけですね。

次に、Excel VBAで扱える日付関数にどんなものがあるか見てみましょう。

Excel VBAで扱える日付関数一覧

ExcelVBAで使用できる日付関数一覧となります。

CDate 指定した値を日付型 (Date) に変換します。
Date 指定された日付に対応するシリアル値を返します。
DateAdd 時間を加算して返します。
DateDiff 二つの日付の間隔を返します。
DatePart 任意の日時の特定項目を返します。
DateSerial 年月日の数値を日付型に変換します。
DateValue 日付を表す文字列をシリアル値に変換します。
Day シリアル値を日付に変換します。
Hour シリアル値を時刻に変換します。
IsDate シリアル値を日付型 (Date) に変換できるか判定します。
Minute シリアル値を時刻の分に変換します。
Month シリアル値を月に変換します。
MonthName シリアル値を月を表す文字列に変換します。
Now 現在の日付と時刻に対応するシリアル値を返します。
Second シリアル値を時刻の秒に変換します。
Time 指定した時刻に対応するシリアル値を返します。
TimeSerial シリアル値を時刻を表す文字列に変換します。
TimeValue 時刻を表す文字列をシリアル値に変換します。
Weekday シリアル値を曜日に変換します。
WeekdayName 指定した曜日の名前を返します。
Year シリアル値を年に変換します。

次に、各関数の使用方法について実例をもとに具体的に説明をしていきます。

Excel VBA日付関数の使用方法

Excel VBAの日付関数の使用方法について説明をします。

現在の日付を取得する

現在の日付を取得するには、Date関数を使用します。
Data関数でWindowsシステムで設定している日付を取得することができます。

Date 指定された日付に対応するシリアル値を返します。

サンプルコード:

Sub test()
    Debug.Print Date
End Sub

現在(2021/07/01)の日付が取得できます。
結果:

2021/07/01

時間を含む現在の日付を取得する

また、時間を含む今の日付を取得する場合はNow関数を使います。

Now 現在の日付と時刻に対応するシリアル値を返します。

サンプルコード:

Sub test()
    Debug.Print Now
End Sub

現在(2021/07/01 0:00:00)の時刻を含む日付が取得できます。
結果:

2021/07/01 0:00:00

年・月・日を整数で取得する

年・月・日を整数で取得するには以下の関数を使用します。

Year シリアル値を年に変換します。
Month シリアル値を月に変換します。
Day シリアル値を日付に変換します。

サンプルではDate関数で現在の日付から年・月・日を取得しています。

サンプルコード:

Sub test()
    Debug.Print Year(Date)
    Debug.Print Month(Date)
    Debug.Print Day(Date)
End Sub

結果:

2021
7
1

日付を加算、減算する

日付を加算、減算するには、DateAdd関数を使用します。

DateAdd 時間を加算して返します。

DateAdd関数の書式は以下の通りです。

DateAdd(<設定値>,<計算>,<値(日付)>)
<設定値> 説明
yyyy
q 四半期
m
y 年間通算日
d
w 週日
ww
h
n
s

設定値について、正の場合は将来日付としてカウント、負の場合は過去日付として計算されます。

タカヒロ
タカヒロ
つまり、日付の加減算は設置値の正負により行う形になります。

日付の加算

現在(2021/07/01)から二か月後の値を返します。

Sub test()
    Debug.Print DateAdd("m", 2, Date)
End Sub

結果:

2021/09/01

現在(2021/07/01 0:00:00)から2時間後の値を返します。

Sub test()
    Debug.Print DateAdd("h", 2, Now)
End Sub

タカヒロ
タカヒロ
時間を含め今の日時を取得する場合はNow関数を指定するようにしてください。
Date関数の場合は日付はとれますが、時間は除外され、0時開始となるためです。


結果:

2021/07/01 2:00:00

日付の減算

現在(2021/07/01)から2か月前の値を返します。

Sub test()
    Debug.Print DateAdd("m", -2, Date)
End Sub

結果:

2021/05/01

現在(2021/07/01 0:00:00)から2時間前の値を返します。

Sub test()
    Debug.Print DateAdd("h", -2, Now)
End Sub

結果:

2021/06/30 22:00:00

日付形式の文字列を日付型の値に変換する

日付形式の文字列を日付型の値に変換するにはCDate関数を使用します。

CDate 指定した値を日付型 (Date) に変換します。

Excelシートの値が日付として入っていてもTextプロパティなどで取得すると文字列として扱われます。

その場合、VBA上では日付であったとしても文字列なので加減算や比較はできないこととなりますので、

加減算や比較ができる日付型に変換する必要があるという訳です。

書式は以下の通りです。

CDate(<日付にしたいデータ>)

サンプルでは直接文字列”2021年7月1日”をCDate関数の値に設定しています。

サンプルコード:

Sub test()
    Debug.Print CDate("2021年7月1日")
End Sub

年、月、日が/となり日付型として出力されました。
結果:

2021/07/01

また、DateValue関数でも同じく日付形式の文字列を日付型の値に変換することができます。

DateValue 日付を表す文字列をシリアル値に変換します。
DateValue(<日付にしたいデータ>)

サンプルコード:

Sub test()
    Debug.Print DateValue("2021年7月1日")
End Sub

結果:

2021/07/01

“午後3.00.00”のように日本語表記の時刻を日付型に変換するTimeValue関数があります。

TimeValue(<時間にしたいデータ>)

サンプルコード:

Sub test()
         Debug.Print TimeValue("午後3.00.00")
End Sub

結果:

15:00:00

日付型に変換できるか判定し、エラーを回避する方法

うるう年以外の2021/2/29などカレンダーに存在しない値が入るケースがある場合は日付型に変換できません。

もし以下コードを実行すると、

Sub test()
    Debug.Print CDate("2021/2/29")
End Sub

「型が一致しません。」のエラーが表示されます。

【VBA】実行時エラー’13’「型が一致しません。」が出た場合の確認箇所と対処方法

そんな時に便利なのはIsDate関数を使って日付型変換可否を判断することです。

IsDate シリアル値を日付型 (Date) に変換できるか判定します。
IsDate(<日付にしたいデータ>)

結果はブーリアン型で返ります。Trueであれば日付型として有効、Falseであれば日付型として扱えない結果となります。

True:日付型に変換できます。
False:日付型に変換できません。

うるう年ではない”2021/2/29″が日付型として有効化チェックをしてみましょう。

Sub test()
    If IsDate("2021/2/29") Then
        Debug.Print "日付型に変換できます。"
    Else
        Debug.Print "日付型に変換できません。"
    End If
End Sub

結果は、

日付型に変換できません。

となります。

「型が一致しません。」のエラーも出ませんね。

日付型の値から書式指定の文字列に変換する

日付型の値を文字列に変換するにはFormat関数を使用します。

Format(Date, <設定値>)

時刻であれば”hh:mm:ss”、冒頭の/なしの年月であれば”yyyymm”となります。

“yyyymm”形式に変換

Sub test()
    Debug.Print Format(CDate("2021/7/1"), "yyyymm")
End Sub

結果:

202107

他の書式も設定可能です。

“yyyy年mm月dd日”形式へ変換

Sub test()
    Debug.Print Format(CDate("2021/7/1"), "yyyy年mm月dd日")
End Sub

結果:

2021年07月01日

西暦から和暦に変換

Sub test()
    Debug.Print Format(CDate("2021/7/1"), "ggge年mm月dd日")
End Sub

結果:

令和3年07月01日

和暦から西暦に変換

Sub test()
    Debug.Print Format(CDate("令和3年07月01日"), "yyyy/mm/dd")
End Sub

結果:

2021/07/01

日付型の値から数値のシリアル値を取得する

日付型の値から数値のシリアル値を取得する方法について説明をします。

VBAでは日付型の値はシリアル値と説明をしましたが、ウインドウで値を表示させるときは数値ではなく既定のフォーマットに則った日付表記となります。

数値のシリアル値に変換するためにはCDbl関数を使用します。

CDbl関数は引数をDouble型(倍精度浮動小数点数型)に変換しますので、本来持っている数値のシリアル値を確認することができるという訳です。
書式:

CDbl(<任意の文字列式または数式>)

試してみましょう。

サンプルコード:

Sub test()
    Debug.Print CDbl(CDate("2021/7/1"))
    Debug.Print CDbl(DateValue("2021/7/1"))
End Sub

結果:

44378
44378

CDate、DateValue関数共に数値で出力され、同じ結果となりましたね。

年・月・日の数値からシリアル値を作成する

年・月・日の数値からシリアル値を作成するにはDateSerial関数を使用します。

DateSerial 年月日の数値を日付型に変換します。

書式は以下の通りです。

DateSerial(<年>,<月>,<日>)

サンプルでは年を2021、月を7、日を1に指定しました。

サンプルコード:

Sub test()
    Debug.Print DateSerial(2021, 7, 1)
End Sub

結果:

2021/07/01

数値のシリアル値がとれているかCDbl関数を使い確認してみましょう。

Sub test()
    Debug.Print CDbl(DateSerial(2021, 7, 1))
End Sub

結果:

44378

問題ないですね。

日付を比較する

比較の判定はIF文の不等号でおこない、現在”2021年7月1日”と比較しそれ以前であれば過去、以降であれば未来という判定結果となります。

サンプルコード:

Sub test()
    If Date < CDate("2021年7月2日") Then
            Debug.Print "未来の日付です。"
        Else
            Debug.Print "過去の日付です。"
    End If
End Sub

結果:

未来の日付です。


DateAdd関数
を使い日付の加減を行うことも可能です。
今日から2日をプラスします。
サンプルコード:

Sub test()
    If DateAdd("d", 2, Date) < CDate("2021年7月2日") Then
            Debug.Print "過去の日付です。"
        Else
            Debug.Print "未来の日付です。"
    End If
End Sub

結果:

過去の日付です。

さいごに

いかがでしょうか。

今回は、

Excel VBAで日付の取得/加減算/書式変換/比較/エラー回避する方法

についてまとめました。

他にも便利な方法がありますので、よろしければご参照ください。



この記事の関連キーワード

こちらの記事の関連キーワード一覧です。クリックするとキーワードに関連する記事一覧が閲覧できます。



タカヒロ

タカヒロ
実質無料で読めるExcelVBA本についてまとめました。
もしVBA本購入を検討されていたら、どれだけお得か確かめてみてください。

【¥0】実質無料のExcelVBAおすすめ本25選!初級~中級まで網羅!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です