【入門編】【上級プロフェッショナル向け】FSO一括削除・更新操作の直前に全変更対象の事前シミュレーション(Dry-Run)を行う安全機構 – VBScript (Visual Basic Scripting Edition)解析バイブル

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

「消してしまった」をゼロにする。VBScriptにおける最強の護身術:FSO Dry-Run(シミュレーション)の実装術

こんにちは。自動化の深淵へようこそ。

マクロの記録機能を使って「あ、これ便利だな」と感動したことはありませんか? それは素晴らしい第一歩です。でも、もしあなたが「大量のファイルを、特定の条件で一括削除する」というコードを書こうとしているなら、一度立ち止まって、私の目を見てください。

「そのコード、実行する前に『何が起きるか』を予見できていますか?」

プロの現場では、コードの正しさと同じくらい、あるいはそれ以上に「壊さないこと(安全性)」が重視されます。一度実行してしまった `FSO.DeleteFile`(ファイル削除)は、ゴミ箱を経由せずに消え去ることがあります。取り返しがつかない事態を防ぐための、エンジニアの魂とも言える設計思想……それが今回お伝えする「Dry-Run(ドライラン/空回し)」です。

今日は、FileSystemObject(FSO)を使いこなしながら、安全に、そしてスマートにファイルを操作する「プロの設計図」を一緒に学んでいきましょう。

1. なぜ「いきなり実行」はプロ失格なのか?

初心者のうちは、つい「動けばいい」と考えてしまいがちです。
「特定の拡張子のファイルを全部消す」というプログラムを書いたとしましょう。

' 【危険な例】もし条件が間違っていたら、大切なシステムファイルまで消してしまう!
Set fso = CreateObject("Scripting.FileSystemObject")
fso.DeleteFile "C:\Work\*.tmp"

もし、`*.tmp` と書くつもりが、誤って `*.*` と書いてしまったら? あるいは、対象フォルダのパスを間違えて `C:\Windows` を指定してしまったら?

プログラムは一瞬の隙も与えず、あなたの指示通りに、冷酷に、すべてを破壊します。

Dry-Run(シミュレーション)とは

Dry-Runとは、「実際には書き換えや削除を行わず、動作の結果だけをログに書き出す」という手法です。
「もし実行したら、これとこれが消える予定ですよ」というプレビューを見せることで、人間が最終確認を行うプロセスを挟みます。これが、現場で事故を起こさないための「安全機構」です。

2. 仕組みの設計図:3つのステップ

高度な自動化スクリプトは、以下の3つのフェーズを分離して設計します。

1. 探索フェーズ (Scan Phase):
対象となるファイルやフォルダを、条件に合致するものだけ探し出し、リストアップする。
2. 報告フェーズ (Report Phase):
リストアップした内容を、コンソールやログファイルに「プレビュー」として出力する。
3. 実行フェーズ (Execution Phase):
(ここが重要!) ユーザーの「本当に実行していいですか?」という承諾を得てから、初めて実際の操作を行う。

これらを一つの関数にまとめ、`isDryRun` という「スイッチ(真偽値)」で制御するのがプロの書き方です。

3. 実践:安全な一括削除スクリプトのテンプレート

さあ、実際にコードを書いていきましょう。今回は「特定の拡張子を持つファイルを、サブフォルダまで含めて探して削除する」というシナリオで、Dry-Run機能を実装します。

' ==========================================================================
' Script Name: SafeFileCleaner.vbs
' Description: Dry-Run機能を備えた、安全なファイル一括削除スクリプト
' ==========================================================================

Option Explicit

' --- 設定エリア ---
Dim TARGET_DIR, TARGET_EXT, IS_DRY_RUN
TARGET_DIR = "C:\TestFolder"  ' 操作対象のルートフォルダ
TARGET_EXT = ".tmp"           ' 削除対象の拡張子
IS_DRY_RUN = True             ' 【重要】Trueならシミュレーション、Falseなら本番実行

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

Sub Main()
    Dim fso, targetFolder
    Set fso = CreateObject("Scripting.FileSystemObject")

    ' 1. フォルダの存在チェック(これ、基本中の基本です!)
    If Not fso.FolderExists(TARGET_DIR) Then
        WScript.Echo "エラー: 指定されたフォルダが見つかりません: " & TARGET_DIR
        WScript.Quit
    End If

    WScript.Echo "--- 処理を開始します ---"
    If IS_DRY_RUN Then
        WScript.Echo "[MODE] シミュレーションモード (実際には削除しません)"
    Else
        WScript.Echo "[MODE] 本番実行モード (!!! 警告: 実際に削除します !!!)"
    End If
    WScript.Echo "---------------------------------------"

    ' 2. 再帰的な探索と処理の開始
    Set targetFolder = fso.GetFolder(TARGET_DIR)
    ProcessFolder targetFolder, fso

    WScript.Echo "---------------------------------------"
    WScript.Echo "処理が完了しました。"
End Sub

' --- フォルダを再帰的に探索するサブルーチン ---
Sub ProcessFolder(objFolder, fso)
    Dim objFile, objSubFolder
    
    ' A. フォルダ内のファイルをチェック
    For Each objFile In objFolder.Files
        ' 条件判定: 拡張子が一致するか?
        If LCase(fso.GetExtensionName(objFile.Name)) = LCase(Replace(TARGET_EXT, ".", "")) Then
            
            ' 実行(またはシミュレーション)の分岐
            If IS_DRY_RUN Then
                ' 【Dry-Run】ログに出力するだけ
                WScript.Echo "[PREVIEW] 削除対象: " & objFile.Path
            Else
                ' 【本番】実際に削除を実行
                On Error Resume Next ' ファイルが使用中の場合などのエラー対策
                objFile.Delete True
                If Err.Number <> 0 Then
                    WScript.Echo "[ERROR] 削除失敗: " & objFile.Name & " (理由: " & Err.Description & ")"
                    Err.Clear
                Else
                    WScript.Echo "[SUCCESS] 削除完了: " & objFile.Path
                End If
                On Error GoTo 0
            End If
            
        End If
    Next

    ' B. サブフォルダを再帰的に探索(ここがプロのテクニック:再帰処理)
    For Each objSubFolder In objFolder.SubFolders
        ProcessFolder objSubFolder, fso
    Next
End Sub

4. コードの徹底解説:ここが「プロ」の分かれ目

このコードには、単なる「マクロの記録」には現れない、重要な設計思想が詰まっています。

① 再帰処理 (Recursion)

`ProcessFolder` 関数の中で、自分自身である `ProcessFolder` を呼び出していますよね? これを再帰処理と呼びます。
これを使うことで、「フォルダの中にフォルダがあり、その中にまたフォルダがある……」という複雑な階層構造を、どんなに深くても一気に、かつシンプルに探索できるのです。

② `On Error Resume Next` の戦略的運用

ファイル操作において、エラーは避けて通れません。「別のプログラムがそのファイルを開いている(使用中)」といった理由で、削除に失敗することがよくあります。
プロは、エラーでプログラムを強制終了させるのではなく、`On Error Resume Next` を使ってエラーを一時的に受け流し、「どのファイルが失敗したか」をログに残しつつ、処理を最後まで完遂させる設計にします。

③ `LCase` による大文字・小文字の吸収

Windowsでは拡張子の大文字・小文字(`.TMP` と `.tmp`)を区別しないことが多いですが、プログラム上では厳密に区別されることがあります。`LCase` 関数を使ってすべて小文字に揃えて比較することで、こうした「表記ゆれによる漏れ」を防いでいます。

5. 陥りやすいエラーと回避策

最後に、あなたが現場で直面するであろう「壁」を教えておきましょう。

  • 「アクセスが拒否されました」エラー
  • 原因: 管理者権限が必要なフォルダや、読み取り専用のファイルに対して操作を行おうとした場合に発生します。
  • 対策: スクリプトを「管理者として実行」するか、対象範囲をユーザー権限のあるフォルダに限定してください。
  • 「ファイルが使用中です」エラー
  • 原因: Excelやメモ帳などでそのファイルを開いている状態です。
  • 対策: 上記のコードのように、エラーハンドリングを組み込み、「失敗したファイルだけスキップして次に進む」作りが鉄則です。
  • 無限ループの恐怖
  • 原因: 再帰処理の条件が不適切だと、プログラムが止まらなくなります。
  • 対策: 今回のように「フォルダ内のサブフォルダを順に辿る」という明確な終了条件(フォルダがなくなったら終わる)を意識しましょう。

結びに:道具を「制御」する楽しさ

いかがでしたか?
単に「ファイルを消す」という動作に、「シミュレーション」という安全装置を加えるだけで、コードの信頼性は劇的に向上します。

自動化エンジニアの仕事は、コードを短く書くことではありません。「予測可能な、信頼される仕組みを作ること」です。

ここをクリアすれば、VBScriptの基本はバッチリですよ。自信を持って、次のステップへ進んでください。応援しています!

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