VBA User Forms



Using Word 2003 I have created a user form within a document template with
text fields, dropdown lists etc. for users to enter required data. When I
create a new document based on the template, the form is displayed and the
values entered are populated in the document at the linked bookmarks.
However, I would like to know what code I need to write so that when you open
the document the previously entered data is displayed in the form so you can
see which fields have been filled in. At the moment the form opens, but all
fields are blank.

Jay Freedman

The key point is to write a procedure in the UserForm's code, specifically
naming the procedure UserForm_Initialize(). (You can quickly get the Sub and
End Sub lines for this by choosing UserForm in the left-hand dropdown at the
top of the code window, and then choosing Initialize from the right-hand
dropdown.) This procedure runs when your UserForm is first created in
memory, and before it appears on the screen. In the procedure, you need code
to get the existing values (or as many of them as do exist, recognizing that
none of them will exist in a new document) and put them into the UserForm's

In addition to the AutoNew or Document_New macro that shows the UserForm
when a new document is being created, you'll need an AutoOpen or
Document_Open macro that shows the UserForm when an existing document is
re-opened. It can probably just repeat the same code from the AutoNew macro,
although that isn't necessarily true.

Although you can extract the values from the bookmarks in your current
template, you might find it worthwhile to change the setup a bit. Word
supports things called "document variables", which are named strings that
are stored invisibly within the document (they're part of the file that's
saved to disk) and which can be created and read by macros and UserForms.
They're much more robust than bookmarks, since users have no access to them.
Your UserForm's OK_Click procedure can store the values from the user's
entries in document variables, and the UserForm_Initialize procedure can
read those values. Then instead of bookmarks, the document body can contain
DocVariable fields that display the values. Even if a user deletes one of
these fields (and they're harder to delete unintentionally than are
bookmarks), the data won't be lost, and the document can be repaired just by
inserting a new field. Look in the main help for the topic on DocVariable
fields, and in the VBA help for the topic on the Variables collection.

Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.


Hello Jay,

Many thanks for your reply - I understand the principle and have replaced my
bookmarks with DocVariable field. However, I still can't get the user form
to display the data entry - I've used the sub AddDocumentVariable() and then
UseDocumentVariable() but that doesn't appear to be doing anything.

Sub adddocumentvariable()

ThisDocument.Variables.Add Name:="DocName"
ThisDocument.Variables.Add Name:="DocVersion"
ThisDocument.Variables.Add Name:="RevDate"
ThisDocument.Variables.Add Name:="Team"

End Sub

Sub UseDocumentVariable()

Dim txtDocName As String
Dim txtDocVersion As String
Dim txtRevDate As String
Dim txtTeam As String

txtDocName = ThisDocument.Variables("DocName").Value
txtDocVersion = ThisDocument.Variables("DocVersion").Value
txtRevDate = ThisDocument.Variables("RevDate").Value
txtTeam = ThisDocument.Variables("Team").Value

End Sub

Am I completely on the wrong track with this?

Many thanks in advance.

Jay Freedman

Not completely wrong, but you did ignore something I said before. Because
you picked arbitrary names for your procedures, there is nothing that makes
them run. VBA specifically associates the procedure name
UserForm_Initialize() with an event that occurs when you call the userform,
so that procedure (if it exists) runs automatically at the correct time.
Similarly, there's an event that occurs when the user clicks the OK
button -- if you assigned the name cmdOK to that button, for example, then
the event runs a procedure named cmdOK_Click(). [Note that renaming the
userform does _not_ cause a change in the name of UserForm_Initialize().]

Now, you don't have to rename your procedures if you don't want to, but then
you do have to call your procedures from the proper ones. For example:

Private Sub UserForm_Initialize()
End Sub

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question