I am trying to create a dynamic User_form, where all the Controls
are created at Run-Time.
I have 2 array of Combo-Boxes, first array of Combo-Boxes is "Catgeory" (CatCBArr
) , and the second array of Combo-Boxes is "Item" (ItemCBArr
).
I want, that once I select a value from the first Combo-Box of "Category", let's say CatCBArr(0)
, that only the related Items in ItemCBArr(0)
will be displayed.
Issue: I can't figure out how to modify the second Combo-box (ItemCBArr(0)
) according to the value selected in the first Combo-box (CatCBArr(0)
)
User_Form Code (relevant section)
Option Explicit
Dim ItemsNumofRows As Long
Dim QtyTB As MSForms.TextBox
Dim CatCB As MSForms.ComboBox
Dim ItemCB As MSForms.ComboBox
Dim Key As Variant
' dynamic Form controls (related to new Classes)
Dim CatCBArr() As New cComboBox
Dim ItemCBArr() As New cComboBox
Dim QtyTBArr() As New cTextBox
Private Sub UserForm_Initialize()
' reset flags
ItemsNumofRows = 5
TasksNamesUpd = False
TasksColUpd = False
ItemsRows_ControlsInit '<-- upload all Controls at run-time
Check_FormHeight
End Sub
'======================================================
Private Sub ItemsRows_ControlsInit()
For ItemRow = 0 To ItemsNumofRows
' add Category Combo-boxes
Set CatCB = Me.Controls.Add("Forms.ComboBox.1", "Cb" & ItemRow, True)
With CatCB
' loop through Dictionay items (view category)
For Each Key In Dict.Keys
.AddItem Key
Next Key
.SpecialEffect = fmSpecialEffectSunken
.Left = 40
.Width = 100
.Height = 18
.Top = 54 + 20 * ItemRow
ReDim Preserve CatCBArr(0 To ItemRow)
Set CatCBArr(ItemRow).ComboBoxEvents = CatCB
End With
' add Item Combo-boxes
Set ItemCB = Me.Controls.Add("Forms.ComboBox.1", "Cb_" & ItemRow, True)
With ItemCB
.SpecialEffect = fmSpecialEffectSunken
.Left = 160
.Width = 100
.Height = 18
.Top = 54 + 20 * ItemRow
ReDim Preserve ItemCBArr(0 To ItemRow)
Set ItemCBArr(ItemRow).ComboBoxEvents = ItemCB
End With
Next ItemRow
End Sub
cComboBox Class Code
Public WithEvents ComboBoxEvents As MSForms.ComboBox
Private Sub ComboBoxEvents_Change()
Dim CBIndex As Long
' get for ID number (row number), from third character in String Name.
' e.g "Cb1" will result 1)
CBIndex = CInt(Mid(ComboBoxEvents.Name, 3))
' ??? How do I get the Value, and update the second combo-box Items
Select Case ComboBoxEvents.Value
End Select
End Sub
GUI User_Form screen-shot
Alright, here's the basics. Your class cCombobox I replicated as follows:
Next, I created a UserForm1 that adds 2 comboboxes, one of which I add to a local variable of type cComboBox.
Even though this works, the above approach is not very clean, since your class is not self-contained - It has to be aware of the UserForm. A better way would be to link the boxes in the class already and then just pass them from the Userform when you initialize your arrays of controls. Then it would be:
cComboBox class:
Here you see you already link the boxes in a self-contained class. In the event handler you could create a lookup for the values, etc. Then in the UserForm1 code you initialize them as follows:
EDIT: Based on the fact that it needs to be an array, you can amend the userform as follows:
In the array you can access each box as
LinkedComboBox(i).DependBox
andLinkedComboBox(i).TriggerBox
. You won't need the two seperate arrays anymore, since everything is already contained in thisLinkedComboBox
array