首页 > 解决方案 > 使用循环删除用户窗体中的图像控件

问题描述

我创建了一个用户窗体,它可以创建多达 6 个图像控件,并在按下命令按钮时用图片填充它们(通过复选框,您可以选择图片)。

现在,当按下命令按钮时,我希望在重新加载图像控件和图片之前删除所有带有图片的图像控件,这样Unload当一个人想要通过复选框。我试图通过循环图像控件来做到这一点,但这不适用于我的代码。你有什么建议我可以解决这个问题吗?谢谢你。

请记住:整个想法是将此删除过程作为子中的第一个操作;我不想Unload Me等...)

Option Explicit
Dim i, k As Byte

Private Sub cmdGetGraphics_Click()
Dim sum_cb As Byte, cb_slct As Byte, y As Byte, sum_img As Byte
Dim Img As MSForms.Image
Dim Control As Control
Dim F(1 To 6) As Integer
Dim img_name As String

For Each Control In Me.Controls
    If TypeName(Control) = "Image" Then
        For i = 1 To 6
          Me.Controls.Remove "Image" & i 'error occurs here: Invalid Argument
        Next i
    End If
Next Control

标签: excelvbaloopscontrolsuserform

解决方案


I)“无效论点”问题背后的原因是什么?

我假设您创建了额外的图像控件,导致运行时错误“无效参数” - 请参阅案例 [2.2]。

[1]一旦您在循环中找到第一个 Image 控件,您就已经删除了循环 For Each的完整“Image”和 i 控件集For i = 1 to 6。重要的是要知道,For Each循环不会纠正Me.Controls当前删除中的原始内容,而是会尝试分析整个集合(即Image2Image3在接下来的步骤中等)。

案例[2.1]如果您的“图像”和 i 控件集仅限于这6 个元素,则根本不会发生任何运行时错误“无效参数”:稍后TypeName检查Image2- 不再存在 - 导致一个Object类型而不是,Image从而防止进一步尝试再次删除您的六个“图像”和 i 控件。

案例[2.2]您创建了额外的图像控件:一旦For Each循环检查了一个额外的图像控件,TypeName测试就会找到一个Image类型并尝试再次删除已经删除的六包。=> 因此控件名称不存在,参数实际上是无效的。

二、结论

在任何情况下,您都应避免将该.Remove方法应用于已删除的控件。例如,一劳永逸地使用以下代码就足够了:

For i = 1 To 6
    Me.Controls.Remove "Image" & i          ' property doesn't need brackets
Next i 

IMO 甚至会更好,但是重新考虑编码逻辑并重用图像控件而不是删除它们。因此,您可以通过临时分配一个值轻松清空其 ►.Picture属性,并在需要时立即重新分配所选图像名称。- Cf如何清除用户窗体中的图像?LoadPicture(vbNullString)LoadPicture

附加提示

您的声明行Dim i, k As Byte意味着未指定的变量i默认为 Variant。- 所以我建议说Dim i As Long, k As Byte(在 VBA 中,声明没有内存优势 As Integer,尤其是关于超过整数限制的行数或列数;抛开可能需要整数的 API 函数)

在 Userform 的代码模块本身中通过Unload Me. 为了更深入地了解我建议阅读文章“UserForm1.Show?” .

语法- 请参阅 MS 帮助删除方法


推荐阅读