【VBAリファレンス】VBA100本ノック66本目攻略:FileSystemObjectで全サブフォルダを再帰的に探索する極意

スポンサーリンク

概要:VBAにおけるファイル探索の壁を突破する

VBA100本ノックの66本目として立ちはだかる「全サブフォルダから特定のファイルを探し出す」という課題は、多くの初級者が中級者へとステップアップする際の最初の大きな関門です。単に特定のフォルダ内のファイルを取得するだけであれば「Dir関数」で十分ですが、サブフォルダを無限に深く探索し、構造を問わずにファイルを見つけ出すには「再帰処理」というアルゴリズムの概念が不可欠になります。本稿では、VBA開発の現場で必須となるFileSystemObject(以下FSO)を用いた、堅牢で効率的なファイル探索手法を徹底的に解説します。

詳細解説:なぜDir関数ではなくFSOと再帰を使うのか

実務において、フォルダ構造は極めて複雑です。「フォルダAの中にフォルダBがあり、その中にさらにフォルダCがある」といった階層構造をDir関数だけで処理しようとすると、コードが複雑化し、メンテナンス性が著しく低下します。

そこで登場するのがFSOです。FSOはWindowsのファイルシステムをオブジェクトとして操作できる強力なライブラリです。これに「再帰処理(Recursive Procedure)」を組み合わせます。再帰処理とは、自分自身を呼び出す関数を作成し、フォルダの中を潜りながら処理を繰り返す手法のことです。

具体的には、以下の3ステップでロジックを組み立てます。
1. 指定したフォルダ内の全ファイルを取得し、処理を行う。
2. 指定したフォルダ内の全サブフォルダを取得する。
3. サブフォルダに対して自分自身(関数)を再度呼び出し、同じ処理を繰り返す。

この手法を用いることで、階層がいくつあろうとも、プログラム側が自動的に最深部まで探索してくれるため、コードを簡潔に保つことが可能です。

サンプルコード:再帰的探索の決定版

以下に、指定したフォルダ以下の全ファイルを検索し、そのパスをイミディエイトウィンドウに出力するプロシージャを提示します。


Option Explicit

' 参照設定で「Microsoft Scripting Runtime」を追加することを推奨します
Sub SearchAllFiles()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim rootPath As String
    rootPath = "C:\TargetFolder" ' 探索したいルートフォルダを指定
    
    If Not fso.FolderExists(rootPath) Then
        MsgBox "指定されたフォルダが存在しません。"
        Exit Sub
    End If
    
    ' 再帰処理の開始
    Call RecursiveSearch(fso.GetFolder(rootPath))
    
    Set fso = Nothing
    MsgBox "探索が完了しました。"
End Sub

Sub RecursiveSearch(ByVal targetFolder As Object)
    Dim subFolder As Object
    Dim fileItem As Object
    
    ' 1. 現在のフォルダ内のファイルを処理
    For Each fileItem In targetFolder.Files
        ' ここにファイルに対する処理(例:名前のチェックや読み込み)を記述
        Debug.Print fileItem.Path
    Next fileItem
    
    ' 2. サブフォルダを巡回(これが再帰の肝)
    For Each subFolder In targetFolder.SubFolders
        Call RecursiveSearch(subFolder)
    Next subFolder
End Sub

実務アドバイス:プロとして意識すべき「落とし穴」

このコードは非常に強力ですが、実務で使用する際には以下の3点に注意してください。

第一に「権限エラー」です。システムフォルダやアクセス権限のないフォルダに遭遇すると、VBAは「実行時エラー70:書き込み禁止です」といったエラーで停止します。実務では必ず「On Error Resume Next」等を用いてエラーを制御し、アクセスできないフォルダをスキップするロジックを組み込むのがプロの流儀です。

第二に「処理速度」です。数万個のファイルがある環境で全てのファイルに対して何らかの処理を行うと、VBAは非常に低速になります。探索の途中で「ファイル名が一致したら即座に終了する」といった早期リターン(Exit Sub)の仕組みを組み込むことで、無駄な探索を省く工夫をしましょう。

第三に「循環参照への配慮」です。稀にシンボリックリンク等により、フォルダ構造がループしている場合があります。深い階層制限(深さのカウント)を設けるか、FSOのプロパティを適切に判定することで、無限ループを回避する安全装置を用意しておくことを強く推奨します。

まとめ:再帰処理をマスターしてVBAの限界を超える

VBA100本ノック66本目は、単なるファイル探索の問題ではありません。再帰処理という「問題を小さく分割して解決する」というプログラミングの核心を学ぶための登竜門です。

一度このパターンをマスターしてしまえば、フォルダ整理ツールの作成、大量のログファイルの集計、特定の条件に合致するバックアップファイルの抽出など、業務効率化の幅が劇的に広がります。最初は再帰の動きを追うのが難しいかもしれませんが、まずは上記のコードをコピーし、ステップ実行(F8キー)でどのようにフォルダを潜っていくのかを視覚的に確認してください。その動きを理解できた時、あなたは中級者以上のVBAエンジニアとしての階段を確実に上ったことになります。

技術は反復です。ぜひ、このテンプレートを自分なりにカスタマイズし、現場の業務改善に役立ててください。

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