VBAサンプル集
エクセルでファイル一覧を作成.№8(インデント)

ExcelマクロVBAでファイル一覧を作成、サブフォルダ以下を全て取得
公開日:2013年5月以前 最終更新日:2014-11-11

エクセルでファイル一覧を作成.№8(インデント)


エクセルでファイル一覧を作成します、


サブフォルダ以下も全て取得し、一覧表示します、



さて、前回の再帰処理で、サブフォルダも以下も全て取得できましたので、


後は、体裁を整えるだけになりました。



今回は、サブフォルダ毎に、列をずらして(インデントして)、見やすくします。


以下が修正後のプログラムです。




Option Explicit


Public Const cnsRow As Long = 4 '開始行
Public Const cnsCol As Long = 2 '開始列
Public ColMax As Long       '最終列の保存


Sub ファイル一覧取得()
  Dim objFSO As FileSystemObject
  Dim strDir As String
  Dim i As Long, j As Long
  
  strDir = Cells(cnsRow, cnsCol)
  'FileSystemObjectのインスタンスの生成
  Set objFSO = New FileSystemObject
  'フォルダの存在確認
  If Not objFSO.FolderExists(strDir) Then
    MsgBox ("指定のフォルダは存在しません")
    Exit Sub
  End If
  '表示領域を初期設定
  Range(Rows(cnsRow), Rows(Cells.SpecialCells(xlCellTypeLastCell).Row)).Clear
  Range(Columns(cnsCol), Columns(Cells.SpecialCells(xlCellTypeLastCell).Column)).ColumnWidth = 3
  Cells(cnsRow, cnsCol) = strDir
  '開始行列
  i = cnsRow + 1
  j = cnsCol
  ColMax = cnsCol
  '再帰処理モジュールのコール
  Call GetDirFiles(objFSO.GetFolder(strDir), i, j)
  'オブジェクトの解放
  Set objFSO = Nothing
  '列幅を調整
  Range(Columns(cnsCol), Columns(Columns.Count)).ColumnWidth = 3

  Range(Columns(ColMax), Columns(ColMax + 2)).EntireColumn.AutoFit

End Sub

Sub GetDirFiles(ByVal objFolder As Folder, ByRef i As Long, ByVal j As Long)
  Dim objFolderSub As Folder
  Dim objFile As File
  '最終列が増えた場合は、サイズの前に1列追加する
  If j > ColMax Then
    Columns(j).Insert Shift:=xlToRight
    ColMax = j
  End If
  'サブフォルダの取得
  For Each objFolderSub In objFolder.SubFolders
    Cells(i, j) = objFolderSub.Name
    i = i + 1
    Call GetDirFiles(objFolderSub, i, j + 1)
  Next
  'ファイルの取得
  For Each objFile In objFolder.Files
    With objFile
      Cells(i, j) = .Name
      Cells(i, ColMax + 1) = WorksheetFunction.RoundUp(.Size / 1024, 0)
      Cells(i, ColMax + 1).NumberFormatLocal = "#,##0 ""KB"""
      Cells(i, ColMax + 2) = .DateLastModified
      i = i + 1
    End With
  Next
  'オブジェクトの解放
  Set objFolderSub = Nothing
  Set objFile = Nothing
End Sub


太字が修正部分です。


Public Const cnsRow As Long = 4 '開始行
Public Const cnsCol As Long = 2 '開始列
Public ColMax As Long       '最終列の保存

パブリック変数として、開始行、開始列を持ちます。

シートモジュールのボタンクリックでも使用できるように。

また、処理中の最終列をどのモジュールからも参照できるようにします。


Range(Rows(cnsRow), Rows(Cells.SpecialCells(xlCellTypeLastCell).Row)).Clear

開始行から、エクセルが保持している最終セルの行までを、一括でクリアしています。


Cells(cnsRow, cnsCol) = strDir
退避してある指定フォルダをセルに戻します。


i = cnsRow + 1
j = cnsCol
ColMax = cnsCol

開始行(指定フォルダの位置)の次からを、表示開始行として、変数に入れます。

開始列を変数に入れます。

ColMaxは最終列なので、開始時は、開始列を入れておきます。


Call GetDirFiles(objFSO.GetFolder(strDir), i, j)
モジュールの引数に、列が増えているので追加しています。


Sub GetDirFiles(ByVal objFolder As Folder, ByRef i As Long, ByVal j As Long)

列を引数に追加します。

この引数は、ByValである事に注意して下さい。

元のCall元に変数の変化を戻しません。


If j > ColMax Then
  Columns(j).Insert Shift:=xlToRight
  ColMax = j
End If

最終列が増える場合は、サイズ、更新日時の列を後ろにずらします。


Cells(i, j) = objFolderSub.Name
フォルダ名を最終列にいれます。


Call GetDirFiles(objFolderSub, i, j + 1)

再帰呼び出しで、現在列を1加算します。

ByValなので、戻ってきても値は変化しません。


Cells(i, j) = .Name

ファィル名を最終列にいれます。


Cells(i, ColMax + 1) = WorksheetFunction.RoundUp(.Size / 1024, 0)
Cells(i, ColMax + 1).NumberFormatLocal = "#,##0 ""KB"""
Cells(i, ColMax + 2) = .DateLastModified
サイズ、更新日時を、最終列の隣に入れます。


Range(Columns(cnsCol), Columns(Columns.Count)).ColumnWidth = 3

列幅を全て3に統一します。


Range(Columns(ColMax), Columns(ColMax + 2)).EntireColumn.AutoFit

最終列と、サイズ、更新日時の列をオートフィットで列幅調整します。

最終列は、ファィル名が全て見えるようにする為です。

これでも、手前の階層で長いファイル名は途中で見えなくなってしまいます。

ロジックで、これを全て表示するのは大変なので、適当に列幅を指定するのが良いと思います。


列の変数jは、実際には、値を加算していませんので、ByRefでも動作に問題はありません。

しかし、ByValと宣言することで、プログラムを理解し易くしています。


これで、サブフォルダ毎にインデントされ、見易くなりました。



列の追加削除がある場合は、ボタンが移動しないようにしておく必要があります。


デザインモードで、ボタンを選択し、


「コントロールの書式」→「プロパティ」


ここで、「セルに合わせて移動やサイズ変更をしない」にチェックを付けます。


また、印刷時に邪魔な場合は、「オブジェクトを印刷しない」にもチェックして下さい。



今回は、技術的には何も新しい事はありませんでした。


問題は、列のインデントの実現を、いかに簡単に行うかでしょう。


変数jの値を変化させずに、再帰呼び出しの際に、「j + 1」としている所がポイントでしょう。



省略時のByRefについて


そもそもVBAでは、省略時が、ByRefと言うのは解せない。


VB.NETでは、記述を省略すると、ByValが自動で付加されます。


本来は、そうあるべきだと思うのですが、何故ByRefにしているのでしょうかね。


多分、昔の負の遺産といったところなんでしょう。


値を元に戻す事は、プログラマーが意識して記述する必要があるはずです。


無意識に値が戻っていると言うのは、非常に危険なのですが。


VBAをやり初めて、ある程度出来るようになってきた時に、


必ず戸惑う事になるのではないかと危惧します。


かといって、初めてVBAをやる人に、ByValを指定するように説明するのは大変です。


作成済の過去のプログラムもあるので、省略時は、ByRefのままにしておき、


新規作成時に、自動でByValを付加してくれれば良いのではないかと思うのですが。


多分、VBAでは、ずっとこのままでしょうね。





同じテーマ「ファイル一覧を作成」の記事

エクセルでファイル一覧を作成.№1(概要)
エクセルでファイル一覧を作成.№2(Dir関数1)
エクセルでファイル一覧を作成.№3(Dir関数2)
エクセルでファイル一覧を作成.№4(FileLen,FileDateTime)
エクセルでファイル一覧を作成.№5(FileDialog)
エクセルでファイル一覧を作成.№6(FileSystemObject1)
エクセルでファイル一覧を作成.№7(FileSystemObject2)
エクセルでファイル一覧を作成.№8(インデント)
エクセルでファイル一覧を作成.№9(罫線)
エクセルでファイル一覧を作成.№10(完成)


新着記事NEW ・・・新着記事一覧を見る

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ