Excelが大好きだ!

Excel大好き経理マンがExcelの事を書き綴っていきます。


スポンサードリンク

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

前回はDir関数を利用したファイル検索を検証した。

www.excellovers.com

今回は再帰処理を利用して指定フォルダ内だけでなく、フォルダ内のフォルダの中身を検索できるようにしてみる。

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

前回は1つのプロシージャで実現したが、今回は3つのプロシージャに分割して機能を実現した。

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

・DirSearch関数・・・前処理やCollectionに蓄積した検索結果を配列へ変換する

・Dir_Search・・・DirSearch内で呼び出される。実際のDir関数での検索を行う。

FileSearch

Option Explicit
Dim myCol As Collection
'-----------------------------------------------------------------------------------
Sub FileSearch()
     Cells.Clear
     Set myCol = New Collection
     
     Dim myVar As Variant
     myVar = DirSearch("C:\Users\ユーザー名\Desktop\", True)
     
     'DirSearchの返り値が空配列でなければセルに検索結果を転記
     If UBound(myVar) <> -1 Then
          Range("A1").Resize(UBound(myVar), 1).Value = myVar
     End If
     Set myCol = Nothing
End Sub

冒頭でモジュールレベル変数でCollection型を宣言。この変数にDir関数の検索結果を蓄積していく。

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

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

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

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

DirSearch関数

'-----------------------------------------------------------------------------------
Rem DirSearch関数
Rem 第1引数 FolderPath:検索対象とするフォルダパスを指定する
Rem 第2引数 SubFolderSearch:フォルダ内のサブフォルダ内を検索対象とするかどうか
Rem 返り値 見つかったファイルのフルパス一覧を2次元配列として返す。
Rem 1件もファイルが見つからなかった場合は空配列を返す。
Rem 関数内sub Dir_Searchが溜め込んだ検索結果コレクションを配列へ転記する
'-----------------------------------------------------------------------------------

Function DirSearch(FolderPath As String, SubFolderSearch As Boolean) As Variant
     Dir_Search FolderPath, SubFolderSearch
     
     Dim myItem As Variant
     '検索結果を蓄積していたCollectionから配列へ転記してからセルへ一括転記
     If myCol.Count = 0 Then
          DirSearch = Array()
     Else
          Dim myVar As Variant
          Dim i As Long: i = 1
          
          ReDim myVar(1 To myCol.Count, 1 To 1)
          For Each myItem In myCol
               myVar(i, 1) = myItem
               i = i + 1
          Next
          DirSearch = myVar
     End If
End Function

DirSearch関数は次に紹介するDir_Searchがモジュールレベル変数Collectionに蓄積した検索結果を配列へと変換して外部へ返す役割を担っている。

Dir_Search

'-------------------------------------------------------------------------------------
Rem Dir_Search
Rem 第1引数 FolderPath:検索対象とするフォルダパスを指定する
Rem 第2引数 SubFolderSearch:フォルダ内のサブフォルダ内を検索対象とするかどうか
Rem Dir関数を利用してファイル・フォルダを検索。検索結果をモジュールレベルCollectionへ蓄積していく。
'-------------------------------------------------------------------------------------

Private Sub Dir_Search(FolderPath As String, SubFolderSearch As Boolean)
     Dim myFileName As String
     Dim myFolderCol As Collection
     Set myFolderCol = New Collection
     
     'ファイルとフォルダを検索対象とする
     myFileName = Dir(FolderPath, VbFileAttribute.vbSystem + VbFileAttribute.vbHidden + VbFileAttribute.vbDirectory)
     
     '検索対象が見つからなくなるまでループ処理
     Do Until myFileName = ""
          '見つかったものが該当フォルダ及び親フォルダの場合は処理なし
          If myFileName = "." Or myFileName = ".." Then

          '見つかったものがフォルダ内フォルダの場合はフォルダ一覧コレクションに登録
          ElseIf GetAttr(FolderPath & myFileName) And vbDirectory Then
               myFolderCol.Add FolderPath & myFileName
          
          '上記2つ以外はファイル一覧コレクションに登録
          Else
               myCol.Add FolderPath & myFileName
          End If
          myFileName = Dir
     Loop
          
          
     ’サブフォルダー内検索処理
     '引数SubFolderSearchがTrueの場合は再帰処理で中を検索していく
     Dim myItem As Variant
     If SubFolderSearch = True Then
          For Each myItem In myFolderCol
               Dir_Search myItem & "\", SubFolderSearch
          Next
     End If
End Sub

本件の中核となるDir_Search。

実際にDir関数でファイル・フォルダの検索を行い検索結果をモジュールレベル変数Collectionへ蓄積していく。

Dir関数はフォルダ名・ファイル名のみを返すので、Collectionへ追加する際は親フォルダ部分を追加してから行う。

Dir関数の検出結果がフォルダなのかファイルなのかを判定するためにGeAttr関数とビットアンド演算を利用している。

www.excellovers.com

www.excellovers.com

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

まとめ

DirSearch関数の引数設定をもう少し柔軟に受けることが出来るようにすれば、検索対象の絞り込みも設定できるようになるだろうが、作り込みについては次回以降の別のファイル検索についても検証してからにしてみようと思います。