フォルダ内の一括ファイル情報取得
VBA応用(フォルダ内のファイル一覧の取得)
http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_080.html
EXCEL VBA マクロで 応答なし を回避
http://d.hatena.ne.jp/umonist/20130826/p1
上記をほとんど使わさせていただいて以下のように記述。
ほぼそのままだけれど、軽くなるよう&応答なしの処理部分追記。
'変数の宣言 Option Explicit Private g_cntFILE As Long 'ファイル数 Private g_cntPATH As Long 'パス Sub フォルダ選択テスト() Dim objFSO As FileSystemObject Dim strPathName As String Dim objShell As Object Set objShell = CreateObject("Shell.Application") ' ルートとなるフォルダの指定 (※modAPIBrowseForFolder2.bas) 'strPATHNAME = modAPIBrowseForFolder2.BrowseForFolder( _ "ルートフォルダを指定して下さい。", True) strPathName = objShell.browseforfolder(0, "ルートフォルダ指定", &H1) End Sub '******************************************************************************* ' 全体処理(ルートフォルダを指定して探索を開始) '******************************************************************************* Sub 指定フォルダ内出力() Dim objFSO As FileSystemObject 'Dim strPathName As String Dim strPathName As String, vntPathName As Variant Dim objShell As Object Dim xlAPP As Application Const cnsTitle = "フォルダ内のファイル名一覧取得" Application.ScreenUpdating = False '変更を反映させない Application.Calculation = xlCalculationManual '再計算を手動にする Set xlAPP = Application ' InputBoxでフォルダ指定を受ける vntPathName = xlAPP.InputBox("参照するフォルダ名を入力して下さい。", _ cnsTitle, "C:\") ' ① If VarType(vntPathName) = vbBoolean Then Exit Sub strPathName = vntPathName ' フォルダの存在確認 If Dir(strPathName, vbDirectory) = "" Then ' ② MsgBox "指定のフォルダは存在しません。", vbExclamation, cnsTitle Exit Sub End If ' 処理開始 Cells.ClearContents Set objFSO = New FileSystemObject ' FSO Debug.Print strPathName ' ルートフォルダから探索開始 Call SEARCH_SUB_FOLDER(objFSO.GetFolder(strPathName), 0, 0) 'Call SEARCH_SUB(objFSO.GetFolder(strPATHNAME), 0, 0) ' 参照OBJECTを破棄 Set objFSO = Nothing '元に戻す Application.StatusBar = False Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic ' 処理完了(結果表示) MsgBox "処理が完了しました。" & vbCr & vbCr & _ "フォルダ数=" & g_cntPATH & vbCr & _ "ファイル数=" & g_cntFILE, vbInformation End Sub '******************************************************************************* ' フォルダ単位のサブ処理(再帰動作,引数はFile-Object,行,カラム) '******************************************************************************* Private Sub SEARCH_SUB_FOLDER(ByVal objPATH As Folder, _ ByRef GYO As Long, _ ByVal COL As Long) Dim objPATH2 As Folder Dim objFILE As File ' 現在フォルダをシート上に表示 g_cntPATH = g_cntPATH + 1 ' 参照フォルダ数を加算 GYO = GYO + 1 ' 行を加算 COL = COL + 1 ' カラムを加算 Cells(GYO, COL).Value = "[" & objPATH.Name & "]" ' ■先ずサブフォルダを探索するループ処理 For Each objPATH2 In objPATH.SubFolders ' フォルダ単位のサブ処理(再帰呼び出し) Call SEARCH_SUB_FOLDER(objPATH2, GYO, COL) Next objPATH2 ' ■本フォルダの各ファイルをシート上に表示するループ処理 COL = COL + 1 ' カラムを加算 For Each objFILE In objPATH.Files g_cntFILE = g_cntFILE + 1 ' 参照ファイル数 GYO = GYO + 1 ' 行を加算 With objFILE ' ファイル名+(最終更新日時+ファイルサイズ) 'ファイル名+最終更新日時+バイト 'Cells(GYO, COL).Value = .Name & _ " (" & .DateLastModified & " " & _ Format(.Size, "#,##0") & "Bytes)" 'ファイル名、最終更新日時、バイトを分けて出力 Cells(GYO, COL).Value = .Name Cells(GYO, COL + 1).Value = .DateLastModified '最終更新日時 Cells(GYO, COL + 2).Value = Format(.Size, "#,##0") & "Bytes)" 'バイト End With Next objFILE DoEvents Application.StatusBar = "処理中" ' 参照OBJECTを破棄 Set objPATH = Nothing End Sub
上記の設定しないで
階層とファイル数あるものを一括ですると止まっていたので、
これで動いてくれるといいのだけれど・・・。
再帰関数だと呼び出すたびに
調べてみるとスタックフレームが割り振られ、
スタックオーバーフローになる。
これで重くてどうしようもなければ
再帰関数の部分をスタックで帰る場所
元のサブフォルダを格納しておき、下の階層全部終わったら戻る
ような書き方に変えるのがいいのかな。