office交流网--QQ交流群号

Access培训群:792054000         Excel免费交流群群:686050929          Outlook交流群:221378704    

Word交流群:218156588             PPT交流群:324131555

使用Controls.Remove CStr(ctr.Name) 删除动态创建的控件提示出错:不能在此上下文中使用此命令

2020-05-04 08:00:00
zstmtony
原创
3548

使用Controls.Remove CStr(ctr.Name) 删除动态创建的控件提示出错:不能在此上下文中使用此命令

运行到此即出错、提示: '运行时错误 '444': 无法删除控件 。不能在此上下文中使用此命令。


先看看微软官方对Controls.Remove的帮助


Remove 方法                        

从集合中删除一个成员,或者从框架、页面或窗体中删除一个控件。

语法

object.Remove( collectionindex)

Remove 方法的语法有以下几个成分:

成分 说明 
object 必需。一个有效对象。 
collectionindex 必需。成员在集合内的位置或索引。可以是数字,也可是字符串。如果该值是数字,则最小值为零,最大值比集合中的成员数少一。若该值为字符串,则必须对应有效的成员名。 

说明

此方法只删除在运行时间添加的控件。但如果想删除在设计时间添加的控件,则会出错。



VBA动态创建控件使用的是以下的代码


    Dim ctrLable As Control
    Dim ctrTextBox As Control
    Dim ctrComboBox As Control
    Dim i As Integer
    With Me
        For i = 1 To 10
            '添加标签控件
            Set ctrLable = .Controls.Add("Forms.Label.1", "lblAuto" & i, True)
            With ctrLable
                .Caption = "第" & i & "个标签"
                .Left = 10
                .Top = 35 + (i - 1) * 35
                .Tag = "AutoControl"
                .Visible = True
                'Debug.Print .Name
            End With
            '添加文本框控件
            Set ctrTextBox = .Controls.Add("Forms.TextBox.1", "txtAuto" & i, True)
            With ctrTextBox
                .Left = 10 + 50
                .Top = 35 + (i - 1) * 35
                .Width = 70
                .Height = 20
                .Tag = "AutoControl"
                'Debug.Print .Name
            End With
            '添加组合框件
            Set ctrComboBox = .Controls.Add("Forms.ComboBox.1", "cboAuto" & i, True)
            With ctrComboBox
                .Left = 10 + 50 + 70
                .Top = 35 + (i - 1) * 35
                .Width = 70
                .Height = 20
                .Tag = "AutoControl"
                '.Visible = false
                .RowSource = "系统_库位列表"
                'Debug.Print .Name
            End With
            
        Next i
        
    End With

    Me.cmdRemoveControl.SetFocus
    Me.cmdCreateControl.Enabled = False


而删除控件使用的是这样的代码


 Dim ctr As Control
 For Each ctr In frmWuLiaoXinXi.Controls
 
    If ctr.Tag & "" = "AutoControl" Then
        Me.Controls.Remove CStr(ctr.Name)  'If Not (TypeOf ctr Is MSForms.TextBox) Then
    End If
 Next



但提示出错:不能在此上下文中使用此命令。


后经过不断尝试调试,发现原来是VBA的一个Bug, 即如果是使用 Me.Controls.Add("Forms.TextBox.1", "txtAuto" & i, True) 这种方式 在运行状态动态创建的控件,不会去判断与已有控件是否重名。

原来是因为重名的原因,自动创建的控件,即使与原设计时加的控件重名,系统也不会报错。
现修改将我代码创建的控件使用特殊的前缀后完美解决了


另注意 Me.Controls.Remove 只能删除代码在运行状态动态创建的控件,而不能删除在设计状态添加的控件


相关知识


下面程序是在EXCEL-VBA运行
Sub adf()

  Dim Ctl As Control

  For Each Ctl In Formtest.Controls

    Debug.Print Ctl.Name, TypeName(Ctl)

    Formtest.Controls.Remove Ctl

  Next

End Sub
 
上面程序是参考编写的

cc = UserForm1.Controls.Count

For TC = 1 To cc - 1

If TypeName(UserForm1.Controls.Item(TC)) = "Image" Then

IC = IC + 1

End If

Next

If IC >= 1 Then

For DC = 1 To IC

UserForm1.Controls.Remove "image" & DC + 1

Next

End If

在网上又找了一段程序。目标实现

Sub RemoveBtn()

    Dim ctl As MSForms.Control

    Set vbc = ThisWorkbook.VBProject.VBComponents("UserForm1")

    For Each ctl In vbc.Designer.Controls

        vbc.Designer.Controls.Remove ctl.Name

    Next ctl

End Sub
要注意:Designer.Controls.Remove ctl.Name
运行不成功,有两个注意事项:
1是确保VBE当前模式是设计模式。
2如果仍报错,使用CStr函数,强制返回控件名字符串,(今天刚刚摸索出来的技巧,原理暂时不知道)
Designer.Controls.Remove CStr(ctl.Name)

分享