再帰的にファイルを検索
■ファイル一覧
ファイル情報はFileオブジェクトにありますが、ファイルを一覧という意味では、FolderオブジェクトのFilesプロパティが必要です
そして、一覧を作成する上では、このFilesプロパティをFor Each…Nextのステートメントを使用して、Fileオブジェクトを取り出していきます
そのため、作成したGetFileInfo関数でファイル名を表示するタイミングで、指定するファイルパターンに一致するファイル情報(FIleオブジェクト)を取得します
Sub GetFileInfo(path As String, ptrn As String, data As Collection) Dim fl As file With New FileSystemObject ' pathのファイルを取得 For Each fl In .GetFolder(path).files ' ファイルパターンに一致するものだけ取り出す If (UCase(fl.name) Like UCase(ptrn)) Then ' Fileオブジェクトをコレクションに格納 Call data.Add(fl) End If Next End With End Sub
・説明
先ほどのソースとは以下の内容を変更しています
- ファイルパターンを引数で受け取る
- Fileオブジェクト格納用にコレクションを引数で受け渡す
- ファイル名とファイルパターンを判定して該当する場合はFileオブジェクトをコレクションに格納する
■再帰的に検索
これを基にして、カレントフォルダのパス配下のフォルダも再帰的に検索して、該当ファイルのFileオブジェクトを全てコレクションに格納していきます
Sub GetFileInfo( path As String, ptrn As String, data As Collection) Dim fl As File Dim fo As Folder With New FileSystemObject ' pathのファイルを取得 For Each fl In .GetFolder(path).Files ' ファイルパターンに一致するものだけ取り出す If (UCase(fl.name) Like UCase(ptrn)) Then ' Fileオブジェクトをコレクションに格納 Call data.Add(fl) End If Next ' pathのサブフォルダを取得 For Each fo In .GetFolder(path).SubFolders ' サブフォルダを指定して再帰的に呼び出す Call GetFileInfo(fo.path, ptrn, data) Next End With End Sub
・説明
前半部は先ほどと同じで指定フォルダのFilesプロパティからFileオブジェクトを取得しています
後半部に指定フォルダのSubFoldersプロパティからFolderオブジェクトを取得しています
ここで取得したFolderオブジェクトのPathプロパティを関数に渡して再帰的に呼び出すことで、カレントフォルダの配下のサブフォルダも全て検索することになります
なお、上記ソースはファイルを先に検索して、次にサブフォルダを検索しています
先にサブフォルダを表示して、サブフォルダ配下のファイルを優先して取得する場合、2つあるFor Each…Nextのステートメントの順番を入れ替えれば、それが可能です
Treeみたいに指定フォルダのファイルが先の方が見やすいので、上記のようにしています
■Collectionオブジェクト
Collectionオブジェクトを引数で使用しており、オブジェクトには以下が含まれています
- Addメソッド
- Countプロパティ
- Itemメソッド
- Removeメソッド
何よりも通常のVBAで使用する配列を拡張するReDimを使用するのではなく、次々とAddしていくことが可能なので便利です
オブジェクトへの参照は、配列のようにインデックス指定もできますし、一意なKeyを設定して、Itemを格納しておくことができるので、Key指定でオブジェクトへの参照が可能です
■Dirはダメよ
ファイル検索というと、簡単に使えるDir関数を思い浮かべる方がいると思いますが、使えないわけではないのですが、万能ではないのであまりお勧めしません!
特にMicrosoftのリファレンスサイトを見ても書いてないのですが、指定するパスの文字数が128か256文字だったか忘れましたが、それ以上に長いパスを指定すると仕事しなくなりますw
それに再帰的な呼び出しには対応していないので、カレントフォルダ配下を探すとなると、配下のフォルダを変数に保存しておいて、順次にパスを変えてDir関数を呼び出して・・を繰り返すことになります
サンプルソースを書こうかとも思いましたが、面倒なのでやめましたw
FileSystemObjectをお使い頂くことをお勧めします!
■次回
これでファイル一覧のFileオブジェクトがコレクションに取得できましたので、あとはこれをループで回して、1つずつFileオブジェクトを取得して、ファイル情報を別のシートに出力していくだけですね!
目標はこんな感じの一覧です
それはまた次の機会にw