excelvbalistboxuserform

Adjust vertical scrollbar range in Excel userform listbox


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

Solution

  • 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