<目次>
(1) VBAでフォルダを再帰的に検索する方法について
(1-1) 構文
(1-2) サンプルプログラム
(1) VBAでフォルダを再帰的に検索する方法について
(動画)イメージ
親フォルダ ┗伝票_AAA商店フォルダ ┗伝票_AAA商店_20201230_1359.xlsx ⇒① ┗伝票_AAA商店_20210828_2048.xlsx ⇒② ┗伝票_BBBスーパーフォルダ ┗伝票_BBBスーパー_20210101_1934.xlsx ⇒③ ┗伝票_BBBスーパー_20210829_2102.xlsx ⇒④ ┗伝票_BBBスーパー_20220322_1639.xlsx ⇒⑤ ┗伝票_CCC市場フォルダ ┗伝票_CCC市場_20210503_1638.xlsx ⇒⑥ ┗伝票_CCC市場_20210829_2237.xlsx ⇒⑦
(図100)やりたい処理のイメージ例

(1-1) 構文
Public Sub MainProcess()
'# ファイル操作用オブジェクトの生成
Dim objFSO As FileSystemObject
Set objFSO = New FileSystemObject
'# 集計対象のファイルがある、親ファイルのパスを指定
HostFolder = "C:\"
'# 親フォルダを指定して再起的フォルダ探索を実行
AggregateFolderData objFSO.GetFolder(HostFolder)
End Sub
Sub AggregateFolderData(Folder)
'# 引数で与えたフォルダをループし、子フォルダがあれば、更に再帰的な探索を実行
Dim SubFolder
For Each SubFolder In Folder.SubFolders
AggregateFolderData SubFolder
Next
'# 引数で与えたフォルダに子フォルダが無ければ、フォルダ配下のファイルを対象にした処理を実行
Dim File
For Each File In Folder.Files
'# 各ファイルに対して行う処理
Next
End Sub
(図132)

(1-2) サンプルプログラム
(サンプル)
'# 集計するブックで、何行目まで転記したか?を管理する値
Dim cursor As Integer
Public Sub MainProcess()
Dim objFSO As FileSystemObject
Set objFSO = New FileSystemObject
'# 集計対象の親ファイルのパスを設定します
'# まずはシートの変数wCにシートの情報をセットします
Dim wC As Worksheet: Set wC = ThisWorkbook.Worksheets("集計シート")
'# 「集計対象フォルダ」の値をセットし、最後に「\」を補記
Dim HostFolder As String: HostFolder = wC.Cells(2, 2).Value + "\"
'# 集計の開始行数をセット
'# (※今回の例では「集計シート」の明細は5行目から開始するので5をセット)
cursor = 5
'# 親フォルダを指定して再起的フォルダ探索を実行
'# (※前半が関数名、後半は引数のパスです)
AggregateFolderData objFSO.GetFolder(HostFolder)
End Sub
Sub AggregateFolderData(Folder)
'# 転記する対象の集計シート
Dim wC As Worksheet: Set wC = ThisWorkbook.Worksheets("集計シート")
'# 引数で与えたフォルダをループし、子フォルダがあれば、更に再帰的な探索を実行
Dim SubFolder
For Each SubFolder In Folder.SubFolders
AggregateFolderData SubFolder
Next
'# 各ブックを開く際に使う一時的なWorkbook変数
Dim tmpBook As Workbook
'# 開いたブックの行をループする変数
Dim i1 As Integer
'# 引数で与えたフォルダに子フォルダが無ければ、フォルダ配下のファイルを対象にした処理を実行
'# (※つまり、これ以上は再帰的にフォルダ検索せずに、現在の直下のファイルを処理する)
Dim fl
For Each fl In Folder.Files
'# ブックを開く
Set tmpBook = Workbooks.Open(fl)
Debug.Print tmpBook.Name
'# 開いたブックの行を順番にループ
'# (※各伝票の明細行が14行目~なので開始は14、終了の20000は十分大きな値を設定)
For i1 = 14 To 20000
'# もし開いているブックの明細行が空白ならForループを抜ける
'# (No、商品名、単価、数量、金額、備考が全て空白の場合)
If tmpBook.ActiveSheet.Cells(i1, 5) = "" _
And tmpBook.ActiveSheet.Cells(i1, 6) = "" _
And tmpBook.ActiveSheet.Cells(i1, 7) = "" _
And tmpBook.ActiveSheet.Cells(i1, 8) = "" _
And tmpBook.ActiveSheet.Cells(i1, 9) = "" Then Exit For
'# ヘッダー部の転記
wC.Cells(cursor, 2) = tmpBook.ActiveSheet.Cells(5, 5) '# 伝票ID
wC.Cells(cursor, 3) = tmpBook.ActiveSheet.Cells(7, 3) '# 顧客ID
wC.Cells(cursor, 4) = tmpBook.ActiveSheet.Cells(8, 3) '# 顧客名
wC.Cells(cursor, 5) = tmpBook.ActiveSheet.Cells(4, 11) '# 購入日
'# 開いたブックの「i1」行目の必要な列を、集約するブックにコピー
wC.Cells(cursor, 6) = tmpBook.ActiveSheet.Cells(i1, 4) '# 明細No
wC.Cells(cursor, 7) = tmpBook.ActiveSheet.Cells(i1, 5) '# 商品名
wC.Cells(cursor, 8) = tmpBook.ActiveSheet.Cells(i1, 6) '# 単価
wC.Cells(cursor, 9) = tmpBook.ActiveSheet.Cells(i1, 7) '# 数量
wC.Cells(cursor, 10) = tmpBook.ActiveSheet.Cells(i1, 8) '# 金額
wC.Cells(cursor, 11) = tmpBook.ActiveSheet.Cells(i1, 9) '# 備考
'# 集約するブックの行番号をインクリメント
cursor = cursor + 1
Next
'# ブックを閉じる
tmpBook.Close
Next
End Sub
(図131)
