VBScriptを掌握せよ:BOM判定による「文字化けゼロ」のファイル読み込みアーキテクチャ
VBScriptで業務自動化ツールを開発する際、避けて通れないのが「文字コードの壁」だ。`ADODB.Stream`でファイルを読み込む際、安直に`Charset = “UTF-8″`と決め打ちしていないだろうか? それは、将来発生する「特定の環境でだけ文字化けする」という悪夢への招待状に他ならない。
真のエンジニアは、推測でコードを書かない。バイナリから真実を読み取るのだ。今回は、BOM(Byte Order Mark)を解析し、あらゆるファイルを安全に処理するための極限のロジックを伝授する。
なぜ「決め打ち」はNGなのか
多くの初心者が犯すミスは、ファイルを開く前にエンコーディングを決めつけてしまうことだ。しかし、Windows環境では歴史的経緯から「Shift-JIS」「UTF-8 (BOMあり/なし)」「UTF-16」が混在する。
特に、`ADODB.Stream`はBOMがないUTF-8を正しく認識できない。この場合、適切に判定し、必要であればバイナリモードで制御を奪う必要がある。
BOM判定アルゴリズムの核心
ファイルの先頭数バイトをバイナリとして読み取り、以下のシグネチャを比較する。
| エンコーディング | BOM (16進数) |
| :— | :— |
| UTF-8 | `EF BB BF` |
| UTF-16 LE | `FF FE` |
| UTF-16 BE | `FE FF` |
| その他 (Shift-JIS等) | 上記以外 |
堅牢なファイル読み込みの実装コード
このコードは、単なるスクリプトではない。ファイルシステムという不確定要素からエンコーディングを抽出し、安全にメモリへロードするための「ゲートキーパー」だ。
Option Explicit
‘ メイン処理例:ファイルを安全に読み込む
Dim filePath: filePath = “C:\temp\data.txt”
Dim content: content = ReadFileSafe(filePath)
WScript.Echo content
Function ReadFileSafe(path)
Dim adoStream, binaryData, charset, bom
‘ 1. バイナリモードでBOMを読み取る
Set adoStream = CreateObject(“ADODB.Stream”)
adoStream.Type = 1 ‘ adTypeBinary
adoStream.Open
adoStream.LoadFromFile path
binaryData = adoStream.Read(3) ‘ 先頭3バイトを読み取り
adoStream.Close
‘ 2. BOM判定ロジック
charset = “Shift-JIS” ‘ デフォルト
If Not IsNull(binaryData) Then
bom = Hex(AscB(MidB(binaryData, 1, 1))) & _
Hex(AscB(MidB(binaryData, 2, 1))) & _
Hex(AscB(MidB(binaryData, 3, 1)))
If Left(bom, 6) = “EFBBBF” Then
charset = “UTF-8”
ElseIf Left(bom, 4) = “FFFE” Then
charset = “UTF-16LE”
ElseIf Left(bom, 4) = “FEFF” Then
charset = “UTF-16BE”
End If
End If
‘ 3. 確定したCharsetでテキストとして読み込み直す
adoStream.Type = 2 ‘ adTypeText
adoStream.Charset = charset
adoStream.Open
adoStream.LoadFromFile path
‘ BOM付きUTF-8の場合、先頭のBOMを除去する処理が必要なケースが多い
ReadFileSafe = adoStream.ReadText
adoStream.Close
Set adoStream = Nothing
End Function
アーキテクトとしての注意点
1. 「BOMなしUTF-8」の罠
上記のロジックで判定できない最大の敵が「BOMなしUTF-8」だ。これを見分けるには、統計的な解析(バイトの並びがUTF-8のルールに合致するか)が必要となるが、VBScriptで実装するには非常にコストが高い。
実務レベルでは、「UTF-8ならBOMを付ける」という運用ルールを徹底させるか、エラーハンドリングを強化して「読めない場合はShift-JISとして再試行」するフォールバック設計を推奨する。
2. パフォーマンスの最適化
`ADODB.Stream`は非常に強力だが、インスタンス生成はコストが高い。大量のファイルを処理する場合は、ループ内で何度も`CreateObject`を呼ぶのではなく、必要に応じてキャッシュやリサイクルを検討せよ。
3. データベース連携時の落とし穴
ファイルから読み取ったデータをDBへ投入する際、ADODB.Streamで正規化したテキストデータはUnicodeである。DB側のカラム型(`VARCHAR` vs `NVARCHAR`)がエンコーディングと適合しているか、常に確認すること。ここを疎かにすると、データ移行時に「?」が大量発生する悲劇を招く。
まとめ
VBScriptで「動くもの」を作るのは簡単だ。しかし、「止まらないもの」を作るには、こうした低レイヤーの挙動に対する理解が不可欠となる。
今回提示したBOM判定ロジックは、あなたの自動化ツールを「動けばいい」というレベルから「プロフェッショナルな品質」へと引き上げる一歩目だ。今日から「決め打ちのコード」を捨て、バイナリの真実を読み解く設計に切り替えてほしい。
