【问题标题】:VBA UserForm running twice when changing .Caption更改.Caption时VBA用户窗体运行两次
【发布时间】:2012-07-26 11:37:20
【问题描述】:

我正在从 SolidWorks 运行 VBA 宏。该表单兼作两种类型文档的输入。在UserForm.Initialize 子例程中,我根据打开的文档类型更改用户窗体的Caption 的名称。每当我这样做时,程序都会重新运行UserForm.Initialize,当一切都完成后,它会从它离开的地方继续运行,有效地运行两次。

有人知道解决这种奇怪行为的方法吗?我尝试将 FormName.Caption 命令放入它自己的 Sub 中,但结果是一样的。

非常感谢。

【问题讨论】:

  • 初始化事件不应发生两次。您是否已单步执行代码以确保 .caption 更新导致重复?您始终可以将标题更改移动到激活事件。从技术上讲,这意味着它会显示错误的标题,但在它改变之前的时间几乎无法区分。
  • @DanielCook 但这不会导致 more 重新运行代码吗? (即每次激活/点击表单时)
  • 是的,它肯定会。但是,如果您将标题存储到在初始化事件期间确定的用户表单的私有字符串中,它将几乎没有开销。但实际上我只是提到了一些可能在没有实际解决您的问题的情况下有效的东西。这就是为什么我没有将其列为答案的原因。 :-)

标签: vba caption userform solidworks


【解决方案1】:

我无法复制问题,我不知道 SolidWorks 是什么,所以这可能与它有关。也许您可以发布一个虚构的示例,显示 Initialize 被调用了两次。

我的猜测是它与自动实例化变量有关。当您使用 UserForm1 时,您正在实例化一个名为 UserForm1 的对象变量,它指向一个也称为 UserForm1 的对象。这类似于在 Dim 语句中使用 New 关键字。您从未定义过 UserForm1(变量),但 VBA 定义了,并且在您第一次使用它时,它会自动实例化。

在用户表单类模块中工作时,您应该尝试使用 Me 关键字(用户表单是与其他对象一样的类,只是它们具有用户界面元素)。在 Initialize 事件中,说

Me.Caption = "blah"

而不是

UserForm1.Caption = "blah"

可能是(只是一个我无法证明的理论)设置为“我指向一个真实实例”的标志在您更改 Caption 属性时尚未设置,并且通过使用自动实例化变量 UserForm1,您正在强制另一个实例化。

更好的是,不要使用自动实例化变量,尽管它们很方便(也不要在 Dim 语句中使用 New 关键字)。您可以控制创建和销毁变量的时间,这是最佳实践。标准模块中的类似内容

Sub uftst()

    Dim uf As UserForm1

    Set uf = New UserForm1 'you control instantiation here

    'Now you can change properties before you show it
    uf.Caption = "blech"
    uf.Show

    Set uf = Nothing 'overkill, but you control destruction here

End Sub

请注意,如果 ShowModal 属性设置为 False,则代码将继续执行,因此在无模式运行时不要破坏该变量。

【讨论】:

  • +1 表示完全正确。我不喜欢迷你 Markdown 格式,所以我发布一个新答案只是为了展示如何复制问题。
  • 太棒了,这很有魅力。也感谢您提供更多信息!
【解决方案2】:

正如 Dick 建议的那样,您应该能够通过确保使用 me.caption 而不是 Userform1.caption 来阻止该行为。

您可以通过以下方式为好奇的人复制该问题:

创建一个用户表单 (Userform1) 确保将 ShowModal 设置为 false,否则您将无法看到。

在模块中添加以下内容:

Option Explicit
Sub ShowUserForm()
    Dim uf As UserForm1
    Set uf = New UserForm1
End Sub

在 UserForm1 中列出以下代码:

Option Explicit
Private Sub UserForm_Initialize()
    UserForm1.Caption = "I'm UserForm1!" 'This will call the Initialize method of Userform1 not Me.
    Me.Caption = "I'm Me!" 
    Me.Show
End Sub

运行 ShowUserForm。您现在有两个具有不同标题的用户表单。

顺便说一句,如果您有像我显示的 Initialize 方法,将 Set uf = Nothing 添加到 ShowUserForm 子实际上无法关闭任一表单。

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2020-09-25
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多