ListBoxを操作するクラスモジュール ④ 選択行の指定列の値を返す
ListBoxを操作するクラスモジュールを、私なりに作成中。
前回は、検索文字を含む行を全て選択してみた。
infoment.hatenablog.com
今日も、前回の続きから。
今まで何度も面倒臭さを感じていたのが、こちらの場面。
- リストボックス内の1つ以上の行を選択。
- 指定した行の、指定列の値を取得。
そこで今回は、指定行指定列の値を返す関数を作成してみた。
作戦はこうだ。
- 選択された行のインデックスを、配列に格納して返す。
- 1. で取得した配列から、選択された行数を求める。
- 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列目を表示」だ(そのまんま)。
「二つ以上選択されていない場合」などのエラー処理を省けば、
一行で取得可能だ。
Private Sub CommandButton1_Click() MsgBox Lbc.SelectedValues(1, 2) End Sub
「りんごとばなな」ボタンで行選択したのち実行してみれば、
- 2番目の行 ⇒ 「ばなな」の行
- 3番目の列 ⇒ 「数量」の列
ということで、「3」という値が表示された。
今回も、上手く行ったようだ。
もともとの予定では、これぐらいまでだった。
しかし、作っている内に欲が出てきた。
というわけで、もう少し続きます。
参考まで。