昨日は、ListBoxのクリックイベントを用いて、ファイルの絞り込みを行ってみた。
infoment.hatenablog.com
でも、何だかまだしっくりこない。もう少し模索してみた。
しっくりこない理由は、直ぐに分かった。
リストボックスが4つ、5つと増えた場合、併せて直さなければならない箇所が複数あるからだ。そこで、リストボックスの増減に追従するよう変更してみた。
標準モジュール
まずListBoxの名称について、役割を名称に反映するのではなく、
- ListBox1
- ListBox2
- ListBox3
のようにListBox + 連番とした。
そのため、昨日あったEnumの一部が無くなっている。
Option Explicit ' 取得する対象(フォルダ名か、ファイル名か) Public Enum ReturnGroup myVbFolder myVbFile End Enum
' 何に格納するか(配列か、コレクションか) Public Enum ReturnType myVbSeq myVbCol End Enum
Public Const ParentFolderPath As String = "C:\Temp" Public myListBoxes() As MSForms.ListBox Public LB() As SelectFileClass
ユーザーフォーム(SelectFileForm)
リストボックスの増減に、機能を追従させる。
作戦はこうだ。
- ユーザーフォーム上にリストボックスがいくつあるか調べる。
- リストボックスを配列化
- 併せて、クリックイベント用に登録
Option Explicit Dim SQC As SeaquenceClass
Private Sub UserForm_Initialize() PathLabel.Caption = ParentFolderPath ' ↓今回追加した箇所 Dim myControl As Control Dim iMax As Long iMax = 0 For Each myControl In Me.Controls If TypeName(myControl) = "ListBox" Then iMax = iMax + 1 End If Next Dim i As Long ReDim LB(1 To iMax) ReDim myListBoxes(1 To iMax) For i = 1 To iMax Set myListBoxes(i) = Me.Controls("ListBox" & i) Set LB(i) = New SelectFileClass LB(i).SetListBox myListBoxes(i), i Next ' ↑今回追加した箇所 Set SQC = New SeaquenceClass myListBoxes(1).List = SQC.GetFolderFileNames(ParentFolderPath) End Sub
クラスモジュール(SelectFileClass)
最後に、昨日のクラスモジュールにつて、リストボックス数を可変にした。
Option Explicit ' リストボックスのクリックイベント検知用 Private WithEvents myListBox As MSForms.ListBox ' クリックされたリストボックスの番号 Dim myIndex As Long ' 指定フォルダ内のフォルダ名やファイル名を配列化 Dim SQC As SeaquenceClass
' 各リストボックスをクリックイベント検知用にセット Public Sub SetListBox(newListBox As MSForms.ListBox, _ Index As Long) Set myListBox = newListBox myIndex = Index End Sub
※↓昨日の、リストボックスの配列化分を削除
Private Sub Class_Initialize() Set SQC = New SeaquenceClass End Sub
※↓リストボックスの増減に対応
' リストボックスのクリックイベント Private Sub myListBox_Click() Dim myList As Variant ' ラベルの値変更。 SelectFileForm.PathLabel = myPath Dim iMax As Long iMax = UBound(myListBoxes) ' クリックされたリストボックスごとに、myListの内容変更。 Select Case myIndex Case 1 To iMax - 2 myList = SQC.GetFolderFileNames(myPath) Case iMax - 1 myList = SQC.GetFolderFileNames(myPath, myVbFile) Case iMax myList = Array() Exit Sub End Select ' クリックされたリストボックスの次以降を全てクリア。 Dim i As Long For i = myIndex + 1 To UBound(LB) myListBoxes(i).Clear Next If UBound(myList) <> -1 Then With myListBoxes(myIndex + 1) .List = myList End With End If End Sub
' リストボックスがクリックされた時点での、クリックされた内容を ' 反映したパスの取得。 Private Function myPath() As String Dim TempCol As Collection Set TempCol = New Collection TempCol.Add ParentFolderPath Dim i As Long For i = 1 To myIndex TempCol.Add myListBoxes(i).Value Next myPath = Join(SQC.ToArray(TempCol), "\") End Function
結果、同じ動きを実現できた。
一つのフォルダ内に、ファイルとサブフォルダが混在する場合などについては、後日また検討してみるとします。
参考まで。