【テクニカル・上級編】【ログ記録強化】On Error Resume NextとErrオブジェクトを組み合わせたFSO操作エラーログ出力 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握せよ:FSOにおける堅牢なエラーハンドリングと「沈黙の死」の回避

VBScriptは、現代のモダンな言語群から見れば「化石」のように見えるかもしれない。しかし、Windows環境の深部で、管理者権限という特権を盾に、システムを制御し続けるその姿は、まさにレガシーシステムの「心臓」だ。

FSO(FileSystemObject)を用いたファイル操作において、稚拙なコーディングは即座にシステムを停止させる。特に、ネットワークドライブの切断や排他制御によるエラーを放置することは、運用現場における最大の罪だ。本稿では、`On Error Resume Next`の呪縛を解き、エラーを「資産」へと変える極限のログ戦略を伝授する。

—

1. エラーハンドリングの「設計思想」

VBScriptにはTry-Catchブロックが存在しない。我々が頼れるのは`On Error Resume Next`という、諸刃の剣だけだ。これを無計画に使うことは、エラーを隠蔽し、事後検証を不可能にする「沈黙の死」を招く。

シニアエンジニアとして守るべき鉄則はただ一つ。「発生したエラーを即座に捕捉し、Errオブジェクトのコンテキストを退避させ、直ちにエラー監視をリセットする」ことだ。

核心となる実装パターン

以下は、ファイル移動操作をカプセル化した、実戦配備可能な堅牢なテンプレートである。

‘ — 極限まで最適化したファイル移動処理 —
Function SafeFileMove(sourcePath, destPath)
Dim fso, errNum, errDesc
Set fso = CreateObject(“Scripting.FileSystemObject”)

On Error Resume Next ‘ 予期せぬIOエラーを捕捉するために一時的に有効化

fso.MoveFile sourcePath, destPath

‘ エラーが発生したか?
If Err.Number <> 0 Then
errNum = Err.Number
errDesc = Err.Description

‘ エラー情報をログ出力(後述)
WriteErrorLog “MoveFileError”, “Src:” & sourcePath & ” | Dst:” & destPath & ” | Err:” & errNum & ” | Desc:” & errDesc

‘ Errオブジェクトをクリアし、即座に監視を中断(非常に重要)
Err.Clear
SafeFileMove = False
Else
SafeFileMove = True
End If

On Error GoTo 0 ‘ エラーハンドリングをデフォルトに戻す

‘ オブジェクトの明示的破棄(GC任せにしない)
Set fso = Nothing
End Function

—

2. メモリ最適化とオブジェクトのライフサイクル

VBScriptのエンジンは、オブジェクトの参照カウンタがゼロにならない限り、メモリを解放しない。特に`FileSystemObject`をループ内で繰り返しインスタンス化することは、メモリリークの温床となり、長時間のバッチ処理では致命的なパフォーマンス低下を招く。

  • インスタンスの再利用: 可能であれば、クラスレベルあるいはグローバルスコープでインスタンスを一つ作成し、処理終了まで使い回す。
  • 明示的Nothing: 処理の終了後、あるいは大きなループの節目で`Set obj = Nothing`を徹底すること。これにより、レガシーなWindows Script Host(WSH)上でもメモリの断片化を抑制できる。

—

3. 「ログ」はシステム監査の命綱である

単に`WScript.Echo`で画面に吐き出すだけの運用は、自動化とは呼べない。システム管理者が真に求めるのは、「いつ、どこで、何が起き、どう対処すべきか」が記録されたタイムスタンプ付きの構造化ログだ。

Sub WriteErrorLog(category, message)
Dim fso, logFile, ts
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ ログファイルパス(環境変数を利用してセキュアに指定)
Dim logPath
logPath = “C:\Logs\System_Ops_” & DateDiff(“d”, “1970/01/01”, Date) & “.log”

‘ 追記モード(8)で開く。存在しない場合は作成(True)
Set logFile = fso.OpenTextFile(logPath, 8, True)

‘ タイムスタンプを付与した構造化ログ
logFile.WriteLine “[” & Now & “] [” & category & “] ” & message

logFile.Close
Set logFile = Nothing
Set fso = Nothing
End Sub

—

4. チーフアーキテクトからの提言

VBScriptは「古い」のではない。「完成されている」のだ。WindowsというOSのアーキテクチャそのものと深く結びついているため、APIの挙動を深く理解していれば、他の高級言語を凌駕するほど軽量かつ高速に動作する。

運用における極意

1. ネットワークパスの罠: UNCパス(`\\server\share\…`)を扱う際は、必ず事前に`fso.FolderExists`で疎通を確認せよ。これを怠ると、タイムアウト待ちでスクリプトが数分間フリーズする。
2. 排他制御の考慮: ファイル操作中に他のプロセスがロックしている場合、`Err.Number`は必ず`70`(Permission Denied)を返す。このエラーを検知した際、`WScript.Sleep`を用いてリトライを試みるロジックを組み込むのが、プロフェッショナルの矜持だ。

技術は手段に過ぎない。しかし、その手段を極限まで研ぎ澄ますことこそが、エンジニアとしての価値を決定づける。このコードをベースに、貴殿の環境で「落ちないスクリプト」を構築せよ。

健闘を祈る。

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