■お題
指定したフォルダ以下にある全てのフォルダを表示すること
指定したフォルダ以下にある全てのフォルダを表示すること
■解答例
ファイルシステムオブジェクトの「オブジェクト.SubFolders」を使えばよさそうですね。
まずは、考え方です。こういう風に考えてみました。
指定フォルダに対し、「オブジェクト.SubFolders」で指定フォルダ内のサブフォルダが取得できます。
例えば、指定フォルダには10個のフォルダがあったとします。
この情報を配列に格納しておきます。
次に、この配列に対しDoLoopで一つ一つ、サブフォルダを取得するのを繰り返せばよさそうです。
ただし、DoLoop内で新たに見つけたサブフォルダを処理の候補にいれる為共通の配列に格納する必要があります。
↑新たにみつけたものを追加。
そこで、引数の受け渡しに参照渡し(ByRef)で渡してフォルダのリストを更新し続けます。
まずは、サブフォルダの一覧を取得するテストコードを書いてみます。
5行目:今回は、C:\testフォルダパスを指定
7行目:ファイルシステムオブジェクトを生成
8行目:Folders型とFolder型のオブジェクトの変数を宣言
9行目:指定したフォルダ内の全てのフォルダの情報を取得
11行目:For文で8行目で取得した全てのフォルダ情報を一つずつ渡していく
12行目:フォルダ情報のうち、パスのプロパティをデバック表示する
13行目:繰り返し。
これで、指定したフォルダ内にあるフォルダパスを取得できますね。
では、参照渡しで一つの配列にフォルダパスを格納するあたりを確認するコードを書いてみます。
- test2_main -
4行目:指定するファルダ名を格納する変数
5行目:今回は、C:\testフォルダパスを指定
7行目:フォルダパスを一括管理する用の変数です。
参照渡しでサブ関数に渡してフォルダパス情報を受け取るのに使います。
8行目:フォルダパスが追加されるか確認するために、適当に何か配列に格納しておきます。
9行目:パスと、配列を渡し、"test2_b"で第一引数のパス配下にあるフォルダ情報を格納させる。
11行目:参照渡しで格納してもらった配列の中身をFor文で確認する為For文で使う変数を宣言
12行目:For文で配列の一覧を確認
13行目:デバック表示する
14行目:繰り返し
- test2_sub -
18行目:ファイルシステムオブジェクトを生成
19行目:Folders型とFolder型のオブジェクトの変数を宣言
20行目:指定したフォルダ内の全てのフォルダの情報を取得
22行目:動的に配列を増やす際に使う変数を宣言。要素数の管理に使用。
23行目:再宣言するために現在の配列の最後の要素数を調べる。
そして、再宣言するために1多くしとく。(注:後で問題発生します)
25行目:For文で19行目で取得した全てのフォルダ情報を一つずつ渡していく
26行目:配列の要素数を再定義をする。 Preserveキーワードをつけないと今まで格納した
データが消えてしまうので、Preserveキーワードをつけておく。
27行目:最後の要素にフォルダパスを格納する
29行目:配列の再定義に使う変数を1つインクリメントする
30行目:繰り返し
メモ:Uboundは、配列の一番最後の要素数を返す。
あとは、DoLoopで繰り返す部分を作れば完成ですね。
ファイルシステムオブジェクトの「オブジェクト.SubFolders」を使えばよさそうですね。
まずは、考え方です。こういう風に考えてみました。
指定フォルダに対し、「オブジェクト.SubFolders」で指定フォルダ内のサブフォルダが取得できます。
例えば、指定フォルダには10個のフォルダがあったとします。
この情報を配列に格納しておきます。
次に、この配列に対しDoLoopで一つ一つ、サブフォルダを取得するのを繰り返せばよさそうです。
ただし、DoLoop内で新たに見つけたサブフォルダを処理の候補にいれる為共通の配列に格納する必要があります。
↑新たにみつけたものを追加。
そこで、引数の受け渡しに参照渡し(ByRef)で渡してフォルダのリストを更新し続けます。
まずは、サブフォルダの一覧を取得するテストコードを書いてみます。
Option Explicit Sub test1() Dim FolderPath As String FolderPath = "C:\test" Dim FSO As New FileSystemObject Dim Folders As Folders, Folder As Folder Set Folders = FSO.GetFolder(FolderPath).SubFolders For Each Folder In Folders Debug.Print Folder.Path Next End Sub4行目:指定するファルダ名を格納する変数
5行目:今回は、C:\testフォルダパスを指定
7行目:ファイルシステムオブジェクトを生成
8行目:Folders型とFolder型のオブジェクトの変数を宣言
9行目:指定したフォルダ内の全てのフォルダの情報を取得
11行目:For文で8行目で取得した全てのフォルダ情報を一つずつ渡していく
12行目:フォルダ情報のうち、パスのプロパティをデバック表示する
13行目:繰り返し。
これで、指定したフォルダ内にあるフォルダパスを取得できますね。
では、参照渡しで一つの配列にフォルダパスを格納するあたりを確認するコードを書いてみます。
Option Explicit Sub test2_main() Dim FolderPath As String FolderPath = "C:\test" Dim FolderList As Variant FolderList = Array("FolderPass_1", "FolderPass_2", "FolderPass_3") Call test2_sub(FolderPath, FolderList) Dim Folder As Variant For Each Folder In FolderList Debug.Print Folder Next End Sub Sub test2_sub(ByVal FolderPath As String, ByRef FolderList As Variant) Dim FSO As New FileSystemObject Dim Folders As Folders, Folder As Folder Set Folders = FSO.GetFolder(FolderPath).SubFolders Dim i As Integer i = UBound(FolderList) + 1 For Each Folder In Folders ReDim Preserve FolderList(i) FolderList(i) = Folder.Path i = i + 1 Next End Sub
- test2_main -
4行目:指定するファルダ名を格納する変数
5行目:今回は、C:\testフォルダパスを指定
7行目:フォルダパスを一括管理する用の変数です。
参照渡しでサブ関数に渡してフォルダパス情報を受け取るのに使います。
8行目:フォルダパスが追加されるか確認するために、適当に何か配列に格納しておきます。
9行目:パスと、配列を渡し、"test2_b"で第一引数のパス配下にあるフォルダ情報を格納させる。
11行目:参照渡しで格納してもらった配列の中身をFor文で確認する為For文で使う変数を宣言
12行目:For文で配列の一覧を確認
13行目:デバック表示する
14行目:繰り返し
- test2_sub -
18行目:ファイルシステムオブジェクトを生成
19行目:Folders型とFolder型のオブジェクトの変数を宣言
20行目:指定したフォルダ内の全てのフォルダの情報を取得
22行目:動的に配列を増やす際に使う変数を宣言。要素数の管理に使用。
23行目:再宣言するために現在の配列の最後の要素数を調べる。
そして、再宣言するために1多くしとく。(注:後で問題発生します)
25行目:For文で19行目で取得した全てのフォルダ情報を一つずつ渡していく
26行目:配列の要素数を再定義をする。 Preserveキーワードをつけないと今まで格納した
データが消えてしまうので、Preserveキーワードをつけておく。
27行目:最後の要素にフォルダパスを格納する
29行目:配列の再定義に使う変数を1つインクリメントする
30行目:繰り返し
メモ:Uboundは、配列の一番最後の要素数を返す。
あとは、DoLoopで繰り返す部分を作れば完成ですね。
Option Explicit Sub main() Dim FolderName As String, Result() As String FolderName = "C:\test" Result = GetAllFolderPath(FolderName) Dim f As Variant For Each f In Result Debug.Print f Next End Sub Function GetAllFolderPath(ByVal FolderName As String) Dim FolderPathList() As String, LastIndex As Integer LastIndex = -1 Call GetFolderPath(FolderName, FolderPathList, LastIndex) If LastIndex = -1 Then GetAllFolderPath = Array("") Exit Function End If Dim i As Integer i = 0 Do Call GetFolderPath(FolderPathList(i), FolderPathList, LastIndex) i = i + 1 Loop While i < LastIndex GetAllFolderPath = FolderPathList End Function Sub GetFolderPath(ByVal FolderName As String, ByRef FolderPathList As Variant, ByRef LastIndex As Integer) Dim FSO As New FileSystemObject Dim Folders As Folders, Folder As Folder Set Folders = FSO.GetFolder(FolderName).SubFolders For Each Folder In Folders LastIndex = LastIndex + 1 If LastIndex = 0 Then ReDim FolderPathList(LastIndex) Else ReDim Preserve FolderPathList(LastIndex) End If FolderPathList(LastIndex) = Folder.Path Next End Sub動的配列用の変数は、要素数が確定する前にUBoundを使うとエラーとなるので 使わずに、要素数を知るために、管理用に一つ変数を増やして参照渡しして管理してます。 使い方は、GetAllFolderPathに調べたいフォルダのパスを引数として渡す。 で、要素数を指定してない配列を返り値に受け取る。 以上。 ちなみに、下記フォルダ構成だと。 イミディエイトウィンドウには、こんな出力になる。
0 件のコメント:
コメントを投稿