フォルダを部分一致で検索する方法を解説します。
FileSystemObject+Like演算子による検索
フォルダを部分一致検索するには、
FileSystemObject(以下FSO)を使うのがおすすめです。
これがフォルダではなくファイルを部分一致で判定したい場合は、
対象ファイル名 = Dir(検索フォルダパス & "\*.xlsx")
と、Dir関数にワイルドカード*を渡す方法が簡単です。
しかし同じようにフォルダの部分一致判定を行おうとすると、
- 1回目の実行が相対パスを意味する「.」を返してしまう
- 引数にvbDirectoryを指定してもファイルも検索してしまう
という問題が発生してしまい、コードが複雑になります。
FSOの方がコードが短く、またFSOは環境依存文字にも強いため、
今回の処理にはFSOを採用しましょう。
ソースコード
Sub フォルダ名が売上データ○○になっているフォルダを取得する() Dim FSO As New FileSystemObject Dim 検索フォルダ As Folder Set 検索フォルダ = FSO.GetFolder("C:\Users\○○\Desktop\検索フォルダ") Dim 該当フォルダ As Folder Dim フォルダ候補 As Folder For Each フォルダ候補 In 検索フォルダ.SubFolders If フォルダ候補.Name Like "売上データ*" Then Set 該当フォルダ = フォルダ候補 Exit For End If Next If Not 該当フォルダ Is Nothing Then MsgBox "該当フォルダのパス:" & 該当フォルダ.Path End If End Sub
解説
フォルダ内にあるすべての子フォルダ(SubFolders)を調べ、
1つずつLike演算子による判定を行うコードです。
まず判定のメインとなるLike演算子ですが、
任意の文字列を表す*以外にも以下の条件記法が使えます。
条件記法 | 判定 |
---|---|
* | 任意の文字列(0文字も含む) |
? | 任意の1文字 |
# | 任意の数字1文字 |
[A-Z] | A~Zの内の1文字 |
[!A-Z] | A~Zでない1文字 |
※ A,Zには好きな文字を指定可能
Dir関数より細かい指定をすることができ、
例えば「yyyymmdd」に合致するフォルダを探したいときは、
「########」とすることで8桁の数値を判定できます。
かなり細かい条件まで指定できますが、「yyyymmddの中で一番最近のもの」のようにこれでも絞り切れない条件が必要な場合は、フォルダ名をセルに書き出してソートするなど細かく対応してください。
続いてFileSystemObjectに関する部分ですが、
こちらはSubFoldersで全ての子フォルダを取得する基本に忠実なコードです。
FSOのSetには事前バインディングを使用していますので、
このコードを実行する場合は「Scripting Runtime」を参照設定をしてください。
FileSystemObjectの各プロパティに関する詳しい解説はここでは省略します。
以下の一覧ページよりお探しください。
www.limecode.jp
Dir関数を利用する方法
一応ですが、Dir関数を使用する方法も置いておきます。
前述の通りFSOはUnicode(環境依存)文字を扱えるというメリットがあり、
またLike演算子に比べてDir関数は*と?しか条件に使用できないため、
Dir関数を使用したコードで書く意味は特にありません。
Dir(vbDirectory)の仕様の参考にでもしてください。
ソースコード
Sub フォルダ名が売上データ○○になっているフォルダを取得する() Dim 検索フォルダパス As String 検索フォルダパス = "C:\Users\○○\Desktop\検索フォルダ" Dim 該当フォルダパス As String Dim dir結果値 As String dir結果値 = Dir(検索フォルダパス & "\売上データ*", vbDirectory) Do While dir結果値 <> "" Dim dir結果パス As String dir結果パス = 検索フォルダパス & "\" & dir結果値 If GetAttr(dir結果パス) And vbDirectory Then 該当フォルダパス = dir結果パス Exit Do End If dir結果値 = Dir() Loop If 該当フォルダパス <> "" Then MsgBox "該当フォルダのパス:" & 該当フォルダパス End If End Sub
解説
FSOと違いDir関数は直接ワイルドカードを扱えるため、
Like演算子を使用しなくても、
dir結果値 = Dir(検索フォルダパス & "\売上データ*", vbDirectory)
という指定で部分一致検索を行うことができます。
このおかげで「ファイル名」の検索はDir関数で1発なのですが、
前述の通り「フォルダ名」の検索はこれではうまくいきません。
なぜならDir(パス, vbDirectory)という書き方は、
「フォルダまたはファイルを探す処理」になってしまうためです。
(詳しい解説はここでは省きます)
よって上記のコードは「売上データ○○.xlsx」をひっかける可能性があり、
これを防ぐためにパスがフォルダかどうかを、
If GetAttr(dir結果パス) And vbDirectory Then
このコードをループ内に記載して判定する必要があります。
そのせいでフォルダ/ファイルすべてをチェックするDo文が必要になり、
FSOよりも長く読みづらいコードになってしまいますね。
Dir関数はフォルダの検索が少々苦手なため、
FSOを使用した方がスッキリかける場合が多いです。
複雑なフォルダ管理を求められるマクロが必要になったら、
FileSystemObjectの習得をおすすめいたします。