特定のフォルダの中に、さらにどのようなフォルダ(サブフォルダ)が存在するのかを調べ、その一覧をExcelシートに書き出したい、という場面は、ファイルの整理や集計作業の前処理としてよく発生します。
FileSystemObject(FSO)
のFolder
オブジェクトが持つ**.SubFolders
プロパティ**を使えば、この処理を簡単に行うことができます。
この記事では、指定したフォルダの直下にあるサブフォルダの一覧を取得する基本的な方法と、さらにその中のフォルダもすべて洗い出す応用テクニックを解説します。
【準備】参照設定
FSOを快適に利用するため、VBAエディタでツール
> 参照設定
を開き、**「Microsoft Scripting Runtime」**にチェックを入れておくことを推奨します。
完成したVBAコード(直下のサブフォルダのみ取得)
以下は、このマクロが書かれているExcelファイルと同じ場所にあるフォルダを対象に、その直下にあるサブフォルダの名前をすべてアクティブシートのA列に書き出すVBAコードです。
'参照設定: Microsoft Scripting Runtime
Sub ListImmediateSubfolders()
' 変数を宣言します
Dim fso As New FileSystemObject
Dim targetFolder As Folder
Dim subFolder As Folder
Dim rowIndex As Long
'--- 1. 親となるフォルダのオブジェクトを取得 ---
Set targetFolder = fso.GetFolder(ThisWorkbook.Path)
' 書き出し先のシートをクリアし、ヘッダーを設定
ActiveSheet.Cells.ClearContents
ActiveSheet.Range("A1").Value = "サブフォルダ名"
rowIndex = 2
'--- 2. .SubFoldersコレクションをループ処理 ---
For Each subFolder In targetFolder.SubFolders
'--- 3. サブフォルダの情報をシートに書き出す ---
ActiveSheet.Cells(rowIndex, "A").Value = subFolder.Name
ActiveSheet.Cells(rowIndex, "B").Value = subFolder.Path
rowIndex = rowIndex + 1
Next subFolder
ActiveSheet.Columns("A:B").AutoFit ' 列幅を自動調整
MsgBox "サブフォルダの一覧取得が完了しました。"
' オブジェクトを解放
Set subFolder = Nothing
Set targetFolder = Nothing
Set fso = Nothing
End Sub
コードのポイント解説
① fso.GetFolder(パス)
まず、起点となる親フォルダの情報をFolder
オブジェクトとして取得します。
② .SubFolders
プロパティ
For Each subFolder In targetFolder.SubFolders
これが処理の核心部分です。Folder
オブジェクトの.SubFolders
プロパティは、そのフォルダの直下にあるすべてのサブフォルダの集まり(コレクション)を返します。
For Each
ループを使ってこのコレクションを巡回させることで、各サブフォルダをFolder
オブジェクトとして一つずつ変数(subFolder
)に取り出し、処理を行うことができます。
③ サブフォルダの情報を書き出す
ループの中で、変数subFolder
もFolder
オブジェクトであるため、.Name
(名前)や.Path
(フルパス)、.DateCreated
(作成日時)といった様々なプロパティにアクセスして、その情報をシートに書き出すことができます。
【応用】すべての階層のサブフォルダを再帰的に取得する
.SubFolders
は直下のフォルダしか取得しません。もし、サブフォルダのさらにその中にある孫フォルダ、ひ孫フォルダ…と、すべての階層のフォルダをリストアップしたい場合は、**「再帰処理」**というテクニックを使います。
'--- 実行の起点となるメインのSub ---
Sub ListAllSubfoldersRecursively()
Dim fso As New FileSystemObject
Dim startFolder As Folder
Set startFolder = fso.GetFolder(ThisWorkbook.Path) ' 開始フォルダを設定
ActiveSheet.Cells.ClearContents
' 再帰処理を呼び出す
GetSubfolders startFolder, 0
MsgBox "すべての階層のサブフォルダ一覧を取得しました。"
End Sub
'--- 自分自身を呼び出す再帰処理のSub ---
Private Sub GetSubfolders(ByVal parentFolder As Folder, ByVal indentLevel As Integer)
Dim subFld As Folder
' 親フォルダの直下のサブフォルダをループ
For Each subFld In parentFolder.SubFolders
' インデントを付けてフォルダ名を出力
ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1).Value = _
String(indentLevel * 4, " ") & subFld.Name
' ★自分自身を呼び出し、さらに下の階層を検索
GetSubfolders subFld, indentLevel + 1
Next subFld
End Sub
GetSubfolders
というプロシージャの中で、さらに自分自身を呼び出しています。これにより、見つかったサブフォルダを起点に、さらにその中のサブフォルダを探しにいく、という処理がフォルダがなくなるまで繰り返され、すべての階層をリストアップできます。
まとめ
- フォルダの直下にあるサブフォルダの一覧を取得するには、
Folder
オブジェクトの**.SubFolders
**コレクションをFor Each
ループで処理する。 - すべての階層を対象にしたい場合は、**「再帰処理」**というテクニックで
SubFolders
の探索を繰り返す。
FSOの.SubFolders
プロパティを使いこなすことで、複雑なフォルダ構造の分析や、複数階層にわたるファイルの検索といった高度な処理を自動化できます。