<目次>
(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)