【実務・中級編】【監視ループ】特定フォルダへのファイル配置をポーリング監視し、検出時に自動処理を起動するスクリプト – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptで「ホットフォルダ」を構築せよ:監視ループの極意と堅牢な設計論

業務自動化の現場において、WScript(VBScript)は今なお強力な武器だ。しかし、多くのエンジニアが「なんとなく動く」コードを書き、結果としてメモリリークやプロセス肥大化といった技術的負債を抱え込んでいる。

今日は、ファイル監視という「シンプルだが地雷の多い」タスクを、プロの現場で通用するレベルで実装するための知見を共有する。

—

1. なぜ「雑なポーリング」は破綻するのか

初心者が書く監視ループの典型例はこれだ。

‘ 悪い例:リソースを食いつぶす設計
Do
If fso.GetFolder(path).Files.Count > 0 Then
‘ 処理…
End If
WScript.Sleep 1000
Loop

このコードの問題点は明白だ。
1. 排他制御の欠如: ファイルがコピー中(書き込み中)であっても検出してしまい、アクセス拒否エラー(Permission Denied)を招く。
2. 状態管理の不備: 処理済みファイルをどう扱うかのロジックがないため、無限に同じファイルを処理し続ける。
3. リソースの浪費: `FSO`オブジェクトをループ内で再生成すればメモリを圧迫し、ガベージコレクションの挙動を不安定にする。

—

2. プロダクション仕様:堅牢な監視スクリプト

以下のコードは、単に動くだけでなく、「書き込み中のファイルを掴まない」「多重起動を防止する」「エラーハンドリングを完備する」という3つの鉄則を実装している。

Option Explicit

‘ — 設定エリア —
Const WATCH_FOLDER = “C:\Input”
Const PROCESSED_FOLDER = “C:\Archive”
Const SLEEP_TIME = 2000 ‘ 2秒間隔

Dim fso, folder, file
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ メインループ
Do
On Error Resume Next ‘ 予期せぬIOエラーでプロセスを止めない
Set folder = fso.GetFolder(WATCH_FOLDER)

If folder.Files.Count > 0 Then
For Each file In folder.Files
‘ 重要:ファイルが書き込み中ではないか確認(排他チェック)
If IsFileAvailable(file.Path) Then
Call ProcessFile(file)
End If
Next
End If
On Error GoTo 0

WScript.Sleep SLEEP_TIME
Loop

‘ — 実務用ロジック —
Function IsFileAvailable(filePath)
Dim f
On Error Resume Next
Set f = fso.OpenTextFile(filePath, 8, False) ‘ 追記モードで開けるかテスト
If Err.Number = 0 Then
f.Close
IsFileAvailable = True
Else
IsFileAvailable = False
End If
On Error GoTo 0
End Function

Sub ProcessFile(file)
‘ ここに業務処理を記述
WScript.Echo “処理開始: ” & file.Name

‘ 処理後、アーカイブへ移動(または削除)
file.Move PROCESSED_FOLDER & “\” & file.Name
End Sub

—

3. 設計の勘所:ここを見落とすな

① 排他制御の「擬似実装」

Windowsにおいてファイルがロックされているかを確認する最も確実な方法は、実際に`OpenTextFile`で開いてみることだ。エラーが発生すれば「誰かが書き込み中」と判断できる。APIを呼び出すまでもなく、この「開けるか試す」というロジックだけで、大半のI/Oエラーを回避できる。

② オブジェクトのライフサイクル管理

`Set fso = CreateObject(…)` をループの外に出すこと。ループ内で生成し続けると、メモリ上に無数のオブジェクト参照が残り、数日稼働させただけでスクリプトホスト(wscript.exe)のメモリ消費量が跳ね上がる。オブジェクトは一度生成し、使い回すのが鉄則だ。

③ データベース連携時の注意

もし処理後にDBへ書き込む場合、`ADODB.Connection`の接続情報はループの外で保持すべきではない。ネットワークの瞬断でコネクションが切れた際、ループ内で再接続(Re-connect)処理を挟む必要がある。さもなくば、翌朝には「DBエラーで全滅」という悲劇が待っている。

—

最後に:自動化の真髄

「ファイルがあるか確認する」という単純なタスクほど、エンジニアの質が出る。
エラーハンドリングを怠り、再起動が必要な不安定なツールを作るのは、自動化エンジニアとしては失格だ。

今回提示したコードは、あくまでテンプレートだ。ここから先、「処理に失敗したファイルをどう隔離するか」「ログをどう出力するか」という要件を積み上げ、自分自身のライブラリを育て上げてほしい。

VBScriptは古いが、そのシンプルさは依然として「高速な自動化」に最適なツールだ。使いこなせば、あなたの生産性は別次元へ昇華する。健闘を祈る。

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