我的用户窗体是在一个较长的子例程中间打开的,该子例程需要在用户窗体关闭后完成执行。
您的程序做的事情太多,需要分解成更小、更专业的程序。
做到这一点的正确方法是将范式从过程转变为事件驱动。
而不是像这样显示表单的默认实例:
StartingSINT_Popup.Show vbModeless 'Open userform
拥有一个包含 WithEvent 实例的类模块:
Private WithEvents popup As StartingSINT_Popup
Private Sub Class_Initialize()
Set popup = New StartingSINT_Popup
End Sub
Public Sub Show()
popup.Show vbModeless
End Sub
Private Sub popup_Closed()
' code to run when the form is closed
End Sub
在表单的代码隐藏中,声明一个Closed 事件:
Public Event Closed()
然后在 QueryClose 处理程序中引发它:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then 'controlbox was clicked (the "red X button")
Cancel = True 'would otherwise destroy the form instance
Me.Hide 'always hide, never unload
End If
RaiseEvent Closed
End Sub
现在假设您将该类命名为 PopupPresenter,您的程序现在可以这样做:
Private presenter As PopupPresenter
Public Sub DoStuff()
Set presenter = New PopupPresenter
'do stuff...
presenter.Show
'rest of the code in this scope will run immediately AND THIS IS FINE
End Sub
将演示者保持在模块级别,以便在DoStuff 完成时对象不会超出范围,并在表单关闭时传递演示者对象需要完成其工作的任何变量/值或状态。您可以通过公开属性或公共字段/变量来做到这一点(虽然更喜欢属性,但这是另一个话题):
Private WithEvents popup As StartingSINT_Popup
Public Foo As String
Private Sub Class_Initialize()
Set popup = New StartingSINT_Popup
End Sub
Public Sub Show()
popup.Show vbModeless
End Sub
Private Sub popup_Closed()
' code to run when the form is closed
MsgBox Foo
End Sub
Private presenter As PopupPresenter
Public Sub DoStuff()
Set presenter = New PopupPresenter
'do stuff...
presenter.Show
presenter.Foo = "some data"
'rest of the code in this scope will run immediately AND THIS IS FINE
End Sub