Вот очень простой пример, который просто связывает элементы управления с ячейками рабочего листа: в этой форме это, вероятно, можно было бы легче обработать, установив ControlSource
(https://www.ozgrid.com/Excel/free-training/ExcelVBA2/excelvba2lesson15.htm), но если вы хотите, чтобы он был более гибким (т.е.уметь проверять вводимые данные), тогда вам нужно будет обрабатывать события и делать это следующим образом.
Код для класса обработки событий "clsControl":
Option Explicit
Public linkedCell As Range
Public WithEvents cbo As MSForms.ComboBox
Public WithEvents txt As MSForms.TextBox
Private Sub cbo_Change()
'here you handle the change in a combo box
Me.linkedCell.Value = cbo.Value
End Sub
Private Sub txt_Change()
'here you handle the change in a text box
Me.linkedCell.Value = txt.Value
End Sub
Код в пользовательской форме:
Option Explicit
Private ControlsCollection As Collection
Private Sub UserForm_Activate()
Dim n As Long, t As Long, rngCombo As Range, rngTxt As Range
Dim con As Object
Set ControlsCollection = New Collection
t = 20 'top position
'start positions for linked cells
Set rngCombo = Sheet2.Range("A2")
Set rngTxt = Sheet2.Range("C2")
For n = 1 To 10
Set con = Me.Controls.Add("Forms.ComboBox.1", "cmbo_" & n)
With con
.Height = 18
.Width = 72
.Left = 18
.top = t + (n - 1) * 25
.RowSource = "Some_List"
End With
ControlsCollection.Add ControlWrapper(con, rngCombo.Offset(n - 1, 0))
Set con = Me.Controls.Add("Forms.TextBox.1", "txt_" & n)
With con
.Height = 18
.Width = 72
.Left = 100
.top = t + (n - 1) * 25
End With
ControlsCollection.Add ControlWrapper(con, rngTxt.Offset(n - 1, 0))
Next n
End Sub
'Create an instance of our event-handling class, and assign a control
' and a linked cell
Private Function ControlWrapper(con As Object, rng As Range) As clsControl
Dim rv As New clsControl
'assign to the appropriate control type in the calss instance
Select Case TypeName(con)
Case "ComboBox": Set rv.cbo = con
Case "TextBox": Set rv.txt = con
End Select
Set rv.linkedCell = rng
Set ControlWrapper = rv
End Function
Полученные forn и связанные ячейки, после заполнения нескольких значений:
РЕДАКТИРОВАТЬ 6/ 4/2019
Вот что-то немного другое - каждый экземпляр класса представляет строку в пользовательской форме. Я удалил все ссылки на связанные ячейки, чтобы сохранить код кратким.
Модуль класса:
Option Explicit
'each item is a control on a "row" of the userform
'here we just havce two combos and a textbox
' but could be more...
Public WithEvents cbo1 As MSForms.ComboBox
Public WithEvents cbo2 As MSForms.ComboBox
Public WithEvents txt As MSForms.TextBox
Private Sub cbo1_Change()
'handle the change in a combo box
Me.txt.Value = cbo1.Value & ":" & cbo2.Value
End Sub
Private Sub cbo2_Change()
'handle the change in a combo box
Me.txt.Value = cbo1.Value & ":" & cbo2.Value
End Sub
Private Sub txt_Change()
'here you handle the change in a text box
End Sub
Код пользовательской формы:
Private Sub UserForm_Activate()
Dim n As Long, t As Long
Dim con As Object, obj As clsControl
Set ControlsCollection = New Collection
t = 20 'top position
For n = 1 To 10
Set obj = New clsControl
Set con = Me.Controls.Add("Forms.ComboBox.1", "cmbo_" & n)
With con
.Height = 18
.Width = 72
.Left = 18
.Top = t + (n - 1) * 25
.RowSource = "Some_List"
End With
Set obj.cbo1 = con
Set con = Me.Controls.Add("Forms.ComboBox.1", "cmbo_" & n)
With con
.Height = 18
.Width = 72
.Left = 100
.Top = t + (n - 1) * 25
.RowSource = "Some_List"
End With
Set obj.cbo2 = con
Set con = Me.Controls.Add("Forms.TextBox.1", "txt_" & n)
With con
.Height = 18
.Width = 72
.Left = 200
.Top = t + (n - 1) * 25
End With
Set obj.txt = con
ControlsCollection.Add obj
Next n
End Sub