You have a custom VBA userform in Word that works well inside one document but disappears or resets every time you close and reopen the file. This happens because VBA userforms are stored in the document module and are destroyed when the document unloads. This article explains how to design a VBA userform that retains its state and settings across document sessions by storing data in a persistent location such as a template, a registry key, or a simple text file.
Key Takeaways: Persisting a Word VBA Userform Across Sessions
- Store userform in a global template (Normal.dotm): Keeps the form and its code available across all documents and sessions.
- Use VBA’s SaveSetting and GetSetting: Write and read userform control values to the Windows registry so they survive a document close.
- Load settings in UserForm_Initialize: Populate controls from the registry or a file when the form opens, restoring the last state.
Why VBA Userforms Reset When the Document Closes
A VBA userform embedded in a specific document (.docm) is part of that document’s VBA project. When Word closes the document, the entire VBA project is unloaded from memory. All variable values, form control states, and any unsaved data are lost. The form itself still exists in the document file, but its runtime state — such as text box entries, combo box selections, or checkbox states — is gone.
The core problem is the difference between design-time persistence (the form stays in the file) and runtime persistence (the values the user entered vanish). To make the form truly persist across sessions, you must separate the form’s code from the document’s lifecycle. The two reliable approaches are:
- Move the userform to a global template so it remains loaded as long as Word runs
- Save and restore control values using an external storage mechanism such as the Windows registry, a text file, or a custom XML part in the document
Method 1: Store the Userform in a Global Template
A global template like Normal.dotm stays loaded for the entire Word session. Any userform placed in Normal.dotm is available from any document. Its controls hold their values until the user closes Word or unloads the form manually. This method is the simplest way to keep a form alive across multiple document opens and closes within the same Word session.
Prerequisites
- Access to the VBA editor (Alt+F11)
- Permission to modify Normal.dotm — this is usually allowed unless your IT policy restricts it
- The userform code must be self-contained and not reference specific document properties that change
Steps to Add the Userform to Normal.dotm
- Open the VBA editor and locate Normal.dotm
Press Alt+F11. In the Project Explorer, look for the project named “Normal.” This is your Normal.dotm template. If you do not see the Project Explorer, press Ctrl+R. - Insert a new userform into Normal.dotm
Right-click the Normal project, select Insert > UserForm. A blank form appears in the editor. Add the controls you need: text boxes, combo boxes, check boxes, and command buttons. - Write the form code in Normal.dotm
Double-click the form or a control to open the code pane. Write the event handlers such as UserForm_Initialize and button click procedures inside the Normal project. Do not use the ThisDocument module of any specific .docm file. - Create a macro to display the form
Insert a standard module in Normal.dotm. Write a Sub procedure likeSub ShowMyForm()that containsUserForm1.Show. Assign this macro to a ribbon button or keyboard shortcut for easy access. - Save Normal.dotm
Word prompts you to save changes to Normal.dotm when you exit. Accept the prompt. The form is now part of the global template and will load every time Word starts.
Method 2: Save and Restore Control Values Using the Registry
Storing the form in a global template keeps the form alive during a Word session, but closing Word destroys all runtime values again. If you need values to survive a full Word restart, you must write them to an external store. The Windows registry is the most convenient location because VBA provides built-in functions: SaveSetting, GetSetting, GetAllSettings, and DeleteSetting.
Steps to Persist Userform Values to the Registry
- Choose a registry key path
VBA writes toHKEY_CURRENT_USER\Software\VB and VBA Program Settings\. Use your application name and section name. Example: AppName = “MyWordTools”, Section = “UserForm1”. - Save control values when the form closes
In the UserForm_QueryClose event, call SaveSetting for each control. Example for a text box named txtName:SaveSetting "MyWordTools", "UserForm1", "Name", txtName.Text. For a check box:SaveSetting "MyWordTools", "UserForm1", "Option", CStr(chkOption.Value). - Restore control values when the form opens
In the UserForm_Initialize event, call GetSetting for each control and assign the value. Example:txtName.Text = GetSetting("MyWordTools", "UserForm1", "Name", ""). The fourth parameter is the default value if the setting does not exist. - Handle combo boxes and list boxes
Save the selected index or the text. For a combo box:SaveSetting "MyWordTools", "UserForm1", "ComboSel", cboOptions.ListIndex. Restore by setting the ListIndex property. - Test persistence across a Word restart
Open Word, run the form, enter values, close the form, close Word completely, reopen Word, and run the form again. The controls should show the previously entered values.
Method 3: Save and Restore Control Values Using a Text File
If registry access is restricted on your network, use a simple INI-style text file stored in the user’s AppData folder. This method works on any Windows configuration and does not require registry permissions.
Steps to Persist Values to a Text File
- Determine the file path
UseEnviron("APPDATA") & "\MyWordTools\FormSettings.txt". Create the folder if it does not exist using the MkDir statement. - Write a helper function to save settings
Open the file for Output, write each control name and value separated by a delimiter such as a pipe character. Example:Print #1, "Name|" & txtName.Text. Close the file. - Write a helper function to load settings
Open the file for Input, read each line, split by the delimiter, and assign the value to the matching control. Use a Select Case or If block to match control names. - Call the save function in QueryClose and the load function in Initialize
This mirrors the registry approach but uses a file instead. The form remains independent of the document.
If the Userform Still Loses Data After These Methods
The form is stored in a document module instead of a template
If you placed the userform in a .docm file and close that file, the form is unloaded. Move the form to Normal.dotm or another global template. To verify, open the VBA editor and check which project contains the form’s folder.
The SaveSetting function does not write to the registry
On locked-down corporate computers, the registry write may be blocked. Use the text file method instead. Test by running a simple SaveSetting call in the Immediate pane: SaveSetting "Test", "Test", "Test", "Hello". If no error occurs, the registry is writable.
The UserForm_Initialize event does not fire
This event runs only when the form is loaded into memory. If you hide the form instead of unloading it, Initialize does not fire again. Use the Show method each time you need the form, or call a custom subroutine that reloads settings before showing the form.
Global Template vs Registry vs Text File: Key Differences
| Item | Global Template (Normal.dotm) | Windows Registry | Text File (AppData) |
|---|---|---|---|
| Persistence scope | Current Word session only | Across all Word sessions and restarts | Across all Word sessions and restarts |
| Setup complexity | Low — add form to Normal.dotm | Medium — write SaveSetting/GetSetting code | Medium — write file I/O code |
| Permission required | Write access to Normal.dotm | Write access to HKCU registry | Write access to AppData folder |
| Data visibility | Not stored externally | Visible in regedit | Visible in File Explorer |
| Best for | Quick session-only persistence | Enterprise environments with registry access | Locked-down computers or roaming profiles |
Now you can build a Word VBA userform that keeps its state across document sessions. Start by moving the form to Normal.dotm for session persistence, then add SaveSetting and GetSetting calls for full restart persistence. If registry access is blocked, switch to a text file stored in the AppData folder. For advanced scenarios, consider storing settings in a custom XML part inside the document itself using the CustomXMLPart object — this keeps the data attached to the file even when emailed.