レガシーの深淵:FSOで挑む「鉄壁のCSVバリデーター」構築術
VBScript。この枯れた技術を「古い」と切り捨てる者は、システムの真の保守性というものを理解していない。膨大なレガシー資産が稼働するWindows環境において、余計なランタイムを要求せず、OS標準のシェル環境で完結するこの言語は、依然として最強の「ラスト・リゾート」だ。
本稿では、ファイルシステムオブジェクト(FSO)を極限まで使い倒し、データ取り込みの「関所」となるバリデーターを構築する。泥臭いパース処理を、アーキテクトの視点からいかに堅牢に実装するか。その極意を伝授する。
—
1. FSOの「作法」を再定義する
FSOは便利だが、無造作に扱えばメモリリークとI/Oボトルネックの温床となる。大量のCSVを処理する際、最も避けなければならないのは「大きなファイルを一気にメモリへ展開すること」だ。
我々は`OpenTextFile`によるストリーム読み込みを選択する。1行ずつメモリにロードし、即座に評価し、破棄する。このサイクルこそが、メモリ消費を最小化する唯一の道である。
オブジェクトのライフサイクル管理
VBScriptには自動GC(ガベージコレクション)があるが、COMオブジェクトの解放を言語に委ねるのは甘えだ。`Set obj = Nothing` を明示的に呼び出し、参照カウントを即座にゼロに近づける。これが、数万行のログ処理でもフリーズさせないための鉄則だ。
—
2. 実装:堅牢なデータクレンジングエンジン
以下のスクリプトは、単なるパースツールではない。列数検証と型チェックを通過しない行を即座に「隔離」する、システム連携の要となるモジュールだ。
Option Explicit
‘ ———————————————————
‘ CSVバリデーター・コアエンジン
‘ ———————————————————
Const ForReading = 1, ForWriting = 2
Dim fso, tsInput, tsError, strLine, arrCols
Dim lineNum, errorCount
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 入力ファイルとエラーログの定義
Set tsInput = fso.OpenTextFile(“data_import.csv”, ForReading)
Set tsError = fso.OpenTextFile(“error_log.csv”, ForWriting, True)
lineNum = 0
errorCount = 0
Do Until tsInput.AtEndOfStream
lineNum = lineNum + 1
strLine = tsInput.ReadLine
‘ Splitで配列化し、列数チェック
arrCols = Split(strLine, “,”)
‘ 【検証ロジック】列数が4でない場合は異常とみなす
If UBound(arrCols) <> 3 Then
WriteError lineNum, “列数不整合”, strLine
Else
‘ 【型チェック】第3列が数値であることを保証する
If Not IsNumeric(Trim(arrCols(2))) Then
WriteError lineNum, “数値変換エラー”, strLine
End If
End If
Loop
‘ クリーンアップ:リソースを確実に解放する
tsInput.Close
tsError.Close
Set tsInput = Nothing
Set tsError = Nothing
Set fso = Nothing
WScript.Echo “処理完了:エラー件数 ” & errorCount
Sub WriteError(row, reason, content)
tsError.WriteLine “Row ” & row & ” [” & reason & “]: ” & content
errorCount = errorCount + 1
End Sub
—
3. シニアエンジニアが意識すべき「隠れた地雷」
文字コードの罠
`OpenTextFile`メソッドの第4引数(`Tristate`)を軽視してはならない。デフォルトの`-2`(システムデフォルト)は、UTF-8ファイルを読み込む際に文字化けを引き起こすことがある。必要に応じて`ADODB.Stream`オブジェクトへの切り替えを検討すべきだ。FSOが対応できない高機能なエンコーディングが必要な場合は、迷わずAPIレベルの調整を行う。
Split関数の限界
`Split`関数は、ダブルクォーテーションで囲まれたカンマ(例:`”Tokyo, Japan”`)を無視できない。もしCSVの仕様がRFC 4180に準拠した複雑なものであるなら、正規表現(`VBScript.RegExp`)を併用し、トークナイザーを自作する覚悟が必要だ。
パフォーマンスの最適化
もしこのツールで数ギガバイトのファイルを扱うなら、`WScript.Echo`でいちいち標準出力へ書き出すのはやめるべきだ。I/O操作はプログラム実行における最大のコストである。バッファリングを行い、一定行数ごとにまとめて書き出す手法が、OSのオーバーヘッドを抑える鍵となる。
—
結論:コードは「対話」である
ここで示したコードはあくまで骨子だ。現場では、さらに「ヘッダー行のスキップ処理」「異常検知時の再試行回数」「ログのローテーション」といった実装が求められるだろう。
VBScriptは古い。しかし、そのシンプルさゆえに、実装者の「論理的思考の純度」がそのままコードの品質に直結する。泥臭いデータ処理こそ、システムの信頼性を支える最前線である。このツールが、あなたの現場の安定運用に寄与することを確信している。
さあ、コードを書き換え、現場のノイズを消し去る準備を始めよう。
