I have a dynamic multicolumn listbox which can range from 1 to 100 rows. The userform has a fixed height, therefore a vertical scrollbar shows when required.
When 100 rows are listed, the scrollbar understands there are 500-600 of them, leading to an empty area at the bottom.
How do I set the scrollbar to automatically fit to the number of listed rows?
Code that fills the listbox:
Sub RefreshLBIndoor()
Dim i As Integer, j As Integer, k As Byte
With ListBoxIndoor ' This is the listbox name
.ColumnCount = 6
j = 1
For i = 3 To SupportList.ListObjects("ProductList_table").DataBodyRange.Rows.Count + 2 ' Data begins from row 3
' Column F (number 6) contains the filter for which rows to populate the listbox
If InStr(1, SupportList.Cells(i, 6), "Example", vbTextCompare) = 1 Then
For k = 3 To 8
.AddItem
.Column(k - 3, j - 1) = SupportList.Cells(i, k).Value
Next k
j = j + 1
End If
Next i
On Error Resume Next
.ListIndex = 0
End With
End Sub
The issue is that an item was being added for each column in each row. Moving .AddItem outside of the column loop fixed the problem. I also added .Clear to clear the listbox on refresh.
Sub RefreshLBIndoor()
Dim i As Integer, j As Integer, k As Byte
With ListBoxIndoor ' This is the listbox name
Rem Clear the listbox when you refresh it
.Clear
.ColumnCount = 6
j = 1
For i = 3 To SupportList.ListObjects("ProductList_table").DataBodyRange.Rows.Count + 2 ' Data begins from row 3
' Column F (number 6) contains the filter for which rows to populate the listbox
If InStr(1, SupportList.Cells(i, 6), "Example", vbTextCompare) = 1 Then
Rem AddItem once per row
.AddItem
For k = 3 To 8
.Column(k - 3, j - 1) = SupportList.Cells(i, k).Value
Next k
j = j + 1
End If
Next i
On Error Resume Next
.ListIndex = 0
End With
End Sub
Here is an improved version of my answer that takes advantage of the data being stored in a ListObject:
Sub RefreshLBIndoor()
Rem use Long for your counters
Dim r As Long, c As Long
Dim Values As Variant
With ListBoxIndoor ' This is the listbox name
Rem Clear the listbox when you refresh it
.Clear
.ColumnCount = 6
Rem Load the Values into an array to improve efficiency
Values = SupportList.ListObjects("ProductList_table").DataBodyRange.Value
For r = 1 To SupportList.ListObjects("ProductList_table").ListRows.Count
If InStr(1, SupportList.Cells(r, 6), "Example", vbTextCompare) = 1 Then
Rem AddItem once per row
.AddItem
For c = 3 To 8
.Column(c - 3, .ListCount - 1) = Values(r, c)
Next
End If
Next
On Error Resume Next
.ListIndex = 0
End With
End Sub