【実務・中級編】【対話型CLIフォーム構築】CScript 標準入力時の自動入力補完とデフォルト値提示を組み込んだ高度な入力ハンドラー – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【対話型CLIフォーム構築】CScript 標準入力時の自動入力補完とデフォルト値提示を組み込んだ高度な入力ハンドラー

現場の自動化スクリプトにおいて、GUIの構築はオーバースペックであり、かつ環境依存のトラブルの温床となる。確実な稼働が求められるエンタープライズ領域において、WSH(Windows Script Host)の `CScript.exe` によるCUIベースの対話型インターフェースは、今なお最強の武器だ。

しかし、素朴な `WScript.StdIn.ReadLine` をそのまま使ったバッチファイルやVBScriptは、実務の現場では使い物にならない。
「エンターキーを押されただけで空文字が返り、後続処理が爆発する」「デフォルト値を提示したいのに、ユーザーが自力で入力し直さなければならない」「WScriptで実行してしまい、ハングアップしたように固まる」——こうした無駄な手戻りを生むコードは、今日で終わりにする。

今回は、VBScriptのストリーム制御とオブジェクトのライフサイクルを極限まで理解したプロフェッショナルだけが書ける、「デフォルト値自動適用」「空入力ガード」「CScript強制判定」を完備した極限の入力ハンドラーを伝授する。

1. なぜ「素の入力処理」は現場で破綻するのか?

多くの開発者がやりがちな実装を見てみよう。

‘ 【アンチパターン】絶対にやってはいけない実装
Dim userInput
WScript.StdOut.Write “接続先サーバー名を入力してください: ”
userInput = WScript.StdIn.ReadLine

‘ ここでユーザーが何も入力せずにEnterを押すと、userInputは空文字になる
If userInput = “” Then
userInput = “localhost” ‘ デフォルト値を入れたつもり
End If

このコードの何が致命的か?
1. 視覚的フィードバックの欠如: ユーザーはデフォルトが何であるかを知る術がない。勘でEnterを押すしかない。
2. 実行ホストの未確認: これを誤って `WScript.exe`(GUIモード)で実行すると、標準入出力が存在しないため、スクリプトは容赦なくエラーで沈黙するか、無限ループに陥る。
3. 文字コードの罠: 日本語環境の標準入力は、Shift-JIS(CP932)やUTF-8など実行コンソールのコードページに左右される。ここを考慮しないと、全角文字を入力された瞬間に文字化け、あるいはパースエラーを引き起こす。

我々が目指すべきは、「ユーザーが思考せず、Enter連打でも安全にデフォルト値で完走できる堅牢なフォーム」である。

2. 堅牢なCLI入力ハンドラーの設計思想

今回構築するモジュールは、以下の3つの要件を完璧に満たす。

1. ホストプロセスの厳密な自己防衛:
実行基盤が `CScript.exe` であることを実行時プロパティから判定し、`WScript.exe` であれば強制終了、または自動的に `CScript` で再起動をかける。
2. 洗練されたプロンプト表現:
`[デフォルト値]` を視覚的にブラケット表示し、ユーザーが空エンター(単なる改行)を行った瞬間に、そのデフォルト値をシームレスに採用する。
3. 再利用可能なカプセル化:
関数として完全に独立させ、1行の呼び出しであらゆるデータ型の入力を安全に回収できるようにする。

3. 【プロダクションコード】完全版対話型入力ハンドラー

以下のコードをコピーし、`.vbs` ファイルとして保存して `cscript scriptname.vbs` で実行してほしい。これが現場で生き残るためのコードだ。

Option Explicit

‘ ==============================================================================
‘ スクリプト実行ホストの強制検証(CScript以外での誤爆を防ぐ)
‘ ==============================================================================
Call EnsureCScriptEnvironment()

‘ メイン処理(業務フォームのシミュレーション)
WScript.Echo “=== データベース移行バッチ 構成ウィザード ===”
Dim dbServer, dbPort, executeMode

‘ 1. 文字列入力のテスト(デフォルト値あり)
dbServer = PromptInput(“接続先データベースサーバー”, “db.internal.local”)

‘ 2. 数値入力のテスト(デフォルト値あり)
dbPort = PromptInput(“接続ポート番号”, “1433”)

‘ 3. 選択式/フラグ入力のテスト
executeMode = PromptInput(“実行モード (DryRun/Commit)”, “DryRun”)

‘ 入力結果のサマリー出力
WScript.Echo vbCrLf & “— 設定完了 —”
WScript.Echo “サーバー : ” & dbServer
WScript.Echo “ポート : ” & dbPort
WScript.Echo “モード : ” & executeMode

‘ ==============================================================================
‘ 関数名: PromptInput
‘ 概要 : デフォルト値提示と空入力ガードを備えたCLI入力ハンドラー
‘ 引数 : message (String) – プロンプトメッセージ
‘ defaultValue (String) – ユーザーが未入力の際に採用するデフォルト値
‘ 戻り値: String – 確定した入力値
‘ ==============================================================================
Function PromptInput(ByVal message, ByVal defaultValue)
Dim rawInput, displayPrompt

‘ デフォルト値が存在する場合のプロンプト整形
If defaultValue <> “” Then
displayPrompt = message & ” [” & defaultValue & “]: ”
Else
displayPrompt = message & “: ”
End If

Do
‘ 標準出力へプロンプトを表示(改行なし)
WScript.StdOut.Write displayPrompt

‘ 標準入力からの読み込み
rawInput = WScript.StdIn.ReadLine

‘ 前後の空白を除去
rawInput = Trim(rawInput)

‘ 未入力(空エンター)の場合はデフォルト値を適用
If rawInput = “” Then
rawInput = defaultValue
End If

‘ 有効な値が得られた場合はループを抜ける
Exit Do
Loop

PromptInput = rawInput
End Function

‘ ==============================================================================
‘ サブルーチン名: EnsureCScriptEnvironment
‘ 概要 : WScript.exeでの誤実行を検知し、CScriptで自己再起動する
‘ ==============================================================================
Sub EnsureCScriptEnvironment()
Dim hostFullName, fullName, args, arg, cmd

hostFullName = WScript.FullName
‘ パスの小文字比較で CScript かどうかを判定
If Right(LCase(hostFullName), 11) = “wscript.exe” Then
‘ コマンドライン引数を再構築
args = “”
For Each arg In WScript.Arguments
‘ スペースを含む引数に対応するためダブルクォーテーションで囲む
args = args & ” “”” & arg & “”””
Next

‘ CScript.exe を使って自分自身を再起動
cmd = “cscript.exe //Nologo “”” & WScript.ScriptFullName & “””” & args

CreateObject(“WScript.Shell”).Run cmd, 1, False

‘ GUIホスト側のプロセスは即座に終了
WScript.Quit
End If
End Sub

4. コードの深層解説:プロフェッショナルの技法

① `WScript.StdOut.Write` と改行の制御

一般的な `WScript.Echo` は、出力の末尾に強制的に改行(CRLF)を付加してしまう。これではプロンプトの右側にカーソルを置くことができない。
`WScript.StdOut.Write` を用いることで、コンソールの同じ行にユーザーの入力を待つカーソルを美しく静置させることができる。

② 自己修復型ホスト判定 (`EnsureCScriptEnvironment`)

開発者がいくら「CScriptで実行しろ」と言っても、エンドユーザーは必ずエクスプローラからファイルをダブルクリック(=WScript.exeで起動)する。
このスクリプトは、起動された瞬間子プロセスとして `cscript.exe` を自身にアタッチして再起動し、元のWScriptプロセスを `WScript.Quit` で消滅させる。運用者泣かせの「ダブルクリック事故」をコードレベルで完全に根絶している。

③ トリムと空文字のハンドリング

ユーザーが意図せずスペースを入力した場合や、単にEnterを押しただけのケースを `Trim(rawInput)` で正規化。空文字であれば即座に `defaultValue` にすり替えることで、後続のデータベース接続文字列生成やファイルパス構築フェーズにおいて、値が空であることによる例外の発生確率をゼロに収束させている。

5. 実務応用:ファイル・DB連携へのブリッジ

この入力ハンドラーで取得した変数は、そのまま実務のインフラ自動化に直結できる。

‘ 例: 入力されたサーバー名とポートを使ってODBC接続を行う場合
Dim conn, connectionString
Set conn = CreateObject(“ADODB.Connection”)

connectionString = “Provider=SQLOLEDB;Server=” & dbServer & “;Port=” & dbPort & “;Database=Master;Trusted_Connection=yes;”

On Error Resume Next
conn.Open connectionString
If Err.Number <> 0 Then
WScript.StdOut.WriteLine “[ERROR] データベースへの接続に失敗しました: ” & Err.Description
WScript.Quit 1
End If
On Error GoTo 0

WScript.StdOut.WriteLine “[SUCCESS] 接続確立完了。”
conn.Close
Set conn = Nothing

総括

VBScriptは「古い言語」ではない。WSHの特性とストリーム入出力の挙動を完全に掌握したエンジニアの手にかかれば、インフラ自動化やローカルバッチにおいて、他のどのモダン言語よりも軽量かつセキュアに動作する極上のツールへと生まれ変わる。

今回紹介した対話型入力ハンドラーをあなたのライブラリに組み込み、属人化しやすくエラーの多い手動オペレーションを、今日から完全自動化へとシフトさせてほしい。

タイトルとURLをコピーしました