下位フォルダーを含めたファイルリストを作成する : 再帰処理

下位フォルダーを含めたファイルリストを作成するマクロです。まずは、なれないと混乱しがちな再帰処理について解説していきます。

再帰処理とは 分身を作ること

プロシージャは、処理の途中で自分自身を呼び出すことができます。自分を呼び出すと、分身を作って同じ処理をさせられます。この呼び出しを「再帰呼び出し」といい、再帰呼び出しを使った処理を「再帰処理」といいます。

深さや要素数が特定できない階層やグループ構造を持つデータを扱う際の定番の処理です。

プロシージャには1つの階層内を処理する機能を持たせます。階層内に下位階層があれば分身を作って処理をさせます。必要になったら分身を作ればよいので、不特定階層のデータに対応できるという仕掛けです。分身の処理が終わると、呼び出し元に帰って処理を継続します。

以下のフォルダー・ファイルで再帰処理を行う場合の遷移を説明します。

再帰処理

  1. 本体プロシージャは、フォルダー(A) を担当
    下位フォルダー(B) が見つかったので分身1号にパス(再帰呼び出し)
  2. 分身1号は、フォルダー(B) を担当
    下位フォルダー(E) が見つかったので分身2号にパス(再帰呼び出し)
  3. 分身2号は、フォルダー(E) を担当
    → 下位フォルダーなし → ファイル[H] を処理
    分身2号退場。分身1号に帰る
  4. 分身1号は、担当フォルダー(B) 内の処理を継続
    → ほかに下位フォルダーなし → ファイル[F][G] を処理
    分身1号退場。本体プロシージャに帰る
  5. 本体プロシージャは、担当フォルダー(A) 内の処理を継続
    → ほかに下位フォルダーなし → ファイル[C][D] を処理
    本体の処理終了

ファイルリストを配列に格納するマクロ

'呼び出し元のプロシージャ
Dim aryFile() As String  'ファイル名を格納する動的配列
Dim cnt As Long  '検出ファイルのカウント
Const pathFolder As String = "D:\test"

cnt = 0
f_getFileArray pathFolder, aryFile, cnt

'各ファイル(配列aryFileの要素)を処理 ======
'要参照設定: Microsoft Scripting Runtime
Function f_getFileArray(aPath As String, aryFile() As String, cnt As Long)

  Dim oFS As New FileSystemObject
  Dim oFile As File
  Dim oFolder As Folder

  'サブフォルダーの処理: 再帰呼び出し
  For Each oFolder In oFS.GetFolder(aPath).SubFolders
     f_getFileArray oFolder.Path, aryFile, cnt
  Next

  'ファイルの処理: サイズ1MB以上のファイルを配列に追加
  For Each oFile In oFS.GetFolder(aPath).Files
    If oFile.Size > 1000000 Then
      cnt = cnt + 1
      ReDim Preserve aryFile(1 To cnt)
      aryFile(cnt) = oFile.Path
    End If
  Next

  Set oFile = Nothing
  Set oFolder = Nothing
  Set oFS = Nothing
End Function
処理の流れ

f_getFileArray は、1つのフォルダー内の処理を行います。

フォルダー内にサブフォルダーがあれば再帰呼び出しをして(分身を作って)、その処理を行わせます。サブフォルダーがないか、サブフォルダーの処理が終了(分身の処理が終了)したら、ファイルの処理が実行されます。

aryFile()cnt をパス回し

動的配列のaryFileと検出カウンターのcnt の変数を呼び出し元で宣言しています。呼び出し元からf_getFileArray 本体へ、本体から分身へ…と参照渡しすることで累積的に値を格納するようにしています。

FileSystemObject の使用

フォルダー・ファイルの情報取得にFileSystemObject を使っています。VBEの[ツール]-[参照設定]から「Microsoft Scripting Runtime」にチェックを入れてください。

Dir 関数でもリスト作成はできますが、このような処理ではファイルの付帯情報を確認したり取得したりするケースが多いので、FileSystemObject のほうが使い勝手がよいのです。この例ではファイルサイズで対象を絞り込んでいます。

タイトルとURLをコピーしました