I have the following code in a Form Module in an xlsm:
Public Sub DoModal() ' Note: Called by LaunchHelper which is associated with F12 in Workbook_Open
Dim ewsActive As Worksheet: Set ewsActive = ThisWorkbook.ActiveSheet
If ewsActive Is Overview Then ' Overview is the CodeName of one of the Worksheets
Set ewsOverview = ewsActive ' This is a Private variable in the Form Module
ShowSafe
End If
End Sub
Private Sub ShowSafe() ' Calling Show directly caused random crashes, I concluded that these were caused by that the Form was not loaded into memory, this function makes sure, it is in memory before calling Show
Dim blnLoaded As Boolean: blnLoaded = False
Dim objForm As Object: For Each objForm In UserForms
If objForm.name = Me.name Then
blnLoaded = True
Exit For
End If
Next objForm
If blnLoaded = False Then
Load Me
End If
Show
End Sub
As far as I know:
VBA is single-threaded, it can never happen that two Subs or Functions are executed in parallel (e.g. while processing Worksheet_Activate, Worksheet_SelectionChange is also called, and the order of executing the statements inside those two functions is undetermined).
However, if we look at Excel+VBA as a system, then it is multi-threaded because Excel and VBA run in parallel (and Excel is multi-threaded itself, in addition).
My problem is:
I see a race condition in DoModal, because checking and acting is not atomic, and the following scenario is possible:
(1) The condition ewsActive Is Overview is evaluated as true, so we start executing the branch inside the If block.
(2) The execution is taken over by Excel, where the user switches to a different Worksheet.
(3) ShowSafe is called while we the ActiveSheet is not Overview but something else.
Do you agree with my reasoning? Is it correct that in spite of the checking, the Form might show up on a different Worksheet? So far, I have not succeded in making this error happen but I would like to know if it was possible in theory, even if it has only a low chance.
Where can I find more information about problems and guarantees related to multi-threading in VBA?