VBA在userform中dynamic创build几个文本框/combobox

我使用combobox和文本框dynamic创build一个用户窗体。 每行之一。 用户将select他想要的行数。 到目前为止,我可以根据行数调整Userform的大小并创build第一行。 但是第二行发生错误:运行时错误“-2147221005(800401f3)”:无效的类string结果是Userform生成这里是我的代码。 为了简化我将行variables分配给Nb = 3

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 

问题出在.Name = "Combobox" & i

我怀疑这是由于“Combobox1”是任何新插入的combobox控件的默认名称,因此:

  • 第一次迭代后,你有一个combobox命名“Combobox1”

  • 在第二次迭代中, Set CBName = UF2.Designer.Controls.Add("Forms.ComboBox.1")语句试图生成一个combobox,其名称在任何后续明确的Name属性分配之前默认为“Combobox1”,但是,已经是您分配给第一个combobox的名称。 因此“暧昧的名字”错误

所以有三种方法可以避免“不明确名称”错误:

  • 改变.Name = "Combobox" & i .Name = "ComboBox" & i.Name = "ComboBox" & i

    案例的差异足以避免与默认名称冲突

  • 完全省略这个陈述

    并有VBA为您命名“ComboBox1”,“ComboBox2”,…

  • 使用Set CBName = UF2.Designer.Controls.Add("Forms.ComboBox.1", Name:="Combobox" & i)

    即您在combobox实例化时指定Name

除此之外,你的代码会碰到“userform_initialize”的代码写入问题,因为它会写入与combobox一样多的subs

要面对所有上述问题并进行一些重构,您的代码可能如下所示:

 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 

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

类String始终是Forms.ComboBox.1 – 从不.2或.3

所以呢:

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