サブフォルダを含めてファイル一覧を取得する(WSHでDirコマンドを実行)|Excel VBA |
WSH(Windows Script Host)の機能を利用してWindowsのDirコマンドを実行し、ファイル名の一覧を取得します。
Dirコマンドでは、対象となるフォルダやファイル属性、並び順、サブフォルダを含むかどうかの指定などを簡単に行うことができます。
次のサンプルはサブフォルダ内のファイルも含めたファイル名の一覧を取得し、A列にパスを、B列にファイル名を出力します。定数SEARCH_DIRに指定したフォルダについて、定数SEARCH_FILEで指定したファイルを検索します。
Sub Sample() Const SEARCH_DIR As String = "C:\Work" 'フォルダ名の末尾の"\"は不要 Const SEARCH_FILE As String = "*.csv" Dim tmpFile As String Dim strCmd As String Dim buf() As Byte Dim FileList() As String Dim myArray() As String Dim cnt As Long, pt As Long, i As Long 'Dirコマンドの結果を出力する一時ファイル tmpFile = Environ("TEMP") & "\Dir.tmp" 'Dirコマンド用の文字列を編集 strCmd = "Dir """ & SEARCH_DIR & "\" & SEARCH_FILE & _ """ /b/s/a:-d > """ & tmpFile & """" 'WSHでDirコマンドを実行 ---------------(1) With CreateObject("Wscript.Shell") .Run "c
md /c" & strCmd, 7, True End With '該当ファイルの存在チェック If FileLen(tmpFile) < 1 Then MsgBox "該当するファイルがありません" Exit Sub End If 'Dirコマンドの結果を出力した一時ファイルを読み込み Open tmpFile For Binary As #1 ReDim buf(1 To LOF(1)) Get #1, , buf Close #1 Kill tmpFile FileList() = Split(StrConv(buf, vbUnicode), vbCrLf) 'Dirコマンドの出力件数 cnt = UBound(FileList) 'ワークシート書き出し用の配列 ---------(2) ReDim myArray(1 To cnt, 1 To 2) For i = 1 To cnt pt = InStrRev(FileList(i - 1), "\") myArray(i, 1) = Left(FileList(i - 1), pt) 'パス myArray(i, 2) = Mid(FileList(i - 1), pt + 1) 'ファイル名 Next i '配列の値をワークシートに出力 ActiveSheet.UsedRange.ClearContents Range("A1").Value = "パス" Range("B1").Value = "ファイル名" Range("A2").Resize(cnt, 2).Value = myArray End Sub
(1)ではWSHのWshShellクラスのインスタンスを作成し、Runメソッドを実行します。コマンドプロンプトを呼び出し、変数strCmdで指定した命令(Dirコマンド)を実行しています。
Dirコマンドは次のような構文で記述します。
Dir パス\ファイル名 オプション
パスやファイル名にはワイルドカードを使用できます。パスを省略するとカレントフォルダが対象となり、ファイル名を省略するとすべてのファイルが対象になります。
サンプルではDirコマンドの出力結果を「>」で一時ファイルにリダイレクトしています。
Dirコマンドで指定できる主なオプションは次のとおりです。
オプション | 説明 |
---|---|
/b | フォルダ名・ファイル名のみを表示する。ただし /s オプションと一緒に指定した場合はパスも表示する |
/s | 指定したフォルダと、そこに含まれるサブフォルダの配下のすべてのファイルを表示する |
/o:並び順 | 並べ替えて表示する。並び順の指定子の前に「-」をつけると逆順になる n(名前のアルファベット順)、e(拡張子順)、s(サイズの小さい順)、d(日時の古い順)、g(フォルダを先に並べる) (例 /o:-d 日時の新しい順) |
/a:属性 | ファイルの属性を指定する。ファイル属性の指定子の前に「-」をつけるとそれを除く指定になる d(フォルダ)、h(隠しファイル)、s(システムファイル)、r(読取専用ファイル)、a(アーカイブ) (例 /a:d フォルダを検索 ) |
フォルダ名とファイル名を分けずにA列にフルパスで書き出す場合は、(2)以降のコードを次のようにすることもできます。
ActiveSheet.UsedRange.ClearContents
Range("A1").Resize(cnt, 1).Value = WorksheetFunction.Transpose(FileList)
ファイル名の一覧を取得する簡易な方法として、VBAのDir関数とループ処理を組み合わせる方法もあります。ただし、サブフォルダを含めるには再帰処理を行う必要があります。
詳細は「サブフォルダを含めてファイル一覧を取得する(Dir関数の再帰呼び出し)」を参照してください。
また、FSO(File System Object)を使って取得する方法もあります。FSOには作成年月日や最終アクセス日など、詳細な情報を取得できるプロパティがあります。
しかし一般に、FSOを使う方法よりもDirコマンドを使う方法の方が高速です。
取得したい項目やデータ量に応じて使い分けると良いでしょう。