2017-01-30 2 views
1

Я создаю динамически Userform с помощью comboboxes и текстовых полей. по одному на каждую строку. Пользователь будет выбирать, сколько строк он хочет. Пока я могу настроить размер Userform в соответствии с количеством строк и создать первую строку. Но произошла ошибка для второй строки: Ошибка времени выполнения '-2147221005 (800401f3)': Неверная строка класса Результат Userform generated Вот мой код. для упрощения я выделил переменную строки к Nb = 3VBA создает несколько текстовых полей/comboboxes динамически в userform

Public Sub CommandButton2_Click() 

    Dim Nb As Integer 'Nb = number of people to record 
    Dim UF2 As Object 
    Dim TbHour, TbBin As msforms.TextBox 'txtbox for number of hours done and bins 
    Dim CBName As msforms.ComboBox 'List with names 
    Dim i 'i = loop to create rows 

    Nb = 3 

    Set UF2 = ThisWorkbook.VBProject.VBComponents.Add(3) 
     With UF2 
     .Properties("Caption") = "Packing record" 
     .Properties("Width") = "250" 
     .Properties("Height") = "50" 
     .Properties("Height") = .Properties("Height") * Nb + 10 
     End With 

    For i = 1 To Nb 
     Set CBName = UF2.Designer.Controls.Add("forms.combobox." & i) **'here is where the error happens on the second For/Next loop** 
      With CBName 
      .Name = "Combobox" & i 
      .Top = 0 
      .Top = .Top * i + 10 
      .Left = 10 
      .Width = 100 
      .Height = 20 
      End With 

      With UF2.CodeModule 
       .InsertLines 1, "Public sub userform_initialize()" 
       .InsertLines 2, "Me.ComboBox1.AddItem (""1"")" 
       .InsertLines 3, "End sub" 
      End With 

     Set TbHour = UF2.Designer.Controls.Add("forms.textbox." & i) 
      With TbHour 
      .Top = 0 
      .Top = .Top * i + 10 
      .Left = 120 
      .Width = 50 
      .Height = 20 
      End With 

    Next i 

    i = i + 1 
Set TbBin = UF2.Designer.Controls.Add("forms.textbox." & i) 
     With TbBin 
     .Top = 10 
     .Top = .Top * i 
     .Left = 180 
     .Width = 50 
     .Height = 20 
     End With 


    VBA.UserForms.Add(UF2.Name).Show 
    ThisWorkbook.VBProject.VBComponents.Remove UF2 


    End Sub 
+0

Почему бы просто не объявить переменную 'New ComboBox' и' .Add' этот объект? –

+0

Как вы это пишете? До сих пор я всегда использовал «controls.add (« forms.xxxx.1 ») ' – MCircular

+0

В упрощенных выражениях, которые соответствуют комментарию ...' Me.Controls.Add (New ComboBox) ' –

ответ

1

проблема заключается в .Name = "Combobox" & i

Я подозреваю, что это из-за «ComboBox1» является по умолчанию имени любого вновь вставленного списку элемента управления, так что:

  • после первой итерации у вас есть выпадающий вы имени «ComboBox1»

  • на 2-й итерации оператор Set CBName = UF2.Designer.Controls.Add("Forms.ComboBox.1") пытается сгенерировать комбобокс, чье имя перед любым последующим явным присвоением свойств Name по умолчанию имеет значение «Combobox1», которое, тем не менее, уже является именем, которое вы назначили первому combobox. следовательно, «Неоднозначность Name» ошибка

Итак, есть три способа, вы можете избежать «Неоднозначное Имя» Ошибка:

  • изменения .Name = "Combobox" & i к .Name = "ComboBox" & i

    , где разница в случае достаточно во избежание противоречия с по умолчанию имя

  • опустить это tatement вообще

    и имеют имя VBA для вас "ComboBox1", "ComboBox2", ...

  • использование Set CBName = UF2.Designer.Controls.Add("Forms.ComboBox.1", Name:="Combobox" & i)

    т.е.Вы назначаете Name прямо на поле со списком конкретизации

Кроме этого, ваш код будет попал в «userform_initialize» написания кода проблемы, так как он будет писать столько подводных лодок, как ComboBoxes добавить

Чтобы противостоять все, что выше проблемы и сделать некоторые рефакторинг, ваш код может быть следующим:

Option Explicit 

Public Sub CommandButton2_Click() 
    Dim nb As Integer 'Nb = number of people to record 
    Dim UF2 As Object ' or use 'As VBComponent' 
    Dim i 'i = loop to create rows 

    nb = 3 
    Set UF2 = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm) 
    With UF2 
     .Properties("Caption") = "Packing record" 
     .Properties("Width") = "250" 
     .Properties("Height") = "50" 
     .Properties("Height") = .Properties("Height") * nb + 10 

     .CodeModule.InsertLines 2, "Public sub userform_initialize()" '<--| start writing your "UserForm_Initialize" sub code 
     For i = 1 To nb 
      With .Designer.Controls.Add("Forms.ComboBox.1", Name:="Combobox" & i) ' or simply: With .Designer.Controls.Add("Forms.ComboBox.1") 
       .top = 20 * (i - 1) + 5 
       .Left = 10 
       .Width = 100 
       .Height = 20 
      End With 

      .CodeModule.InsertLines 2 + i, "Me.ComboBox" & i & ".AddItem (""1"")" '<--| keep adding lines to your "UserForm_Initialize" sub code 

      With .Designer.Controls.Add("forms.textbox.1") 
       .top = 0 
       .top = 20 * (i - 1) + 5 
       .Left = 120 
       .Width = 50 
       .Height = 20 
      End With 
     Next i 
     .CodeModule.InsertLines 2 + i, "End sub" '<--| finish writing your "UserForm_Initialize" sub code 

     i = i - 1 
     With .Designer.Controls.Add("forms.textbox.1") 
      .top = 20 * (i - 1) + 5 
      .Left = 180 
      .Width = 50 
      .Height = 20 
     End With 


     VBA.UserForms.Add(.Name).Show 
    End With 
    ThisWorkbook.VBProject.VBComponents.Remove UF2 
End Sub 
+0

Спасибо! Он отлично работает! Я не знаю, почему я попробовал что-то более сложное, чем нужно было – MCircular

+0

Добро пожаловать – user3598756

2

Set CBName = UF2.Designer.Controls.Add("forms.combobox." & i)

Класс строка всегда Forms.ComboBox.1 - никогда 0,2 или 0,3

Поэтому сделать:

Set CBName = UF2.Designer.Controls.Add("Forms.ComboBox.1")

+0

Это то, что я думал, но у меня есть ошибка «Время выполнения: неоднозначное имя» на одной и той же кодовой строке – MCircular

+0

Я сожалею, что не потратил на это много времени. пользователь дал вам идею использовать именование во время креатина: Set CBName = UF2.Designer.Controls.Add («Forms.ComboBox.1», «Combo» & i) – MacroMarc