How to filter data automatically into Listbox using two combo-boxes data as criteria with VBA.
On a user-form we have two combo-boxes. These combo-boxes are populated with unique data using the ‘dictionaries‘ concept.
The list-box is populated with filtered data based on selections in the two combo-boxes.
The image below shows the filtered data in the list-box.

Watch the video below before studying the VBA code:
Option Explicit
Private Sub cbRegion_Change()
Call FilterData
End Sub
Private Sub cbItem_Change()
Call FilterData
End Sub
Private Sub FilterData()
Dim Region As String
Dim Item_Type As String
Dim myDB As Range
With Me
If .cbRegion.ListIndex < 0 Or .cbItem.ListIndex < 0 Then Exit Sub
Region = .cbRegion.Value Item_Type = .cbItem.Value
End With
With ActiveWorkbook.Sheets(“MYDATA”)
Set myDB = .Range(“A1:D1”).Resize(.Cells(.Rows.Count, 1).End(xlUp).Row)
End With
With myDB
.AutoFilter ‘remove filters
.AutoFilter Field:=1, Criteria1:=Region ‘ filter data
.SpecialCells(xlCellTypeVisible).AutoFilter Field:=3, Criteria1:=Item_Type ‘ filter data again
Call UpdateListBox(Me.MyListbox, myDB, 1)
.AutoFilter
End With
End Sub
Sub UpdateListBox(MyListbox As MSForms.ListBox, myDB As Range, columnToList As Long)
Dim cell As Range, dataValues As Range
If myDB.SpecialCells(xlCellTypeVisible).Count > myDB.Columns.Count Then Set dataValues = myDB.Resize(myDB.Rows.Count + 1) MyListbox.Clear ' we clear the listbox before adding new elements For Each cell In dataValues.Columns(columnToList).SpecialCells(xlCellTypeVisible) With Me.MyListbox .AddItem cell.Value .List(.ListCount - 1, 1) = cell.Offset(0, 1).Value .List(.ListCount - 1, 2) = cell.Offset(0, 2).Value .List(.ListCount - 1, 3) = cell.Offset(0, 3).Value End With Next cell Else MyListbox.Clear ' if no match then clear listbox End If
MyListbox.SetFocus
End Sub
Private Sub UserForm_Initialize()
Dim dict, key
Dim lastrow As Long
lastrow = Application.WorksheetFunction.CountA(Range(“A:A”))
With Sheets(“MYDATA”).Range(“A2:A” & lastrow)
dict = .Value
End With
With CreateObject(“scripting.dictionary”)
.comparemode = 1 ‘vbTextCompare – case of words doesn’t matter: apple is the same as Apple
For Each key In dict
If Not .exists(key) Then .Add key, Nothing Next If .Count Then Me.cbRegion.List = Application.Transpose(.keys)
End With
With Sheets(“MYDATA”).Range(“C2:C” & lastrow)
dict = .Value
End With
With CreateObject(“scripting.dictionary”)
.comparemode = 1
For Each key In dict
If Not .exists(key) Then .Add key, Nothing
Next
If .Count Then Me.cbItem.List = Application.Transpose(.keys)
End With
End Sub
Further Reading:
Download a sample file: