再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

先日お話ししました

指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得

の中で、どのようにフォルダの処理を移動していったかをご説明いたします。

再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

今回作成したプロシージャ

Sub 指定したフォルダ内とサブフォルダ内全部のファイル名取得()  ’・・・①
    'アクティブシートから処理対象のフォルダパスを取得し
    'そのフォルダ内とサブフォルダ内全部のファイル名を全てアクティブシートに取得
    '【変数】
    Dim ws As Worksheet '処理対象シート
    Dim pt As String    '処理対象パス
    Dim t_row As Long   'ファイル名書出行
    '■変数セット
    Set ws = ActiveSheet '変数ws=アクティブシートをセット
    pt = ws.Range("A3")  '変数ptにセルA3のパスをセット
    t_row = 6            'ファイル名を書き出す初めのセルの行番号をセット
    '■指定したフォルダ内とサブフォルダ内全部のファイル名をセルに書き出し
    Call ファイル名一覧取得(pt, ws, t_row)  ’・・・②
End Sub  ’・・・⑥

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long)  ’・・・③
    Dim FSO As Object       'FileSystemObject
    Dim fn As String        'ファイル名
    Dim s_fd As Object      'フォルダ
    fn = Dir(pt & "\*.*")   '変数fnに1個目のファイル名を格納
    Do While fn <> ""            'fnが空欄になるまでDo While内の処理を続ける
        ws.Cells(t_row, 1) = fn  '対象セルにファイル名を書き出し
        t_row = t_row + 1        'ファイル名を書き出すセルの行番号+1(一つ下の行番号)
        fn = Dir()  '変数fnに次のファイル名を格納(ファイルが無い場合は空欄になる)
    Loop
    Set FSO = CreateObject("Scripting.FileSystemObject") 'FileSystemObjectのインスタンス化
    For Each s_fd In FSO.GetFolder(pt).SubFolders        '変数s_fdに対象フォルダ内のサブフォルダを順に取得
        Call ファイル名一覧取得(s_fd.Path, ws, t_row)   '再帰処理  ’・・・④
    Next s_fd
    Set FSO = Nothing 'FSOを空っぽにする
End Sub  ’・・・⑤

「再帰処理」を使った処理順

今回の処理で、指定しているのは「C:\VBA\第1階層」という一番上の階層のパスのみ。

それなのに、下の階層の全てのフォルダ、更にはその下の階層全てのフォルダまで、ファイル名を読み込みにいっています。

それらのことを可能にしているのが「再帰処理」なのです。

再帰処理」とは、1つのプロシージャが終了していない途中で「自分自身」を呼び出す処理のことなのです。

上記処理でいうと

Sub 指定したフォルダ内とサブフォルダ内全部のファイル名取得()・・・①

Call ファイル名一覧取得(pt, ws, t_row)・・・②

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long)・・・③

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理・・・④

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long)・・・③

Call ファイル名一覧取得(s_fd.Path, ws, t_row)
‘再帰処理・・・④



といった具合に、「 For Each s_fd In FSO.GetFolder(pt).SubFolders」で受け取ったサブフォルダが無くなるまでフォルダパスを変更しながら、「自分自身」の処理を繰り返すのです。

■■■スポンサーリンク■■■

フォルダの処理順

フォルダ図の丸番号と下記「プロシージャ内の処理順と処理対象フォルダのパス」の丸番号の意味は異なります。

再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

■■■スポンサーリンク■■■

プロシージャ内の処理順と処理対象フォルダのパス

「↓↓↓」は、処理対象フォルダのパスです。
」はファイル名取得処理です。
文中の丸番号は、上記プロシージャに記載している丸番号のことです。

Sub 指定したフォルダ内とサブフォルダ内全部のファイル名取得()・・・①

Call ファイル名一覧取得(pt, ws, t_row) ‘・・・②
↓↓↓「pt」→ C:\VBA\第1階層→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
 C:\VBA\第1階層 のファイル名を取得

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→C:\VBA\第1階層\第2階層1→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層1 のファイル名を取得

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→C:\VBA\第1階層\第2階層1\第3階層1→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層1\第3階層1 のファイル名を取得
↓↓↓「第3階層1」以下にサブフォルダが無いため For Each を抜ける

End Sub・・・⑤
↓↓↓「pt」→C:\VBA\第1階層\第2階層1(ひとつ前の処理の For Each に戻る)

End Sub・・・⑤
↓↓↓C:\VBA\第1階層(ひとつ前の処理の For Each に戻る)

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→C:\VBA\第1階層\第2階層2→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層2 のファイル名を取得

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→C:\VBA\第1階層\第2階層2\第3階層2「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層2\第3階層2のファイル名を取得
↓↓↓「第3階層2以下にサブフォルダが無いため For Each を抜ける

End Sub・・・⑤
↓↓↓「pt」→C:\VBA\第1階層\第2階層2(ひとつ前の処理の For Each に戻る)

End Sub・・・⑤
↓↓↓「pt」→C:\VBA\第1階層(ひとつ前の処理の For Each に戻る)

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→
C:\VBA\第1階層\第2階層3→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層3 のファイル名を取得

Call ファイル名一覧取得(s_fd.Path, ws, t_row) ‘再帰処理 ’・・・④
↓↓↓「s_fd.Path」→
C:\VBA\第1階層\第2階層3\第3階層3→「pt」として受け取り

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long) ‘・・・③
C:\VBA\第1階層\第2階層3\第3階層3 のファイル名を取得
↓↓↓「第3階層3以下にサブフォルダが無いため For Each を抜ける

End Sub ‘・・・⑤
↓↓↓ 「pt」→C:\VBA\第1階層\第2階層3(ひとつ前の処理の For Each に戻る)

End Sub ‘・・・⑤
↓↓↓ 「pt」→C:\VBA\第1階層(ひとつ前の処理の For Each に戻る)

End Sub ‘・・・⑤

End Sub・・・⑥

長い道のりでしたね。

「再帰処理」・・・一目コードを見ただけでは理解するのは難しいと思います。

「F8」キーでステップインしながら、処理の流れを自分の目で確かめてみると「なるほど!」って瞬間がやってきます。

私ってヒマ???

【参考】

指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
指定したフォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
再帰処理とは?フォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)
ファイルのフルパスからファイル名のみを取得 InStrRev関数(Excel VBA)
指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
FileSystemObjectとは?CreateObject 関数 FolderExists・GetFolderの使い方
FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止
再帰処理とは?指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
ファイルのフルパスからファイル名のみを取得 Split関数(Excel VBA)
Callステートメントとは 引数 括弧()の使い方(Excel VBA)
指定したフォルダ内から「特定の文字を含まないファイル名」を取得(Excel VBA)
ワイルドカードとは。使い方いろいろ。(Excel)
Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
指定したフォルダのファイル名を取得し、そのファイル名を一括で変換(Excel VBA)
Excel起動時に「コンパイルエラー」。64ビット システムで Declareステートメントに、PtrSafe属性を設定(Excel VBA )
「ファイルを開く」ダイアログボックス から ファイル名を取得(Excel VBA)
「ファイルを開く」ダイアログボックス から 複数 ファイル名を取得(Excel VBA)
指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
再帰処理とは?指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)

■■■スポンサーリンク■■■