kiyo_hikoのブログ

メモ+日記?

VBA使ってフォルダーのサブフォルダーとファイルを再帰的に拾う

いろいろ切り詰めていたが、そろそろボーナスだから最近は財布の紐もゆるめいて来て、Excel2010を買った。これで家でもExcelを勉強できるようになった。

手始めにFileSystemObjectを使った。


FileSystemObject (以下FSO) を使うには、VBEの参照設定で、Microsoft Scripting Runtimeをチェックする。

Dim fso As Object
Set fso = OreateObject("Scrpting.FileSystemObject")

↑でもFSOのインスタンスを作れるみたいだが、めんどくさいしインテリセンスが効かない。


VBAの文法はなんだか煩雑さを感じるが、とりあえずFSOはモジュールレベルでNew付きで宣言しておけば記述が簡単そう。

Private fso As New Scripting.FileSystemObject

この書き方でデメリットがあるかどうかは不明。


FileとFiles、FolderとFoldersというクラスがあって、これらに慣れるため、とにかくあるフォルダーの中身を再帰的に列挙するコードを書いた。
mainのGetFolderの引数を、見たいパス文字列にしてmainを実行する。

Sub main()
    search fso.GetFolder("test"), 0
End Sub

' あるフォルダーのサブフォルダーとファイルを再帰しながら列挙する
Sub search(ByVal folder As Folder, ByVal depth As Long)
    Dim fo As folder
    Dim fi As file
    Debug.Print duplicate(depth, "│" & vbTab) & "├" & folder.Name & " <DIR>"
    For Each fo In folder.SubFolders
        If Mid(fo.Name, 1, 1) <> "." Then search fo, depth + 1
    Next
    For Each fi In folder.files
        Debug.Print duplicate(depth + 1, "│" & vbTab) & "├─" & fi.Name _
            & " (" & Round(fi.size / 1024) & "KB" & ")"
    Next
End Sub

' 文字列sをn個繋げた文字列を返す
Function duplicate(ByVal n As Long, ByVal s As String)
    Dim ss As String
    Dim i  As Long
    For i = 0 To n - 1: ss = ss & s: Next i
    duplicate = ss
End Function

↓こうなった。

f:id:kiyo_hiko:20130519041904p:plain

追記

ファイルの階層表示がずれていたので直した。
searchの9行目、depthをdepth + 1にした。画像を差し替えた。