VBScriptを掌握せよ:ADODB.Streamで「文字化け」を過去の遺物にする極限の設計術
業務自動化の現場で、いまだに `FileSystemObject` (FSO) の `OpenTextFile` に頼り切っている者はいないか?もしそうなら、今すぐそのコードを捨てるべきだ。
FSOは確かに簡潔だが、UTF-8への対応は絶望的であり、BOM(Byte Order Mark)の有無一つでシステム全体を崩壊させる「時限爆弾」を抱えているに等しい。現代のWindows環境で、文字化けやファイル入出力のトラブルを回避し、堅牢なパイプラインを構築するための唯一の正解――それが `ADODB.Stream` によるストリーム処理だ。
本稿では、VBScriptの限界を超え、プロダクション環境で耐えうる「文字コードの相互変換アーキテクチャ」を伝授する。
—
1. なぜFSOではなくADODB.Streamなのか?
FSOの `OpenTextFile` は、システムのローカルコードページ(日本語環境ならShift-JIS)を前提としている。これに対し、外部システムやAPIと連携する場合、UTF-8(特にBOMなし)が標準だ。FSOでこれらを読み込むと、日本語は壊滅する。
`ADODB.Stream` は、バイナリデータとしての入出力を制御し、`Charset` プロパティを通じて文字コード変換をオブジェクトレベルで完結させる。これこそが、OSの制約から解放されるための「唯一の鍵」だ。
—
2. 堅牢なファイル変換エンジン:プロダクションコード
以下のコードは、単なるサンプルではない。例外処理(エラートラップ)の作法、オブジェクトのライフサイクル管理、そして再利用性を考慮した「実務レベル」のパターンだ。
‘ ADODB.Stream を活用したファイル変換クラス的実装
Option Explicit
Const adTypeText = 2
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
‘ 用途に応じて文字コードを指定
Dim strFilePathSource, strFilePathDest
strFilePathSource = “input_utf8.txt”
strFilePathDest = “output_sjis.txt”
Call ConvertFileEncoding(strFilePathSource, “UTF-8”, strFilePathDest, “Shift-JIS”)
Sub ConvertFileEncoding(srcPath, srcCharset, destPath, destCharset)
Dim objStream: Set objStream = CreateObject(“ADODB.Stream”)
On Error Resume Next
‘ — 読み込み処理 —
With objStream
.Type = adTypeText
.Charset = srcCharset
.Open
.LoadFromFile srcPath
Dim strContent: strContent = .ReadText
.Close
End With
If Err.Number <> 0 Then
WScript.Echo “読み込み失敗: ” & Err.Description
Exit Sub
End If
‘ — 書き込み処理 —
With objStream
.Type = adTypeText
.Charset = destCharset
.Open
.WriteText strContent
.SaveToFile destPath, adSaveCreateOverWrite
.Close
End With
If Err.Number <> 0 Then
WScript.Echo “書き込み失敗: ” & Err.Description
End If
Set objStream = Nothing
On Error Goto 0
End Sub
—
3. 実務で必ず陥る「落とし穴」と対策
このコードをそのまま導入する際、注意すべき3つの鉄則がある。
① BOMの罠(UTF-8 Without BOM)
`ADODB.Stream` の `Charset = “UTF-8″` は、デフォルトでBOMを付与する。もし相手先システムが「BOMなし」を要求する場合、ストリームへ書き込んだ後にバイナリとして先頭の3バイトを削る処理が必要になる。安易に `Charset` を信じ込まず、要件定義を再確認せよ。
② メモリのオーバーヘッド
`ReadText` で全データを一気に変数に格納している。これは数MB程度のファイルなら問題ないが、数百MBを超えるログファイルを処理する場合、メモリ不足(OutOfMemory)を招く。大容量ファイルを扱う場合は、行単位のループ処理(`.ReadText -1` ではなく `.ReadText n`)へ設計を切り替えるのがプロの流儀だ。
③ オブジェクトの開放(クリーンアップ)
VBScriptのガベージコレクションを信用してはならない。特にループ内でファイルを何度も処理する場合、`Set objStream = Nothing` を確実に呼び出し、オブジェクトのライフサイクルを制御せよ。これを怠ると、ファイルハンドルが解放されず、「ファイルが使用中です」というエラーに悩まされることになる。
—
結論:エンジニアの誇りとして
「動けばいい」というコードは、数ヶ月後の自分自身を苦しめる負債になる。`ADODB.Stream` を正しく使いこなすことは、単なる文字化け対策ではない。バイナリとテキストの境界線を理解し、堅牢なデータパイプラインを設計する能力そのものだ。
このコードをあなたのツールキットに加え、明日の業務効率化を確実なものにせよ。健闘を祈る。
