【入門編】【複数文字コード混在ログ解読】ADODB.Streamを用いたShift-JIS/UTF-8自動判定とUnicode統一パース – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!VBScriptの世界へようこそ。
今日は、現場のエンジニアが思わず頭を抱えてしまう「複数文字コードが混在したログファイルの解読と統一」という、実務でめちゃくちゃ役立つテーマについてお話しします。

「古い基幹システムが出力するShift-JISのログ」と「最近のクラウドサービスが吐き出すUTF-8のログ」。これらが同じフォルダに混ぜこぜで置かれていて、いざ集計しようとしたら文字化けの嵐……。そんな絶望的な状況に出会ったことはありませんか?

マクロの記録から一歩抜け出し、Windowsの標準機能であるWSH(Windows Script Host)と`ADODB.Stream`を極めれば、こんな混沌とした状況も一瞬でクリアできます。
ここをクリアすれば、あなたのVBScriptのスキルは間違いなくワンランク上の「プロの領域」に到達します。さあ、一緒に扉を開けましょう!

なぜログの文字コードで苦労するのか?

VBScriptでファイルを開くとき、よく使われるのが `Scripting.FileSystemObject`(FSO)の `OpenTextFile` メソッドですよね。

‘ FSOを使ったおなじみの書き方(実は罠がある)
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(“log.txt”, 1, False)
content = ts.ReadAll

実はこの方法、ファイルの文字コードを自動判別してくれないという致命的な弱点があります。Shift-JISのつもりでUTF-8のファイルを読むと、日本語が完全に崩壊して謎の記号の羅列になってしまいます。BOM(Byte Order Mark)の有無でも挙動が変わるため、現場のエンジニア泣かせのバグの温床になるのです。

そこで登場するのが、データベース接続などで使われるコンポーネント `ADODB.Stream` です。これを「ファイル読み込みの魔術師」として使いこなせるようになりましょう。

解決の鍵:`ADODB.Stream` による文字コード自動判定のメカニズム

`ADODB.Stream` オブジェクトを使うと、バイナリデータとしてファイルを一度メモリ上に読み込み、文字コードを指定してテキストに変換(デコード)することができます。

しかし、「どの文字コードで保存されているか分からないファイル」をどうやって読めばいいのでしょうか?
答えはシンプルです。「まずUTF-8として読んでみて、ダメなら(あるいは文字化けチェックをして)Shift-JISで読み直す」、あるいは「ファイルの先頭バイト(BOMなど)を覗き見る」というアプローチをとります。

今回は、実務で最も確実な「UTF-8(BOM付き/なし)の判定トライアル + 失敗時はShift-JISにフォールバック(切り替え)」を行う堅牢なロジックを構築します。

実践!文字コード自動判別・統一パース モジュール

それでは、開発現場でそのままコピー&ペーストして使える実用スクリプトを公開します。
指定したフォルダ内にある `.log` ファイルをすべて走査し、文字コードを自動判別して、すべてキレイなUnicode(UTF-16)のひとつのテキストにまとめて出力するプロ仕様のコードです。

‘ =====================================================================
‘ ログ自動判別・統合スクリプト (LogUnifier.vbs)
‘ 概要: Shift-JISとUTF-8が混在するログを自動判別し、Unicodeに統一して出力
‘ =====================================================================
Option Explicit

Dim fso, targetFolder, outputFile, file, stream
Dim outputStream, lineText

‘ 1. オブジェクトの準備
Set fso = CreateObject(“Scripting.FileSystemObject”)
targetFolder = fso.GetParentFolderName(WScript.ScriptFullName) ‘ スクリプトと同じフォルダ
outputFile = targetFolder & “\Unified_Log_Result.txt”

‘ 出力用ストリームの作成 (UTF-16LEで書き出すことで文字化けを完全に防止)
Set outputStream = CreateObject(“ADODB.Stream”)
outputStream.Type = 2 ‘ 1:Binary, 2:Text
outputStream.Charset = “unicode”
outputStream.Open

WScript.Echo “ログの統合処理を開始します…”

‘ 2. フォルダ内のファイルをループ処理
For Each file in fso.GetFolder(targetFolder).Files
‘ 拡張子が .log のファイルのみを対象にする
If LCase(fso.GetExtensionName(file.Name)) = “log” Then

WScript.Echo “処理中: ” & file.Name

‘ ログファイルをテキストとして安全に読み込む関数を呼び出し
lineText = ReadTextFileWithAutoDetect(file.Path)

‘ 統合結果ファイルに書き込み(ファイル名ヘッダー付き)
outputStream.WriteText “— FILE START: ” & file.Name & ” —” & vbCrLf
outputStream.WriteText lineText & vbCrLf
outputStream.WriteText “— FILE END —” & vbCrLf & vbCrLf

End If
Next

‘ 3. 結果を保存してクリーンアップ
outputStream.SaveToFile outputFile, 2 ‘ 2:上書き保存
outputStream.Close
Set outputStream = Nothing
Set fso = Nothing

WScript.Echo “処理が完了しました!出力先: ” & outputFile

‘ =====================================================================
‘ 関数: ADODB.Streamを用いた文字コード自動判定・読み込みロジック
‘ =====================================================================
Function ReadTextFileWithAutoDetect(filePath)
Dim stream
Set stream = CreateObject(“ADODB.Stream”)

‘ ステップ1: まずは「UTF-8」として読み込みを試みる
stream.Type = 2 ‘ Textモード
stream.Mode = 3 ‘ 読み書きモード
stream.Charset = “utf-8”

On Error Resume Next
stream.Open
stream.LoadFromFile filePath

If Err.Number <> 0 Then
‘ ファイルが開けない等の致命的エラー
ReadTextFileWithAutoDetect = “[エラー: ファイルを開けませんでした]”
stream.Close
Set stream = Nothing
Exit Function
End If
On Error Goto 0

Dim textContent
textContent = stream.ReadText(-1) ‘ 全データ読み込み
stream.Close

‘ ステップ2: UTF-8特有の文字化け(不正なバイトシーケンス等)の簡易チェック
‘ もし文字化けの兆候(Replacement Character ” が大量発生など)があればShift-JISとみなす
‘ ※実務ではBOMの有無や特定の例外トラップで判定を最適化します
If InStr(textContent, “”) > 0 Then
‘ UTF-8でデコードして化けたということは、Shift-JISの可能性が高い!
Set stream = CreateObject(“ADODB.Stream”)
stream.Type = 2
stream.Mode = 3
stream.Charset = “shift_jis” ‘ 日本語Shift-JISを指定

stream.Open
stream.LoadFromFile filePath
textContent = stream.ReadText(-1)
stream.Close
End If

Set stream = Nothing
ReadTextFileWithAutoDetect = textContent
End Function

コードのここがポイント!エンジニアの知見

1. `ADODB.Stream.Charset = “unicode”` の威力
最終的な出力ファイルに `unicode`(UTF-16LE)を指定している点がミソです。これにより、世界中のどんな特殊文字や日本語が混ざっていても、絶対に文字化けしない最強の受け皿が完成します。
2. フォールバック(二段構え)の思想
プログラムは「こうであるはずだ」と決めつけると必ず破綻します。「まずはUTF-8で読んでみて、ダメならShift-JISに切り替える」というフェイルセーフ(安全装置)の考え方が、現場で生き残るタフなコードの秘訣です。
3. オブジェクトの確実な解放
VBScriptでは、ループ内で何度も `CreateObject` を行うとメモリリーク(メモリのゴミが溜まる現象)を引き起こすリスクがあります。今回は関数内で適切に `Close` と `Set … = Nothing` を行い、リソースを完全に管理しています。

陥りやすいエラーと対策

  • エラー「ファイルが見つかりません」または「プロセスはファイルにアクセスできません」
  • 原因: 対象のログファイルを別のアプリケーション(エディタや監視ツールなど)が開いたままにしている場合、VBScriptから排他制御でアクセスできずエラーになります。
  • 対策: ログ集計を行う際は、必ずログ出力が停止している時間帯(バッチ実行時間など)に走査するか、ファイルを別フォルダにコピーしてから処理するようにしてください。

まとめ

いかがでしたでしょうか?
今回は、VBScriptと `ADODB.Stream` を組み合わせて、文字コードの異なるログファイルを華麗に料理する方法を解説しました。

「たかがVBScript、されどVBScript」。
こうしたOS標準のコンポーネントの奥深くまで理解して使いこなせるようになると、専用のツールがないサーバー環境や緊急時のデータ処理において、あなたはチームの「救世主」になれます。

ここをクリアしたあなたなら、もうVBScriptの基礎はバッチリです!
日々の面倒な手作業をコードで自動化し、エンジニアとしてのスマートな時間を手に入れてくださいね。それでは、次のステップでお会いしましょう!

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