Excel VBA Dir関数(2)ファイル・フォルダを複数検索する

Excel マクロ、VBA

スポンサーリンク

Dir関数とワイルドカードを使ってファイル名を書き出す

前回の記事で述べたが、Excel VBAのDir関数は、たとえば
Dir(“D:\ダウンロード\普通のファイル.xlsx“)
としたなら「普通のファイル.xlsx」とファイル(・フォルダ)名そのものを返すものだ。

そして、指定したファイル・フォルダが存在しなかったら空文字列を返す。

だから、ファイル・フォルダの名前を指定して、それが本当に存在するのかを調べるという用途に使える。
VBAの中で、特定のファイル名とかを指定する時に、それの存在を事前チェックするのに使えるわけだ。

Excel VBA Dir関数(1)基本仕様

ワイルドカードを使った検索

しかしDir関数が力を発揮するのは、
*(長さゼロも含む任意の文字)
?(1文字)
という、ワイルドカードを使った検索だろう。

?の方を使うことは私はほぼ無いので、*の方に絞って話を進める。

たとえば

Dir(“D:\ダウンロード\*.xls“)

とすると、「D:\ダウンロード\」フォルダの中にある拡張子「.xls」のファイルが何か見付かる
(なんか以前のExcelでは、xlsという3文字の拡張子を指定すると、xlsxとかxlsmとか4文字の拡張子まで検索に引っかかったらしいが、今はそんな挙動は確認できなかった)

何か見付かるという書き方をしたわけだが、本当に何か1つのファイル・フォルダが見付かるだけなので、それで終わっても何の役にも立たないだろう。

このワイルドカード*を使った検索は、フォルダやファイルを片っ端から全部検索していくといった用途に使えるものであり、そのためにはループ処理を掛けることになる。

Dir関数の特性を生かしたループ処理

そこで大事なことだが、Dir関数は、最初の1回は引数を指定する必要があるが、2回目以降は引数を指定すれば直前の検索動作を繰り返し実行するということだ。

たとえば

Debug.Print Dir(“D:\ダウンロード\*.xlsx”)
Debug.Print Dir
Debug.Print Dir
Debug.Print Dir
Debug.Print Dir

とすると、2行目以降の単なるDirは、1行目の
Debug.Print Dir(“D:\ダウンロード\*.xlsx”)
を繰り返し実行していることになり、拡張子xlsxのファイルを繰り返し検索しているわけだ。

そしてDir関数では、全てのExcelファイルを検索したいといった使い道が多いはずなので、Dir関数でそういう目的のファイルが見付からなくなるまでループを掛けるという処理を記述すれば良い。

VBAのループ文となると通常はForだが、このDir関数については、検索結果が品切れするまで繰り返すということなのでDo~Loopで良いだろう。

だから、「D:\ダウンロード\」フォルダ内のExcelファイル=拡張子に「xls」文字を含むファイルを全て書き出すマクロとなると、次のような感じになる。

サブフォルダを書き出してみる

同様に、フォルダを片っ端から検索する場合には、Dir関数の属性vbDirectoryを指定すれば良いのだが、ファイルの場合とは違う点がある。

ファイル検索の時と同様に

とすれば全てのフォルダを検索できるのだが、フォルダだけでなくファイルまで全て検索されてしまうのは前回述べた通りだ。

しかもこの場合、「.」「..」という訳の分からない2つのものも抽出されてしまう。
これは以前の記事で少し述べたが、
「.」なら自フォルダ
「..」なら1つ上のフォルダ
を示す。

もちろん、こんな妙なものは普通は排除しなければならない。

Excel VBA 空のフォルダを一括削除するマクロ

ということで、まずファイル・フォルダが両方見付かる中から「フォルダ」属性のものを見付けるが、これは以前に紹介したGetAttr関数で行う。
そして「.」「..」の2つを除く処理はストレートに記述する。

以上をまとめると、サブフォルダを一覧に書き出すマクロは次のようになる。

うん、とても面倒だ。
Dir関数はこのように、属性を指定できる割に別途GetAttr関数を併用しないといけなかったりで、どうにも不便なことが大きい。

これなら、FileSystemObjectというやつが、多機能で便利なことが多いんじゃないかと思う。
FileSystemObjectについては、内容が多くなるけど、また今度書いてみようと思う。

Dir関数も、前回述べたようなファイルの有無を調べる簡易的用途なら、普通に使えるんだけどね。

スポンサーリンク