現場のエンジニアへ:UNCパスを支配せよ。FSOとネットワーク資源の「危うい関係」を断ち切る極意
業務自動化の現場で最も「泣きを見る」ポイントの一つが、ローカルディスクを離れ、UNCパス(`\\Server\Share`)へ直接アクセスする場面だ。
「なぜかスクリプトが止まる」「たまに権限エラーが出る」「ネットワークが不安定だとハングアップする」。これらは運が悪いのではない。ファイルシステムオブジェクト(FSO)という強力だが無防備なツールを、ネットワークの不確定性に対して無策で投げ込んでいるからだ。
今日は、ネットワーク越しにFSOを使い倒すための、プロフェッショナルな設計思想と実装パターンを伝授する。
—
1. UNCパスの「見えない壁」を突破する
FSOは優秀だが、ネットワーク資源に対しては極めて「直情的」だ。
特に、スクリプト実行ユーザーとネットワーク共有先の認証が一致しない場合、何の前触れもなく「Permission Denied(70)」を吐く。
鉄則:ネットワークパスは「存在確認」から始めろ
多くの初心者は、いきなり `FSO.GetFolder(path)` を叩く。これは禁じ手だ。存在しない、あるいはアクセス権がないパスに対してオブジェクトを生成しようとすれば、スクリプトは即座にクラッシュする。
‘ 悪手:いきなりオブジェクトに触れる
Set objFolder = FSO.GetFolder(“\\Server\Share\Data”)
これでは、ネットワークの一時的な瞬断や認証の揺らぎでスクリプトが死ぬ。まずは `FolderExists` メソッドで「物理的に叩ける状態か」を冷徹に確認するのが、堅牢なスクリプトの第一歩だ。
—
2. 実務現場で死なない「ネットワークチェック」実装例
以下は、UNCパスに対する堅牢なアクセスラッパーだ。単にパスを渡すのではなく、「接続を確認し、失敗した場合は明示的にエラーを握りつぶして通知する」という設計思想で書いている。
Option Explicit
‘ ネットワーク上のフォルダへ安全にアクセスする関数
Function GetSecureFolder(strPath)
Dim fso, objShell
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 1. 物理的な存在チェック
If Not fso.FolderExists(strPath) Then
‘ ここでエラーを投げず、ログを残して終了するか、接続リトライを促す
WScript.Echo “警告: 指定されたパスへ接続できません: ” & strPath
Set GetSecureFolder = Nothing
Exit Function
End If
‘ 2. オブジェクトの取得
On Error Resume Next
Set GetSecureFolder = fso.GetFolder(strPath)
If Err.Number <> 0 Then
WScript.Echo “致命的エラー: アクセス権限またはネットワークタイムアウト – ” & Err.Description
Set GetSecureFolder = Nothing
End If
On Error GoTo 0
End Function
‘ — 利用例 —
Dim targetFolder
Set targetFolder = GetSecureFolder(“\\RemoteServer\SharedFolder”)
If Not targetFolder Is Nothing Then
WScript.Echo “アクセス成功: ” & targetFolder.Path
‘ ここでファイル操作を行う
End If
—
3. なぜ「ドライブ割り当て」を避けるのか?
「UNCパスが不安定なら、`net use` でドライブレターを割り当てればいい」という意見がある。確かに一時的には安定する。しかし、以下の理由から私は推奨しない。
- 環境依存性: 実行するPCごとに、そのドライブレターが空いている保証がない。
- 競合のリスク: 別のバッチ処理が同じドライブレターを掴んでいれば、システム全体が破壊される。
- クリーンアップの負荷: スクリプト終了時に割り当てを解除する処理が失敗すれば、ゾンビ接続が溜まり続ける。
UNCパスで完結させることは、スクリプトの移植性と独立性を守るための「プロの矜持」だ。
—
4. ネットワーク遅延・切断への備え:パフォーマンスの真実
ネットワーク越しに数千のファイルをループ処理する場合、FSOの `Files` コレクションを安易にループさせてはならない。一度のネットワーク要求でメタデータを全て取得しようとするため、通信帯域を圧迫し、タイムアウトを引き起こす。
高度な設計手法:
1. 必要な情報だけをキャッシュする: ファイル名やサイズ、更新日時が必要な場合、一度に取得せず、配列に格納するなどの最適化を行う。
2. 小刻みなタイムアウト処理: 大規模なファイル操作が必要な場合、VBScript単体ではなく、PowerShellの `Get-ChildItem` を併用し、その結果をテキストで受け取る設計も検討すべきだ。
—
最後に:自動化の真髄
VBScriptは古いが、そのシンプルさは依然として最強のツールだ。しかし、ネットワークという「外部」と繋がる時、君たちの書くコードは単なる命令文ではなく、「ネットワークの荒波を渡る船舶」でなければならない。
- 存在を疑え(FolderExists)
- エラーを制御下に置け(On Error Resume Next)
- 痕跡を残すな(不要なドライブ割り当てを行わない)
この3つを守るだけで、君の作成する自動化ツールは「たまに止まるおもちゃ」から「現場を支える堅牢なインフラ」へと進化する。
次回の修正では、ぜひこのコードを組み込み、その安定性の違いを体感してほしい。質問があればいつでもどうぞ。君のコードが、今日もどこかの誰かの無駄な時間を削減していることを期待している。
