こんにちは、blueです。
今回はVBA関数であるDir関数について説明しようと思います。
ちなみにこの記事は躓きに対する備忘録です。
主観が入っていると思いますがご容赦くださいませ。
なお正しい説明はOffice Tanakaさんの動画を見られればすべてわかると思います。
FSOが使えればDir関数自体は不要です。
ただ他人のマクロを見たりするとDir関数が出てきたりもするので両方覚えておくことに越したことはないです。
今回は理解するのにややこしかったところについて説明します。
Dir関数のややこしいところ
私の考えるDir関数のややこしいところは以下です。
- 引数は「フルパス」で記載する必要があるが返ってくるのは「ファイル名」である
- ワイルドカードを使わないとファイルの存在確認になる
- ワイルドカードを使うとフォルダ内のファイルを検索してくれるが1つ目しか返してくれない。
- ワイルドカードを使った場合の2つ目以降のファイルは引数なしで指定する必要がある
まずはDir関数の基本について説明します。
Dir関数の基本
Office Tanakaさんも言われている通りDir関数の使い方は以下3つになります。
- Dir(”C:\Users\Public\Book1.xlsx”)
ワイルドカード(*や?)を含まない - Dir(”C:\Users\Public\*.xlsx”)
ワイルドカードを含む - Dir()
1つ目はファイルの存在確認、2つ目と3つ目はフォルダ内のファイル検索としてセットで使います。
この3種類の使い方があるというのが肝です。
次から本題(ややこしかったところ)に入ります。
1.引数は「フルパス」で記載する必要があるが返ってくるのは「ファイル名」である
Dir関数の基本的な書き方と戻り値は以下になります。

ここでややこしいのは「指定はフルパスを要求するのに、返ってくるのはファイル名(ここでは〇〇〇.拡張子とする)のみになる」ということです。
ファイル名のみが必要な場合はこれでよいのですがフルパスやファイルの名前(ここでは〇〇〇とする)のみが欲しい場合などは再度操作する必要があります。
ちなみにFSOであれば取得したファイルオブジェクトのフルパスはPathプロパティで取得可能(リンク参照)ですし、Get〇〇〇Nameメソッド(リンク参照)を使えば以下のようにどの形でも取得することができます。

「Book.xlsx」での取得しかできないのがつらいところです。
2.ワイルドカードを使わないとファイルの存在確認になる
2つ目はDir関数をワイルドカードの有り無しで使い方が変わるというところです。
使わない場合の書き方と戻り値は以下のようになります。

このようにファイルの存在確認になります。
一方使った場合はファイル検索の挙動になります。
ややこしいのは同じ関数なのに2通りの使い方があるというところです。
ちなみにワイルドカードを使わない場合はFSOだとFileExistsメソッドにあたります。
メソッドに関する記事はこちら

Dir関数の挙動としては一つなのでしょうがワイルドカードの有り無しだけで使い方が大きく変わるのがやっかいなところです。
なおDir関数で存在確認をした際、存在する場合はファイル名、存在しない場合は””を返す特徴があります。TrueやFalseではないのもややこしいところです。
3.ワイルドカードを使うと一致するファイルを検索してくれるが1つ目しか返してくれない。
3つ目はワイルドカードを使った場合の戻り値に関する話です。
今回はC:¥Users¥Publicのフォルダ内のファイルを調べることとします。

Dir関数でワイルドカードを使う場合の書き方は以下になります。

ワイルドカードを記載すると該当するファイル名を取得できます。
ただこれだけではすべてのファイルは取得できません。最初のファイルだけになります。
「ファイル検索の為にワイルドカードで指定したのに1つしか取得できない」、これがややこしいところです。
2つ目以降を取得するには以降のDir()を使う必要があります。
4.ワイルドカードを使った場合の2つ目以降のファイルは引数なしで指定する必要がある
先ほど述べた通り、ワイルドカードを使った場合では検索に一致する1つ目のファイルしか取得できませんでした。
2つ目以降は引数なしで指定する必要があります。
Dir関数を引数なしで使い場合の書き方は以下になります。

なお2つ目のファイルがある場合はファイル名が返ってきますがない場合は””で返ります。
これが非常にわかりにくいのですがそういうものらしいです(調べましたがよくわかりませんでした)。
結論として1つ目はDir(”C:\Users\Public\*.xlsx”)、2つ目以降はDir()で取得するということになります。
つまり以下になります。確認のために間にMsgBoxを入れています。
Sub Dir_Function1()
Dim FolderPath As String
Dim FileName As String
FolderPath = "C:\Users\Public"
FileName = Dir(FolderPath & "\*.xlsx")
MsgBox FileName
FileName = Dir()
MsgBox FileName
FileName = Dir()
MsgBox FileName
FileName = Dir()
MsgBox FileName
End Sub
結果は以下のようになります。ファイル名が順にとれていることがわかります。




これらのことから2つ目以降はDo~Loopでまとめればよいということになります。
コードで書くと以下のようになります。
Sub Dir_Function2()
Dim FolderPath As String
Dim FileName As String
FolderPath = "C:\Users\Public"
FileName = Dir(FolderPath & "\*.xlsx")
MsgBox FileName
Do While FileName <> ""
MsgBox FileName
FileName = Dir()
Loop
End Sub
結果的に1つ目の書き方と2つ目以降の書き方が変わります。
この形は暗記するしかないようです。
まとめると以下のようになります。

1つ目の処理と2つ目以降の処理を分けるところを理解しておかないとこのコードを書くことはできません。
今回のまとめ
今回はDir関数のややこしい所について説明しました。
- 引数は「フルパス」で記載する必要があるが返ってくるのは「ファイル名」である
- ワイルドカードを使わないとファイルの存在確認になる
- ワイルドカードを使うとフォルダ内のファイルを検索してくれるが1つ目しか返してくれない。
- ワイルドカードを使った場合の2つ目以降のファイルは引数なしで指定する必要がある
個人的には使いにくい関数でほぼ丸暗記なきがします(丸暗記でいいとはOffice Tanakaさんもおっしゃられてました)。
ただ使用する機会が多いのはワイルドカードを使用するパターンであり、1つ目と2つ目の処理が異なることを理解しておけばある程度は書けると思います。
備忘録ですが参考にしていただければ幸いです。
Dir関数の使い方については以下の書籍で詳しく説明されています。
『複数ブックの操作』の際に活用できる関数なので参考にしてください。
コメント