VBScriptを掌握せよ:FSOを用いた「堅牢な」フォルダ監視ポーリングの極意
VBScriptは「古い」と切り捨てるのは簡単だ。だが、Windows環境において、余計なランタイムを一切必要とせず、メモ帳一つで即座に業務の自動化を実現できるこの言語のポテンシャルは、いまだに現場のエンジニアにとって最強の武器となり得る。
今日は、多くのエンジニアが陥る「安直なポーリング処理」の罠を回避し、実務で安心して運用できる「ファイル監視の最適解」を伝授する。
—
1. なぜ「ただループするだけ」ではいけないのか
初心者が書くコードの典型はこれだ。
「`Folder.Files` を取得し、ループして処理し、`WScript.Sleep` で待つ」。
これには致命的な設計ミスが3つある。
1. 競合リスク: ファイルが完全にコピー(転送)しきっていない瞬間に処理を開始し、アクセス拒否エラーやデータ破損を招く。
2. リソースの枯渇: インスタンス化の乱発により、メモリリークやOSへの負荷を増大させる。
3. 終了不可: 無限ループの脱出経路がなく、タスクマネージャーから強制終了するしかない「野良プロセス」を量産する。
実務に耐えうるコードとは、「処理中」と「未処理」を明確に分離し、例外を飼いならす設計のことを指す。
—
2. 堅牢な監視スクリプトのアーキテクチャ
今回の実装方針は以下の通りだ。
- 移動による排他制御: 新規ファイルを検知したら、直ちに「処理中フォルダ」へ移動させる。これにより、OSレベルでロックをかけ、二重処理を物理的に防ぐ。
- エラーハンドリング: `On Error Resume Next` を盾に、特定の瞬間的なエラーを握りつぶすのではなく、ログ出力とリトライ判定を行う。
実践:プロダクションコード(`monitor.vbs`)
Option Explicit
‘ 設定値
Const WATCH_FOLDER = “C:\Inbox”
Const WORK_FOLDER = “C:\Processing”
Const SLEEP_TIME = 5000 ‘ 5秒間隔
Dim fso, folder, file
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ メインループ
Do
Set folder = fso.GetFolder(WATCH_FOLDER)
For Each file In folder.Files
‘ 隠しファイルや一時ファイルを除外
If Left(file.Name, 1) <> “~” Then
On Error Resume Next
‘ ファイルを移動して排他権を確保
file.Move WORK_FOLDER & “\” & file.Name
If Err.Number = 0 Then
‘ 移動成功:ここで実際の処理を呼び出す
Call ProcessFile(WORK_FOLDER & “\” & file.Name)
Else
‘ 移動失敗:書き込み中等の理由。次回のループへパス
Err.Clear
End If
On Error GoTo 0
End If
Next
WScript.Sleep SLEEP_TIME
Loop
‘ 処理ロジック
Sub ProcessFile(filePath)
WScript.Echo “処理開始: ” & filePath
‘ ここにDB登録やAPI連携の処理を記述
‘ 完了後、ファイルをアーカイブするか削除する
fso.DeleteFile filePath
End Sub
—
3. 実務で「詰まらない」ための重要知見
ファイルの「書き込み中」を判定する
`fso.Move` が失敗する理由は、大抵「相手がまだそのファイルを握っているから」だ。このスクリプトでは、`Move` の戻り値がエラーになることを逆手に取り、「移動できたら処理する」という楽観的排他制御を採用している。これが最も堅牢だ。無理にAPIでロック状態を確認しようとしてはいけない。
データベース連携の鉄則
もしこのスクリプトがDBにデータを書き込むなら、接続状態を毎回確認せよ。
VBScriptの常駐プロセスは、DBのタイムアウトに非常に弱い。必ず処理の直前にコネクションを張り、処理後に確実に閉じる(`Connection.Close`)。もしコネクションプールが切れたら、スクリプト自体を再起動するような監視機構を上位(タスクスケジューラ等)で持たせるのがアーキテクトの知恵だ。
ログ出力は「標準出力」ではなく「ファイル」へ
`WScript.Echo` はコマンドプロンプトで実行しないと見えない。運用時は `cscript.exe //NOLOGO monitor.vbs > log.txt` として実行するか、FSOを使って直接テキストログに追記するように実装を切り替えておくこと。
—
最後に:エンジニアとしての矜持
VBScriptは枯れた技術だが、その分、挙動は予測可能だ。
「動けばいい」というコードと、「運用フェーズでトラブルを起こさない」コードの間には、この程度の設計思想の差がある。
君が書くスクリプトは、夜中に誰も見ていないところで、君の代わりに汗を流す部下のようなものだ。その部下に「なぜその処理をするのか」という明確な意図を持たせることが、真の自動化エンジニアへの第一歩となる。
さあ、このコードをベースに、君の現場の「非効率」を根絶してほしい。
