Populate UserForm ListBox based on ComboBox Selection

JaredArchuleta

New Member
Joined
May 1, 2023
Messages
2
Office Version
  1. 365
Platform
  1. Windows
Hello all, I have the following UserForm and would like to only show ListBox results for the employee that is selected.

1682978849470.png


Here is the current VBA code I am using to populate the list box:

VBA Code:
Sub AnalyzeEmployees()
    Dim DataTable As ListObject
    Set DataTable = ThisWorkbook.Sheets("Data").ListObjects("records")

    Set shData = ThisWorkbook.Sheets("Data")

    Dim rng As Range
    Set rng = shData.Range("C2:G" & shData.Range("A" & shData.Rows.Count).End(xlUp).Row)

    With EmployeeAnalysis.lbxEmployeeResults
        .Clear
        .ColumnCount = rng.Columns.Count

        myArray = rng

        .List = myArray

        .ColumnWidths = "90;100;100;100;50"
        .TopIndex = 0
    End With
    
    EmployeeAnalysis.Show
    
End Sub

I need help with the code for when I select a name, I only see results for the person selected.

The name of my combobox is: cbxEAName

Thank you all in advance
 

Excel Facts

Do you hate GETPIVOTDATA?
Prevent GETPIVOTDATA. Select inside a PivotTable. In the Analyze tab of the ribbon, open the dropown next to Options and turn it off
I have the following UserForm and would like to only show ListBox results for the employee that is selected. When I select the first name in the combobox, I get the correct results.

enter image description here

But when I select any other combox options, all of the data goes into the first column of my listbox. enter image description here

What am I doing wrong?

Here is the current VBA code I am using to populate the list box:
VBA Code:
Private Sub cbxEAName_Change()

Set shData = ThisWorkbook.Sheets("Data")

Dim rng As Range
Set rng = shData.Range("C2:G" & shData.Range("A" & shData.Rows.Count).End(xlUp).Row)

Dim filteredData() As Variant
Dim i As Long
Dim j As Long
Dim numRows As Long

numRows = 0
For i = 1 To rng.Rows.Count
    If rng.Cells(i, 1).Value = EmployeeAnalysis.cbxEAName.Value Then
        numRows = numRows + 1
        ReDim Preserve filteredData(1 To rng.Columns.Count, 1 To numRows)
        For j = 1 To rng.Columns.Count
            filteredData(j, numRows) = rng.Cells(i, j).Value
        Next j
    End If
Next i

With EmployeeAnalysis.lbxEmployeeResults
    .Clear
    .ColumnCount = rng.Columns.Count
    If numRows > 0 Then
        .List = Application.Transpose(filteredData)
    End If
    .ColumnWidths = "90;100;100;100;50"
    .TopIndex = 0
End With

End Sub
 
Upvote 0
Edited

When only one record is found, you end with a 5-Row by 1-Column two-dimensional array. And when you transpose it, you actually end up with a one-dimensional array. As a result, when assigning a one-dimensional array to the List property of the listbox, it fills the column, not the row.

One possible solution would be to first count the number of records found, and then declare and allocate the exact storage space needed for your variable. This way, when only one record is found, you're left with a 1-Row by 5-Column two dimensional array, which you assign to the List property of the listbox. This is also more efficient, since it avoids having to resize your array with Redim Preserve each time a record is found, and it avoids having to transpose the array.

I have amended your macro accordingly...

VBA Code:
Private Sub cbxEAName_Change()

    EmployeeAnalysis.lbxEmployeeResults.Clear
 
    Dim shData As Worksheet
    Set shData = ThisWorkbook.Sheets("Data")
 
    Dim rng As Range
    Set rng = shData.Range("C2:G" & shData.Range("A" & shData.Rows.Count).End(xlUp).Row)
 
    Dim recordCount As Long
    recordCount = Application.CountIf(rng.Columns(1), Me.cbxEAName.Value)
 
    If recordCount = 0 Then Exit Sub
 
    Dim filteredData() As Variant
    ReDim filteredData(1 To recordCount, 1 To rng.Columns.Count)
 
    Dim i As Long
    Dim j As Long
    Dim numRows As Long
 
    numRows = 0
    For i = 1 To rng.Rows.Count
        If rng.Cells(i, 1).Value = EmployeeAnalysis.cbxEAName.Value Then
            numRows = numRows + 1
            For j = 1 To rng.Columns.Count
                filteredData(numRows, j) = rng.Cells(i, j).Value
            Next j
        End If
    Next i
 
    With EmployeeAnalysis.lbxEmployeeResults
        If numRows > 0 Then
            .ColumnCount = rng.Columns.Count
            .ColumnWidths = "90;100;100;100;50"
            .List = filteredData
            .TopIndex = 0
        End If
    End With

End Sub

Hope this helps!
 
Last edited:
Upvote 0
Solution
Correction, since we only need to count the names from the first column in order to get a record count, please replace...

VBA Code:
recordCount = Application.CountIf(rng, Me.cbxEAName.Value)

with

VBA Code:
recordCount = Application.CountIf(rng.Columns(1), Me.cbxEAName.Value)

Hope this helps!
 
Upvote 1

Forum statistics

Threads
1,223,879
Messages
6,175,145
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top