Vbaの数値文字列変換で空白が入る真相とCstr・Strの決定的な違い
エンジニアコミュニティや現場のコードレビューで、最も多くの議論を巻き起こすのが「文字列から数値への逆変換」および「事前の数値チェック」の安全性です。
Val関数のトリッキーな読み取り仕様
文字列から数値を取り出すVal関数は便利ですが、厳格なデータ処理では致命傷になりかねない仕様を抱えています。Val関数は「カンマ(,)に遭遇した時点で処理を中断する」という特性を持っています。
Debug.Print Val("1,000") ' 出力: 1 (1000ではなく1と判定される!) Debug.Print Val("100kg") ' 出力: 100 (単位を無視して数値だけ抽出可能) Debug.Print Val("123") ' 出力: 0 (全角数字は一切認識しない)
カンマ区切りの金額文字列をVal関数で数値化しようとすると、千の位より上が切り捨てられる惨事につながります。カンマを含む数値を処理する際は、あらかじめReplace(str, ",", "")で除去するか、CDblやCLng関数を用いる必要があります。
IsNumeric関数が抱える「緩すぎる判定」の罠
数値判定の定番として知られるIsNumeric関数ですが、現場のプログラマーの間では「判定基準が緩すぎる」として警戒されています。IsNumericは、一般的な半角アラビア数字だけでなく、以下のようなデータに対してもTrueを返します。
- "12e3"(指数表記として解釈されTrue)
- "&HFF"(16進数表記として解釈されTrue)
- "1,234"(カンマ付き数値としてTrue)
- " 123 "(前後に空白があってもTrue)
- "1/2"(一部ロケールにおいて日付や分数として解釈されTrue判定されるリスク)
完全な整数のみを受け入れたい場合は、IsNumeric単体での判定に頼るのではなく、正規表現(VBScript.RegExp)を活用するか、文字列の各文字が0〜9の範囲にあるかをループ検証する自作バリデーション関数の導入が強く推奨されます。