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

IsDate関数は日付かどうか判定するための関数です。
仕事で文字列として西暦なしの日付のみ(例:4/6, 12/31)が羅列している中から一番早い日付を取ってほしい!と依頼されました。

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

そこでIsDate関数を使用して、西暦がないものは日付型でないと判定して、その場合は別の方法を取ろうと考えました。しかし、IsDate関数を使用してみると西暦のない日付を判定するとTrueと返ってきます。
よくよく調べるとCDate関数として変換できるものはすべてTrueになるとのこと。

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

B列はIsDate関数で判定した結果、C列はCdate関数の結果になります。
6,7行目は「型が違います」とエラーが出たため、エラーと表記いたしました。

6.7行目、文書でよく目にすることもあるかと思いますが、どちらの関数とも日付とは認識されません。
8行目、西暦がない文字列の”4/12″が日付と認識されてしまう。
9行目はありえない桁数にしましたが、これもTrueになる。
10行目のコロン(:)を使用した場合、IsDate関数Falseになりますが、Cdate関数は時間として変換可能なようです。ここはCdate関数で変換できるものはIsDate関数Trueになるという法則と違うようです。
11行目の西暦の頭2桁を省略した形、”22/4/12”と書いてもきちんと日付として認識されるようです。

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

西暦のある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

コメントを残す

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

CAPTCHA