スポンサードリンク

サブフォルダ内を含むFileSystemObjectを利用したファイル検索(ファイル検索比較4)

前回はFileSystemObjectを利用して1つのフォルダ内のファイルを検索するコードを検証してみた。

www.excellovers.com

今回は再帰処理を利用して指定フォルダ内だけでなくフォルダ内フォルダの検索を実現してみようと思う。

再帰処理でフォルダ内検索

Dir関数のときと同じように当初は1つだったプロシージャを3つに分割して機能を実現している。

・FileSearch・・・前処理や検索結果のセルへの転記を行う

・FSOSearch・・・前処理やDictionaryオブジェクトに蓄積した検索結果を配列へ変換する

・FSO_Search・・・FSOSearch内で呼び出される。実際のFileSystemObjectでの検索を行う。

FileSearch

Option Explicit

Sub FileSearch()
     Cells.Clear
     
     Dim myVar As Variant
     myVar = FSOSearch("C:\Users\ユーザー名\OneDrive\ドキュメント\", True)
     
     If UBound(myVar) <> -1 Then
          Range("A1").Resize(UBound(myVar), 1).Value = myVar
     End If
End Sub

ここでは次に紹介するFSOSearch関数を呼び出して、検索開始フォルダとサブフォルダ内検索の有無を指定している。

FSOSearch関数は検索結果に関わらず、返り値として配列を返すようにしている。

FSOSearch関数の返り値に対してUbound関数を使用し、返り値が-1(空配列)であれば検索結果が0であるため処理無しとする。

何らかの検索結果がある場合は2次元配列が返ってきているので、セルサイズを合わせて一括で転記している。

FSOSearch関数

'-----------------------------------------------------------------------------------
Rem FSOSearch関数
Rem 第1引数 FolderPath:検索対象とするフォルダパスを指定する
Rem 第2引数 SubFolderSearch:フォルダ内のサブフォルダ内を検索対象とするかどうか
Rem 返り値 見つかったファイルのフルパス一覧を2次元配列として返す。
Rem 1件もファイルが見つからなかった場合は空配列を返す。
Rem 関数内sub FSO_Searchが溜め込んだ検索結果Dictionaryを配列へ転記する
'-----------------------------------------------------------------------------------
Function FSOSearch(FolderPath As String, SubFolderSearch As Boolean) As Variant
     Dim myDic As Dictionary
     Set myDic = New Dictionary
     
     FSO_Search FolderPath, SubFolderSearch, myDic
     
     Dim myItem As Variant
     If myDic.Count = 0 Then
          FSOSearch = Array()
     Else
          Dim myVar As Variant
          Dim i As Long: i = 1
          ReDim myVar(1 To myDic.Count, 1 To 1)
          
          For Each myItem In myDic.Keys
               myVar(i, 1) = myItem
               i = i + 1
          Next
          FSOSearch = myVar
     End If
End Function

FSOSearch関数は次に紹介するFSO_SearchがDictionaryオブジェクトに蓄積した検索結果を配列へと変換して外部へ返す役割を担っている。

FSO_Search

Private Sub FSO_Search(FolderPath As String, SubFolderSearch As Boolean, ByRef FileDictionary As Dictionary)
     Dim myFSO As FileSystemObject
     Dim myFolderDic As Dictionary
     Dim myFile As Variant
     Set myFSO = New FileSystemObject
     Set myFolderDic = New Dictionary
     
     For Each myFile In myFSO.GetFolder(FolderPath).Files
          FileDictionary.Add myFile, ""
     Next
     
     Rem サブフォルダー内検索処理
     Dim myFolder As Variant
     If SubFolderSearch = True Then
          For Each myFolder In myFSO.GetFolder(FolderPath).SubFolders
               FSO_Search myFolder & "\", SubFolderSearch, FileDictionary
          Next
     End If
End Sub

本件の中核となるFSO_Search。

実際にFileSystemObjectでファイル・フォルダの検索を行い検索結果をDictionaryオブジェクトへ蓄積していく。

Dir関数とちがい、FolderオブジェクトのFilesプロパティで抽出されたものはファイルであるので、ファイル属性の判定は必要ない。

サブフォルダ以内の検索はFSO_Search内からFSO_Search自身を呼び出す再帰処理で実現している。

まとめ

コード内容についてはファイル属性の判定以外はDir関数を使用したときと何ら変わりがない内容で実現できる。

ファイル属性の判定については現在テストを行っているフォルダでは問題ないが、なにか特殊なフォルダを検索対象にした際に重要な要素になってくるかもしれない。

が、現時点では割愛。

次回はDir関数でもFileSystemObjectでもない別のファイル検索の方法を検証してみようと思います。