1

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

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

非常感谢。

4

2 回答 2

5

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

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

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

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,则代码将继续执行,因此在无模式运行时不要破坏该变量。

于 2012-07-25T17:53:33.957 回答
1

正如 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 子实际上无法关闭任一表单。

于 2012-07-26T03:37:20.793 回答