VBScriptを掌握せよ:レガシー文字コードの「自動判別・変換」を制する極限の設計論
世の中には、まだ「EUC-JP」や「ISO-2022-JP(JIS)」を吐き出し続ける、頑固で愛おしいレガシーシステムが山ほどある。これらを現代のUTF-8環境で読み解こうとして文字化けと戦い、`Scripting.FileSystemObject` (FSO) の限界に絶望した経験はないだろうか?
FSOは便利だが、所詮は「OSのデフォルトエンコーディング(主にShift-JIS)」の枷に縛られた老兵だ。レガシーコードを扱うなら、我々はFSOという杖を捨て、`ADODB.Stream`という「外科手術のメス」を手に取らねばならない。
本稿では、VBScriptにおける文字コードの壁を打破し、堅牢かつ高速にファイルを変換する「プロダクション・コード」の極意を伝授する。
—
1. なぜ「判別」が必要なのか:現場の現実
多くのエンジニアは、とりあえず `adodb.stream` で `Charset = “shift-jis”` を決め打ちしてエラーを吐かせる。だが、現場のデータは常に混在する。EUC-JPかJISか、あるいはUTF-8 BOM無しなのか。
「推測」はバグの温床だ。
バイナリレベルでヘッダー(あるいはバイト列の傾向)を読み取り、正確にエンコーディングを特定する。これが、保守コストをゼロに近づけるための唯一の解法である。
—
2. 堅牢な実装:自動判別変換エンジンの設計
以下は、ファイルの実体をバイナリとして読み込み、先頭のバイト列からエンコーディングを予測し、安全にUTF-8へ変換するコアロジックだ。
‘ ————————————————————————–
‘ 堅牢なファイル変換エンジン (UTF-8変換)
‘ 設計思想: オブジェクトの開放を確実に行い、メモリリークを防ぐ
‘ ————————————————————————–
Function ConvertToUtf8(strFilePath)
Dim adoStream, binData, strCharset
‘ 1. バイナリとしてファイルを読み込む
Set adoStream = CreateObject(“ADODB.Stream”)
adoStream.Type = 1 ‘ adTypeBinary
adoStream.Open
adoStream.LoadFromFile strFilePath
binData = adoStream.Read(100) ‘ 先頭100バイトで判定
adoStream.Close
‘ 2. エンコーディング判定ロジック
‘ ※簡易的な判定だが、実務ではここでバイト列のパターンマッチを行う
‘ ISO-2022-JPであれば「ESC + $」等のシグネチャをチェックする
strCharset = DetectEncoding(binData)
‘ 3. 変換実行
adoStream.Type = 2 ‘ adTypeText
adoStream.Charset = strCharset
adoStream.Open
adoStream.LoadFromFile strFilePath
‘ UTF-8へ変換して出力(またはメモリ上の文字列として返す)
adoStream.Position = 0
ConvertToUtf8 = adoStream.ReadText
adoStream.Close
Set adoStream = Nothing
End Function
‘ 判定エンジン(簡略版)
Function DetectEncoding(bin)
‘ 実際の現場ではADODBのCharset名をここで決定する
‘ EUC-JP -> “euc-jp”
‘ ISO-2022-JP -> “iso-2022-jp”
‘ Shift-JIS -> “shift-jis”
DetectEncoding = “shift-jis” ‘ デフォルトの逃げ道を作る設計にせよ
End Function
—
3. アーキテクトの助言:ここが「落ちる」ポイントだ
オブジェクトのライフサイクル管理を疎かにするな
VBScriptはガベージコレクションが強力ではない。特に `ADODB.Stream` をループ内で生成し続けると、メモリを食いつぶす。必ず `Set obj = Nothing` を徹底し、プロセスが肥大化しない設計を心がけること。
書き込み時のBOM問題
UTF-8へ変換する際、`ADODB.Stream` はデフォルトでBOM(Byte Order Mark)を付与する。もし連携先が「BOMなしUTF-8」を要求するシステム(例えば古いLinux系アプリ)なら、変換後にバイナリとしてBOM分(3バイト)を削る処理を挟む必要がある。
データベース連携の罠
データベース(OracleやSQL Server)へ流し込む際、VBScriptがメモリ上で持つ文字列は「Unicode(UTF-16)」だ。DBドライバがエンコーディングをどう解釈するかを常に意識せよ。DBに直接流し込む場合は、スクリプト側で変換せず、DB側のコネクション文字列でエンコーディングを指定するのが、パフォーマンス上は最も効率的だ。
—
結論:自動化は「防衛」である
VBScriptを今さら学ぶ理由は、レガシー環境という「戦場」で生き抜くためだ。このコードをそのままコピペして終わりにするのではなく、「どのような文字コードが混入しても、システムを止めない」という防衛的な設計思想を身につけてほしい。
君が書く自動化ツールは、単なるプログラムではない。現場の人間を文字化けの呪縛から解放する、アーキテクトとしての「守護神」であるはずだ。
次は、ADODBのさらに深い階層であるバイナリ操作について深く掘り下げていこう。準備はいいか?
