フォルダ配下(サブフォルダも)ファイル一覧を取得するには【CMD】【ExcelVBA】
コマンドプロンプトとVBAで、フォルダ配下のすべてのファイルの一覧を取得する方法を紹介します。
環境
こういうフォルダ構成の環境があったとします。
C:\test>tree /f
フォルダー パスの一覧: ボリューム Windows-SSD
ボリューム シリアル番号は D0EF-3D22 です
C:.
│ results-001-タイプAとタイプBを比較.pptx
│ results-002-タイプAとタイプCを比較.pptx
│ results-003-タイプBとタイプCを比較.pptx
│ results-004-タイプCとタイプDを比較.pptx
│ test.jpg
│
└─Sub1
│ 果物.xlsx
│
└─Sub2
aaaa.txt
C:\test配下にあるすべてのファイル(サブフォルダ含む)を取得する方法について説明します。
コマンドプロンプト
コマンドプロンプトでやる場合には、Dirコマンドを使います。
dir /b/a:-D/s
/bでパスだけを表示(ファイルサイズや更新日等を表示しない)し、/a:-Dでディレクトリを除きファイルだけを表示し、/sでサブフォルダも検索するという意味になります。
以下は実行してみたところ。
C:\test>dir /b/a:-D/s
C:\test\results-001-タイプAとタイプBを比較.pptx
C:\test\results-002-タイプAとタイプCを比較.pptx
C:\test\results-003-タイプBとタイプCを比較.pptx
C:\test\results-004-タイプCとタイプDを比較.pptx
C:\test\test.jpg
C:\test\Sub1\果物.xlsx
C:\test\Sub1\Sub2\aaaa.txt
VBA
ExcelVBAでやる場合、Dirを使う方法もありますが、私はFIleSystemObjectを使って再帰検索する方法が割と好きでよく使います。
Option Explicit
Public Sub GetFileList()
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject") '---①
Dim stFiles As Collection
Set stFiles = New Collection
Dim oFolder As Object
Set oFolder = FSO.GetFolder("C:\test")
Call GetFileRe(oFolder, stFiles)
If stFiles.Count > 0 Then
Dim vOut() As Variant, ii As Long '---②
ReDim vOut(1 To stFiles.Count) '---②
For ii = LBound(vOut) To UBound(vOut) '---②
vOut(ii) = stFiles(ii) '---②
Next ii
With ThisWorkbook.Worksheets(1)
.Cells(2, 2).Resize(UBound(vOut), 1).Value = WorksheetFunction.Transpose(vOut)
End With
End If
Set oFolder = Nothing
Set FSO = Nothing
Set stFiles = Nothing
End Sub
Private Sub GetFileRe(oFolder As Object, ByRef stFiles As Collection)
Dim oFol As Object
Dim oFile As Object
'---③ ここでFSOをクリエイトしない
For Each oFol In oFolder.SubFolders
'再帰呼出
Call GetFileRe(oFol, stFiles) '---④
Next oFol
For Each oFile In oFolder.Files
'コレクションに追加
stFiles.Add oFile.path, oFile.path
Next oFile
End Sub
①、③の解説
Webを検索していると、CreateObjectを③に記述しているコードを見かけるのですが、再帰呼出されるサブ関数の中でオブジェクトをCreateすることが、私はノイジーに感じてしまうので、①の位置でCreateしました。
②の解説
検索して得た情報をどうやってアウトプットするかですが、Cellsにそのまま書き出すのも一つの手ですが、Cellsに書き出す場合、1レコードを1書き出しというやり方をするのはどうしてものろく感じるので、全部のレコードを一度に1回だけCellsに書き出す方法を採用しています。
そのため、いったんメモリ上のvOutという配列に、コレクションの値を書き出しています。
④の解説
再帰呼出しています。
再帰呼出はネストが深くなるとメモリオーバフロを起こすことがあります。私が経験した環境では、ネストの深さより、ファイル名の長さの方がネックでした(256文字以上のファイル名が存在した)。
そのときは、その長いファイル名だけは飛ばして処理をするようにし、手動でそのファイルだけをあとで付け加えることにしました。自動でなんとかするのは無理でした。
まとめ
ファイル一覧を作成する方法を二つ紹介しました。
ファイル一覧を作成するのは、実務ではほとんどの場合、コマンドプロンプトでやっていました。
dir /s/b/a:-D > list.txt
というように、テキストにリダイレクトして使っていました。
サブフォルダも検索してくれるのがコマンドプロンプトの強みですね。
サブフォルダを検索する必要がなければ、GUIでもできます。
エクスプローラーでファイル名を全部選択し、Shiftキーを押しながら右クリックしてパスのコピーを選べば、ファイル名一覧を取得できます。
何かの参考になれば幸いです。
-
前の記事
【ExcelVBA】CallByNameの使い方 2022.12.14
-
次の記事
【VBScript】サブフォルダも検索してファイル一覧を取得するには 2022.12.16