在 Userform 中动态添加或删除一行组合框也是处理这些组合框输入的参考代码

Posted

技术标签:

【中文标题】在 Userform 中动态添加或删除一行组合框也是处理这些组合框输入的参考代码【英文标题】:Dynamicly add new or remove a line of comboboxes in Userform also a refernce code to handle those comboboxes input 【发布时间】:2022-01-14 01:46:48 【问题描述】:

我有这个用户表单

    该表单包含三个comboboxes 以及“添加新”command button

    一旦用户单击添加新按钮,它将添加另一行带有清除按钮的组合键。

    清除按钮将仅删除该特定的组合框行。添加按钮将在此行下方添加一个新行

    每一行都是一个元素,即 A,B,C... 插入按钮将写入条件,例如A 或 B 或 C 从组合框收集的插入文本将是 #(ProductA === "P25" || ProductB === "P26" || ProductC === "P27")

我正在尝试有一个按钮,可以动态添加带有清除按钮的新组合框行。也清除按钮,只会删除该行组合框。我可以使用here 讨论的代码。但不知道如何处理位置和清除按钮。

【问题讨论】:

如果您包含您尝试使用的确切代码并描述您遇到的具体问题(究竟是什么阻止您实现您想要的?),这将对您的问题有所帮助。跨度> @TimWilliams 我会改写它 我建议您已经创建了所有控件并隐藏那些不需要的控件。当用户按下添加按钮时,您只需显示控件。 @FunThomas 是的,我也做了同样的事情,但它会限制行数。 如果您真的想在运行时创建和删除控件,您将面临很多需要解决的问题。创建控件,将事件附加到控件,必要时处理滚动,删除“行”时重新排列控件的位置。当在第 4 行创建控件时,它需要知道它在第 4 行:您如何管理它。当第 3 行被删除时,之前的第 4 行现在变成了第 3 行:您也需要处理这个问题。所有这些都是可以解决的,但到目前为止,作为一个关于 SO 的问题,它的范围很广。 【参考方案1】:

一个有趣的小项目,所以这是我的“解决方案”(显然还远未完全发挥作用,但具有基本的添加/删除行功能。

我测试的用户表单只有一个命令按钮btnAddRow(用于添加新行)。

DataRow

Option Explicit

Private WithEvents Combo1 As MSForms.ComboBox
Private WithEvents Combo2 As MSForms.ComboBox
Private WithEvents ClearButton As MSForms.CommandButton

Dim controlContainer As Object
Public id As Long

Private Sub ClearButton_Click()
    'calls a method on the parent form to remove the row
    CallByName controlContainer, "RemoveRow", VbMethod, id
End Sub


'create and set up a few properties the controls for a row
Public Sub Create(container As Object, rowId As Long)
    
    Set Combo1 = container.Controls.Add("Forms.ComboBox.1", "C1_" & rowId)
    Combo1.Left = 20
    Combo1.Width = 60
    Combo1.List = Array("Item1", "Item2")
    
    Set Combo2 = container.Controls.Add("Forms.ComboBox.1", "C2_" & rowId)
    Combo2.Left = 90
    Combo2.Width = 60
    Combo2.List = Array("Red", "Blue")
    
    Set ClearButton = container.Controls.Add("Forms.commandbutton.1", "BC_" & rowId)
    ClearButton.Left = 160
    ClearButton.Width = 50
    ClearButton.Height = 20
    ClearButton.Caption = "Clear"
    
    Set controlContainer = container 'keep a reference to the place where the controls are created
    id = rowId                       'identifies this row
End Sub

'set the vertical position on the form for the row
Public Sub Position(rowIndex)
    Dim pTop
    pTop = 15 + (25 * (rowIndex - 1))
    Combo1.Top = pTop
    Combo2.Top = pTop
    ClearButton.Top = pTop
End Sub

'remove the row - called from the parent form
Public Sub Remove()
    With controlContainer.Controls
        .Remove Combo1.Name
        .Remove Combo2.Name
        .Remove ClearButton.Name
    End With
End Sub

'move the "add row" button to this row
Public Sub TakeAdd(btn As MSForms.CommandButton)
    btn.Left = ClearButton.Left + ClearButton.Width + 10
    btn.Top = ClearButton.Top
End Sub

'is this row removable? (last remaining row can't be removed)
Public Sub CanRemove(bRemovable As Boolean)
    ClearButton.Enabled = bRemovable
End Sub

用户表单的代码:

Option Explicit

Dim id As Long              'sequence number for assigning unique id to each row
Dim col As New Collection   'holds instances of the class `DataRow`

Private Sub btnAddRow_Click()
    AddRow 'add a new row
End Sub

Private Sub UserForm_Activate()
    AddRow 'add starting row
End Sub

'add a row
Sub AddRow()
    Dim obj As New DataRow
    id = id + 1
    obj.Create Me, id          'creates the controls
    col.Add obj                'add to the collection
    obj.Position col.Count     'sets row index on form
    obj.TakeAdd Me.btnAddRow   'position the "add row" button
    checkRemove                'check if remove buttons are enabled
End Sub

'remove the specified row
Sub RemoveRow(rowId As Long)
    Dim i As Long
    i = 1
    Do While i <= col.Count
        If col(i).id = rowId Then   'is this the row to remove?
            col(i).Remove           'removes the row from the form
            col.Remove (i)          'removes the class instance from the collection
        Else
            col(i).Position i       '(re)position this row
            i = i + 1
        End If
    Loop
    col(col.Count).TakeAdd Me.btnAddRow '(re)position the "add row" button
    checkRemove        'check if remove buttons are enabled
End Sub

'see if the "remove" buttons should be enabled
Sub checkRemove()
    Dim obj
    For Each obj In col
        obj.CanRemove (col.Count > 1) 'enabled if >1 row on form
    Next obj
End Sub

【讨论】:

以上是关于在 Userform 中动态添加或删除一行组合框也是处理这些组合框输入的参考代码的主要内容,如果未能解决你的问题,请参考以下文章

我可以从文本文件中制作动态组合框吗?

通过userform列表框上的名称管理器的动态范围

在拔出usb时动态添加串口并从组合框中删除它们

为啥即使使用了调用,组合框也会抛出异常

利用jquery给指定的table动态添加一行删除一行

利用jquery给指定的table动态添加一行删除一行