【Excel VBA】IsDate関数に気を付けて!

IsDate関数のMicrosoftの説明を見ると下記のように書かれています。

式が日付であるか、有効な日付または時刻として認識可能な場合には True を返し、それ以外の場合には False を返します。


IsDate(expression)
必須の式引数は、日付または時刻として認識できる日付式または文字列式を含む Variant です。

日付の判定

今回この記事を書こうと思ったのは、仕事で文字列として西暦なしの日付のみ(例:4/6, 12/31)が羅列している中から一番早い日付を取ってほしい!と依頼されたことになります。

西暦が入っている場合は、WorksheetFunction.Min関数を使用すれば簡単に取れます。
が、しかし、今回は西暦がありません。ほとんどが直近の日付のため、恐らく今年なのですが、依頼主の方にお伺いすると、今後継続して利用すると12月と1月が混在することがあるとのこと。
そうなると1月と12月が混じったデータの場合、誤った結果になってしまいます。

そこでIsDate関数を使用して、西暦がないものは日付型でないと判定して、その場合は別の方法を取ろうと考えました。

しかし、IsDate関数を使用してみると西暦のない日付を判定するとTrueと返ってきます。
よくよく調べるとCDate関数として変換できるものはすべてTrueになるとのこと。

下記のコードでいろいろな値を試してみます。

Excel VBA
Sub test()
Application.ScreenUpdating = False
   
   Dim i As Long
   
   With Sheet1
   
   On Error Resume Next
      
      For i = 2 To 15
         
         .Cells(i, 2) = IsDate(.Cells(i, 1))
         .Cells(i, 3) = CDate(.Cells(i, 1))
      
      Next i
      
   On Error GoTo 0
   
   End With
   
Application.ScreenUpdating = True
End Sub

いろいろ試してみると下記のような判定になりました。

上3つはよく見る日程の表記です。もちろんどちらも日付として認識してくれます。

2025_7_26、2025/7/26はやはり左側によって文字列として認識されていることから、どちらの関数も日付として認識はしてもらえませんでした。
20250726も同様に日付として認識はされませんでした。


8行目の7/26ですが、表記は7/26ですが、入力時「’7/26」と頭にアポストロフィを付けて入力しました。やはり西暦がない文字列の”7/26″でも日付として認識されてしまいます…

「13/32/2025」は12か月しかない月を13月に、日付を32日にしてみたらどちらも日付認識はされませんでした。

予想外だったのは赤枠で囲った部分になります。

12行目は2025/7/26をシリアル値にしたものです。IsDate関数はこのシリアル値をFalseと判定してしまいます。
CDate関数は問題なく日付判定してくれます。
CDateとIsDateで結果が別れました。

13行目は「00002025/0007/0026」としてありえない桁数で入力しましたが、IsDate関数もCDate関数も日付として認識されます。

14行目は「7:26」と入力しましたが、IsDate関数はFalse、CDate関数はTrueになり別れました。

15行目は「’25/7/26」と入力しました。文字列として認識されているため、左側によっています。
それでもIsDate関数、CDate関数ともTrue判定です。

こんなに緩いと西暦のある日付かそうでないかの判定は難しいため、別の方法で考えることにしました。

西暦のあるDate型の場合、必ずデータにはスラッシュ(/)が入っているはずです。
今回はスラッシュの数を判定して、日付の判定を行いたいと思いました。

Excel VBA
Dim cnt as long, i as long

With sheet1

   For i = 2 To 11
            
      cnt = Len(.Cells(i, 1)) - Len(Replace(.Cells(i, 1), "/", ""))
            
      If cnt = 2 Then
         '西暦ありの日付
      Else
         '西暦なしの日付
      End If
   Next i

End with

今回の場合は、スラッシュで判定しましたが、入力されている値により日付の判定は考えなければならないと思いました。

日付を入力していても表記がシリアル値の場合は日付認定されないので、入力値がよくても表記を日付型に変えないとIsDate関数は使えないので、難しいですね…

コメントを残す

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

CAPTCHA