HOME > 即効テクニック > Excel VBA > 関数関連のテクニック > セルが文字列かどうか判定する

即効テクニック

関数関連のテクニック

セルが文字列かどうか判定する

(Excel 97/2000/2002/2003/2007)
セルA1に「100」と入力します。
セルB1には「'100」と入力しました。
セルA1は数値データが入力され、セルB1には文字列形式のデータが入力されています。
この両者を区別するには、どうしたらいいでしょう。

VBAには、データが数値かどうかを判定するIsNumeric関数があります。
それで試してみましょう。

Sub Sample1()
  MsgBox IsNumeric(Range("A1").Value) & vbCrLf & _
      IsNumeric(Range("B1").Value)
End Sub   
結果はどちらもTrueです。 Excelは、たとえ文字列として入力したデータであってもそれが計算可能なデータの場合は、内部で数値に自動変換してくれます。 「'100」もExcelにとっては、計算可能なデータと認識されたのでしょう。 「'100」の先頭には「'」を付けています。 Left関数で左端1文字を調べてはどうでしょう。
Sub Sample2()
  MsgBox Left(Range("A1").Value, 1) & vbCrLf & _
      Left(Range("B1").Value, 1)
End Sub   
結果はどちらも1です。 「'」は、続くデータが文字列であることを表す接頭辞として扱われます。 接頭辞は特別な記号ですから、入力されたデータとは認識されません。 ちなみに、両者の文字数を調べると、どちらも3になります。
Sub Sample3()
  MsgBox Len(Range("A1").Value) & vbCrLf & _
      Len(Range("B1").Value)
End Sub   
うーん、困りました。 数値として入力した「100」は右寄せで表示され、「'100」は文字列ですから左寄せで表示されています。 セル内の横位置を表すHorizontalAlignmentプロパティで調べてみましょう。
Sub Sample4()
  MsgBox Range("A1").HorizontalAlignment & vbCrLf & _
      Range("B1").HorizontalAlignment
End Sub   
結果は、どちらも1です。 これは「標準」を表す定数xlGeneralの値です。 数値が右寄せ、文字列が左寄せで表示されるのは、Excelの標準仕様です。 そろそろ答をお教えしましょう。 こんなときは、TypeName関数を使います。 TypeName関数は、引数に指定したバリアント型変数に、どんな形式の値が格納されているかを調べるときに使う関数です。 次のマクロを実行して、結果をご確認ください。
Sub Sample5()
  Dim buf As Variant
  buf = 100
  MsgBox TypeName(buf)
  buf = "tanaka"
  MsgBox TypeName(buf)
End Sub   
このTypeName関数の引数にセルを指定すると、そのセルに入力されているデータの形式が取得できます。
Sub Sample6()
  MsgBox TypeName(Range("A1").Value) & vbCrLf & _
      TypeName(Range("B1").Value)
End Sub   
「100」は"Double"が返り、「'100」は"String"と判明しました。 TypeName関数の引数では、Valueプロパティを省略してはいけません。 TypeName(Range("A1")) では、Range("A1") というオブジェクトを指定したことになり、Range("A1") のオブジェクト型である"Range"という文字列が返されます。 このTypeName関数による判定は「'2009/8/22」のように、文字列として入力された日付データを区別するときにも役立ちます。 セルA2に「2009/8/22」と入力し、セルB2には「'2009/8/22」と入力してください。 セルA2にはシリアル値が入力され、セルB2には文字列データ入力されているのですがExcelの自動おせっかい…もとい、自動変換によって、どちらも日付と認識されます。 次のマクロは、どちらもTrueを返します。
Sub Sample7()
  MsgBox IsDate(Range("A2").Value) & vbCrLf & _
      IsDate(Range("B2").Value)
End Sub
自動変換が行われるような、関数による操作は問題はありません。 次のマクロは、どちらも8月を表す8が返ります。
Sub Sample8()
  MsgBox Month(Range("A2").Value) & vbCrLf & _
      Month(Range("B2").Value)
End Sub
しかし、次のような単純な計算ではエラーになります。
Sub Sample9()
  MsgBox Range("A2").Value + 1 & vbCrLf & _
      Range("B2").Value + 1
End Sub
シリアル値が入力されている Range("A2").Value + 1 は普通に計算が行われて、翌日である 2009/8/23 が返ります。 しかし、文字列である Range("B2").Value + 1 はエラーです。 文字列は計算できないからです。 文字列で入力された「'2009/8/22」などをシリアル値に変換するにはDateValue関数を使います。
Sub Sample10()
  If IsDate(Range("B2").Value) Then
    If TypeName(Range("B2").Value) = "Date" Then
      ''シリアル値が入力されている
      MsgBox Range("B2").Value + 1
    Else
      ''日付が文字列として入力されている
      MsgBox DateValue(Range("B2").Value) + 1
    End If
  Else
    ''日付ではないデータが入力されている
    MsgBox "日付データではありません"
  End If
End Sub