VBA – события прерывания в динамически создаваемом текстовом поле

Я пишу приложение VBA в Excel. У меня есть Userform, который динамически формирует себя на основе данных, содержащихся в одном из рабочих листов. Весь код, который создает различные комбобокс, текстовые поля и ярлыки, работает. Я создал модуль класса для захвата событий OnChange для Comboboxes, и снова это работает так, как ожидалось. Теперь мне нужно отловить события OnChange для некоторых текстовых полей, поэтому я создал новый модуль класса, смоделированный для него, чтобы комбобокс задерживал события.

Public WithEvents tbx As MSForms.TextBox Sub SetTextBox(ctl As MSForms.TextBox) Set tbx = ctl End Sub Public Sub tbx_Change() Dim LblName As String MsgBox "You clicked on " & tbx.Name, vbOKOnly End Sub 

Ящик сообщения только для того, чтобы подтвердить, что он работает, прежде чем идти дальше. Проблема, которую я получаю, заключается в модуле кода UserForm:

 Dim TBox As TextBox Dim tbx As c_TextBoxes '[...] Set TBox = lbl Set tbx = New c_TextBoxes tbx.SetTextBox lbl pTextBoxes.Add tbx 

Это вызывает ошибку несоответствия типа Set TBox=lbl . Это тот же самый код, который отлично подходит для ComboBox, просто с переменными, указанными approriate именами. Я смотрел на это в течение 2 часов. У кого-нибудь есть идеи? Спасибо за любые указатели.

Изменить – вот полный модуль пользовательской формы, с которым у меня возникают проблемы:

 Private Sub AddLines(FrameName As String, PageName As String) Dim Counter As Integer, Column As Integer Dim obj As Object Dim CBox As ComboBox Dim cbx As c_ComboBox Dim TBox As TextBox Dim tbx As c_TextBoxes Dim lbl As Control Set obj = Me.MultiPage1.Pages(PageName).Controls(FrameName) If pComboBoxes Is Nothing Then Set pComboBoxes = New Collection If pTextBoxes Is Nothing Then Set pTextBoxes = New Collection For Counter = LBound(Vehicles) To UBound(Vehicles) For Column = 1 To 8 Select Case Column Case 1 Set lbl = obj.Add("Forms.Label.1", "LblMachine" & FrameName & Counter, True) Case 2 Set lbl = obj.Add("Forms.Label.1", "LblFleetNo" & FrameName & Counter, True) Case 3 Set lbl = obj.Add("Forms.Label.1", "LblRate" & FrameName & Counter, True) Case 4 Set lbl = obj.Add("Forms.Label.1", "LblUnit" & FrameName & Counter, True) Case 5 Set lbl = obj.Add("Forms.ComboBox.1", "CBDriver" & FrameName & Counter, True) Case 6 Set lbl = obj.Add("Forms.Label.1", "LblDriverRate" & FrameName & Counter, True) Case 7 Set lbltbx = obj.Add("Forms.TextBox.1", "TBBookHours" & FrameName & Counter, True) Case 8 Set lbl = obj.Add("Forms.Label.1", "LblCost" & FrameName & Counter, True) End Select With lbl Select Case Column Case 1 .Left = 1 .Width = 60 .Top = 10 + (Counter) * 20 .Caption = Vehicles(Counter).VType Case 2 .Left = 65 .Width = 40 .Top = 10 + (Counter) * 20 .Caption = Vehicles(Counter).VFleetNo Case 3 .Left = 119 .Width = 50 .Top = 10 + (Counter) * 20 .Caption = Vehicles(Counter).VRate Case 4 .Left = 163 .Width = 30 .Top = 10 + (Counter) * 20 .Caption = Vehicles(Counter).VUnit Case 5 .Left = 197 .Width = 130 .Top = 10 + (Counter) * 20 Set CBox = lbl 'WORKS OK Call CBDriver_Fill(Counter, CBox) Set cbx = New c_ComboBox cbx.SetCombobox CBox pComboBoxes.Add cbx Case 6 .Left = 331 .Width = 30 .Top = 10 + (Counter) * 20 Case 7 .Left = 365 .Width = 30 .Top = 10 + (Counter) * 20 Set TBox = lbl 'Results in Type Mismatch Set tbx = New c_TextBoxes tbx.SetTextBox TBox pTextBoxes.Add tbx Case 8 .Left = 400 .Width = 30 .Top = 10 + (Counter) * 20 End Select End With Next Next obj.ScrollHeight = (Counter * 20) + 20 obj.ScrollBars = 2 End Sub 

И вот модуль класса c_Combobox:

 Public WithEvents cbx As MSForms.ComboBox Sub SetCombobox(ctl As MSForms.ComboBox) Set cbx = ctl End Sub Public Sub cbx_Change() Dim LblName As String Dim LblDriverRate As Control Dim i As Integer 'MsgBox "You clicked on " & cbx.Name, vbOKOnly LblName = "LblDriverRate" & Right(cbx.Name, Len(cbx.Name) - 8) 'MsgBox "This is " & LblName, vbOKOnly 'Set obj = Me.MultiPage1.Pages(PageName).Controls(FrameName) Set LblDriverRate = UFBookMachines.Controls(LblName) For i = LBound(Drivers) To UBound(Drivers) If Drivers(i).Name = cbx.Value Then LblDriverRate.Caption = Drivers(i).Rate Next End Sub 

И, наконец, вот модуль класса c_TextBoxes:

 Public WithEvents tbx As MSForms.TextBox Sub SetTextBox(ctl As MSForms.TextBox) Set tbx = ctl End Sub Public Sub tbx_Change() Dim LblName As String 'Does nothing useful yet, message box for testing MsgBox "You clicked on " & tbx.Name, vbOKOnly End Sub 

После некоторого быстрого тестирования я могу воспроизвести вашу ошибку, если я объявляю TBox as TextBox . Я не получаю сообщение об ошибке, если я объявляю TBox as MSForms.TextBox . Я бы порекомендовал объявить все ваши переменные TextBox MSForms .

Тестовый код расположен аналогично вашему. У меня есть MultiPage с Frame где я добавляю элемент Control .

 Private Sub CommandButton1_Click() Dim obj As Object Set obj = Me.MultiPage1.Pages(0).Controls("Frame1") Dim lbl As Control Set lbl = obj.Add("Forms.TextBox.1", "txt", True) If TypeOf lbl Is TextBox Then Debug.Print "textbox found1" 'does not execute End If If TypeOf lbl Is MSForms.TextBox Then Debug.Print "textbox found2" Dim txt1 As MSForms.TextBox Set txt1 = lbl 'no error End If If TypeOf lbl Is MSForms.TextBox Then Debug.Print "textbox found3" Dim txt As TextBox Set txt = lbl 'throws an error End If End Sub 

Я не уверен, почему спецификатор нужен для TextBox а не для ComboBox . Как вы можете видеть выше, хорошим тестом для этого является If TypeOf ... Is ... Then проверить, какие объекты являются типами. Я включил первый блок, чтобы показать, что lbl не является «голой» TextBox , но, опять же, я понятия не имею, почему это так. Может быть, есть другой тип TextBox , который переопределяет декларацию по умолчанию?

  • Вызов массива по пользовательской форме Завершение / закрытие VBA
  • деактивировать пользовательскую форму Excel VBA
  • Добавление проверки в пользовательскую форму
  • Ошибка выполнения VBA Excel VBA -2147319767 (80028029)
  • Динамическое название диаграммы из пользовательской формы
  • VBA- Итерирование по строковым значениям в массиве и идентификация, если они равны определенному тексту
  • Сохранить флажок выбора пользовательской формы в массиве (для репликации на пользовательской форме)
  • Измените пользовательскую форму для работы с несколькими листами
  • Вставьте данные листа в combobox userform без дублирования - Excel Vba
  • Скрыть закрытую кнопку в пользовательской форме excel vba для моей панели выполнения
  • Как прокрутить флажки на динамически созданной пользовательской форме?
  • Давайте будем гением компьютера.