- ベストアンサー
VBA フォルダ一覧を取得したい
フォルダを指定したら、その中のフォルダ一覧を配列に取得したいのです。 どうすればいいでしょう?中の中までは不要です。出来ればFSO使用で教えて下さい。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 たぶん、、、SubFoldersプロパティに辿りつく処までは、そう難しくないでしょうけれど、 FoldersコレクションのItemをindex番号で呼び出せない、という例外に躓く方は少なくない、かと。 以下、 オブジェクト変数の幾つかは省略して書くことも出来ますが、 構造的な理解が得られやすいように、また、エラーへの対応が容易になるように、 ネストしないで、ひとつずつSetするように書いてみました。 ' ' ============================== ' ' /// 参照設定:Microsoft Scripting Runtime Sub Re8891880() Const S_PATH = "ドライブ名:\フォルダパス" Dim vRtn() Dim oFSO As Scripting.FileSystemObject Dim oFld As Scripting.Folder Dim colFlds As Scripting.Folders Dim f As Scripting.Folder Dim i As Long Set oFSO = CreateObject("Scripting.FileSystemObject") ' fso インスタンス生成 Set oFld = oFSO.GetFolder(S_PATH) ' fsoで指定のFolderオブジェクトを取得 Set colFlds = oFld.SubFolders ' 指定のFolderのSubFoldersコレクションを取得 ReDim vRtn(1 To colFlds.Count) ' 配列変数をリサイズ ' ' Foldersコレクション(=この場合はサブフォルダ)の各Folderオブジェクトを総当たり For Each f In colFlds i = i + 1 ' カウンタインクリメント vRtn(i) = f.Name ' (サブ)フォルダ名を配列変数に格納 Next ' ' 以下確認用 Debug.Print "■ フォルダ"""; S_PATH; """ の サブフォルダー一覧 ■" Debug.Print Join(vRtn(), vbLf) End Sub ' ' ==============================
その他の回答 (1)
- cj_mover
- ベストアンサー率76% (292/381)
> 配列はvariant型のようですが、Stringは使えないのでしょうか? 文字列型の配列が必要なら、文字列型で宣言すれば、 Dim vRtn() As String " As String"を書き加えるだけで、そのまま動きます。 特に指定なく、"配列"ということでしたから、 Variant型配列で書いただけのことで、 運用の段階で、必要に応じて書き分けてくれれば良いことです。 要点は値の格納が済んだ後の配列変数を、渡す先の要求次第です。 そういう意味では、一次元配列にするべきか、二次元なのか、 ということも同様に渡す先の要求次第ですから、 Dim 或いは ReDim に関してこちらが書いたものは、 あくまでサンプル、ということです。 > ネットで検索してもセルに直接代入とか、variantが多いようです。 セル範囲(特に単一でないセル範囲の)の値を VBAで出し入れする場合は、基本的にVariant型を使います。 処理が厚量で、Variant型で処理することで遅くなるから、とか、 処理中のどの段階でも常に必ず文字列値として扱うことが約束されている、 とか、の条件によっては、 セル範囲に出力する(配列)変数をString型(配列)として宣言することも 可能ですし、VBA側での処理速度やメモリ使用量についてメリットがある 場合もあります。 一方、Variant型変数には、Empty値、Null値、エラー値、等の 特殊な値を格納することが可能です。 初期値で比較すると、文字列変数では""、Variant型変数はEmpty値です。 セル範囲に""(長さ0の文字列)を返したくない特殊な場面などでは、 出力用配列をVariant型で宣言することが必要なこともあります。 > また、f.Nameの型は何なのでしょうか?string? String型です。 こういうのは、ご自分で確かめた方が良いと思います。 Debug.Print TypeName(f.Name) とか、 Debug.Print VarType(f.Name) = vbString とか、 直接プロシージャに書き込んで走らせてもいいですし、 ステップ実行やブレークポイントの設定などの初歩的なデバッグ作業として、 実行を中断させながら、 ローカルウィンドウでデータ型を確認することも出来ますし、 イミディエイトウィンドウに ? TypeName(f.Name) とか、 ? VarType(f.Name) = vbString とか、書き込んでReturnキーで結果を得ることも出来ます。 以上の説明を整理しますが、 後々の処理を全く意識しないで、唯々フォルダ名を取得したものを 配列変数に格納するだけなら、String型配列を用いれば十分ですし、 中間処理で文字列値をVariant型で加工したりすることがないなら、 そのままセル範囲に出力したとしても、支障はありません。 ただ、セル範囲の値を、v = Range("A1:C5").Value、のように、 一息に変数に格納する場合の受け皿はVariant型以外にないですから、 InputとOutputを揃える意味で (例えば取得した値を直接加工して返す場合もありますから) 出力時もVariant型を使う方がサンプルとしては妥当性がある、 という言い方は出来るのかも知れません。 Excelの、VBAで、セル範囲の値を配列変数で出し入れする場合、の話、であって、 他の場面では当て嵌まらないことも多いですし、 また、人によって教え方が違ってくるレベルの話でもあります。 説明がうまくないかも、ですが、もし解らなくても、あまり気にせず、 日々の実践の中で必要に副った書き方をすることを優先させて行けば好いようにも 思います。 以上です。
お礼
ありがとうございます。よくわかりました。
お礼
ありがとうございます。 実は御推察通り呼び出しで詰まってます。 >vRtn(i) = f.Name ' (サブ)フォルダ名を配列変数に格納 配列はvariant型のようですが、Stringは使えないのでしょうか?ネットで検索してもセルに直接代入とか、variantが多いようです。また、f.Nameの型は何なのでしょうか?string?