我正在从 SolidWorks 运行 VBA 宏。该表单兼作两种类型文档的输入。在UserForm.Initialize
子例程中,我Caption
根据打开的文档类型更改用户窗体的名称。每当我这样做时,程序都会重新运行UserForm.Initialize
,当它全部完成后,它会从它离开的地方继续,有效地运行两次。
有谁知道解决这种奇怪行为的方法?我尝试将命令放入它自己的 Sub 但结果是一样的。FormName
.Caption
非常感谢。
我正在从 SolidWorks 运行 VBA 宏。该表单兼作两种类型文档的输入。在UserForm.Initialize
子例程中,我Caption
根据打开的文档类型更改用户窗体的名称。每当我这样做时,程序都会重新运行UserForm.Initialize
,当它全部完成后,它会从它离开的地方继续,有效地运行两次。
有谁知道解决这种奇怪行为的方法?我尝试将命令放入它自己的 Sub 但结果是一样的。FormName
.Caption
非常感谢。
我无法复制这个问题,我不知道 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,则代码将继续执行,因此在无模式运行时不要破坏该变量。
正如 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 子实际上无法关闭任一表单。