エクセルVBAで使うコードの備忘録。VBAで指定フォルダ内のファイル数をサブフォルダ内も含めてすべて取得するコード。ちなみにサブフォルダを含まず、指定フォルダ内のみのファイルを取得する場合はこちらをご覧ください。
フォルダ一覧を取得する
下部フォルダも含めたすべてのファイルを取得するには、まず指定フォルダ内に存在するサブフォルダ一覧を取得する必要があります(サブフォルダの一覧を取得するコードについてはこちらをご参照ください)。サブフォルダのパスを全て取得することができてしまえば、あとはそれぞれのフォルダに対してファイル一覧を取得してやればOKです。
当たり前ではありますが、サブフォルダ内も含めて含まれるファイル数がどれだけあるのかを取得したい場合には、下記サンプルコードで取得したフォルダパスの要素数(変数であるfileListの要素数)を取得してやればよいです。
なお、サンプルコードを使用する際はカッコに囲まれた部分([***])を自分のプログラムに合わせて変更してください。
サンプルコード
'--- 指定フォルダ内に含まれるすべてのファイルパスを取得 ---'
Public Sub GetAllFilePath()
'--- ファイル一覧を取得したいフォルダのパス ---'
Dim folderPath As String
folderPath = "[フォルダパス]"
'--- サブフォルダのパス一覧を取得 ---'
Dim folderList As Variant
folderList = GetFolderPath(folderPath)
'--- 指定フォルダのファイルパスを取得
Dim fileList() As String
fileList = GetFileListFso(folderPath)
'--- ファイル数を保存する変数 ---'
Dim n As Long
Dim m As Long
'--- サブフォルダのファイルパスを取得し順次結合する
Dim tmpList() As String
Dim i As Long
Dim s As Variant
For Each s In folderList
tmpList = GetFileListFso(CStr(s))
n = GetArrayLength(fileList)
m = GetArrayLength(tmpList)
If (0 < n + m) Then
ReDim Preserve fileList(1 To n + m)
For i = 1 To m
fileList(n + i) = tmpList(i)
Next i
End If
Next s
End Sub
'--- 1次元配列の要素数を取得する関数 ---'
Public Function GetArrayLength(vList As Variant) As Long
Dim n As Long
If (IsEmptyArray(vList)) Then
n = 0
Else
n = UBound(vList)
End If
GetArrayLength = n
End Function
'--- フォルダに含まれる(サブフォルダ除く)のファイル一覧を取得する関数 ---'
Public Function GetFileListFso(folderPath As String) As String()
'--- ファイルシステムオブジェクト ---'
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
'--- ファイル数を格納する変数 ---'
Dim n As Variant
n = fso.GetFolder(folderPath).Files.Count
If (0 < n) Then
'--- ファイル名を格納する配列 ---'
Dim str() As String
ReDim str(1 To n)
'--- ファイル名を格納 ---'
i = 1
Dim f As Object
For Each f In fso.GetFolder(folderPath).Files
str(i) = f.Path
i = i + 1
Next f
End If
GetFileListFso = str
End Function
'--- サブフォルダを再帰的に取得する関数 ---'
Public Function GetFolderPath(folderPath As String) As String()
'--- ファイルシステムオブジェクト ---'
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
'--- フォルダ数を格納する変数 ---'
Dim n As Variant
n = fso.GetFolder(folderPath).SubFolders.Count
If (0 < n) Then
'--- フォルダパスを格納する配列 ---'
Dim str() As String
ReDim str(1 To n)
'--- フォルダパスを格納 ---'
Dim i As Long
Dim j As Long
Dim m As Long
i = 1
Dim strTmp() As String
'フォルダパスを指定してすべてのサブフォルダを取得
Dim f As Object
For Each f In fso.GetFolder(folderPath).SubFolders
str(i) = f.Path
strTmp = GetFolderPath(str(i)) '再帰的呼び出し
If (Not IsEmptyArray(strTmp)) Then
m = UBound(strTmp, 1)
Else
m = 0
End If
'サブフォルダ内にさらにフォルダがあればその分だけ配列を拡張
n = UBound(str, 1)
ReDim Preserve str(1 To n + m)
For j = 1 To m
str(i + j) = strTmp(j)
Next j
i = i + m + 1
Next f
End If
GetFolderPath = str
End Function
'--- 配列が空かどうかを判定する関数 ---'
Public Function IsEmptyArray(arrayTmp As Variant) As Boolean
On Error GoTo ERROR_
If (0 < UBound(arrayTmp, 1)) Then
IsEmptyArray = False
End If
Exit Function
ERROR_:
IsEmptyArray = True
End Function