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

先日お話ししました

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

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

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

使用したプロシージャはこちら。

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 buf As String 'ファイル名
    Dim fd As Object  'フォルダ
    buf = Dir(pt & "\" & "*.*")  '変数bufに1個目のファイル名を格納
    Do While buf <> ""           'bufが空欄になるまでDo While内の処理を続ける
        ws.Cells(t_row, 1) = buf '対象セルにファイル名を書き出し
        t_row = t_row + 1        'ファイル名を書き出すセルの行番号+1(一つ下の行番号)
        buf = Dir()  '変数bufに次のファイル名を格納(ファイルが無い場合は空欄になる)
    Loop
    Set FSO = CreateObject("Scripting.FileSystemObject") 'FileSystemObjectのインスタンス化
    For Each fd In FSO.GetFolder(pt).SubFolders          'サブフォルダ群から1つずつfnに入れて順に処理
        Call ファイル名一覧取得(fd.Path, ws, t_row) '再帰処理・・・④
    Next 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 ファイル名一覧取得(fd.Path, ws, t_row) ‘再帰処理・・・④

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

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



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

■スポンサーリンク

フォルダの処理順は下記の通りです。
(フォルダ図の丸番号と下の説明分の丸番号の意味は異なります。)

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

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

Call ファイル名一覧取得・・・②

↓↓↓ C:\VBA\第1階層
Sub ファイル名一覧取得・・・③
 C:\VBA\第1階層のファイル名を取得

Call ファイル名一覧取得・・・④
↓↓↓C:\VBA\第1階層\第2階層1

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層1のファイル名を取得

Call ファイル名一覧取得 ・・・④
↓↓↓C:\VBA\第1階層\第2階層1\第3階層1

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層1\第3階層1のファイル名を取得
↓↓↓「第3階層1」以下にサブフォルダが無いため終了

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

End Sub・・・⑤

↓↓↓C:\VBA\第1階層(ひとつ前の処理に戻る)

Call ファイル名一覧取得・・・④
↓↓↓C:\VBA\第1階層\第2階層2

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層2のファイル名を取得

Call ファイル名一覧取得・・・④
↓↓↓C:\VBA\第1階層\第2階層2\第3階層2

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層2\第3階層2のファイル名を取得
↓↓↓「第3階層2」以下にサブフォルダが無いため終了

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

End Sub・・・⑤

↓↓↓C:\VBA\第1階層(ひとつ前の処理に戻る)

Call ファイル名一覧取得・・・④
↓↓↓C:\VBA\第1階層\第2階層3

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層3のファイル名を取得

Call ファイル名一覧取得・・・④
↓↓↓C:\VBA\第1階層\第2階層3\第3階層3

Sub ファイル名一覧取得・・・③
C:\VBA\第1階層\第2階層3\第3階層3のファイル名を取得
↓↓↓「第3階層3」以下にサブフォルダが無いため終了

End Sub・・・⑥

長い道のりでしたね。

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

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

私ってヒマ???

【参考】
指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
フォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)

■スポンサーリンク

■ランキングに参加しています。
↓このブログを気に入っていただけましたら、ポチッとお願いします。
にほんブログ村 IT技術ブログへ
にほんブログ村