VBScriptを「使い捨て」で終わらせるな:堅牢な引数バリデーションの極意
VBScriptは、現代のモダンな言語と比較すれば確かにプリミティブだ。しかし、WSH(Windows Script Host)というOS直結の実行環境を操る上で、これほど軽量かつ強力な武器はない。
多くの現場で散見されるのは、「引数が渡されることを前提とした、脆いスクリプト」だ。誰かが引数を入力ミスした瞬間、あるいは引数を省略した瞬間にスクリプトはランタイムエラーを吐き、運用担当者を呼び出す。
プロの自動化エンジニアにとって、スクリプトの停止は「恥」である。
今回は、コマンドライン引数の不整合を完全に封じ込め、業務の自動化パイプラインを止めることのない「堅牢なバリデーション設計」を伝授する。
—
なぜ `IsNumeric` や `IsDate` だけでは不十分なのか
初心者は「型チェックさえすれば安全だ」と考える。しかし、それは大きな誤解だ。VBScriptの型判定は極めて寛容である。例えば `IsNumeric` は、文字列としての `”123″` も、指数表記の `”1E+02″` も `True` を返す。
真に堅牢なバリデーションとは、「型チェック」と「デフォルト値の適用」、そして「論理範囲の制約」を分離して実装することにある。
バリデーション実装の鉄則
1. Argumentsの存在確認: `WScript.Arguments.Count` を使い、引数の過不足を事前に検知する。
2. デフォルト値の先行定義: 異常値や未指定時は、あらかじめ安全な「既定値」へフォールバックさせる。
3. 明示的な型変換: 判定後に `CInt`, `CDate` 等で型を確定させる。
—
プロダクション・コード:堅牢な引数パースの実装
このテンプレートは、そのまま実務のテンプレートとして利用できる。無駄な処理を削ぎ落とし、エラーハンドリングを標準化したものだ。
Option Explicit
‘ ——————————————————————
‘ 堅牢な引数バリデーション・テンプレート
‘ ——————————————————————
‘ 1. デフォルト値の定義(ここで設定を集中管理する)
Const DEFAULT_THRESHOLD = 0
Const DEFAULT_TARGET_DATE = “2023/01/01”
Dim threshold, targetDate
‘ 2. 引数の取得とバリデーション
threshold = GetValidatedNumeric(0, DEFAULT_THRESHOLD)
targetDate = GetValidatedDate(1, DEFAULT_TARGET_DATE)
WScript.Echo “実行パラメータ: Threshold=” & threshold & “, TargetDate=” & targetDate
‘ 以降、この変数を使ってDB接続やファイル操作を行う
‘ — 以下、ユーティリティ関数 —
‘ 数値バリデーション
Function GetValidatedNumeric(idx, defaultValue)
If WScript.Arguments.Count > idx Then
If IsNumeric(WScript.Arguments(idx)) Then
GetValidatedNumeric = CDbl(WScript.Arguments(idx))
Exit Function
End If
End If
‘ 不正、または未指定時はデフォルト値を返す
GetValidatedNumeric = defaultValue
End Function
‘ 日付バリデーション
Function GetValidatedDate(idx, defaultValue)
If WScript.Arguments.Count > idx Then
If IsDate(WScript.Arguments(idx)) Then
GetValidatedDate = CDate(WScript.Arguments(idx))
Exit Function
End If
End If
GetValidatedDate = CDate(defaultValue)
End Function
—
運用で死なないための注意点
1. 「暗黙の型変換」という罠
VBScriptは実行時に型を動的に解決するが、これに甘えると `+` 演算子で「加算」ではなく「文字列連結」が発生するなどのバグを生む。必ず `CDbl()` や `CStr()` で、処理の直前に型を固定せよ。
2. ファイルシステムとの連携における注意
引数でファイルパスを受け取る場合、`IsNumeric` は通用しない。その際は `Scripting.FileSystemObject` の `FileExists` や `FolderExists` を使い、「そのパスが物理的にアクセス可能か」までをバリデーションの範囲に含める必要がある。これが「動くスクリプト」と「仕事が終わるスクリプト」の境界線だ。
3. デバッグの可視化
運用環境では、スクリプトが「なぜそのデフォルト値を選択したのか」が不明だと調査に時間がかかる。バリデーションがデフォルト値にフォールバックした際は、イベントログに書き出すか、少なくともコンソールに警告を出力する設計にしておくこと。
—
結びに:エンジニアの誇りとして
スクリプトを書くということは、自分の代わりにPCに判断させるということだ。あなたが寝ている間に動くコードが、たった一つの引数の不整合で停止するのは、エンジニアとしての設計ミスに他ならない。
「動けばいい」という考えは捨てよ。
「どのような異常な入力が来ても、正しくエラーを補足し、安全な既定動作に導く」。この哲学こそが、あなたの作る自動化ツールを、単なるスクリプトから「信頼できる業務資産」へと昇華させる。
次は、例外処理における `On Error Resume Next` の正しい使い方と、その副作用を完全に制御する設計について議論しよう。準備はいいか。
