> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Convenience Function for Passing Values Between Forms via a Hidden Global Form
- URL: https://nolongerset.com/getinfo/
- Published: 2023-09-29T19:33:36.000Z
- Updated: 2026-05-08T12:36:30.000Z
- Description: I don't always use a global form to stash user-provided values, but when I do, I use this GetInfo() function.
- Author: Mike Wolfe
- Tags: Code Library, #FormFunctions, #Import 2026-05-20 02:59

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](https://nolongerset.com/the-global-form/).

To be honest, I rarely use this technique in new development. I work very hard to [avoid global state](https://nolongerset.com/overuse-of-global-state/) of any kind. My current [rule of thumb](https://nolongerset.com/proper-use-of-global-state/) 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:

```vba
'Calling Code
Forms!Global!Message = "Enter Report Date"
DoCmd.OpenForm "GetDate", , , , , A_DIALOG
If Forms!Global!OK Then
    'User entered data and clicked OK; we can do stuff now
End If

'=========================================================
'Form_GetDate code behind
Private Sub Cancel_Click()
    Forms![Global]![OK] = False
    DoCmd.Close
End Sub

Private Sub OK_Click()
    Forms![Global]![StartDate] = Me![ReportDate]
    Forms![Global]![OK] = True
    DoCmd.Close
End Sub
'=========================================================
```

The `A_DIALOG` constant is a dead giveaway to veteran Access developers that this is *old* code.

The pattern was very consistent:

1. Set a prompt for the dialog to the `Message` control on the Global form
2. Open the form (*GetDate*, in this example) in dialog mode
3. Each *GetXxxx* form had a text box bound to `Forms!Global!Message` to display the prompt
4. If user clicks \[Cancel\], set the Global **OK** control to `False` and close form
5. 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
6. 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](https://nolongerset.com/convenience-functions/): **GetInfo()**.

## The Code

```vba
'---------------------------------------------------------------------------------------
' 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](https://nolongerset.com/guard-clauses/), as shown below:

```vba
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:*

[Pass Values Between Forms in Access Without Using a Hidden Global FormUsing a hidden “global” form is a common way to return user-entered data to your program, but there is a better way.![](https://nolongerset.com/favicon.png)No Longer SetMike Wolfe![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2023/10/Designer--8-.png)](https://nolongerset.com/pass-values-without-global-form/)

[GetInfoForm(): Get User Input Without Needing a Global FormThe GetInfoForm() function simplifies the task of returning user input from an unbound form without stashing values in a hidden global form.![](https://nolongerset.com/favicon.png)No Longer SetMike Wolfe![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2023/10/GetInfoForm---Get-User-Input-Without-Needing-a-Global-Form--2-.png)](https://nolongerset.com/getinfoform/)