【ExcelVBA】Dir関数でサブフォルダ名一覧を取得する

ExcelVBA
記事内に広告が含まれています。

あるフォルダ内のフォルダ一覧、つまりサブフォルダの一覧を取得したいときは、Dir関数が便利です。

ここから先の説明はめちゃくちゃ長いので、先に結論を書いておきます。

こう書きます。

Dim 戻り値 As String
Dim 属性 As Integer

戻り値 = Dir(“C:\Users\ユーザー名\Desktop\*”,vbDirectory)

Do While 戻り値 <> “”
      ‘戻り値の内、余計なフォルダは対象から外す
  IF (戻り値 <>”.” And 戻り値 <>”..”) Then

    ‘戻り値の属性を取得
        属性 = GetAttr(“C:\Users\ユーザー名\Desktop\” & 戻り値)

    ‘フォルダ属性のもののみ処理する
    If ( 属性 AND vbDirectory)>0 Then
      ‘ここに処理を書く
    End If
  End If

  ‘次のフォルダ名を取得する
  戻り値= Dir()
Loop

では、長くなりますが1つずつ説明していきます。

Dir関数の考え方

別のページで書きましたが、フォルダがあるか・ないか調べるときは、Dir関数が使えます。

Dir関数は、
・指定したフォルダがある場合⇒そのフォルダ名を返す
・指定したフォルダがない場合⇒””(長さ0の文字列)を返す

これを応用して、このページの本題である「サブフォルダ一覧を取得する」を考えていきます。

Dir関数で、サブフォルダ名一覧を取得する方法

サブフォルダ名に「ワイルドカード(*)」を使う

例えば、Desktop内に「売上」フォルダがあるか・ないか、調べたいときは、こう書きます。

Dir(“C:\Users\ユーザー名\Desktop¥売上”,vbDirectory)

これを応用します。

Dir(“C:\Users\ユーザー名\Desktop¥*”,vbDirectory)

「売上」を「*」(ワイルドカード)に変えました。

「*」は、その部分は”どんな文字でも”・”何文字でも”OK、という意味です。

つまり、

Desktopフォルダにある、どんな名前でも何文字の名前でもいいから、全てのフォルダを取ってきてね、という意味になるのです。

まず1番目のフォルダを取得する

では、Dir関数が取ってきたフォルダ名を、変数に入れてみます。

Dim 戻り値 As String
戻り値 = Dir(“C:\Users\ユーザー名\Desktop\*”)

ここで返ってくるフォルダ名は、Desktopフォルダ内の”最初”のフォルダ名です。

Dir関数で返ってくるフォルダの順番

”最初”とあえて書いたのには、

”最初”の意味が、フォルダのあるディスク(CドライブとかDドライブとか)のファイルシステムによって違うからです。

詳しくはこの記事を見てください。

Windowsの場合は、ほぼ「フォルダ名の昇順」に返ってくると覚えていて問題ないかと思います。

同じ条件で2番目のフォルダを取得する

さて、”最初”の意味が少しややこしかったですが、

Desktopフォルダ内の1番目のフォルダは、無事に取得することができました。

でも、今回のテーマは、”全てのフォルダ”を取得することです。

2番目、3番目、・・・そして、最後のフォルダまで、全てのフォルダを取得したいのです。

そこで、次にお話するのは、Dir関数のちょっと変わった使いかたです。

Dir()

フォルダ名を書き忘れているわけではありません、これで正解なんです!

実は、()の中に何も書かない場合、直前に書いた()と同じ条件でフォルダを探し、次に見つかったフォルダを返してくれます。

具体例を見てみましょう。

Dim 戻り値1 As String
Dim 戻り値2 As String
変数1 = Dir(“C:\Users\ユーザー名\Desktop\*”,vbDirectory)
変数2 = Dir()

”戻り値2 = Dir()”は、”戻り値2 = Dir(“C:\Users\ユーザー名\Desktop\*”,vbDirectory)” と、同じ意味です。

つまり、戻り値1には、Desktopフォルダの1番目のフォルダ名が、

そして、戻り値2には、Desktopフォルダの2番目のフォルダ名が入ります。

同じ条件で3番目以降のフォルダも取得する

これで、Desktopフォルダ内のサブフォルダのうち、1番目も2番目も、無事に取得することができました。

でも、今回のテーマは、”全てのフォルダ”を取得することです。

しつこいですが、

3番目、4番目、・・・そして、最後のフォルダまで、全てのフォルダを取得したい・・・のです。

フォルダの数だけ変数を作って、フォルダの数だけDir()を繰り返す??

フォルダの数を先に調べないといけない??

それは面倒なので、こんな風に書いてみます。

Dim 戻り値 As String

戻り値 = Dir(“C:\Users\ユーザー名\Desktop\*”,vbDirectory)

Do While 戻り値 <> “”
  ‘ここに、やりたい処理を書く

  ‘次のフォルダ名を取得する
  戻り値= Dir()
Loop

戻り値= Dir()によって、Desktopフォルダ内にフォルダがある限り、戻り値にはフォルダ名が入ります。

そして、「Do While 戻り値 <> “”」 の、「戻り値 <> “”」は、戻り値にフォルダ名が入る限り繰り返す、という意味なので、

Desktopフォルダ内のサブフォルダの数分、繰り返し処理をすることができます。

いざ実行してみる

Desktopフォルダに、次のようなファイルやフォルダがあるとします。

ファイル1.xlsx
Aフォルダ
Bフォルダ

この状態でさっきのコードを実行すると、

こんな一覧がDir関数から返ってきます。

.
..
ファイル1.xlsx
Aフォルダ
Bフォルダ

「Aフォルダ」「Bフォルダ」だけを取りたかったんですが・・・。

問題その1:余計なフォルダが返ってきてしまう

見慣れない「.」「..」があります・・・。

「.」はカレントフォルダ(つまりフォルダ)、そして「..」はカレントフォルダの親フォルダ(これもフォルダ)、のことです。

Dir関数で全てのフォルダを取ろうとすると、こんな不要なものまで取ってきてしまいます。

エクスプローラーとか目では見えないけど、実はそんなフォルダを隠し持っているんです。

そういうものだと思ってください。

だから、これらは処理対象から外す必要があります。

問題その2:フォルダだけでなくファイルも返ってきてしまう

Dir(“C:\Users\ユーザー名\Desktop¥*”,vbDirectory)

こんな風に、2番目の引数に「vbDirectory」を指定しましたよね。

フォルダのみを取ってきて欲しいから「vbDirectory」を指定しているわけですが、

実はこれ、フォルダのみではなくファイルも取ってきてしまうんです!!

何のために指定するんだ!と思ってしまいますが、そういうものなので仕方ありません。

https://moglutton.com/excelvba-dir-return-attr/

なので、Dir関数の戻り値をさらにチェックして、フォルダかどうか確認する必要があります。

問題1・2を解決するコード

というわけで、

・戻り値の内、余計なフォルダは対象から外す

・戻り値の内、フォルダ属性のもののみ処理する

という2つの対応をすると、こうなります。

Dim 戻り値 As String
Dim 属性 As Integer

戻り値 = Dir(“C:\Users\ユーザー名\Desktop\*”,vbDirectory)

Do While 名前 <> “”
      ‘戻り値の内、余計なフォルダは対象から外す
  IF (戻り値 <>”.” And 戻り値 <>”..”) Then

    ‘戻り値の属性を取得
        属性 = GetAttr(“C:\Users\ユーザー名\Desktop\” & 戻り値)

    ‘フォルダ属性のもののみ処理する
    If ( 属性 AND vbDirectory)>0 Then
      ‘ここに処理を書く
    End If
  End If

  ‘次のフォルダ名を取得する
  戻り値= Dir()
Loop

「If ( 属性 AND vbDirectory)>0 Then」の部分は、ビット演算です。もし難しければ、こういうものだと思ってください。

これでようやく完成です!

長かったですね、お疲れ様でした(^^)/

サイト運営者
もぐらっとん

シスエムエンジニア歴15年。フリーランスになって2年。家庭と両立するため在宅で仕事をしています。
RPA(Uipath)開発・運用と、ブログ運営(Wordpress)をしています。
※当ブログとは別に、主婦ブログも運営しています
https://syufumesen.com/

もぐらっとんをフォローする
ExcelVBA
シェアする
もぐらっとんをフォローする
もぐらっとんWEB
タイトルとURLをコピーしました