🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA の IsNumeric — 数値でないものにまで True と答える理由

|

Excel VBA の IsNumeric — 数値でないものにまで True と答える理由

TL;DRIsNumeric(value) は、VBA が値を数値に変換できそうだと判断したとき True を 返します — その網は、あなたが思い描いているきれいな整数よりもずっと広く張られています。"1E5" (科学表記)、"&HFF"(16 進リテラル)、"1,000"(桁区切り)、" 42 "(空白で囲まれた文字列)、 さらには "12-"(末尾の符号)にまで True と答えます。しかも 地域設定に依存する ので、"1,5" はドイツのマシンでは数値、アメリカのマシンでは数値ではありません。安上がりな第一の関門としては 使えますが、きっちり きれいな整数や数字だけのコードが必要になった瞬間、代わりに Like 演算子 で形そのものを固定しましょう。

Sub IsNumericSurprises()
    Debug.Print IsNumeric("123")      ' True  - 予想どおり
    Debug.Print IsNumeric("1E5")      ' True  - 100000 と読む(科学表記)
    Debug.Print IsNumeric("&HFF")     ' True  - 255 と読む(16 進リテラル)
    Debug.Print IsNumeric("1,000")    ' True  - 桁区切り
    Debug.Print IsNumeric("  42  ")   ' True  - 前後の空白は無視される
    Debug.Print IsNumeric("12-")      ' True  - 末尾の符号が許される

    Debug.Print IsNumeric("12.3.4")   ' False - 小数点が 2 つ
    Debug.Print IsNumeric("")         ' False - 空文字列
    Debug.Print IsNumeric("2026-01-01") ' False - これは日付、IsDate を使う
End Sub

この記事で学べること

  • 考え方の軸 — IsNumeric が試すのは「VBA が解析できるか」であって、あなたの意図ではない
  • 力の順に並んだ 3 つのテキストテスターと、それぞれが答える問い
  • 科学表記と 16 進リテラルがなぜそのまま通り抜けるのか
  • 空白・符号・桁区切りがなぜすべて通ってしまうのか
  • IsNumeric が地域設定に依存し、それがマシンをまたいでデータを壊す理由
  • IsNumeric・IsNumberIsDate の違いと、代わりに使うべき厳格なチェック

考え方の軸:IsNumeric は「VBA が解析できるか」を測る、あなたの意図ではない

IsNumeric は検証関数ではありません。これは VBA 自身の型強制のプレビューです。CDbl(あるいは Val 系の解析の裏で働く暗黙の変換)がエラーを出さずに飲み込んでしまう文字列すべてに対して True を 返します。これは意図的に寛大なルールです。VBA の数値パーサーは、科学表記、16 進数・8 進数のリテラル、 通貨記号や桁区切り記号、そして前後の空白まで理解するからです。

だから、頭の中で立てるべき正しい問いは「これは数値か?」では決してありません。「頼んだら VBA は これを数値に変換するか?」です — そして、その答えが Yes になるのは、あなたが望むよりもはるかに 多くの場面です。以下の驚きはすべて、この一つの捉え方からまっすぐに導かれます。

力の順に並んだ 3 つのテスター

IsNumeric は、はしごの最初の段です。どんな文字列も信じる前に、まず試す — そして VBA は 3 つの テスターを手渡してきます。それぞれが 別々の 問いに答え、それぞれが独自のやり方であなたに嘘をつきます。

テスター 答える問い 決まってつく嘘
IsNumeric VBA はこれを数値として解析できるか? "1E5""&HFF""12-" に Yes と言う
Like 文字列全体 がこの形に収まるか? 大文字小文字はモジュール全体のスイッチ次第
RegExp 本物のパターンに一致するか、そして中身は何か? Global を設定して SubMatches に届くまで何も返さない

弱いものに手を伸ばせば不正なデータがすり抜け、重いものに手を伸ばせば準備の海で溺れます。腕の見せどころは、 自分が本当はどの問いを尋ねているのかを見抜くことです。IsNumeric はいちばん緩い問いに答えるので、 最も手軽に手が伸び、最も間違えやすいのです。「数値かもしれない」では締まりが足りないとき — きっちり 3 桁、あるいは正の数、あるいは英字を含まないコードが必要なとき — あなたはもう最下段を離れていて、 Like か本物のパターンが欲しくなっています。

罠 1:科学表記と 16 進リテラルはそのまま通り抜ける

誰もが引っかかる 2 つ、"1E5""&HFF"

Debug.Print IsNumeric("1E5")    ' True
Debug.Print CDbl("1E5")         ' 100000     <- E は指数
Debug.Print IsNumeric("&HFF")   ' True
Debug.Print CLng("&HFF")        ' 255        <- &H は 16 進リテラル

これはバグではありません — VBA が一貫しているだけです。しかし、そのフィールドが 数量 ではなく コード であるときには、これはデータの惨事になります。1E5 のような製品 ID、12E3 のような口座の枝番、たまたま &H で始まる部品番号 — どれも検証を通り抜け、変換した瞬間に黙って巨大な整数に化けます。ユーザーは ラベルを入力したのに、あなたのマクロは数百万の数値を格納し、何も言わずに次へ進んでいました。

列が識別子を保持するためのものなら、IsNumeric は門として完全に見当ちがいです — 欲しいのは 「数値として解析できる」ではなく「まさにこの文字の並び」です。それは Like 演算子 かまっすぐな文字列比較の仕事であって、IsNumeric の仕事ではありません。

罠 2:空白・符号・桁区切りはすべて通る

VBA のパーサーは数値まわりの化粧に寛容なので、以下はすべて True を返します。

Debug.Print IsNumeric("  42  ")  ' True - 前後の空白は取り除かれる
Debug.Print IsNumeric("+5")      ' True - 先頭の符号
Debug.Print IsNumeric("12-")     ' True - 末尾の符号(あの有名なやつ)
Debug.Print IsNumeric("1,000")   ' True - 桁区切り
Debug.Print IsNumeric("(5)")     ' True - 会計スタイルの負数

末尾に符号が付くケース("12-")はほとんど全員の意表を突きますし、会計の丸かっこ("(5)")は、 財務のエクスポートを取り込んだら負数の半分がかっこでくるまれて届いた、というときの正真正銘の落とし穴です。 一方で、通り そう に見えるものは通りません。内側の空白("1 2")、分数("1/2")、そして空文字列は すべて False を返します。ルールは「数字に見える」ではなく「VBA が受け入れる数値の形のどれかに一致する」 であり、その集合は直感よりも広く、そして奇妙です。

罠 3:地域設定に依存し、マシンをまたぐとデータを壊す

これはテストを生き延び、本番で牙をむく、あの静かな罠です。IsNumeric は、小数点と桁区切りについて マシンの地域設定を尊重します。

' 米国のマシン(小数点 = ".")
Debug.Print IsNumeric("1,5")   ' False - ここではコンマは小数点ではない
Debug.Print IsNumeric("1.5")   ' True

' ドイツのマシン(小数点 = ",")
Debug.Print IsNumeric("1,5")   ' True  - コンマこそが小数点
Debug.Print IsNumeric("1.5")   ' True  - ドットは桁区切りとして読まれる

同じブック、同じマクロが、誰が開くかによって 2 つの異なる答えを出します。あなたの席で通る検証が、 同僚の "1,5"1.5 として通してしまう — あるいは頭から拒否する — のに、あなたはそれをテストでは 決して目にしません。値がファイルや Web ページ、別の地域から来るときは、IsNumeric がどこでも同じ意味を 持つと信じるのではなく、明示的な前提を置いて自分で解析しましょう(CDbl は地域設定を 尊重し、Val は常に . を小数点として扱います)。

IsNumeric・IsNumber・IsDate の違い

人が取り替えのきくものとして手を伸ばす 3 つの関数、しかし仕事は 3 つとも別物です。

  • IsNumeric(x)文字列 が数値として解析できるかを問う VBA 関数。本記事が扱うのはこれです。
  • Application.WorksheetFunction.IsNumber(cell) — ワークシートの ISNUMBER。セルに格納された値が すでに 数値型かを問います。テキストは解析しません。テキスト書式のセルに入った 123 に対しては IsNumeric("123")True でも IsNumberFalse です。
  • IsDate(x) — 日付のための兄弟の門。IsNumeric("2026-01-01")False なので、日付であるべきものには IsDate を使います。そして IsDateIsNumeric に負けず劣らず地域設定に依存する点に注意してください。

すでにセルにある値について尋ねているなら IsNumber を、変換する前にテキストを洗っているなら IsNumeric を使いましょう。

意見:IsNumeric は安上がりな門であって、検証ではない

IsNumeric は、明らかなゴミ — 空セル、名前、はぐれた記号 — を素早く弾く関門としては、その居場所を 稼いでいます。それらは安く投げ捨てさせましょう。しかし、あなたのルールが「数値かもしれない」より 厳しくなった日 — 5 桁の郵便番号、正の数量、英字を含まない注文コード — には、IsNumeric は資産で あることをやめ、誤った安心感に変わります。あなたが受け入れるつもりのなかった科学表記、16 進数、 空白で埋めた文字列、地域固有の区切り記号に、青信号を出してしまうからです。

直し方は、形を声に出して言うことです。「きっちり 3 桁」なら s Like "###"。「数字だけ、長さは任意」なら Len(s) > 0 And Not (s Like "*[!0-9]*")。構造のあるもの — 取り出すべきグループ、繰り返すパターン — なら、 あなたははしごのてっぺんまで登っていて、本物のパターン が欲しくなっています。そして、 何を通すと決めたにせよ、テストしたのと同じ地域設定の前提のもとで直ちに変換しましょう。そうすれば 「有効」と「変換済み」が食い違うことは決してありません。

検証そのものが仕事のとき — それを説明する

本当の仕事の半分は「これは数値か」ではなく「この列を掃除して — 数値に見えるコードを剥がし、桁数の 違うものに印を付け、残りを変換し、どの行に触れたか教えて」です。IsNumericLike の形チェック、 地域を意識した変換、例外のログをつなぎ合わせる頃には、配管が答えを覆い隠してしまいます。 ExcelMaster なら、その目的を 普通の言葉で — 「C 列を正の整数の数量として検証して、失敗した行をすべて理由付きで一覧にして」 — と 言うだけです。そして、データを読み、本物のルールを適用し、まずファイルをバックアップし、例外を返す Python を生成します。あなたはチェックを説明するだけ。科学表記も、空白の詰め物も、地域設定も、それが 処理します。

よくある質問

VBA の IsNumeric は何をしますか?

IsNumeric(expression) は Boolean を返します。VBA が式を数値に変換できるなら True、できないなら False です。寛大な関数で — 科学表記、16 進数(&H)・8 進数(&O)のリテラル、桁区切り、前後の 空白、先頭や末尾の符号まで受け入れます — つまり「きれいな整数」ではなく「数値として解析できる」を 意味します。

数値でない値に IsNumeric が True を返すのはなぜですか?

その値が VBA のパーサーの認識する形だからです。"1E5" は科学表記、"&HFF" は 16 進リテラル、"1,000" は桁区切り、"12-" は末尾の符号 — VBA にとってはどれも有効な数値の形です。もっと厳格な定義が必要なら、 IsNumeric ではなく Like で形を検査しましょう(たとえば、きっちり 3 桁なら s Like "###")。

VBA で文字列が数字だけかを確認するには?

IsNumeric ではなく Like パターンを使います。Len(s) > 0 And Not (s Like "*[!0-9]*") は、s が空でなく、 数字でない文字を 1 つも含まないときにだけ True になります — IsNumeric とは違い "1E5""1,000""12-" を拒否する、正真正銘の「数字だけ」チェックです。

VBA の IsNumeric と IsNumber の違いは?

IsNumeric は、文字列が数値として 解析できるか を試す VBA 関数です。WorksheetFunction.IsNumber (ワークシートの ISNUMBER)は、セルの値が すでに 数値型として格納されているかを試します。123 が 入ったテキストセルは IsNumeric = True でも IsNumber = False です。

IsNumeric は地域設定の影響を受けますか?

はい。IsNumeric はマシンの小数点と桁区切りを使うので、コンマが小数点のマシンでは "1,5" は数値、 ドットが小数点のマシンでは数値ではありません。移植性のある結果が欲しいなら、IsNumeric がどこでも 同じ挙動をすると当てにするのではなく、明示的なルールで変換しましょう(Val は常に . を小数点に使い、 CDbl は現在の地域設定を尊重します)。

検証環境

検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-04.

関連ガイド: VBA Like · VBA Regex · VBA CStr · VBA InStr · VBA Split