Convenience Function for Passing Values Between Forms via a Hidden Global Form
One technique for passing values back and forth between forms and reports in Microsoft Access is to stash them temporarily on a hidden "Global" form.
To be honest, I rarely use this technique in new development. I work very hard to avoid global state of any kind. My current rule of thumb is that global variables should be limited to those values that must be set at runtime, but do not change throughout the life of the application.
That said, I maintain dozens of Access applications that are over 20 years old. Many of those applications use this technique. One pattern in particular showed up again and again:
The pattern was very consistent:
- Set a prompt for the dialog to the
Message
control on the Global form - Open the form (GetDate, in this example) in dialog mode
- Each GetXxxx form had a text box bound to
Forms!Global!Message
to display the prompt - If user clicks [Cancel], set the Global OK control to
False
and close form - If user clicks [OK], transfer values from GetXxxx text boxes to equivalent fields on the Global form, set Global OK control to
True
, and close form - In the calling code, check the value of the Global OK control to see what user did
These same four lines of calling code appeared everywhere in many of these older applications.
There was nothing inherently wrong with the approach, it was just inefficient. Those four lines of code could be replaced with one line by introducing a convenience function: GetInfo().
The Code
'---------------------------------------------------------------------------------------
' Procedure : GetInfo
' DateTime : 7/28/2008 16:22
' Author : Mike Wolfe
' Purpose : Simplifies the process of getting user input via custom input forms.
' Source : https://nolongerset.com/getinfo/
' Usage : If GetInfo("Get2Dates","Please enter report dates:") Then
' 'If we make it in here, we know the user hit OK
' End If
' 12/16/10 : Added optional parameter OpenArgs.
'---------------------------------------------------------------------------------------
'
Function GetInfo(GetDataFormName As String, _
Optional Message As String = vbNullString, _
Optional OpenArgs As String = vbNullString) As Boolean
With Forms!Global
!Message = Message
!OK = False
DoCmd.OpenForm GetDataFormName, , , , , acDialog, OpenArgs
GetInfo = !OK
End With
End Function
Usage
The introduction of this function required no changes to the GetXxxx forms themselves. This made it very easy to refactor the calling code without having to make additional changes.
When refactoring to introduce the GetInfo() function, I also "inverted" the If...Then statement to make it a guard clause, as shown below:
If Not GetInfo("GetDate", "Enter Report Date") Then Exit Sub
A Better Way
I'll cover my preferred approach for doing this in a future article. Stay tuned.
UPDATE [2023-10-27]: The following articles document my preferred approach: