Example Apps for Businesses, Schools & Developers

Version 1.3           Approx 0.4 MB (zipped)                 First Published 7 Jan 2024


This idea for this article came from a thread posted by Clara Barton at Access World Forums

In her original post, Clara wrote:

Everything I've read says to close the calling form before opening the new form.
If I don't dim and set the strWhere and the OpenArgs before the form closes, I lose them.
I can do that or I can move the DoCmd.Close to after the DoCmd.OpenForm. What is the proper way and why?

As with many such questions, there is no 'proper' way. It depends on what you are trying to do.

However, it is important to understand that (with one important exception), the rest of the procedure used to open the second form will then complete even if this code also closes the first form. This is true whether or not the second form is modal and/or popup.

The important exception is when the second form is opened as a dialog.
When a form is opened in dialog mode, it is both popup and modal but also prevents any other code executing whilst the form remains open. This affects the sequence of events.

The example app contains 2 forms. Form1 has two buttons which are used to open Form2 normally or in dialog mode.

Two Forms
The code on the first form is:

Sub CloseFormMsg()
      ' Show message, close form then show another message
      MsgBox "Form1 still open but will close when you click OK", vbInformation, "Message from Form1"
      DoCmd.Close acForm, Me.Name
      MsgBox "Form1 now closed", vbInformation, "Message from Form1"
End Sub

Private Sub Command0_Click()
      ' Open Form 2 normally
      DoCmd.OpenForm "Form2"
      'Close Form1 & show messages
      CloseFormMsg
End Sub

Private Sub Command1_Click()
      ' Open Form 2 as acDialog and set OpenArgs = "Dialog"
      DoCmd.OpenForm "Form2", , , , , acDialog, "Dialog"
      'Close Form1 & show messages
      CloseFormMsg
End Sub



The second form code is:

Private Sub Command0_Click()
      DoCmd.Close acForm, Me.Name
      DoCmd.OpenForm "Form1"
End Sub

Private Sub Form_Load()
      If Me.OpenArgs = "Dialog" Then
            Me.Command0.Caption = "Close Dialog Form2"
      Else
            Me.Command0.Caption = "Close and reopen Form1"
      End If
      MsgBox "Form2 open and will be visible when you click OK", vbExclamation, "Message from Form2"
End Sub



When the top button is pressed on Form1, Form2 opens hidden until this message box from Form2 is clicked:

Form1+Msg1
Form2 then appears together with the first message from Form1

Both Forms + Msg2
When this is clicked, Form1 closes, after which the second message from Form 1 is shown.

Form2 + Msg3
However, if the second form is opened as a dialog, the first message is seen after which the second form opens.
Notice also that it is in a different position. Dialog forms are also popups so their position is relative to the whole screen rather than the Access application window.

Form2 Dialog
The button on Form2 has a changed caption indicating it is a dialog form.

The remaining code on Form 1 is paused until Form 2 is closed, after which the other two messages appear in turn with Form1 closing after the first message.



Download

Click to download the example app:   FormOpenCloseTest_v1.3     ACCDB file - Approx 0.4 MB (zipped)



Additional Info

Surprisingly, Access does not provide any native code to detect whether a form is open as a dialog.
For that reason, I used OpenArgs as a simple method of obtaining the information.

To do this in code, you need to use an API. The following code is based on that provided by Philipp Stiefel at How to check if an Access Form is open in dialog mode
The code can be saved in a form class module or (better) from a standard module so it can be reused in multiple forms

Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long

Private Const GWL_EXSTYLE As Long = -20
Private Const WS_EX_DLGMODALFRAME As Long = &H1

Public Function IsFormDialog(frm As Form) As Boolean
      Dim hWnd As LongPtr
      Dim lngStyle As Long

      hWnd = frm.hWnd
      lngStyle = GetWindowLong(hWnd, GWL_EXSTYLE)
      IsFormDialog = CBool((lngStyle And WS_EX_DLGMODALFRAME) = WS_EX_DLGMODALFRAME)

End Function



Possible usage:

In the Form_Load event, use:   MsgBox "Form opened as Dialog = " & IsFormDialog(Me)

Similar code is also available at StackOverflow: How to check the State of a Access 2003 Form, Modal or Modeless?



Feedback

Please use the contact form below to let me know whether you found this article interesting/useful or if you have any questions/comments.

Please also consider making a donation towards the costs of maintaining this website. Thank you



Colin Riddington           Mendip Data Systems                 Last Updated 7 Jan 2024



Return to Example Databases Page




Return to Top