リストボックスのクリックをWIthEventsで検知してファイルの絞り込みを行う
昨日は、リストボックスのクリックをとりあえず検知してみた。
infoment.hatenablog.com
今日は、実際にファイルの絞り込みを行ってみる。
といっても私的都合で、今日は詳しい解説を書く元気がない。それは後日に回すとして、とりあえず今までの分も含めた一式、作成した分を掲載しておく。
クラスモジュール(SeaquenceClass)
指定フォルダのファイル名を取得したり、コレクションを配列化するためのもの。
Option Explicit Dim FSO As FileSystemObject
Private Sub Class_Initialize() Set FSO = New FileSystemObject End Sub
'[用 途] ' コレクションを一次元配列に変換する '[引 数] ' col as Collection 元データ '[戻り値] ' 一次元配列 Public Function ToArray(col As Collection) As Variant Dim seq As Variant ReDim seq(col.Count - 1) Dim c As Variant Dim i As Long i = 0 For Each c In col seq(i) = c i = i + 1 Next ToArray = seq End Function
'[用 途] ' 指定フォルダ下にあるフォルダ名やファイル名を取得 '[引 数] ' folder_path As String 指定フォルダ ' return_group As ReturnGroup 取得対象(フォルダ or ファイル) ※初期値:フォルダ ' return_type As ReturnType 格納方法(配列 or コレクション) ※初期値:配列 '[戻り値] ' 「フォルダまたはファイル」名称を格納した「配列またはコレクション」 '[備 考] ' 標準モジュールの列挙型(ReturnGroup および ReturnType)とセットで使用 Public Function GetFolderFileNames(folder_path As String, _ Optional return_group As ReturnGroup = myVbFolder, _ Optional return_type As ReturnType = myVbSeq) As Variant Dim TempCol As Collection Set TempCol = New Collection On Error GoTo er ' 名称取得。 Select Case return_group 'フォルダの場合。 Case myVbFolder Dim myFolder As Folder For Each myFolder In FSO.GetFolder(folder_path).SubFolders TempCol.Add myFolder.Name Next ' ファイルの場合。 Case myVbFile Dim myFile As File For Each myFile In FSO.GetFolder(folder_path).Files TempCol.Add myFile.Name Next End Select ' 格納方法。 Select Case return_type ' 配列の場合。 Case myVbSeq GetFolderFileNames = ToArray(TempCol) ' コレクションの場合。 Case myVbCol Set GetFolderFileNames = TempCol End Select Exit Function er: GetFolderFileNames = Array() End Function
クラスモジュール(SelectFileClass)
ユーザーフォーム内のリストボックス等コントロール用。
Option Explicit ' リストボックスのクリックイベント検知用 Private WithEvents myListBox As MSForms.ListBox ' クリックされたリストボックスの番号 Dim myIndex As Long ' 指定フォルダ内のフォルダ名やファイル名を配列化 Dim SQC As SeaquenceClass '各リストボックス Dim myListBoxes(ListBoxNumber.myVbFolder1 To ListBoxNumber.myVbFile1) As MSForms.ListBox
' 各リストボックスを配列化 Private Sub Class_Initialize() Set SQC = New SeaquenceClass Set myListBoxes(ListBoxNumber.myVbFolder1) = SelectFileForm.FolderListBox1 Set myListBoxes(ListBoxNumber.myVbFolder2) = SelectFileForm.FolderListBox2 Set myListBoxes(ListBoxNumber.myVbFile1) = SelectFileForm.FileListBox1 End Sub
' 各リストボックスをクリックイベント検知用にセット Public Sub SetListBox(newListBox As MSForms.ListBox, _ Index As Long) Set myListBox = newListBox myIndex = Index 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
' リストボックスのクリックイベント Private Sub myListBox_Click() Dim myList As Variant ' ラベルの値変更。 SelectFileForm.PathLabel = myPath ' クリックされたリストボックスごとに、myListの内容変更。 Select Case myIndex Case ListBoxNumber.myVbFolder1 myList = SQC.GetFolderFileNames(myPath) Case ListBoxNumber.myVbFolder2 myList = SQC.GetFolderFileNames(myPath, myVbFile) Case Else 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
標準モジュール
Option Explicit ' 取得する対象(フォルダ名か、ファイル名か) Public Enum ReturnGroup myVbFolder myVbFile End Enum ' 何に格納するか(配列か、コレクションか) Public Enum ReturnType myVbSeq myVbCol End Enum ' リストボックス Public Enum ListBoxNumber myVbFolder1 = 1 myVbFolder2 myVbFile1 End Enum Public Const ParentFolderPath As String = "C:\Temp" Public LB(ListBoxNumber.myVbFolder1 To ListBoxNumber.myVbFile1) As New SelectFileClass
' リストボックスのクリックイベント検知用。 Public Sub SetLB() With SelectFileForm LB(ListBoxNumber.myVbFolder1).SetListBox .FolderListBox1, ListBoxNumber.myVbFolder1 LB(ListBoxNumber.myVbFolder2).SetListBox .FolderListBox2, ListBoxNumber.myVbFolder2 LB(ListBoxNumber.myVbFile1).SetListBox .FileListBox1, ListBoxNumber.myVbFile1 End With End Sub
ユーザーフォーム(SelectFileForm)
今のところ、これだけ。
Option Explicit Dim SQC As SeaquenceClass Private Sub UserForm_Initialize() PathLabel.Caption = ParentFolderPath Set SQC = New SeaquenceClass FolderListBox1.List = SQC.GetFolderFileNames(ParentFolderPath) Call SetLB End Sub
結果は、以前と同じ動作をさせることができた。
でも、まだ何だかしっくりこない。もっと簡単にできるような気がする。
引き続き、模索してみます。
参考まで。