Excel VBA: Multi-level dependant lists ComboBoxes. some problem in extracting unique lists

talha_ansari

New Member
Joined
Jul 23, 2021
Messages
1
Office Version
  1. 2019
  2. 2016
Platform
  1. Windows
i have a file containing the sample userform of 3 sample combo boxes every next combobox is dependant to the previous.

there is a simple vba behind it, which i think should work correctly.

Option Explicit

Private Sub UserForm_Initialize()
' set worksheet
Dim sh As Worksheet
Set sh = Sheets("Clients")
'declare variable
Dim i As Long
For i = 2 To Application.WorksheetFunction.CountA(sh.Cells(1, 1).EntireColumn)
If Application.WorksheetFunction.CountIf(sh.Range("A2", "A" & i), sh.Cells(i, 1)) = 1 Then
Me.ComboBox1.AddItem sh.Cells(i, 1)
End If
Next i
End Sub
Private Sub ComboBox1_Change()
Me.ComboBox2.Clear

' set worksheet
Dim sh As Worksheet
Set sh = Sheets("Clients")
'declare variable
Dim i As Long
For i = 2 To Application.WorksheetFunction.CountA(sh.Cells(1, 1).EntireColumn)
If sh.Cells(i, 1) = Me.ComboBox1.Value And _
Application.WorksheetFunction.CountIf(sh.Range("B2", "B" & i), sh.Cells(i, 2)) = 1 Then

Me.ComboBox2.AddItem sh.Cells(i, 2)

End If
Next i


End Sub

Private Sub ComboBox2_Change()
Me.ComboBox3.Clear

' set worksheet
Dim sh As Worksheet
Set sh = Sheets("Clients")
'declare variable
Dim i As Long
For i = 2 To sh.Range("A10000").End(xlUp).Row
If sh.Cells(i, 1) = Me.ComboBox1.Value And sh.Cells(i, 2) = Me.ComboBox2.Value And _
Application.WorksheetFunction.CountIf(sh.Range("C2", "C" & i), sh.Cells(i, 3)) = 1 Then

Me.ComboBox3.AddItem sh.Cells(i, 3)

End If
Next i

End Sub


it does work for starting items but not for further. the issue is in
Application.WorksheetFunction.CountIf(sh.Range("B2", "B" & i), sh.Cells(i, 2)) = 1

as well as in
Application.WorksheetFunction.CountIf(sh.Range("C2", "C" & i), sh.Cells(i, 3)) = 1

when it try to get unique items for combobox list.

any solution please.


1627085628024.png


1627085685589.png
 

Excel Facts

Square and cube roots
The =SQRT(25) is a square root. For a cube root, use =125^(1/3). For a fourth root, use =625^(1/4).
@talha_ansari Welcome to the Forum

Here's an example of 3 dependent combobox in a userform.
Note:
1. Data must be in an actual table (not just in a range)
2. You only need to adjust the code in this part:
'====YOU MAY NEED TO ADJUST THE CODE IN THIS PART:====
'sheet's name where the list is located.
Private Const sList As String = "Sheet1"
'Table name where the list is located
Private Const tbl As String = "Table1"


The sample workbook:

The code
VBA Code:
Dim vList
Dim d As Object

'====YOU MAY NEED TO ADJUST THE CODE IN THIS PART:====
'sheet's name where the list  is located.
Private Const sList As String = "Sheet1"
'Table name where the list  is located
Private Const tbl As String = "Table1"


Private Sub UserForm_Initialize()
vList = Sheets(sList).ListObjects("Table1").DataBodyRange.Columns("A:C")
    Set d = CreateObject("scripting.dictionary")
    d.CompareMode = vbTextCompare
End Sub

Private Sub ComboBox1_Change()
       ComboBox2.Value = ""
       ComboBox3.Value = ""

End Sub

Private Sub ComboBox2_Change()
       ComboBox3.Value = ""

End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
          d(vList(i, 1)) = Empty
    Next
       ComboBox1.List = d.keys
End Sub


Private Sub ComboBox2_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
    If UCase(vList(i, 1)) = UCase(ComboBox1.Value) Then d(vList(i, 2)) = Empty
    Next
       ComboBox2.List = d.keys
End Sub

Private Sub ComboBox3_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
        If UCase(vList(i, 1)) = UCase(ComboBox1.Value) And UCase(vList(i, 2)) = UCase(ComboBox2.Value) Then
            d(vList(i, 3)) = Empty
        End If
    Next
       ComboBox3.List = d.keys
End Sub
 
Upvote 0
Solution
Cross posted

@ talha_ansari
Please see Forum Rule 13 about cross-posting and adjust accordingly. Read this to understand why we (and other sites like us) consider this to be important.
 
Last edited:
Upvote 0
@talha_ansari Welcome to the Forum

Here's an example of 3 dependent combobox in a userform.
Note:
1. Data must be in an actual table (not just in a range)
2. You only need to adjust the code in this part:
'====YOU MAY NEED TO ADJUST THE CODE IN THIS PART:====
'sheet's name where the list is located.
Private Const sList As String = "Sheet1"
'Table name where the list is located
Private Const tbl As String = "Table1"


The sample workbook:

The code
VBA Code:
Dim vList
Dim d As Object

'====YOU MAY NEED TO ADJUST THE CODE IN THIS PART:====
'sheet's name where the list  is located.
Private Const sList As String = "Sheet1"
'Table name where the list  is located
Private Const tbl As String = "Table1"


Private Sub UserForm_Initialize()
vList = Sheets(sList).ListObjects("Table1").DataBodyRange.Columns("A:C")
    Set d = CreateObject("scripting.dictionary")
    d.CompareMode = vbTextCompare
End Sub

Private Sub ComboBox1_Change()
       ComboBox2.Value = ""
       ComboBox3.Value = ""

End Sub

Private Sub ComboBox2_Change()
       ComboBox3.Value = ""

End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
          d(vList(i, 1)) = Empty
    Next
       ComboBox1.List = d.keys
End Sub


Private Sub ComboBox2_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
    If UCase(vList(i, 1)) = UCase(ComboBox1.Value) Then d(vList(i, 2)) = Empty
    Next
       ComboBox2.List = d.keys
End Sub

Private Sub ComboBox3_DropButtonClick()
Dim i As Long
    d.RemoveAll
    For i = LBound(vList) To UBound(vList)
        If UCase(vList(i, 1)) = UCase(ComboBox1.Value) And UCase(vList(i, 2)) = UCase(ComboBox2.Value) Then
            d(vList(i, 3)) = Empty
        End If
    Next
       ComboBox3.List = d.keys
End Sub
Hello,

Your code helped me to start structuring my comboboxes and their dependencies. However, could we have this as a dynamic dependency as in all the comboboxes would contain the unique values from the columns and their contents are effected as per the selection in any of the comboboxes?

Thank you in advance for your help!!!
 
Upvote 0
However, could we have this as a dynamic dependency as in all the comboboxes would contain the unique values from the columns and their contents are effected as per the selection in any of the comboboxes?
By "dynamic dependency " do you mean interdependency? for example if combobox1 changes then combobox2 changes and vice versa?
Could you upload a sample workbook (without sensitive data) to a sharing site like dropbox.com or google drive?
And then share the link here.
 
Upvote 0
By "dynamic dependency " do you mean interdependency? for example if combobox1 changes then combobox2 changes and vice versa?
Could you upload a sample workbook (without sensitive data) to a sharing site like dropbox.com or google drive?
And then share the link here.
Hello Akuini,

Yes, Its actually interdependency what I meant. Unfortunately I am not able to Upload the file as its quite weighty, however if it is of any use, you would find attached the image of my combobox, where I want each combobox to hold unique elements from a table called "DynamicPath_2" in a sheet called "MDB" and they all are supposed to be interdependent except "N° Maco" which is a textbox populated based on the value of "Name of Project" combobox. below is the code I have gathered and put in place so far.

Dim vList
Dim d As Object

'sheet's name where the list is located.
Private Const sList As String = "MDB"
'Table name where the list is located
Private Const tbl As String = "DynamicPath_2"



Private Sub UserForm_Initialize()

vList = Sheets(sList).ListObjects("DynamicPath_2").DataBodyRange.Columns("A:M")
Set d = CreateObject("scripting.dictionary")
d.CompareMode = vbTextCompare

End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 3)) = UCase(ComboBox2.Value) Then d(vList(i, 1)) = Empty

Next
ComboBox1.List = d.keys
End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
d(vList(i, 1)) = Empty

Next
ComboBox1.List = d.keys
End Sub


Private Sub ComboBox2_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 1)) = UCase(ComboBox1.Value) Then d(vList(i, 3)) = Empty

Next
ComboBox2.List = d.keys

End Sub

Private Sub ComboBox2_Change()
Dim myRange As Range, f As Range

Set myRange = Worksheets("MDB").Range("B:C")

Set f = myRange.Find(What:=ComboBox2.Value, LookIn:=xlValues, Lookat:=xlWhole, MatchCase:=False) '<--| try and find combobox selected value
If f Is Nothing Then
TextBox1.Value = ""
Else '<--| ... otherwise...
TextBox1.Value = f.Offset(, -1)

End If
End Sub


Private Sub ComboBox3_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 1)) = UCase(ComboBox1.Value) And UCase(vList(i, 3)) = UCase(ComboBox2.Value) Then d(vList(i, 4)) = Empty

Next
ComboBox3.List = d.keys
End Sub

In the above code, I have managed to make combobox2 and combobox3 dependent on the value of combobox1. However I couldn't manage to accomplish the interdependency.

Thank you really for your help... You are also welcome to change the codes completely if required.
 
Upvote 0
Hello Akuini,

Yes, Its actually interdependency what I meant. Unfortunately I am not able to Upload the file as its quite weighty, however if it is of any use, you would find attached the image of my combobox, where I want each combobox to hold unique elements from a table called "DynamicPath_2" in a sheet called "MDB" and they all are supposed to be interdependent except "N° Maco" which is a textbox populated based on the value of "Name of Project" combobox. below is the code I have gathered and put in place so far.

Dim vList
Dim d As Object

'sheet's name where the list is located.
Private Const sList As String = "MDB"
'Table name where the list is located
Private Const tbl As String = "DynamicPath_2"



Private Sub UserForm_Initialize()

vList = Sheets(sList).ListObjects("DynamicPath_2").DataBodyRange.Columns("A:M")
Set d = CreateObject("scripting.dictionary")
d.CompareMode = vbTextCompare

End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 3)) = UCase(ComboBox2.Value) Then d(vList(i, 1)) = Empty

Next
ComboBox1.List = d.keys
End Sub

Private Sub ComboBox1_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
d(vList(i, 1)) = Empty

Next
ComboBox1.List = d.keys
End Sub


Private Sub ComboBox2_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 1)) = UCase(ComboBox1.Value) Then d(vList(i, 3)) = Empty

Next
ComboBox2.List = d.keys

End Sub

Private Sub ComboBox2_Change()
Dim myRange As Range, f As Range

Set myRange = Worksheets("MDB").Range("B:C")

Set f = myRange.Find(What:=ComboBox2.Value, LookIn:=xlValues, Lookat:=xlWhole, MatchCase:=False) '<--| try and find combobox selected value
If f Is Nothing Then
TextBox1.Value = ""
Else '<--| ... otherwise...
TextBox1.Value = f.Offset(, -1)

End If
End Sub


Private Sub ComboBox3_DropButtonClick()
Dim i As Long
d.RemoveAll
For i = LBound(vList) To UBound(vList)
If UCase(vList(i, 1)) = UCase(ComboBox1.Value) And UCase(vList(i, 3)) = UCase(ComboBox2.Value) Then d(vList(i, 4)) = Empty

Next
ComboBox3.List = d.keys
End Sub

In the above code, I have managed to make combobox2 and combobox3 dependent on the value of combobox1. However I couldn't manage to accomplish the interdependency.

Thank you really for your help... You are also welcome to change the codes completely if required.
 

Attachments

  • VBA screen.JPG
    VBA screen.JPG
    49.9 KB · Views: 31
Upvote 0
Unfortunately I am not able to Upload the file as its quite weighty
Can you cut down your file? just keep the userform & sheet "MDB" & about 100 rows of data in it. I need to understand your data,.

where I want each combobox to hold unique elements from a table called "DynamicPath_2"
Do you mean all column has unique data? or all columns has duplicate but you want to show only unique data in the combobox?
 
Upvote 0
Can you cut down your file? just keep the userform & sheet "MDB" & about 100 rows of data in it. I need to understand your data,.


Do you mean all column has unique data? or all columns has duplicate but you want to show only unique data in the combobox?
Hello Akuini,

Here is a link to dropbox : Comparaison - Copie.xlsm

and my columns have duplicate but I want to show only unique data in the combobox

Thank you
 
Upvote 0
Ok, I'll try to write the code tomorrow.
 
Upvote 0

Forum statistics

Threads
1,223,907
Messages
6,175,300
Members
452,633
Latest member
DougMo

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