指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

【本日のミッション】

Excel VBAにて指定したフォルダ内とサブフォルダ内全てのファイル名を取得し、Excelのシートに書き出せ

以前お話しした

指定したフォルダ内のファイル名全てを取得(Excel VBA)

の応用版ですね。

指定したフォルダ内のファイル名だけではなく、サブフォルダ全部のファイル名を取得したい時だってありますよね(#^.^#)

今回指定フォルダにするのはこちらです。

この第1階層フォルダ(←前回のミッションで「第一」って漢数字になっていたのを修正・・・)のファイルとサブフォルダ内のファイル、合計21個のファイル名を取得していきます。

 

Excelマクロ有効ブック(.xlsm)のファイルを新規作成します。

そのファイルのシートに下記の通り、フォルダのパスを入力するセル(A3)、取得したファイル名を書き出すセル(6行目1列目)を準備します。

フォルダパスには、ファイル名を取得したい一番上の階層のフォルダのフルパスを入力します。

このシートをアクティブにした状態で、Alt+F11でVsual Basic Editerを起動します。

[挿入]-[標準モジュール]で新規モジュールを作成し、下記の通りコードを記入します。

■スポンサーリンク

Sub 指定したフォルダ内とサブフォルダ内全部のファイル名取得()

    'アクティブシートから処理対象のフォルダパスを取得し
    'そのフォルダ内とサブフォルダ内全部のファイル名を全てアクティブシートに取得

    '【変数】
    Dim ws As Worksheet '処理対象シート
    Dim pt As String    '処理対象パス
    Dim t_row As Long   'ファイル名書出行

    '■変数セット
    Set ws = ActiveSheet '変数ws=アクティブシートをセット
    pt = ws.Range("A3")  '変数ptにセルA3のパスをセット
    t_row = 6            'ファイル名を書き出す初めのセルの行番号をセット

    '■指定したフォルダ内とサブフォルダ内全部のファイル名をセルに書き出し
    Call ファイル名一覧取得(pt, ws, t_row)
End Sub

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long)
    Dim FSO As Object 'FileSystemObject
    Dim buf As String 'ファイル名
    Dim fd As Object  'フォルダ
    buf = Dir(pt & "\" & "*.*")   '変数bufに1個目のファイル名を格納
    Do While buf <> ""            'bufが空欄になるまでDo While内の処理を続ける
        ws.Cells(t_row, 1) = buf  '対象セルにファイル名を書き出し
        t_row = t_row + 1         'ファイル名を書き出すセルの行番号+1(一つ下の行番号)
        buf = Dir() '変数bufに次のファイル名を格納(ファイルが無い場合は空欄になる)
    Loop
   Set FSO = CreateObject("Scripting.FileSystemObject") 'FileSystemObjectのインスタンス化
   For Each fd In FSO.GetFolder(pt).SubFolders          'サブフォルダ群から1つずつfnに入れて順に処理
       Call ファイル名一覧取得(fd.Path, ws, t_row)        '再帰処理
   Next fd
   Set FSO = Nothing 'FSOを空っぽにする
End Sub

お気づきですか?

今回のコードは2つのプロシージャ(Sub~End Subまで)から成り立っているんです。

「Sub 指定したフォルダ内とサブフォルダ内全部のファイル名取得」プロシージャのどこかにカーソルを置いてF5キーをクリックしてください。

Excelのシートを見てください。

うわ~~~~!!

これ、初めてできたとき感激しました。

ファイル操作のVBAが少し使えるようになるだけで、「神」みたいに思えちゃう(#^.^#)

ちなみに、どんな順番でファイルを取得したかと申しますとこんな感じです。

上の階層から順に攻めていくのかと思っていたのですが、初めに攻めたフォルダの下の階層の方が先に処理されるんですね。

今回難しいポイントは4つ。

■Callとは?

他のSubプロシージャやFunctionプロシージャの処理を行います。

「Call」を省略して、プロシージャの名前だけでも処理してくれるのですが、私は後から見たとき、これナニ?ってならないように「Call」を付けるようにしています。

今回、私は

Call ファイル名一覧取得(pt, ws, t_row)

みたいに、プロシージャ名の後ろに「(変数)」を指定しています。

今日は簡単に説明しちゃいますね。

「指定したフォルダ内とサブフォルダ内全部のファイル名取得」プロシージャ内で、セットした変数「pt」「 ws」「 t_row」をお弁当箱に入れて、「ファイル名一覧取得」プロシージャに持っていきますよ~、みたいな感じです。

お弁当箱に入れて持ってきた変数は、持って行った先のプロシージャでも、それぞれが何者(データ型)か宣言し、そのプロシージャ内で利用します。

Sub ファイル名一覧取得(pt As String, ws As Worksheet, t_row As Long)

この引数の深~~~いお話はまた次の機会↓にさせて頂きますね。

参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)

■For Eachとは?

For Each 変数 In コレクション
    ***処理***
Next  

とすることで、コレクションの中にあるもの1つ目から順に変数に入れてNextまでの処理を行い、コレクションの中にあるもの全ての処理が終わったらNext以降の処理に移ります。

今回は「fd」という変数をObjectとして宣言しています。Objectはここではフォルダです。

For Each fd In FSO.GetFolder(pt).SubFolders

Call ファイル名一覧取得(fd.Path, ws, t_row)

Next fd

コレクション部の「FSO.GetFolder(pt).SubFolders」ってナゾですよね。意味合いとしては、変数pt(処理対象パス)のフォルダのサブフォルダ群のことです。

残りの2つのポイントは、後日ご説明させていただきます。

■CreateObject(“Scripting.FileSystemObject”)とは

CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得

■再帰処理とは?

再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

【参考】
指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
フォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)

■スポンサーリンク

■ランキングに参加しています。
↓このブログを気に入っていただけましたら、ポチッとお願いします。
にほんブログ村 IT技術ブログへ
にほんブログ村