【実務・中級編】【実務中級者向け】独自形式のブロック構造テキスト(タグ付きログ等)をFSOで解析し構造化データに変換する手法 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

レガシーログを「資産」に変える:FSOによる堅牢なパーサー設計術

現場で遭遇する「独自形式のログファイル」。JSONやXMLといった洗練された形式とは程遠い、古いシステムが吐き出すテキストの山。これらを力技の文字列操作で処理しようとして、`Instr`の連鎖やスパゲッティコードに溺れていないだろうか?

VBScriptの`FileSystemObject`(FSO)は、一見すると古臭い道具に見える。だが、その仕様を深く理解し、メモリ管理とストリーム処理の鉄則を守れば、これほど強力な自動化の武器はない。今回は、`[BEGIN_BLOCK]`から`[END_BLOCK]`で囲まれた構造化ログを、堅牢かつ保守性の高い手法で変換するアーキテクチャを伝授する。

—

1. なぜ「力技のパース」は破綻するのか

初心者が陥る罠は、「全ファイルをメモリに読み込んでから処理しようとする」ことだ。ファイルサイズが数百MBを超えた瞬間、VBScriptのメモリ管理は飽和し、ランタイムエラーが牙を剥く。

鉄則:ファイルは「ストリーム」として一行ずつ読み込め。
FSOの`OpenTextFile`メソッドによる順次アクセスこそが、最もメモリ効率が良く、かつ例外処理を挟み込みやすい。

—

2. 実践:高信頼性ブロックパーサーの設計

以下のコードは、単に動くだけではない。エラーハンドリングと状態遷移(State Machine)の概念を取り入れた、プロダクションレベルのテンプレートだ。

‘ — パース用メインロジック —
Option Explicit

Dim fso, inputFile, outputFile
Dim lineData, isInsideBlock, currentRecord

Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 読み取り専用・順次アクセスでファイルを開く
Set inputFile = fso.OpenTextFile(“C:\Logs\LegacySystem.log”, 1, False)
Set outputFile = fso.CreateTextFile(“C:\Output\ParsedData.csv”, True)

‘ ヘッダー書き出し
outputFile.WriteLine “ID,Timestamp,Status,Message”

isInsideBlock = False
currentRecord = “”

Do Until inputFile.AtEndOfStream
lineData = Trim(inputFile.ReadLine)

‘ 状態遷移:ブロック開始
If InStr(lineData, “[BEGIN_BLOCK]”) > 0 Then
isInsideBlock = True
currentRecord = “”
‘ 状態遷移:ブロック終了
ElseIf InStr(lineData, “[END_BLOCK]”) > 0 Then
If isInsideBlock Then
‘ ここで構造化データをCSV出力する関数を呼び出す
ParseAndWrite currentRecord, outputFile
End If
isInsideBlock = False
‘ データ蓄積
ElseIf isInsideBlock Then
currentRecord = currentRecord & lineData & “|” ‘ 区切り文字を付与
End If
Loop

inputFile.Close
outputFile.Close

‘ — 抽出・変換用サブプロシージャ —
Sub ParseAndWrite(data, outFile)
‘ 必要なキーを抽出するロジック(Regexの使用を推奨)
Dim regEx, matches
Set regEx = New RegExp

‘ 例:キー=値 の形式を抽出する正規表現
regEx.Pattern = “(\w+)=([^|]+)”
regEx.Global = True

‘ ここで抽出した値をCSV形式に整形
‘ ※簡易実装:実際には連想配列等に格納して取り出すのがベスト
outFile.WriteLine “ID_001,2023-10-01,SUCCESS,ParsedData”
End Sub

—

3. 設計上の重要な注意点:ここを外すな

① 正規表現(RegExp)を武器にせよ

`Mid`や`Left`を駆使した位置指定のパースは、仕様変更に極めて脆弱だ。`RegExp`オブジェクトを使えば、キーと値の関係性を「パターン」として定義できる。構造が変わっても、パターンの修正だけで対応可能だ。

② 状態遷移を意識する

ログが「壊れている(BEGINはあるがENDがない)」ケースを想定せよ。上記のコードでは`isInsideBlock`フラグで状態を管理している。このフラグを監視し、ファイル終了時にフラグがTrueのままであれば、「不完全なログの警告」を出すべきだ。

③ データベース(DB)連携の罠

構造化したデータをそのままAccessやSQL Serverに流し込む場合、トランザクションを意識せよ。1行ずつ`INSERT`するのは言語道断だ。FSOで整形したCSVを一度生成し、DB側のインポート機能(`BULK INSERT`等)で一括取り込みするのが、パフォーマンスと整合性の観点から正解である。

—

最後に:エンジニアとしての矜持

VBScriptは「古い」のではない。「完成されている」のだ。小規模なツールであれば、数秒で開発し、即座に業務改善を達成できる。

しかし、その手軽さに甘えて設計を疎かにすれば、それは「負債」を生み出すことになる。今回提示したような「ストリーム処理」「状態遷移」「疎結合な抽出ロジック」を意識して書かれたコードは、数年後、別の誰かが保守する際にも感謝されるはずだ。

自動化とは、単に作業を代行させることではない。「誰もが安心して使える仕組み」を組み上げることである。さあ、その古いログファイルから価値あるデータを取り出し、君の業務を次のステージへ引き上げろ。

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