【VBA】VarTypeで数値・日付・文字列を自動判定するマクロ
セルに入力されたデータが「数値」なのか、「文字列」なのか、「日付」なのか、一目でわからなくて困ったことはありませんか?
日付と数値と文字列が混在している一覧表をそのまま処理しようとすると、意図しないエラーが発生したり、間違ったデータが出力されたりしてしまいます。
私はこれまでに年間50件以上のマクロ開発を受注してきましたが、「データの型が混在していて処理に困っている」というご相談は本当によくあります。
VBAの「VarType関数」を使えば、セルに入力されているデータの種類を自動で判定し、データ型に応じた処理を振り分けることが可能です。
この記事では、VarType関数の基本的な使い方から、実務で使えるサンプルコードまでをわかりやすく解説。
コードをそのままコピペして使える内容にしていますので、VBA初心者の方でも安心して読み進めてください。
手作業による混在データ編集の問題点
日付・数値・文字列が混在している一覧表の編集作業を、手作業でおこなっているとどのような問題が発生するのかを整理しておきましょう。
VBAを導入する前にこの問題をしっかりと理解しておくことで、VarType関数がどれほど強力なツールなのかがよりよくわかります。
問題①:データの種類が判断できずにエラーが発生する
エクセルのセルに見た目では「数値っぽい」データが入っていても、実際には文字列として入力されているケースが多くあります。
たとえば「12345」と入力されていても、セルの書式設定や入力方法によっては文字列として扱われていることがあり、そのまま計算処理に使おうとするとエラーが発生して処理が止まってしまいます。
手作業でデータを確認しながら修正していくのは、件数が増えれば増えるほど時間と手間がかかる一方です。
問題②:日付データが数値として認識されてしまう
エクセルでは、日付は内部的にシリアル値(数値)として管理されています。
「2024/04/01」という日付データも、内部では「45383」のような数値として保持されていて、VBAで単純にセルの値を取得して判定しようとすると、日付なのか数値なのかを正確に区別することができません。
VarType関数を使えば、日付は「vbDate」として判定されるため、数値と日付を正確に分けて処理することが可能です。
問題③:毎回同じ確認作業を繰り返す非効率さ
月次・週次で更新される一覧表の編集作業を、毎回手作業でおこなっている方は非常に多くいます。
データの種類を目視で確認して、種類ごとに別々の処理をして、またチェックして…という繰り返しは、作業者にとって大きな負担です。
しかも、人の目で確認する以上は見落としやミスがどうしても発生してしまいます。
VarType関数を使ったVBAを導入することで、この確認作業を完全に自動化することが可能です。
VBA VarType関数とは?数値判定の基本を理解する
VarType関数はVBAに標準搭載されている関数で、変数やセルの値のデータ型を整数値で返します。
戻り値の整数とデータ型の対応関係を把握しておくだけで、セルの値を正確に判定できるようになります。
まずは基本的な戻り値の一覧を理解しておきましょう。
VarTypeの戻り値と対応するデータ型の一覧
VarType関数が返す主な戻り値は以下のとおりです。
0(vbEmpty)は空白・未入力
2(vbInteger)・3(vbLong)・4(vbSingle)・5(vbDouble)・14(vbDecimal)はいずれも数値系
7(vbDate)は日付型のデータ
8(vbString)は文字列
11(vbBoolean)はTrue/Falseの論理値
VBAには各戻り値に対応する定数(vbDate、vbString など)が用意されているため、数値を直接コードに書く必要はありません。
定数を使うことで、コードの意味が一目でわかりやすくなります。
以下のサンプルコードは、主な戻り値とその意味をまとめたものです。
Sub VarType戻り値例()
' VarTypeの戻り値を定数名で確認
Debug.Print "vbEmpty: " & vbEmpty ' → 0(未初期化)
Debug.Print "vbNull: " & vbNull ' → 1(Null値)
Debug.Print "vbInteger: " & vbInteger ' → 2(整数型)
Debug.Print "vbLong: " & vbLong ' → 3(長整数型)
Debug.Print "vbSingle: " & vbSingle ' → 4(単精度浮動小数点型)
Debug.Print "vbDouble: " & vbDouble ' → 5(倍精度浮動小数点型)
Debug.Print "vbCurrency: " & vbCurrency ' → 6(通貨型)
Debug.Print "vbDate: " & vbDate ' → 7(日付型)
Debug.Print "vbString: " & vbString ' → 8(文字列型)
Debug.Print "vbObject: " & vbObject ' → 9(オブジェクト型)
Debug.Print "vbBoolean: " & vbBoolean ' → 11(論理型)
Debug.Print "vbVariant: " & vbVariant ' → 12(バリアント型)
Debug.Print "vbArray: " & vbArray ' → 8192(配列)
End Sub
このサンプルコードの実行結果がこちら
VBAには上記の定数が用意されており、数値と定数名を対応させて使うことができます。
例えば、変数が整数型かどうかを確認したい場合は「VarType(変数名) = vbInteger」というように記述しましょう。
数値と日付を正確に区別できる理由
先ほど述べたとおり、エクセルでは日付は内部的に数値として管理されています。
しかし、VarType関数を使うと日付データは「vbDate(7)」として返ってくるため、数値(vbDouble など)と区別することが可能です。
IsNumeric関数では日付を数値と区別できないケースがあるため、日付・数値・文字列が混在するデータを扱う際はVarType関数を使うのがベスト。
これがVarType関数の最大のメリットです。
関連記事「日付データをCSV出力するマクロ」では、CSV出力マクロをダウンロードすることができます。
日付データの処理に手こずっている。。。という方は是非参考にしてみてください。
VBA VarTypeで数値を判定するサンプルコード①|基本編
まずは基本となるVarType判定のサンプルコードをご紹介します。
A列に「日付・数値・文字列」が混在して入力されている一覧表を想定し、各セルのデータ型を判定してB列に判定結果を出力するコードです。
実際に使用する際は、シート名・列番号をご自身の環境に合わせて変更してください。
セルのデータ型をB列に出力するVBAコード
Sub VarType判定サンプル()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("一覧")
Dim i As Long
Dim lastRow As Long
Dim cellValue As Variant
Dim dataType As Integer
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
cellValue = ws.Cells(i, 1).Value
dataType = VarType(cellValue)
Select Case dataType
Case vbEmpty '0:空白
ws.Cells(i, 2).Value = "空白"
Case vbDate '7:日付
ws.Cells(i, 2).Value = "日付"
Case vbDouble, vbInteger, vbLong, vbSingle, vbDecimal '数値系
ws.Cells(i, 2).Value = "数値"
Case vbString '8:文字列
ws.Cells(i, 2).Value = "文字列"
Case Else
ws.Cells(i, 2).Value = "その他(" & dataType & ")"
End Select Next i
MsgBox "データ型の判定が完了しました。", vbInformation
End Sub
コードの流れを解説します。
最初の「Set ws = ThisWorkbook.Worksheets(“一覧")」で、処理対象のシートを「一覧」シートに指定しています。
「lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row」は、A列の最終行を自動取得する命令です。
データが増減しても範囲指定を変更する必要がない、とても便利な書き方なのでぜひ覚えておきましょう。
Forループで2行目から最終行まで1行ずつ処理し、各セルの値をcellValueに代入します。
そして「dataType = VarType(cellValue)」でデータ型を取得します。
Select Case文でdataTypeの値に応じて処理を振り分けています。
vbDateなら「日付」、数値系定数なら「数値」、vbStringなら「文字列」をB列に出力するという仕組みです。
シンプルな構造ですが、これだけで日付・数値・文字列の3種類を正確に判定できます。
VBA VarTypeで数値を判定するサンプルコード②|数値のみ集計
次に、実務でよく使われる「数値のみを合計する」処理のサンプルコードを紹介します。
数値と文字列が混在した列に対してSUM関数を使うと正しい結果が得られないことがありますが、VarType関数で数値のみを選別して合計することで、正確な集計が可能です。
数値のみを選別して合計するVBAコード
Sub 数値のみ合計を計算()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("一覧")
Dim i As Long
Dim lastRow As Long
Dim cellValue As Variant
Dim totalAmount As Double
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
totalAmount = 0
For i = 2 To lastRow
cellValue = ws.Cells(i, 3).Value '3列目(金額列)を対象に '数値型の場合のみ合計に加算
If VarType(cellValue) = vbDouble Or _
VarType(cellValue) = vbInteger Or _
VarType(cellValue) = vbLong Then
totalAmount = totalAmount + cellValue
End If
Next i
MsgBox "数値の合計金額:" & Format(totalAmount, "#,##0") & "円", vbInformation
End Sub
コードの流れを解説します。
変数「totalAmount」をDouble型で宣言しておき、数値と判定されたセルの値だけを加算していきます。
If文の中でVarType関数を使い、vbDouble・vbInteger・vbLongのいずれかに該当するセルだけを合計対象としています。
日付や文字列が入っているセルはスキップされるため、エラーを心配することなく処理が完了します。
Format関数で「#,##0」と指定することで、合計金額を3桁区切りで見やすく表示しています。
一覧表の金額列に「-(ハイフン)」や「未確定」などの文字列が混在していても、この処理なら正確な数値のみを集計することができます。
VBA VarTypeで数値を判定するサンプルコード③|混在データ編集応用編
最後に、日付・数値・文字列それぞれに対して異なる編集処理を自動でおこなう、実務レベルの応用サンプルコードをご紹介します。
私が実際に受注した案件でも、「日付・数値・文字列が混在する一覧表の編集処理を自動化したい」というご相談をいただきました。
そのときに活用したVarType関数の実装パターンをベースにしたコードです。
データ型ごとに異なる編集処理を自動でおこなうVBAコード
Sub 混在データの編集処理()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("一覧")
Dim i As Long
Dim lastRow As Long
Dim cellValue As Variant
Dim dataType As Integer
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
cellValue = ws.Cells(i, 2).Value 'B列のデータを対象に
dataType = VarType(cellValue)
Select Case dataType
Case vbDate '日付の場合:yyyy年mm月dd日形式にフォーマット
ws.Cells(i, 3).Value = Format(cellValue, "yyyy年mm月dd日")
Case vbDouble, vbInteger, vbLong, vbSingle '数値の場合:3桁区切りのカンマ付きで表示
ws.Cells(i, 3).Value = Format(cellValue, "#,##0")
Case vbString '文字列の場合:前後のスペースを除去してセットし直す
ws.Cells(i, 3).Value = Trim(cellValue)
Case vbEmpty '空白の場合:C列に「未入力」と表示
ws.Cells(i, 3).Value = "未入力"
Case Else
ws.Cells(i, 3).Value = "要確認"
End Select Next i
MsgBox "データの編集処理が完了しました。", vbInformation
End Sub
コードの流れを解説します。
B列のデータを1行ずつ取得し、VarType関数でデータ型を判定します。
vbDateと判定された場合は、Format関数を使って「2024年04月01日」のような日本語表記にフォーマットしてC列に出力、
数値系(vbDouble・vbInteger・vbLong・vbSingle)と判定された場合は、3桁区切りのカンマ付きの数値形式にフォーマットしてC列に出力、
vbStringと判定された場合は、前後に余分なスペースが含まれていることが多いため、Trim関数でスペースを除去してからC列に出力します。
vbEmptyと判定された場合は、空白セルには「未入力」とC列に出力します。
空白かどうかの判定もVarType関数で確認できるのでとても便利です。
Select Case文で型ごとに処理を分岐させるこの構造は、どんな混在データに対しても応用可能です。
処理内容をカスタマイズするだけで、様々な業務に対応できる汎用性の高いコードです。
VarType関数を使う際の注意点3つ
VarType関数はとても便利な関数ですが、実装する際にいくつか注意しておきたいポイントがあります。
これから紹介する注意点を把握しておけば、「VarTypeで判定したはずなのに思ったとおりに動かない」というトラブルを防ぐことができるでしょう。
注意点①:セルの書式設定と入力値のデータ型は別物
エクセルのセルには「書式設定」があり、見た目を日付形式にしていても実際には文字列として入力されているケースがあります。
たとえば、A列に日付書式を設定していても、そのセルに「2024/04/01」を文字列として手入力した場合、VarType関数はvbStringを返してしまう。
VarType関数が判定するのは「セルに実際に格納されているデータ型」であり、セルの書式設定ではありません。
この違いを理解しておくことが、VarType関数を正しく使うための第一歩です。
注意点②:数値系は複数の定数があるため漏れなく指定する
数値型に対応するVarTypeの定数はvbInteger・vbLong・vbSingle・vbDouble・vbDecimalと複数存在します。
「vbDoubleだけ指定しておけばOK」と思って実装すると、vbIntegerやvbLongとして格納された数値が数値と判定されないという問題が起きます。
数値全般を処理したい場合は、複数の数値系定数をOrでつなぐか、IsNumeric関数と組み合わせて使うと安全です。
上のサンプルコードでは複数定数をOrでつなぐ方法を採用しています。
注意点③:空白セルの扱いを事前に設計しておく
VarType関数は空白セルに対してvbEmpty(0)を返します。
空白セルをSelect Case文のCase Elseに入れて処理させると、「データなし」と「その他の型」が同じ扱いになってしまう。
空白セルを想定した処理が必要な場合は、Case vbEmptyを独立したケースとして記述しておくことをおすすめします。
処理の仕様をあらかじめ明確にしておくと、後から見直す際にも理解しやすいコードになります。
まとめ ~ VarType関数で混在データ編集を完全自動化しよう ~
VarType関数を使えば、セルに入力されているデータが数値なのか、日付なのか、文字列なのかを正確に判定することが可能です。
混在データが多い一覧表の編集作業を手作業でおこなっていた方は、今回紹介したサンプルコードをそのまま使うだけで大幅な時短が実現できます。
実務での使いどころをまとめると以下のようになります。
- 日付・数値・文字列の3種類が混在するデータを型ごとに判定して別処理したい場合
- 数値のみを選別して集計したい場合
- 空白セルを含む一覧表を一括処理したい場合
このような作業が多い場合、VarType関数は非常に効果的です。
今回紹介したコードをベースに、自分の業務に合わせてカスタマイズしてみてください。
VarType関数の活用次第で、これまで毎回30分以上かかっていた編集作業が、ボタン1クリックで完了するようになります。
もし「自分の業務に合わせた複雑なチェック処理を実装したい」「既存のマクロを改良したい」といったご要望がありましたら、マメBlogのエクセルマクロ開発依頼にご相談ください。
業務内容に合わせたオーダーメイドマクロを設定させていただきます。
最後まで読んでいただきありがとうございました。エクセルVBAを使って面倒なルーティーン作業を自動化しちゃいましょう。