VBAの関数「IsNumeric」と、ワークシート関数「ISNUMBER」の違いを解説します。
同じところ
両方とも数値かどうかを判定します。
- 純粋な数値である「1000」や「0.1」はどちらもTRUE
- 明らかに数値でない「みかん」はどちらもFALSE
を返します。
違うところ
IsNumericの方が条件が緩く、ISNUMBERは厳しいです。
ものすごくざっくり意味合いを表すと、
- IsNumeric:「数値に見ることができる」ならTrue
- ISNUMBER:「完璧に数値」ならTrue
という違いがあります。
この違いが一番分かりやすいのが「"1000"」です。
""でくくると文字列なので、これは数値ではなく数「字」ですが、
?IsNumeric("1000") ' = True ?WorksheetFunction.IsNumber("1000") ' = False
こういう結果になります。
使い分け
ひとまず「数値として扱える=LongやDoubleの変数に格納できる」なので、
変数代入時の「型が一致しません」エラーを回避するためのIF文に使うなら、
IsNumericでOKです。
特に、
- 「文字列」や「String型の変数」が事実上の数字か調べるとき
- 日本語入力の「1」を数値としてみたいとき
はIsNumericを使います。
頻出する例としては、
・IsNumeric(Left(○○,1))で、第1文字が数値か調べたい
⇒Left, Mid, RightなどはStringが返るので、IsNumericじゃないとTRUEにならない
・InputBoxにユーザーが入力したものが数値かどうか調べたい
⇒ユーザーは日本語入力も数値として多用してくる
あたりが該当します。
逆にISNUMBERは、
「IsNumericの緩い条件でTRUEになって困ったときに使う」
と思っておけばよいです。
具体的な場面は、↓を参考にしてください。
判定結果の一覧と細かい注意点
両者とも、注意しなければいけない仕様があります。
まずは判定一覧を眺めてください。注意点は赤くしました。
""や空白セル
ISNUMBERは「FALSE」ですが、IsNumericは「TRUE」が返ります。
数値ではないですが、0として見れますからね。
「空を0」として計算していい場面は多いのでありがたい仕様ですが、
データによっては「空セルを特別に処理」する必要があるので注意です。
代わりにIsNumberを使っても、それはそれで意図がつかみづらいので、
ストレートに「If ○○ = "" Then」で分岐しましょう。
日付・時刻
数値に変換できそうですが、意外にもIsNumericは「FALSE」を返します。
なぜか逆に、ISNUMBERが「TRUE」になります。
困ったことに、「時刻はどっちもTRUE」になります。
さらに困ったことに、↑はDate型(シリアル値)の話であり、
「日付に変換できる文字列」はどちらもFALSEを返します。
こんなの覚えてられませんし、覚えたところで使いどころはないので、
「日付にはIsNumericもISNUMBERも使うな。真っ先にIsDateで除外しろ」
と覚えてください。
IsDate("2020/04/01")はTRUEになってくれますし、
IsDate("")はFALSEになってくれるので、
感覚的にわかりやすく、分岐の使い勝手も優秀です。
真偽値TRUE/FALSE
めったに出会いませんが、こいつも厄介なので注意してください。
数値じゃないので、ISNUMBERは当然FALSEですが、
IsNumeric(True)も、IsNumeric(False)も、どちらも「TRUE」になります。
真偽値に「×1」をしてみて、計算上の扱いを見てみましょう。
?True*1 ' = -1 ?False*1 ' = 0
このように、真偽値は中身は、実は数値です。
なので、IsNumericはTRUEを返します。
しかし、同じようにワークシート上で、セルの関数に「=TRUE*1」と入力すると、
=TRUE*1 ' = 1 =FALSE*1 ' = 0
となり、ExcelとVBAでTRUEの値が違うことが分かります。
なので、VBAで「ワークシート上に入力されたTRUE/FALSE」を判定するときは、
数値として見ない方が良いのですが、
反してIsNumericがTRUEを返してしまうので注意してください。
この場合はどっちの関数で判定するか? ですが、それ以前に
「数値も入るかもしれないし、TRUE/FALSEも入るかもしれない」
ような状況が、そもそもヤバいと思います。
判定せざるを得ない状況自体を何とかする方を考えましょう。
例えば、「送料」列に、「宅配しないならFALSE、するなら金額」みたいにデータが入っているのは、IsNumericとISNUMBERが云々以前に、SUM関数すらまともに動きません。(万が一TRUEが入ると、「1」が足されちゃうから)
「宅配」列にTRUE/FALSE、「送料」列に金額と、列を分けることをまず考えるべきです。
「TRUE/FALSEの中身は数値」は、仕様として覚えておきましょう。
まとめ
長くなってしまったのでものすごくざっくりまとめます。
「IsNumeric」と「ISNUMBER」の違いと使い分けは、
- みかん はどっちもFALSE
- 10 はどっちもTRUE
- "10" はIsNumericだけTRUE
- "" もIsNumericだけTRUE
- 日付はどっちも使うな。先にIsDate使え
- TRUE/FALSEはそもそも判定しようとするな
と覚えておきましょう。