I\'d like to use a formless userform so the user can navigate the excel sheet before answering the question on the userform. I need to pause or loop the code until the userform
My userform is opened in the middle of a long subroutine which needs to finish executing after the userform is closed.
Your procedure is doing too many things and needs to be broken down into smaller, more specialized procedures.
The correct way to do this, is to shift the paradigm from procedural to event-driven.
Instead of showing the form's default instance like this:
StartingSINT_Popup.Show vbModeless 'Open userform
Have a class module that holds a WithEvent
instance of it:
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
In the form's code-behind, declare a Closed
event:
Public Event Closed()
And then raise it in the QueryClose
handler:
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
Now say you named that class PopupPresenter
, your procedure can now do this:
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
Keep the presenter at module level so that the object doesn't go out of scope when DoStuff
finishes, and pass any variables/values or state that the presenter object needs to do its job when the form is closed. You can do this by exposing properties or public fields/variables (prefer properties though, but that's a whole other topic):
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