【入門編】【BOMなしUTF-8テキスト結合】ADODB.Stream を利用したヘッダー保持とBOM破壊を抑止する大容量ファイル結合 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptで「BOMなしUTF-8」を制する:ADODB.Streamによる究極のファイル結合術

こんにちは。自動化の現場でVBScriptと長年向き合ってきたエンジニアです。

皆さんは、複数のテキストファイルを結合しようとして、「なぜか文字化けする」「結合したファイルの先頭にゴミのような記号(BOM)が入り込む」といった壁にぶつかったことはありませんか?

VBScriptの標準的な `FileSystemObject` は、残念ながら「BOMなしUTF-8」の繊細な取り扱いが苦手です。しかし、Windowsに標準搭載された `ADODB.Stream` オブジェクトを使いこなせば、バイナリレベルで制御することで、どんな巨大なテキストファイルも正確に、かつ安全に結合できます。

今日は、プロの現場で即戦力となる「BOM破壊を抑止するファイル結合」の極意をお伝えします。

なぜ「BOM」が邪魔をするのか?

まず、敵を知りましょう。
UTF-8ファイルには、先頭に「これはUTF-8ですよ」と示すためのBOM(Byte Order Mark)という3バイトの信号が付与されることがあります。

もし、BOM付きのファイルを複数つなげるとどうなるか。
結合先のファイルの「真ん中」にBOMが紛れ込み、システムがそれを「未知の文字」として誤認し、文字化けやプログラムの読み込みエラーを引き起こします。

我々の目的は、「結合したファイルの先頭にはBOMを許し、それ以降のファイルからはBOMを剥ぎ取る」こと。これを実現するのが `ADODB.Stream` です。

実践コード:BOMを制御して安全に結合する

以下のコードは、指定したフォルダ内のすべての `.txt` ファイルを、一つのファイルに結合するスクリプトです。

‘ — 設定エリア —
strFolder = “C:\Data\Input\”
strOutputFile = “C:\Data\Output\Combined.txt”

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set objStreamOutput = CreateObject(“ADODB.Stream”)

‘ 出力ストリームの初期化
objStreamOutput.Type = 1 ‘ バイナリモード
objStreamOutput.Open

‘ フォルダ内のファイルを走査
For Each file In fso.GetFolder(strFolder).Files
If LCase(fso.GetExtensionName(file.Path)) = “txt” Then

Set objStreamInput = CreateObject(“ADODB.Stream”)
objStreamInput.Type = 1 ‘ バイナリモードで読み込み
objStreamInput.Open
objStreamInput.LoadFromFile file.Path

‘ 【重要】最初のファイル以外は、先頭3バイト(BOM)をスキップする
If objStreamOutput.Size > 0 Then
objStreamInput.Position = 3
End If

‘ 残りのデータをコピー
objStreamOutput.Write objStreamInput.Read

objStreamInput.Close
Set objStreamInput = Nothing
End If
Next

‘ ファイル保存
objStreamOutput.SaveToFile strOutputFile, 2 ‘ 2 = 上書き保存
objStreamOutput.Close

コードの深掘り:エンジニアの着眼点

このコードが「なぜ動くのか」、そして「なぜ壊れないのか」を解説します。

1. バイナリモード(Type = 1)の選択
`ADODB.Stream` を `Type = 2`(テキストモード)で開くと、VBScriptが勝手に文字コード変換を試みます。これが悲劇の始まりです。`Type = 1`(バイナリ)で扱うことで、データの内容を一切いじらず、そのまま「バイトの列」として結合できます。
2. Position = 3 の魔術
UTF-8のBOMは「EF BB BF」の3バイトです。2つ目以降のファイルに対し `Position = 3` を指定することで、先頭のBOMを無視して、純粋なデータ部分からコピーを開始します。これにより、結合後のファイル内にBOMが混入するのを防ぎます。
3. オブジェクトのライフサイクル管理
`ADODB.Stream` はメモリを消費します。ループのたびに `Set objStreamInput = Nothing` で解放し、`Close` を徹底することで、巨大なファイルを結合してもメモリリークを起こさない堅牢な構成にしています。

陥りやすいエラーと対策

  • 「ファイルにアクセスできません」エラー:

これは、結合先のファイルが既に他のプログラムで開かれているか、出力先フォルダが存在しない場合に発生します。`fso.FolderExists` で事前チェックを行う習慣をつけましょう。

  • 「Positionプロパティでエラー」:

ファイルが空(0バイト)の場合、`Position = 3` を設定するとエラーになります。読み込み前に `objStreamInput.Size` を確認するガード句を入れると完璧です。

最後に:ここをクリアすれば、あなたはもう脱・初心者です

VBScriptは古い言語だと言われがちですが、Windows環境における「OS直結のバイナリ操作」において、これほど身軽で強力なツールはありません。

今回扱った「ストリーム制御」の考え方は、VBScriptに限らず、C#やPowerShell、さらにはクラウドのデータ処理にも通じる「データの扱い方の本質」です。

まずはこのコードをコピペして、手元のCSVやログファイルで試してみてください。エラーが出たら、それは「OSと対話できた証」です。怖がらずに、少しずつ設定を変えて遊んでみてくださいね。

皆さんの自動化ライフが、より快適で正確なものになることを応援しています!

タイトルとURLをコピーしました