VBAで任意フォルダのファイル一覧を取得する(Dir関数の使用)
VBAで任意フォルダのファイル一覧を取得する方法について書きます。
マクロから外部ファイルを読込む様な処理で、
(任意)フォルダ直下の全ファイルについて処理したい場合に有効です。
VBAで任意フォルダのファイル一覧を取得する(Dir関数の使用)
参考
Dir関数 microsoft
VBA応用(フォルダ内のファイル一覧の取得)
[ソース]
Public Function getFileList(ByVal folderPass As String, Optional ByVal onlyXLS = 0) As String() '------------------------------------------------------------------------------------------------------ ' getFileList ' 指定したフォルダのファイル一覧を取得する ' ' 引数1:folderPass ・・・ フォルダパス ' 引数2:onlyXLS ・・・ 「.xls」を含むファイル名のみ取得するか否か(デフォルト:0(全てのファイル)) ' ' 戻り:String() ・・・ ファイル一覧 ' ' 使用注:フォルダパスの整合性確認は参照元で実装してください。(If Dir(folderPass, vbDirectory) = "" Then) '------------------------------------------------------------------------------------------------------ Const xlsKey = ".xls" 'Excelファイル判定キー Const cnsDIR = "\*.*" Dim fileName As String Dim ret() As String '返却用配列 Dim i As Long '返却用配列 カウンタ ' 先頭のファイル名取得 fileName = Dir(folderPass & cnsDIR, vbNormal) ' 指定フォルダの全Excelワークブックについて繰り返す Do While fileName <> "" '「.xls」を含むファイル名のみ取得する場合 If onlyXLS Then '「.xls」を含まないファイル名は除外する If InStr(fileName, xlsKey) = 0 Then GoTo nextDO End If End If 'ファイル名を返却用配列に格納 ReDim Preserve ret(i) As String ret(i) = fileName i = i + 1 nextDO: ' 次のファイル名を参照 End Function |
Dir関数の仕様ですが、
1度目のDir呼出しは、第1引数にフォルダパスを設定します。
→先頭のファイル名が返却されます。
※第2引数はファイル種別です。なおvbNormalは規定値なので省略可です。
2度目以降(Doループ処理内)のDir呼出しは引数なしにします。
→ファイルが無くなった時点で空値が返却される様です。
今までマクロを組む時は、このDir()関数の呼出しループ内に処理を記載していたのですが、
コードの可読性UP+再利用の為にFunction化しました。
呼出し元で結局ファイルリスト分ループ処理を実装する必要があるため、処理は増えてしまいます。
フォルダパスの整合性については、参照元で実装する必要があります。
Function内でエラー判定してしまうと、Boolean等の返却が必要になり、あまりきれいにできないかと思った為です。
テストしてみる
以下は、テスト用のモジュールです。[ソース]
Public Sub testGetFileList() 'メッセージ Dim msg As String 'フォルダパス(サンプル) Dim folderPass As String folderPass = "C:\wk\vba\sampleDir" 'ファイルリスト Dim list() As String 'フォルダパスの整合性確認 If Dir(folderPass, vbDirectory) = "" Then msg = MsgBox("指定したフォルダは存在しません", vbOKOnly, "getFileList()のテスト") Exit Sub 'フォルダパスが正しい場合 Else Call addMsg(msg, "指定したフォルダ:") Call addMsg(msg, folderPass) Call addMsg(msg) Call addMsg(msg, "ファイル一覧") Call addMsg(msg, "------------------------------") 'ファイルリストの取得 list = getFileList(folderPass) Dim i As Long 'カウンタ 'ファイルリストの数分ループ For i = 0 To UBound(list, 1) Call addMsg(msg, list(i)) Next i Call addMsg(msg, "------------------------------") End If msg = MsgBox(msg, vbOKOnly, "getFileList()のテスト") End Sub Private Sub addMsg(msg As String, Optional addMsg = "") msg = msg + addMsg + vbCrLf End Sub |
サンプルフォルダを作成して、テストプロシージャを実行してみます。
ファイル一覧が取得できました。サブフォルダは取得されませんね。
フォルダパスが誤っていた場合は、以下の様にエラーとなります。
ちなみに、今回のFunctionには第2引数に「onlyXLS」として、「.xls」を含むファイルのみ抽出するか選択できるようにしてみました。
[onlyXLSを使用する場合のソース]
'ファイルリストの取得 list = getFileList(folderPass, 1) |
この状態でテストモジュール(testGetFileList())を実行した結果は、以下の通りです。
以上です。