指定フォルダ配下をFileSystemObjectで取得する、けどソートは?

VBAで指定フォルダ配下を取得するにはFileSystemObjectを利用します。

ただ、FileSystemObjectではフォルダやファイルが名前でソートされているとは限らないため、対応が必要になります。

大抵の場合はSubFoldersコレクションやFilesコレクションの先頭から順に取得すると名前順になっているようですが、コレクションのため本当に名前順なのかが不明でMicrosoftのヘルプにも明示されていない以上、やはりソート対策は必要になります。

以下で紹介する指定フォルダ配下のフォルダとファイルの一覧を取得するマクロは、フォルダ名とファイル名を昇順ソートした状態で取得します。

また、指定フォルダ内にフォルダとファイルがある場合はエクスプローラーでの表示とは異なり、先にファイルを取得し、そのあとにサブフォルダを取得するようにしています。これを逆にしてエクスプローラの表示と同じように、サブフォルダを先に取得する方法については後述します。


事前設定

以下のコードではFileSystemObjectを参照設定した状態になっていることが前提になります。

そのため、VBA画面のツールメニュー→参照設定を選び、Microsoft Scripting Runtimeにチェックする必要があります。


指定フォルダ内のフォルダとファイルの一覧を取得するマクロ

以下に2つの関数があります。SearchAllDirFile関数とinsertsortAsc関数です。メインとなるのは1つ目のSearchAllDirFile関数で、2つ目のinsertsortAsc関数は配列ソートに使っています。

1つ目のSearchAllDirFile関数の1つ目の引数に一覧を取得したいフォルダを指定し、2つ目の引数に一覧を格納する動的配列を指定します。詳細は後述の使い方を参照ください。

ここでは配列のソートに挿入ソートの仕組みを利用しています。

その理由は、SubFoldersコレクションやFilesコレクションは名前の昇順に並んでいることが多いようで、ソートが不要なことが多いように見えます。

そのため昇順で並んでいることが前提であれば、クイックソートよりも挿入ソートの方が高速のため、挿入ソートを採用しています。

なお、挿入ソートについては「VBAの配列を挿入ソートで並べ替え」で紹介しているコードをそのまま使っています。



ADODBでのソートをお勧めしない理由

上のコードでは名前順のソートを行うために挿入ソートを利用していますが、ADODB.RecordSetクラスを利用するとデータベースのSQLのORDER BYのソート指定のような書き方をすることが可能です。

ただ、この方法はあまりお勧めしません。

理由は、ADODB自体があまり一般的でなくコードがマニアックなものになり保守性が悪いことと、いろんな条件のソートに柔軟に対応しにくいためです。SQLをご存じない方は苦労するかもしれません。

できるだけ多くの人に理解してもらえればと思い、挿入ソートでの方法にしています。


使い方

このようなフォルダ構成で、赤枠部分の一覧を取得したいとします。

その場合は以下のように7行目の1つ目の引数にパスを指定し、2つ目の引数に動的配列を指定します。

実行結果は以下のようになります。



フォルダとファイルの出力順を入れ替えたい場合

上のコードではフォルダ内にあるサブフォルダとファイルの両方がある場合は、先にファイルを出力していますが、フォルダを先に出力したい場合は、上のコードの20行目から46行目のファイル処理部分と、51行目から80行目のフォルダ処理部分の位置を入れ替えてください。