Dir関数を用いた全サブフォルダ・全ファイル取得の技術的アプローチ
Excel VBAにおいて、指定したディレクトリ内のファイルリストを取得する際、最も基本的かつ高速に動作するのがDir関数です。しかし、Dir関数単体では「サブフォルダの階層を自動的に潜る」という機能を持っていません。本稿では、再帰処理(Recursion)というプログラミングの定石を用いて、階層の深さを問わず、ドライブ直下の全ファイルを網羅的に取得するプロフェッショナルな手法を解説します。
ファイルシステムを探索する際、FileSystemObject(FSO)を用いる手法が一般的ですが、Dir関数は外部ライブラリの参照設定を必要とせず、メモリ消費量も極めて少ないという利点があります。システムパフォーマンスを最大限に引き出す必要がある場面において、この手法はエンジニアの武器となります。
Dir関数による再帰探索の技術的詳細
再帰処理とは、関数の中で自分自身を呼び出す手法です。フォルダ階層を探索する場合、以下のステップを繰り返すアルゴリズムを構築します。
1. 指定されたパス内の最初のエントリを取得する。
2. エントリが「ディレクトリ」か「ファイル」かを判定する。
3. 「ファイル」であればリストに追加する。
4. 「ディレクトリ」であれば、そのパスを引数として自分自身(再帰関数)を呼び出し、ステップ1に戻る。
5. ディレクトリ内の全エントリを処理し終えたら、呼び出し元に戻る。
この処理において注意すべき点は、Dir関数の「状態保持」です。Dir関数は呼び出されるたびに内部的に検索状態を保持します。再帰的にDir関数を呼び出すと、親の検索状態が破壊されてしまうため、そのままでは入れ子構造の探索ができません。これを解決するためには、各階層で取得したファイル名やフォルダ名を配列やコレクションに退避させる、あるいはFSOと組み合わせてディレクトリ情報のみを抽出するといった工夫が必要です。今回は、最も堅牢な「FileSystemObjectでフォルダを巡回し、Dir関数でファイルを取得する」ハイブリッドアプローチを推奨します。
全サブフォルダの全ファイルを取得する実務サンプルコード
以下のコードは、指定したルートフォルダ配下の全ファイルを再帰的に取得し、アクティブシートのA列に一覧出力するプロシージャです。
Option Explicit
' メイン処理:検索の開始点となるフォルダを選択させる
Sub ListAllFiles()
Dim targetFolder As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "検索するフォルダを選択してください"
If .Show = -1 Then
targetFolder = .SelectedItems(1)
Else
Exit Sub
End If
End With
' 出力先の初期化
Cells.Clear
Range("A1").Value = "ファイルパス一覧"
' 再帰処理の開始
Call SearchFilesRecursive(targetFolder)
MsgBox "ファイル取得完了", vbInformation
End Sub
' 再帰的にフォルダを探索するサブプロシージャ
Sub SearchFilesRecursive(ByVal folderPath As String)
Dim fso As Object
Dim folder As Object
Dim subFolder As Object
Dim fileName As String
Dim nextRow As Long
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(folderPath)
' 1. 現在のフォルダ内のファイルをDir関数で取得
fileName = Dir(folderPath & "\*.*")
Do While fileName <> ""
nextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(nextRow, 1).Value = folderPath & "\" & fileName
fileName = Dir()
Loop
' 2. サブフォルダを再帰的に探索
For Each subFolder In folder.SubFolders
Call SearchFilesRecursive(subFolder.Path)
Next subFolder
Set folder = Nothing
Set fso = Nothing
End Sub
実務におけるパフォーマンスと安定性のためのアドバイス
プロフェッショナルな現場では、単に動作するコードを書くだけでは不十分です。以下の3点に留意することで、システムの信頼性を飛躍的に向上させることができます。
第一に「エラーハンドリング」の徹底です。ネットワークドライブやシステム保護されたフォルダ(System Volume Informationなど)にアクセスしようとすると、VBAは「実行時エラー70:書き込み禁止」や「アクセス拒否」を返します。再帰関数の冒頭に `On Error Resume Next` を適切に配置し、エラーが発生したフォルダをスキップする設計が不可欠です。
第二に「ファイル数の増大への対応」です。数万件を超えるファイルパスを取得する場合、セルへの逐次書き込みは非常に低速になります。一度配列(Variant型)にパスを格納し、最後に `Range.Value` を用いて一括出力することで、処理時間を数十分の一に短縮可能です。
第三に「隠しファイル・システムファイルの扱い」です。Dir関数はデフォルトでは通常のファイルのみを対象としますが、引数 `vbHidden` や `vbSystem` を指定することで、隠しファイルも含めた全網羅的な取得が可能になります。業務要件に応じて、どのような属性のファイルを抽出対象とするか、仕様を明確に定義してください。
まとめ
Dir関数と再帰処理を組み合わせる手法は、VBAにおけるファイル操作の基礎でありながら、極めて強力な自動化ツールとなります。FileSystemObjectを組み合わせることで、Dir関数の弱点である「階層探索の脆弱性」を補完しつつ、高速なファイル取得を実現できます。
本記事で紹介したコードは、ファイル整理、ログの集計、バックアップ管理など、あらゆる事務処理の自動化に応用可能です。コードをコピー&ペーストするだけでなく、自身の環境に合わせてファイルフィルタ(特定の拡張子のみ抽出するなど)を追加し、カスタマイズを試みてください。Excel VBAは、こうした小さな自動化の積み重ねが、組織全体の生産性を向上させる鍵となります。常に保守性と拡張性を意識したコード設計を心がけ、より高度なシステム開発へとステップアップしていきましょう。
