Over fifty pairs, that calls for a Class Module
Add a Class Module. Use the Properties Window to change its name to clsPairedDependents. Then put this code into the class's code module.
' in clsPairedDependents
Public WithEvents MasterBox As MSForms.ComboBox
Public WithEvents DependentBox As MSForms.ComboBox
Dim DependentLists() As Variant
Dim DisableMyEvents As Boolean
Event Change()
Event MasterChange()
Event DependentChange()
Sub AddDependentList(Index, ParamArray ListItems() As Variant)
Dim ListOfItems As Variant
If UBound(DependentLists) < Index Then ReDim Preserve DependentLists(0 To Index)
If TypeName(ListItems(0)) Like "*()" Then
ListOfItems = ListItems(0)
Else
ListOfItems = ListItems
End If
DependentLists(Index) = ListOfItems
End Sub
Public Sub AddDependentItem(strItem As String, Optional Index As Long = -1)
With DependentBox
If Index < 0 Then
.AddItem strItem
Else
.AddItem strItem, Index
End If
End With
End Sub
Public Sub AddMasterItem(strItem As String, Optional Index As Long = -1)
With MasterBox
If Index < 0 Then
.AddItem strItem
Else
.AddItem strItem, Index
End If
End With
End Sub
Property Get DependentList(Optional rIndex As Long = -1, Optional cIndex As Long = -1) As Variant
If cIndex = -1 And rIndex = -1 Then
DependentList = DependentBox.List
Else
If cIndex = -1 Then cIndex = 0
List = DependentBox.List(rIndex, cIndex)
End If
End Property
Property Let DependentList(Optional rIndex As Long = -1, Optional cIndex As Long = -1, inVal As Variant)
If cIndex = -1 And rIndex = -1 Then
DependentBox.List = inVal
Else
If cIndex = -1 Then cIndex = 0
DependentBox.List(rIndex, cIndex) = inVal
End If
End Property
Property Get DependentListCount() As Long
DependentListCount = DependentBox.ListCount
End Property
Property Get DependentListIndex() As Long
DependentListIndex = DependentBox.ListIndex
End Property
Property Let DependentListIndex(inVal As Long)
DependentBox.ListIndex = inVal
End Property
Property Get DependentText() As String
DependentText = DependentBox.Text
End Property
Property Let DependentText(inVal As String)
DependentBox.Text = inVal
End Property
Property Get DependentValue() As Variant
DependentValue = DependentBox.Value
End Property
Property Let DependentValue(inVal As Variant)
DependentBox.Value = inVal
End Property
Property Get MasterList(Optional rIndex As Long = -1, Optional cIndex As Long = -1) As Variant
If cIndex = -1 And rIndex = -1 Then
MasterList = MasterBox.List
Else
If cIndex = -1 Then cIndex = 0
List = MasterBox.List(rIndex, cIndex)
End If
End Property
Property Let MasterList(Optional rIndex As Long = -1, Optional cIndex As Long = -1, inVal As Variant)
If cIndex = -1 And rIndex = -1 Then
MasterBox.List = inVal
Else
If cIndex = -1 Then cIndex = 0
MasterBox.List(rIndex, cIndex) = inVal
End If
End Property
Property Get MasterListCount() As Long
MasterListCount = MasterBox.ListCount
End Property
Property Get MasterListIndex() As Long
MasterListIndex = MasterBox.ListIndex
End Property
Property Let MasterListIndex(inVal As Long)
MasterBox.ListIndex = inVal
End Property
Property Get MasterText() As String
MasterText = MasterBox.Text
End Property
Property Let MasterText(inVal As String)
MasterBox.Text = inVal
End Property
Property Get MasterValue() As Variant
MasterValue = MasterBox.Value
End Property
Property Let MasterValue(inVal As Variant)
MasterBox.Value = inVal
End Property
Property Get Name() As String
Name = "PairedCombo_" & MasterBox.Name & "_" & DependentBox.Name
End Property
Property Get UFParent() As Object
Set UFParent = MasterBox
On Error Resume Next
Do
Set UFParent = UFParent.Parent
Loop Until Err
On Error GoTo 0
End Property
Private Sub Class_Initialize()
ReDim DependentLists(0 To 0)
End Sub
Private Sub Class_Terminate()
Set DependentBox = Nothing
Set MasterBox = Nothing
End Sub
Private Sub DependentBox_Change()
If DisableMyEvents Then Exit Sub
Set UFParent.ActiveDependentPair = Me
RaiseEvent Change
RaiseEvent DependentChange
End Sub
Private Sub MasterBox_Change()
If DisableMyEvents Then Exit Sub
DisableMyEvents = True
DependentBox.Text = ""
DisableMyEvents = False
If MasterBox.ListIndex <> -1 Then
If UBound(DependentLists) < MasterBox.ListIndex Then
DependentBox.Clear
Else
If TypeName(DependentLists(MasterBox.ListIndex)) Like "*()" Then
DependentBox.List = DependentLists(MasterBox.ListIndex)
Else
DependentBox.Clear
End If
End If
End If
Set UFParent.ActiveDependentPair = Me
RaiseEvent Change
RaiseEvent MasterChange
End Sub
In this Demo user form, I used only 6 Comboboxes and made ComboBox1 the Master box for Combobox2, Combobox3 masters ComboBox4, etc.
The loop in the Initialize event will have to be modified to match the pairings that you want.
Notice that changing either of the paired boxes will 1) make that pair the ActiveDependentPair and fire the ActiveDependentPair_Change event.
In this demo form, the ActiveDependentPair_Change event sets the .Caption of a Label to show some of the properties of clsDependentPair. (The Object Browser will show all of those properties, they mirror the properties of a ComboBox)
Depending on if the Master or the Dependent of the pair caused the Change, either the ActiveDependentPair_MasterChange ActiveDependentPair_DependentChange will fire after the _Change event (but never both)
' in userform's code module
Dim DependentPairs As Collection
Public WithEvents ActiveDependentPair As clsPairedDependents
Private Sub UserForm_Initialize()
Dim MasterList As Variant
Dim DependentLists(0 To 2)
Dim newPair As clsPairedDependents
Dim i As Long
DependentLists(0) = Array("FMA_1", "FMA_2", "FMA_3")
DependentLists(1) = Array("FMB_1", "FMB_2", "FMB_3")
DependentLists(2) = Array("FMC_1", "FMC_2", "FMC_3")
MasterList = Array("PartA", "PartB", "PartC")
Set DependentPairs = New Collection
Rem loop and match master to dependent comboboxes
For i = 1 To 5 Step 2
Set newPair = New clsPairedDependents
With newPair
Set .MasterBox = Me.Controls("ComboBox" & i)
Set .DependentBox = Me.Controls("ComboBox" & (i + 1))
.AddDependentList 0, DependentLists(0)
.AddDependentList 1, DependentLists(1)
.AddDependentList 2, DependentLists(2)
.MasterList = MasterList
End With
DependentPairs.Add Item:=newPair, Key:=newPair.Name
Next i
Set newPair = Nothing
End Sub
Private Sub ActiveDependentPair_Change()
Dim myStr As String
With ActiveDependentPair
myStr = "Active Pair: " & .Name
myStr = myStr & vbCr & "Master: " & vbTab & .MasterBox.Name
myStr = myStr & vbCr & "Dependent: " & vbTab & .DependentBox.Name
myStr = myStr & vbCr & "Master Index: " & .MasterListIndex
myStr = myStr & vbTab & "Dependent Index: " & .DependentListIndex
myStr = myStr & vbCr & "Master Value: " & .MasterText
myStr = myStr & vbTab & "Dependent Value: " & .DependentValue
End With
Label1.Caption = myStr
End Sub
Private Sub ActiveDependentPair_DependentChange()
Me.Caption = ActiveDependentPair.DependentBox.Name & " has changed"
End Sub
Private Sub ActiveDependentPair_MasterChange()
Me.Caption = ActiveDependentPair.MasterBox.Name & " has changed"
End Sub
Bookmarks