ListBoxを操作するクラスモジュール ④ 選択行の指定列の値を返す

ListBoxを操作するクラスモジュールを、私なりに作成中。
前回は、検索文字を含む行を全て選択してみた。
infoment.hatenablog.com

今日も、前回の続きから。
f:id:Infoment:20201004220609p:plain

今まで何度も面倒臭さを感じていたのが、こちらの場面。

  1. リストボックス内の1つ以上の行を選択。
  2. 指定した行の、指定列の値を取得。

そこで今回は、指定行指定列の値を返す関数を作成してみた。
作戦はこうだ。

  1. 選択された行のインデックスを、配列に格納して返す。
  2. 1. で取得した配列から、選択された行数を求める。
  3. 2. で配列を宣言し、選択行の値を全て格納する。

本来は上記3.のみで良いのだろうけど、1.と2.も今後、複数回
登場しそうな気がするので、分けておこう。

クラスモジュール(ListBoxControl)
' 選ばれた行のインデックスが格納された配列。
Public Property Get SelectedIndex() As Variant
    Dim Dict As Object
    Set Dict = CreateObject("Scripting.Dictionary")
        For i = 0 To TargetListBox.ListCount - 1
            If TargetListBox.Selected(i) Then
                Dict(i) = True
            End If
        Next
        
        SelectedIndex = Dict.keys
End Property

' リストボックスの選択行数。
Public Function SelectedCount() As Long
    SelectedCount = UBound(SelectedIndex) + 1
End Function

' リスト内で選択された行の値を配列で取得する。
Public Function SelectedValues() As Variant
    
    ' データ格納用配列。
    Dim arr() As Variant
        
        ' 選択行数が0ならば、空配列を返す。
        If SelectedCount = 0 Then
            arr = Array()
        Else
            
            ' 選択行数が1以上の場合、リストの元となった配列の次元数で
            ' 戻り値となる配列の次元数を変える。
            Dim Counter As Long: Counter = 0
            Select Case DimensionNumber
            
                ' リスト用配列が一次元配列の場合、各行の値は一つしかないため、
                ' 一次元配列に格納する。
                Case 1
                    ReDim arr(SelectedCount - 1)
                        For i = 0 To TargetListBox.ListCount - 1
                            If TargetListBox.Selected(i) Then
                                arr(Counter) = TargetListBox.List(i)
                            End If
                        Next
                ' 二次元配列の場合。
                Case 2
                    ReDim arr(SelectedCount - 1, UBound(ListArray, 2))
                        For i = 0 To TargetListBox.ListCount - 1
                            If TargetListBox.Selected(i) Then
                                For j = 0 To UBound(arr, 2)
                                    arr(Counter, j) = TargetListBox.List(i, j)
                                Next
                                Counter = Counter + 1
                            End If
                        Next
            End Select
        End If
        
        SelectedValues = arr
End Function
ユーザーフォーム

先日のユーザーフォームに、ボタンを一つ追加。
その名も、「選択した2番目の行の3列目を表示」だ(そのまんま)。
f:id:Infoment:20201004221304p:plain

「二つ以上選択されていない場合」などのエラー処理を省けば、
一行で取得可能だ。

Private Sub CommandButton1_Click()
    MsgBox Lbc.SelectedValues(1, 2)
End Sub

「りんごとばなな」ボタンで行選択したのち実行してみれば、

  • 2番目の行 ⇒ 「ばなな」の行
  • 3番目の列 ⇒ 「数量」の列

ということで、「3」という値が表示された。
f:id:Infoment:20201004221752p:plain

今回も、上手く行ったようだ。


もともとの予定では、これぐらいまでだった。
しかし、作っている内に欲が出てきた。

というわけで、もう少し続きます。

参考まで。