VBScriptの「文字の罠」を突破せよ!FSOで全角・半角混在テキストを安全に扱う極意
こんにちは。現場の最前線で自動化システムを構築しているエンジニアです。
VBScriptでファイルシステムオブジェクト(FSO)を使ってテキストファイルを読み込む際、「なぜか文字の位置がずれる」「全角文字が化ける」「期待した場所で切り出せない」といったトラブルに遭遇したことはありませんか?
特に日本語環境では、「1文字=1バイト」という幻想が、あなたのコードを崩壊させる最大の原因です。今日は、VBScriptで全角・半角混在テキストを安全に操るための「SafeRead術」を伝授します。
—
1. なぜ「ズレ」は起きるのか?
まず、コンピュータの内部事情を少しだけ紐解きましょう。
- 半角英数字: 通常「1バイト」で表現されます。
- 全角文字(日本語): 通常「2バイト以上(文字コードによる)」で表現されます。
VBScriptの標準的な文字列操作関数(`Left`, `Mid`, `Len` など)は、「バイト数」ではなく「文字数」を基準に動きます。
しかし、ファイルを読み込む際や、外部システムと連携する際に「バイト単位」で制御しようとすると、この「1文字=1バイトではない」という仕様が仇となり、インデックス(位置)のズレが発生するのです。
—
2. 陥りやすい「NGパターン」
多くの初心者がやりがちなのが、FSOで読み込んだ文字列に対し、無理やりバイト数で計算を適用することです。
‘ 【危険なコードの例】
‘ 10バイト目から切り出そうとして、全角文字が含まれていると……
‘ 実際には文字の途中(マルチバイトの半分)で切れてしまい、文字化けやエラーに。
strData = objTextStream.ReadAll
strPart = MidB(strData, 1, 10) ‘ ← MidBはバイト単位だが、文字境界を無視するため崩壊する
これを防ぐには、「読み込み時に文字コードを明示する」ことと、「処理の基準を文字単位に統一する」という二段構えの防衛策が必要です。
—
3. 【実戦】安全に読み込むためのSafeRead術
FSOでファイルを読み込む際、最も事故が起きにくい「安全な手順」を紹介します。
ステップ1:文字コードを指定してオープンする
FSOの `OpenTextFile` メソッドで、第4引数(Tristate)を `TristateTrue`(Unicode)や `TristateUseDefault`(システムデフォルト)に適切に設定します。特に日本語環境では、ファイルの文字コード(Shift-JISかUTF-8か)を意識することが第一歩です。
ステップ2:Len関数とMid関数の「文字単位」を信じる
VBScriptの `Len` や `Mid` は「文字数」を返します。無理にバイト変換せず、この「文字数」を信じて処理を構築するのが、もっともバグを生みにくい設計です。
‘ 【推奨:安全な読み込みと処理のテンプレート】
Dim fso, ts, content, line
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 1. ファイルを読み込む(TristateUseDefaultでシステム標準のエンコーディングを使用)
Set ts = fso.OpenTextFile(“data.txt”, 1, False, -2)
Do Until ts.AtEndOfStream
line = ts.ReadLine
‘ 2. バイト数ではなく「文字数」で制御する
‘ 全角・半角混在でもLenは「文字の数」を正しく数える
If Len(line) > 10 Then
‘ 安全に左から10文字を抽出
Dim safePart
safePart = Left(line, 10)
WScript.Echo “抽出結果: ” & safePart
End If
Loop
ts.Close
Set ts = Nothing
Set fso = Nothing
—
4. どうしても「バイト数」で切り出したい時は?
もし、固定長フォーマットのログファイルなどで「どうしてもバイト数で切り出したい」という場合は、ADODB.Streamオブジェクトを使うのが「伝説級」の解法です。FSOよりも遥かに強力で、文字コードの変換も自在です。
‘ 【上級編:ADODB.Streamでバイト単位の制御】
Dim ado
Set ado = CreateObject(“ADODB.Stream”)
ado.Type = 2 ‘ adTypeText
ado.Charset = “Shift_JIS” ‘ ファイルの文字コードに合わせる
ado.Open
ado.LoadFromFile “data.txt”
‘ 全体を読み込んで処理
Dim textData
textData = ado.ReadText
‘ ここで処理を行い、必要ならバイト変換を行う
‘ (VBScriptでバイト処理を行う場合はこのオブジェクトが最強です)
ado.Close
—
先輩からのアドバイス:まとめ
VBScriptをマスターする秘訣は、「自分が今、文字数ベースで考えているのか、バイト数ベースで考えているのかを自覚すること」です。
1. 基本は文字数: `Len` や `Mid` を信頼しましょう。これらは全角・半角を気にせず「1文字」として扱ってくれるため、ほとんどの業務ロジックではこれで十分です。
2. どうしてもバイト制御が必要なら: FSOではなく `ADODB.Stream` を選択しましょう。道具には適材適所があります。
この2点さえ押さえておけば、文字化けや位置ズレの悪夢から解放されます。焦らず、一歩ずつコードを書いていけば、必ず「動く」だけでなく「壊れない」自動化ツールを作れるようになりますよ。
応援しています。また何かあればいつでも聞いてくださいね!
