エクセルでファイル一覧を作成 | エクセルでファイル一覧を作成.8(インデント) | ExcelマクロVBAでファイル一覧を作成、サブフォルダ以下を全て取得



最終更新日: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では、ずっとこのままでしょうね。






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

エクセルでファイル一覧を作成.9(罫線)
エクセルでファイル一覧を作成.10(完成)
エクセルでファイル一覧を作成.1(概要)
エクセルでファイル一覧を作成.2(Dir関数1)
エクセルでファイル一覧を作成.3(Dir関数2)
エクセルでファイル一覧を作成.4(FileLen,FileDateTime)
エクセルでファイル一覧を作成.5(FileDialog)

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

SUMIFの間違いによるパフォーマンスの低下について|エクセル関数超技(6月17日)
条件式のいろいろな書き方:TrueとFalseの判定とは|ExcelマクロVBA技術解説(6月15日)
空白セルを正しく判定する方法2|ExcelマクロVBA技術解説(5月6日)
フルパスをディレクトリ、ファイル名、拡張子に分ける|ExcelマクロVBA技術解説(4月15日)
テキストボックスの各種イベント|Excelユーザーフォーム入門(4月9日)
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除|ExcelマクロVBAサンプル集(4月4日)
最後の空白(や指定文字)以降の文字を取り出す|エクセル関数超技(3月26日)
先頭の数値、最後の数値を取り出す|エクセル関数超技(3月26日)
Excelファイルを開かずにシート名をチェック|ExcelマクロVBAサンプル集(3月23日)
数式の参照しているセルを取得する|ExcelマクロVBAサンプル集(3月18日)

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

1.最終行の取得(End,Rows.Count)|ExcelマクロVBA入門
2.RangeとCellsの使い方|ExcelマクロVBA入門
3.Range以外の指定方法(Cells,Rows,Columns)|ExcelマクロVBA入門
4.変数とデータ型(Dim)|ExcelマクロVBA入門
5.徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)|エクセル関数超技
6.セルのコピー&値の貼り付け(PasteSpecial)|ExcelマクロVBA入門
7.定数と型宣言文字(Const)|ExcelマクロVBA入門
8.セルの参照範囲を可変にする(OFFSET,COUNTA,MATCH)|エクセル関数超技
9.CSVの読み込み方法|ExcelマクロVBAサンプル集
10.ひらがな⇔カタカナの変換|エクセル基本操作



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

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


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

    ↑ PAGE TOP