wanna.jp VBAリファレンス
Top > VBA関数リファレンス > VBA IsDate 日付妥当性チェック完全ガイド!データベース登録前の落とし穴と回避策

VBA IsDate 日付妥当性チェック完全ガイド!データベース登録前の落とし穴と回避策

日々のスケジュール管理やデータ入力において、「日付」は非常に重要な情報です。しかし、ユーザーからの入力や外部データには、時に「無効な日付」や「意図しない形式の文字列」が混じり込みます。特に、VBAでシステム開発やバッチ処理を組んでいる方なら、「データベースに無効な日付が登録されてバッチ処理がエラーで停止した…」といった苦い経験があるかもしれませんね。今回は、VBAの標準関数 IsDate を使った日付の妥当性チェックに焦点を当て、その基本的な使い方から、実務で遭遇しがちな「落とし穴」とその賢い回避策までを徹底解説します。あなたのVBAコードをより堅牢にし、システムトラブルを未然に防ぎましょう!

コピペで即実践!IsDate関数の基本コード

まずは、IsDate 関数の基本的な使い方を見ていきましょう。指定した文字列が日付として解釈可能であれば True を、そうでなければ False を返します。


Sub CheckDateValidityBasic()
    Dim strDateInput As String
    Dim result As Boolean

    ' --- テストケース1: 有効な日付(うるう年対応) ---
    strDateInput = "2026/2/29" ' 2026年はうるう年ではないため、本来は無効
    result = IsDate(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsDate結果: " & result & " (IsDateはうるう年を考慮しません。2026/2/29はTrueと判定されます)"

    strDateInput = "2024/2/29" ' 2024年はうるう年のため有効
    result = IsDate(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsDate結果: " & result & " (2024/2/29はTrueと判定されます)"
    
    ' --- テストケース2: 無効な日付 ---
    strDateInput = "2023/2/30"
    result = IsDate(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsDate結果: " & result & " (無効な日付のためFalse)"

    ' --- テストケース3: 無関係な文字列 ---
    strDateInput = "こんにちは"
    result = IsDate(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsDate結果: " & result & " (日付ではないためFalse)"
End Sub
    

補足: IsDate 関数は、内部的にVBAのCDate関数がエラーを発生させるかどうかで判断します。上記の例で "2026/2/29"True となるのは、VBAがこの日付を「翌月(2026/3/1)」として内部的に処理できるためです。厳密な日付妥当性(例: うるう年の判定など)が必要な場合は、追加のロジックが必要になります。しかし、ここで問題視するのは別の「落とし穴」です。

知っておくべき「落とし穴」と、実務で使える回避策!

IsDate 関数は便利ですが、実務では思わぬ挙動に遭遇することがあります。それが、「"13:00" のような時刻のみの文字列も True と判定される」という仕様です。これは、VBAの日付型が内部的に日付と時刻の両方を保持しており、時刻のみの文字列も「今日の日付 + 指定された時刻」として有効な日付型と見なされるためです。

この問題を回避し、「時刻情報を含まない日付のみの文字列」かを厳密にチェックするための実用的なコードをご紹介します。IsDateTrue を返した上で、さらに CDate で変換した結果の時刻部分が「00:00:00」であるかを検証します。


Function IsValidDateOnly(ByVal strInput As String) As Boolean
    ' IsDate関数で基本的な日付妥当性をチェック
    If Not IsDate(strInput) Then
        IsValidDateOnly = False
        Exit Function
    End If

    ' CDateで日付型に変換後、TimeValueで時刻部分を抽出
    ' 時刻部分が「00:00:00」であれば、日付のみの文字列と判断
    If TimeValue(CDate(strInput)) = TimeValue("00:00:00") Then
        IsValidDateOnly = True
    Else
        IsValidDateOnly = False
    End If
End Function

Sub CheckDateValidityWithPitfallAvoidance()
    Dim strDateInput As String
    Dim result As Boolean

    Debug.Print "--- IsValidDateOnly 関数によるチェック ---"

    ' --- テストケース1: 有効な日付(時刻なし) ---
    strDateInput = "2026/2/29" ' 2026年はうるう年ではないが、IsDateはTrue。時刻部分は00:00:00なのでIsValidDateOnlyはTrue。
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (IsDateはTrue、時刻なしと判断)"

    strDateInput = "2023-01-15"
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (時刻なしと判断)"

    ' --- テストケース2: 時刻のみの文字列 (落とし穴) ---
    strDateInput = "13:00"
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (IsDateはTrueだが、時刻情報を含むためFalse)"

    ' --- テストケース3: 日付と時刻が混在する文字列 ---
    strDateInput = "2023/1/1 10:30"
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (IsDateはTrueだが、時刻情報を含むためFalse)"
    
    ' --- テストケース4: 無効な日付 ---
    strDateInput = "2023/2/30"
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (IsDateがFalseのためFalse)"

    ' --- テストケース5: 無関係な文字列 ---
    strDateInput = "データ"
    result = IsValidDateOnly(strDateInput)
    Debug.Print "入力: """ & strDateInput & """, IsValidDateOnly結果: " & result & " (IsDateがFalseのためFalse)"
End Sub
    

この IsValidDateOnly 関数を使うことで、「"13:00"」のような時刻のみの文字列や、「"2023/1/1 10:30"」のような日付と時刻が混在する文字列を False と判定し、本当に日付のみの入力だけを True とすることができます。

まとめ:堅牢なスケジュール管理のために

VBAの IsDate 関数は、日付妥当性チェックの第一歩として非常に有効ですが、その特性を深く理解しておくことが重要です。特に、時刻のみの文字列を True と判定してしまう「落とし穴」は、データベースへの無効なデータ登録や後続のバッチ処理の停止といった深刻な問題を引き起こしかねません。

今回ご紹介した IsValidDateOnly 関数のように、IsDate の結果に加え、TimeValue(CDate(strInput)) = TimeValue("00:00:00") といった追加の検証を行うことで、より堅牢で信頼性の高いVBAコードを構築できます。入力データの種類やデータベースの要件に合わせて、適切な日付チェックロジックを実装し、安定したスケジュール管理システムを運用しましょう。

VBAでの業務効率化、悩み解決します

「このマクロ、もっと速くならないかな?」「エラーが消えない…」
Access/VBA専門のwanna.jpにご相談ください。

無料相談はこちら