今回は、過去3回投稿した、サンプルコードの最終解説をしていきたいと思います。
まだ、投稿を見ていない方は下記のURLからご覧ください!
サンプルコード
Sub ListFilesWithDetails()
Dim folderPath As String
Dim ws As Worksheet
Dim i As Long
Dim sheetName As String
Dim ans As VbMsgBoxResult
' フォルダ選択ダイアログ
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "フォルダを選択してください"
If .Show <> -1 Then Exit Sub
folderPath = .SelectedItems(1)
End With
' シート名の入力
sheetName = InputBox("出力先のシート名を入力してください", "シート名指定", "ファイル一覧")
If sheetName = "" Then Exit Sub
' すでにシートが存在するか確認
On Error Resume Next
Set ws = Worksheets(sheetName)
On Error GoTo 0
If Not ws Is Nothing Then
ans = MsgBox("シート「" & sheetName & "」はすでに存在します。上書きしますか?", vbYesNo + vbExclamation)
If ans = vbNo Then Exit Sub
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
' 新しいシート作成
Set ws = Worksheets.Add
ws.Name = sheetName
' ヘッダー
ws.Cells(1, 1).Value = "ファイル名"
ws.Cells(1, 2).Value = "フルパス"
ws.Cells(1, 3).Value = "更新日時"
ws.Cells(1, 4).Value = "サイズ(KB)"
i = 2
' ファイル一覧取得
Call GetFilesRecursive(folderPath, ws, i)
' 表の整形
ws.Columns("A:D").AutoFit
MsgBox "完了しました!", vbInformation
End Sub
Sub GetFilesRecursive(ByVal folderPath As String, ByRef ws As Worksheet, ByRef rowIndex As Long)
Dim fso As Object, folder As Object, file As Object, subFolders As Object, subF As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(folderPath)
' ファイル一覧取得
For Each file In folder.Files
ws.Cells(rowIndex, 1).Value = file.Name
ws.Cells(rowIndex, 2).Value = file.Path
ws.Cells(rowIndex, 3).Value = file.DateLastModified
ws.Cells(rowIndex, 4).Value = Round(file.Size / 1024, 1)
rowIndex = rowIndex + 1
Next
' サブフォルダも再帰的に処理
Set subFolders = folder.SubFolders
For Each subF In subFolders
GetFilesRecursive subF.Path, ws, rowIndex
Next
End Sub
解説
ファイル一覧取得
' ファイル一覧取得
For Each file In folder.Files
ws.Cells(rowIndex, 1).Value = file.Name
ws.Cells(rowIndex, 2).Value = file.Path
ws.Cells(rowIndex, 3).Value = file.DateLastModified
ws.Cells(rowIndex, 4).Value = Round(file.Size / 1024, 1)
rowIndex = rowIndex + 1
Next
① For Each file In folder.Files
folder.Files
は、対象フォルダ内のファイル一覧です。
それを1件ずつ、file
という変数に入れて処理しています。file
はFile
オブジェクトで、ファイル名やサイズなどの情報を持っています。
② ws.Cells(rowIndex, 1).Value = file.Name
- Excelの
ws
シートのrowIndex
行、1列目(A列)に「ファイル名」を書き込みます。 file.Name
はファイル名(拡張子付き)
③ ws.Cells(rowIndex, 2).Value = file.Path
- B列に「ファイルのフルパス」(例:
C:\MyFolder\file.txt
)を書き込みます。
④ ws.Cells(rowIndex, 3).Value = file.DateLastModified
- C列に「ファイルの最終更新日時」を書き込みます。
file.DateLastModified
はDate
型で、いつ最後に保存されたかを表します。
⑤ ws.Cells(rowIndex, 4).Value = Round(file.Size / 1024, 1)
- D列に「ファイルサイズ(KB単位)」を表示します。
file.Size
はバイト単位なので、/ 1024
でKBに変換。Round(..., 1)
は小数第1位で四捨五入しています(例:123.4KB)。
⑥ rowIndex = rowIndex + 1
- 次のファイルを書き込むために行番号を1行下に進めます。
⑦ Next
- 次のファイルに進み、同じ処理を繰り返します。
サブフォルダも再帰的に処理
' サブフォルダも再帰的に処理
Set subFolders = folder.SubFolders
For Each subF In subFolders
GetFilesRecursive subF.Path, ws, rowIndex
Next
End Sub
①Set subFolders = folder.SubFolders
folder.SubFolders
は、今処理しているフォルダの中にある サブフォルダの一覧 を取得するプロパティ。それをsubFolders
に格納しています。
例:もしC:\Data
フォルダにSub1
とSub2
というフォルダがあれば、subFolders
はこの2つを持ちます。
② For Each subF In subFolders
- サブフォルダを1つずつ、
subF
という変数に入れて処理。
③ GetFilesRecursive subF.Path, ws, rowIndex
- 再帰処理(再帰呼び出し)
GetFilesRecursive
(=自分自身)をまた呼び出しています。subF.Path
はサブフォルダのパス(例:C:\Data\Sub1
)です。
つまり:「サブフォルダの中も、同じようにファイルを一覧にして、さらにその中にサブサブフォルダがあればまた繰り返す」という流れです。
④ Next
と End Sub
Next
で次のサブフォルダへ。- 最後に
End Sub
で処理終了。
再帰処理とは?
「自分自身を中で呼び出す処理」のことです。
- あるフォルダを調べる
- ファイル一覧をシートに出力
- サブフォルダがあれば、その中でもまた同じように繰り返す
- さらにその中にサブフォルダがあれば、また繰り返す…
というふうに 深さ無制限でフォルダをすべて網羅できるようになります。
まとめ
今回も、各コードがどのような動きをしているのか、過去4回に渡って1行ずつ解説してきました。
ぜひ皆さんも実際に書いたり、サンプルを動かしたりしてみてください!
別投稿で、CSVファイルの内容をExcelに転記する方法も紹介しています!