VBScriptを支配せよ:文字化けを撲滅する「BOM判別」の極意
こんにちは。現場で長年VBScriptと格闘してきた、チーフアーキテクトです。
VBScriptで最も多くのエンジニアを絶望させるのが「文字化け」です。`ADODB.Stream`でファイルを開いた瞬間に「文字化けで内容が読めない」「実行時エラーで止まる」……そんな経験はありませんか?
実は、ファイルを開く前に「そのファイルが何者か(エンコーディング)」を自ら判定するという一手間を加えるだけで、あなたのスクリプトは劇的に強固になります。今日は、伝説的な安定性を誇る「BOM判定ロジック」を伝授しましょう。
—
1. なぜ「BOM」を見る必要があるのか?
Windowsの世界では、ファイルはただの「バイトの羅列」です。プログラム側が「これはUTF-8だよ」「これはShift-JISだよ」と正しく解釈してあげないと、メモリ上でデータはゴミになってしまいます。
そこで登場するのがBOM (Byte Order Mark) です。ファイルの先頭に隠された「私はこの形式ですよ」という名札のような数バイト。これさえ読めれば、迷うことなく読み込み処理へ進めます。
BOMのシグネチャ(判別リスト)
| エンコーディング | BOM (16進数) |
| :— | :— |
| UTF-8 | `EF BB BF` |
| UTF-16 LE | `FF FE` |
| UTF-16 BE | `FE FF` |
| Shift-JIS等 | なし (※) |
※BOMがない場合は「Shift-JIS」とみなすのがWindowsレガシー環境の定石です。
—
2. 実装:ADODB.Streamで「先頭を覗き見る」
いきなりテキストとして読み込むのではなく、まずはバイナリモードで先頭3バイトだけを切り取るのがコツです。
‘ — BOM判定関数: 引数にファイルパスを渡すとエンコーディング名を返す —
Function GetEncoding(strFilePath)
Dim objStream, binData, b1, b2, b3
Set objStream = CreateObject(“ADODB.Stream”)
objStream.Type = 1 ‘ バイナリモード
objStream.Open
objStream.LoadFromFile strFilePath
‘ 先頭3バイトを読み込む
binData = objStream.Read(3)
objStream.Close
Set objStream = Nothing
‘ データが3バイト未満の場合はShift-JISとみなす
If LenB(binData) < 2 Then
GetEncoding = "Shift-JIS"
Exit Function
End If
' バイナリ値から各バイトを取り出す
b1 = AscB(MidB(binData, 1, 1))
b2 = AscB(MidB(binData, 2, 1))
b3 = AscB(MidB(binData, 3, 1))
' BOM判定ロジック
If b1 = &HEF And b2 = &HBB And b3 = &HBF Then
GetEncoding = "UTF-8"
ElseIf b1 = &HFF And b2 = &HFE Then
GetEncoding = "UTF-16"
ElseIf b1 = &HFE And b2 = &HFF Then
GetEncoding = "unicodeFFFE" ' Big Endian
Else
' BOMがない場合はデフォルトをShift-JISに
GetEncoding = "Shift-JIS"
End If
End Function
---
3. このコードの「賢い」ポイント
1. Type = 1 (Binary Mode) の活用:
最初からテキストモードで開こうとすると、ADODB.Streamは「文字コードが合わない」という理由で即座にエラーを吐くことがあります。バイナリで開くことで、どんなファイルでも確実に「先頭の数バイト」を確保できます。
2. AscB / MidB 関数の使用:
文字列用の`Asc`や`Mid`ではなく、バイト単位で処理する`AscB`と`MidB`を使うのが、バイナリ操作の鉄則です。これを知っているだけで、あなたはもう「脱・初心者」です。
3. 読み込み時の柔軟性:
この関数で取得した戻り値を、後続の`objStream.Charset = GetEncoding(…)`に渡すだけで、文字化けとは無縁の読み込み処理が完成します。
—
4. 陥りやすい罠:ここだけは気をつけて
- 「無BOMのUTF-8」の罠:
最近のテキストエディタで保存したUTF-8は、BOMが付いていないことが多いです。上記のロジックでは「Shift-JIS」として判定されます。もし現場のファイルが「無BOM UTF-8」メインであれば、Shift-JISの判定ロジックの後に、実際にUTF-8としてデコードできるか試す(例外ハンドリングを組む)という、より高度なアルゴリズムが必要です。
- ファイルロック:
`ADODB.Stream`でファイルを開いたままにすると、他のプロセスがそのファイルを編集できなくなります。使い終わったら必ず `Close` し、`Nothing` を代入してメモリを解放してください。VBScriptのガベージコレクションを信用してはいけません。
—
最後に:エンジニアとしての第一歩
「マクロの記録」で生成されたコードは、その場限りの使い捨てです。しかし、今日あなたが学んだ「バイナリを直接読み解く」という考え方は、どんなプログラミング言語に移行しても一生使える武器になります。
VBScriptは古い言語と言われますが、Windowsの深淵を操る力は今も現役です。ぜひ、このロジックをあなたのツールボックスに加えて、誰よりも安定したスクリプトを書いてください。
応援しています。困ったときは、またいつでも聞きに来てくださいね。
