从用户窗体中删除动态添加的控件

13

我有一个带有动态添加的复选框的Excel用户窗体。

我使用类似以下代码添加复选框:

Set chkBox = Me.Controls.Add("Forms.Checkbox.1", "Checkbox" & i)

我想要移除所有这些复选框。

Dim j As Integer
'Remove all dynamically updated checkboxes
For Each cont In Me.Controls
    For j = 1 To NumControls
        If cont.Name = "Checkbox" & j Then
            Me.Controls.Remove ("Checkbox" & j)
        End If
    Next j
Next cont
我收到了以下错误信息:
Error Message

这里的问题可能是括号在("复选框"和j)中的使用。 - Gene Skuratovsky
1
检查它在哪个 j 失败,并验证是否是在运行时添加的复选框而不是在设计模式下添加的。 - Patrick Lepelletier
回头看,可能修复我的代码的不是检查,而是找到正确选项后退出。@PatrickLepelletier 可能是对的,这可能是检查错误的复选框。话虽如此,Chris 下面的代码应该无论如何都可以解决这个问题。 - ale10ander
1
我回到这篇帖子,只是想知道为什么我没有看到它:我使用 On error resume next 来处理这些事情。 - Patrick Lepelletier
6个回答

14

一种更好的方法可能是跟踪您创建的控件(例如,使用集合),并使用该集合来删除它们。

这样,您的代码就不会绑定于名称格式,并且可以应用于其他控件类型。

Private cbxs As Collection

Private Sub UserForm_Initialize()
    Set cbxs = New Collection
End Sub

' Remove all dynamicly added Controls
Private Sub btnRemove_Click()
    Dim i As Long
    Do While cbxs.Count > 0
        Me.Controls.Remove cbxs.Item(1).Name
        cbxs.Remove 1
    Loop
End Sub


' Add some Controls, example for testing purposes
Private Sub btnAdd_Click()
    Dim i As Long
    Dim chkBox As Control
    For i = 1 To 10
        Set chkBox = Me.Controls.Add("Forms.CheckBox.1", "SomeRandomName" & i)
        chkBox.Top = 40 + i * 20
        chkBox.Left = 20
        cbxs.Add chkBox, chkBox.Name  '- populate tracking collection
    Next

    ' Demo that it works for other control types
    For i = 1 To 10
        Set chkBox = Me.Controls.Add("Forms.ListBox.1", "SomeOtherRandomName" & i)
        chkBox.Top = 40 + i * 20
        chkBox.Left = 60
        cbxs.Add chkBox, chkBox.Name
    Next

End Sub

2
不妨更改变量chkbox的名称。对于集合的酷炫使用加1。 - L42
1
谢谢@L42。是的,我会使用一个泛化的名称。只是为了让OP更清楚地了解这与他原来的代码的关系。 - chris neilsen
1
@PatrickLepelletier 实际上不是这样的,集合项从1开始。(另一方面,字典从0开始)。VBA在起始索引方面可能会非常不一致。 - chris neilsen
我花了很长时间试图弄清楚如何删除在运行时添加到PowerPoint表单的自定义控件,所以这个优雅的解决方案非常好。谢谢@chris。 - Jamie Garroch - MVP
1
友情提示:假设在第二个循环中将集合分配给复选框的代码应编写为cbxs.Add chkBox,chkBox.Name(而不是chkBox.Add ...,否则会导致运行时错误438 对象不支持此属性或方法 :-) @chrisneilsen - T.M.
显示剩余3条评论

3
假设没有其他以“Checkbox”开头的控件名称,
For Each cont In Me.Controls
    If InStr(cont.Name, "Checkbox") = 1 Then
        Me.Controls.Remove cont.Name
    End If
Next cont

不错的方法,非常简单但有效。 - JCO9

2

如果您已经知道控件的名称、类型和数量,为什么要双重循环?

请注意,只有在运行时创建的控件才能被删除。

'the following removes all controls created at runtime
Dim i As Long
On Error Resume Next
With Me.Controls
    For i = .Count - 1 to 0 step -1
        .Remove i
    Next i
End With
Err.Clear: On Error GoTo 0

对于你的情况,如果所有的命名都是正确的。
Dim j&
For j = 1 To NumControls
    Me.Controls.Remove "Checkbox" & j
Next j

还有另一种方法,你可以尝试一下

Me.controls.clear ' from https://learn.microsoft.com/en-us/office/vba/Language/Reference/User-Interface-Help/clear-method-microsoft-forms

1

添加对控件的检查似乎解决了这个问题。不是很确定为什么,但它有效。

   Dim j As Integer
'Remove all dynamically updated checkboxes
For Each cont In Me.Controls
    If TypeName(cont) = "CheckBox" Then
        For j = 1 To NumControls
            If cont.Name = "Checkbox" & j Then
                Me.Controls.Remove cont.Name
                Exit For
            End If
        Next j
    End If
Next cont

2
那个循环里面的循环在做什么? - Gene Skuratovsky
内循环正在检查每个控件的编号。在外循环中,我到达了控制A,但我并不确定它是否是控制1。因此,我会逐个检查每个编号,直到找到正确的编号。 - ale10ander
这并不是通过控制检查来解决的,而是通过找到我要找的内容后退出。恰好在此之前,我的复选框已经被选中了。被接受的答案更加稳定,它不依赖于运气 :) - ale10ander

0

我使用命令按钮重写了原始代码,只是添加了“Me.Controls.Count”而不是“NumControls”,并将“Cont”定义为控件。对我来说似乎工作正常。如果这对您有用,请告诉我:

-->

On Error Resume Next
Dim Cont As Control
Dim C As Integer
'Remove all dynamically updated checkboxes
For Each Cont In Me.Controls
    For C = 1 To Me.Controls.Count
    If Cont.Name = "CommandButton" & C Then
        Me.Controls.Remove ("CommandButton" & C)
    End If
    Next C
Next Cont

0
另一种选择哪些控件保留和哪些删除的方法是使用 .Tag 属性。这允许对添加的控件进行一些精细的控制,例如通过将 .Tag 用作位字段。
在创建时:
With Me.Controls.add("Forms.Label.1", Visible:=True)
{code}
    .Tag = 1
{more code}

然后当整理的时候到来:

For Each C In Me.Controls
    If C.Tag = 1 Then Me.Controls.Remove C.Name
Next

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接