One option would be to programatically add event handler code to the userform's class module as you add the comboboxes.
Another option would be to add all of the comboboxes at design time, set their visible properties to false, and then just make whichever ones you need visible at runtime.
Given the number of comboboxes (40!!!) another option would be to use a class module to mimic a control array - we can set up a communal event handler shared by all of the comboboxes which saves having to use repetitive code. I've attached a simple demonstration of this which dynamically adds 10 comboboxes and gives a message box when the Change event is raised.
All that's required is a blank userform called ufm_Example.
In the ufm_Example class module resides this code:
Code:
Option Explicit
Const sngUFM_WIDTH As Single = 300
Const sngUFM_HEIGHT As Single = 500
Private pComboboxes As Collection
Private Sub UserForm_Initialize()
'resize the userform
Me.Width = sngUFM_WIDTH
Me.Height = sngUFM_HEIGHT
AddComboboxes
End Sub
Private Sub AddComboboxes()
Const sngCBX_WIDTH As Single = 100
Const sngCBX_HEIGHT As Single = 20
Const intCBX_TO_ADD As Integer = 10
Dim intCounter As Integer
Dim cbx As c_Combobox
Dim ctl As MSForms.ComboBox
If pComboboxes Is Nothing Then Set pComboboxes = New Collection
'for this example let's add 10 comboboxes to our userform
For intCounter = 1 To intCBX_TO_ADD
'add the control
Set ctl = Me.Controls.Add(bstrProgID:="Forms.ComboBox.1", _
Name:="Combobox" & intCounter, _
Visible:=True)
With ctl
'position the combobox
.Width = sngCBX_WIDTH
.Height = sngCBX_HEIGHT
.Left = Me.Left + ((Me.Width - ctl.Width) / 2)
.Top = Me.Top + (Me.Height / (intCBX_TO_ADD + 2) * intCounter)
'populate the combobox
.List = Sheet1.Range(Sheet1.Cells(2, intCounter), Sheet1.Cells(9, intCounter)).Value
Set cbx = New c_Combobox
cbx.SetCombobox ctl
pComboboxes.Add cbx
End With
Next intCounter
End Sub
Then all we need is a custom class module called c_Combobox:
Code:
Option Explicit
Public WithEvents cbx As MSForms.ComboBox
Sub SetCombobox(ctl As MSForms.ComboBox)
Set cbx = ctl
End Sub
'a generic change event handler for our comboboxes
Private Sub cbx_Change()
If cbx.ListIndex > -1 Then
MsgBox "You clicked on " & cbx.Name & vbLf & _
"The value is " & cbx.Value
End If
End Sub
I have attached an example workbook containing this code so you can download and experiment with it.
I hope that helps...