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 ・・・新着記事一覧を見る

TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




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


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。


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