【入門編】【実務中級者向け】ネットワーク共有フォルダの接続切れをFSOで検知しローカル代替フォルダへ自動退避するフォールバック処理 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク
スポンサーリンク

【実務の極意】ネットワーク断絶を恐れないVBScript:FSOによる自動フォールバック実装術

こんにちは。現場の自動化設計を統括しているアーキテクトです。

皆さんは、これまで「完璧に動くスクリプト」を書いてきたことでしょう。しかし、実務の世界はそんなに甘くありません。
「昨日まで動いていたのに、なぜか今日はエラーで止まってしまう……」
その原因の多くは、プログラムのロジックミスではなく、「外部環境の変化」にあります。

特に、ネットワーク共有フォルダ(UNCパス)への書き込み処理は、もっともトラブルが起きやすい領域の一つです。ネットワークの瞬断、サーバーのメンテナンス、あるいはVPNの切断。これらが起きた瞬間、あなたのスクリプトは無慈悲なエラーを吐いて停止してしまいます。

今日は、そんな「環境の不安定さ」をあらかじめ計算に入れ、「もしネットワークが死んでいたら、ローカルに逃がす」という、プロの現場で必須となるフォールバック(代替処理)の技術を伝授します。

ここをマスターすれば、あなたのスクリプトは「ただ動くもの」から「止まらない、信頼されるもの」へと進化しますよ。

1. なぜ「ネットワーク接続」はエラーの温床なのか?

まず、なぜ単純なファイル操作でエラーが起きるのか、その本質を理解しましょう。

通常のローカルファイル操作(`C:\Temp` など)は、OSが即座にレスポンスを返します。しかし、ネットワーク越し(`\\Server\Share`)の操作は、以下のプロセスを辿ります。

1. 名前解決: サーバーの名前をIPアドレスに変換する
2. 認証: 接続権限があるか確認する
3. 通信: データのパケットをやり取りする

このプロセスのどこか一つでも、ネットワークの揺らぎによって遅延したり失敗したりすると、VBScriptは「ファイルが見つかりません」や「パスが見つかりません」というエラーを発生させます。

「エラーが起きてから対処する」のではなく、「エラーが起きそうな状況を検知して、事前にルートを切り替える」。これがアーキテクトの思考法です。

2. 実装の鍵:FileSystemObject (FSO) とエラーハンドリング

今回使用する主役は、`FileSystemObject` (FSO) です。
FSOには、フォルダやファイルが存在するかを判定する `FolderExists` メソッドがありますが、実はこれだけでは不十分な場合があります。

なぜなら、ネットワークが「完全に切断されている」のではなく、「応答が極端に遅い(タイムアウト寸前)」場合、判定自体に時間がかかり、スクリプト全体のパフォーマンスを著しく低下させることがあるからです。

そこで、以下のステップで実装します。

1. FSOオブジェクトの生成
2. ネットワークパスの生存確認
3. 生存していれば「ネットワークパス」を、死んでいれば「ローカルパス」を、出力先として採用する

3. 【実践】フォールバック機能付き自動退避スクリプト

それでは、そのまま業務で参考にできるレベルのコードを見ていきましょう。
このスクリプトは、指定したネットワークフォルダが使えない場合、自動的にローカルの `C:\Temp\Fallback` にファイルを保存する仕組みになっています。

' **
' スクリプト名: RobustFileSystemHandler.vbs
' 概要: ネットワーク接続を検知し、切断時はローカルへ自動退避するフォールバック処理
' 作成者: 伝説のチーフアーキテクト
' **

Option Explicit ' 変数の宣言を強制(バグ防止の鉄則!)

' --- 設定エリア ---
Dim strNetworkPath, strLocalFallbackPath, strTargetFileName
strNetworkPath      = "\\Server01\SharedData\Output" ' 本来の保存先(UNCパス)
strLocalFallbackPath = "C:\Temp\Fallback_Output"    ' ネットワーク切断時の退避先
strTargetFileName    = "Report_" & Year(Date) & Month(Date) & Day(Date) & ".txt"

' --- メイン処理 ---
Main

Sub Main()
    Dim objFSO, strFinalDestination, objFile
    
    ' FileSystemObjectのインスタンス化
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    ' 1. 出力先の決定(ここがフォールバックの肝!)
    strFinalDestination = GetAvailablePath(objFSO, strNetworkPath, strLocalFallbackPath)
    
    ' 2. 退避先フォルダが存在しない場合に備えて作成
    If Not objFSO.FolderExists(strFinalDestination) Then
        On Error Resume Next
        objFSO.CreateFolder(strFinalDestination)
        If Err.Number <> 0 Then
            MsgBox "致命的なエラー: 退避先フォルダすら作成できませんでした。" & vbCrLf & Err.Description, 16, "Error"
            Exit Sub
        End If
        On Error GoTo 0
    End If

    ' 3. ファイルの作成と書き込み
    On Error Resume Next ' 書き込み時のエラーを捕捉
    Set objFile = objFSO.CreateTextFile(strFinalDestination & "\" & strTargetFileName, True)
    
    If Err.Number <> 0 Then
        MsgBox "ファイル作成に失敗しました。権限を確認してください。" & vbCrLf & Err.Description, 16, "Error"
    Else
        objFile.WriteLine "【実行ログ】"
        objFile.WriteLine "実行日時: " & Now()
        objFile.WriteLine "保存先: " & strFinalDestination
        objFile.WriteLine "ステータス: 正常に処理されました。"
        objFile.Close
        
        MsgBox "処理が完了しました。" & vbCrLf & "保存先: " & strFinalDestination, 64, "Success"
    End If
    On Error GoTo 0

    ' オブジェクトの解放(メモリ管理の作法)
    Set objFile = Nothing
    Set objFSO = Nothing
End Sub

' **
' 関数名: GetAvailablePath
' 引数: objFSO (FileSystemObject), strRemote (ネットワークパス), strLocal (ローカルパス)
' 戻り値: 使用可能なパスを文字列で返す
' **
Function GetAvailablePath(objFSO, strRemote, strLocal)
    Dim strResult
    
    ' エラーハンドリングを有効化(ネットワーク断絶時のフリーズ防止)
    On Error Resume Next
    
    ' ネットワークフォルダが存在するかチェック
    If objFSO.FolderExists(strRemote) Then
        ' 接続確認に加え、実際にフォルダへの書き込み権限があるか軽くテストするのもプロの技
        ' ここではシンプルにFolderExistsの結果を採用
        strResult = strRemote
    Else
        ' ネットワークが死んでいる場合はローカルパスを返す
        strResult = strLocal
    End If
    
    ' エラーハンドリングを通常の状態に戻す
    If Err.Number <> 0 Then
        ' 判定中にエラーが出た場合も、安全のためにローカルを返す
        strResult = strLocal
        Err.Clear
    End If
    On Error GoTo 0
    
    GetAvailablePath = strResult
End Function

4. コードの深層解説:プロの視点

このコードには、初学者が陥りがちな罠を回避するための「設計思想」が組み込まれています。

① `Option Explicit` の重要性

冒頭に書いたこの一行。これは「すべての変数を必ず宣言せよ」という命令です。VBScriptは宣言なしでも動いてしまいますが、それは「タイポ(打ち間違い)によるバグ」を隠蔽してしまう諸刃の剣です。プロは必ずこれを書きます。

② `GetAvailablePath` 関数によるカプセル化

「パスを決定するロジック」をメイン処理から切り離しました。これにより、メインの処理(ファイルの書き込み)は、「どこに保存するか」という複雑な事情を気にせず、「渡されたパスに書くだけ」という単純な責務に集中できます。これが「関数の責務の分離」です。

③ `On Error Resume Next` の適切な使い方

ここが最も重要です。`On Error Resume Next` は「エラーを無視して進め」という強力な命令ですが、使いどころを間違えると、どこでエラーが起きたか分からなくなります。
今回のコードでは、

  • ネットワークの生存確認(エラーが起きやすい場所)
  • ファイルの作成(権限エラーが起きやすい場所)

という、「エラーが起きることを前提とした箇所」に限定して適用しています。

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

`Set objFSO = Nothing`。
VBScriptはメモリ管理を自動で行ってくれますが、大規模なシステムや、長時間稼働するスクリプトでは、明示的にオブジェクトを解放する習慣をつけておきましょう。これは「リソースを使い果たさない」というエンジニアとしてのマナーです。

5. まとめ:次のステップへ

今回の「フォールバック処理」を実装することで、あなたのスクリプトは単なる「自動化ツール」から、「業務に耐えうるソフトウェア」へと昇格しました。

今回のポイント:

  • ネットワークは常に不安定であると仮定せよ。
  • `FolderExists` だけでなく、エラーハンドリングを組み合わせて判断せよ。
  • 「もしもの時の逃げ道(ローカルパス)」を必ず用意せよ。

ここをクリアすれば、VBScriptの基本はバッチリですよ。
次は、ログファイルにエラー内容を書き出す「ロギング機能」の実装に挑戦してみてください。

困難なエラーに直面しても、落ち着いてロジックを分解すれば必ず解決できます。応援していますよ!

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