
The Anchorage
Personal website of Gregory K. Maxey, Commander USN (Retired)
The information, illustrations and code contained in my "Microsoft Word Tips" are provided free and without risk or obligation.
However, the work is mine. If you use it for commercial purposes or benefit from my efforts through income earned or time saved then a donation, however small, will help to ensure the continued availability of this resource.
If you would like to donate, please use the appropriate donate button to access PayPal. Thank you!
In this Microsoft Word Tips & Microsoft Word Help page I will show you how to create and employ a document template and Userform.
The first section of this tips page provides methods which are universal to all current Word versions (2003, 2007, 2010 and 2013). For a method using content controls with Word 2013, 2010 and a limited bases 2007, see Content Control Method.
Note: Even if you are interested in the Content Control Method, be sure to review this section as well. It contains lots of information on userforms in general that you won't want to miss.
For this section I am going to create a demonstration template with a Userform for a "Student Survey" form. The template provides:
The template when a opened in Word 2010 with field codes displayed is shown in the illustration below.

If you don't know what a template is or if you need help creating one see Word MVP Suzanne Barnhill's: How to Create a Template
Note: If you are using Word 2003 you will use a .dot extension template file. As the template contains a VBA project you must use a macro enabled (.dotm extension) template with Word 2007/2010.
On Doug's suggestion, with one exception, I am departing from an often used practice of using bookmarks as place marker\data stores in the document and will use document variables and DocVariables fields instead.
The exception is that I will use a bookmark for the "Address" information.
Enter the boiler plate text (e.g., form labels, headings, etc.) and the DocVariable fields and/or bookmarks as required.
Note: While not demonstrated here, Content Controls introduced with Word 2007 are excellent place marker/data stores in document templates.
After you create your template and enter the DocVariable fields and bookmark it is time to open the Visual Basic Editor (VBE) to create a standard code module and Userform object.
The Userform for the Student Survey form is shown below:

In this Userform I have included most of the common Userform controls.
I used one uncommon but very handy DateAndTimePicker control for entering the birthday.
Press ALT+F11 to open the Visual Basic Editor (VB Editor or just VBE).

Using the VBE Tools>References menu verify or establish a reference to the Microsoft Forms 2.0 Object Library and Microsoft Windows Common Controls-2.6.0 (SP3) as shown below

Note: Unfortunately Microsoft no longer includes the Microsoft Windows Common Control-2-6-0 (SP3) in the resource library. You need this reference for the DateAndTimePicker control to work. If you are unable to find it in the list of available resources then you will need to download MSCOMCT2.OCX (see Office Help & Support KB 297381). Once you save MSCOMCT2.OCX in your system directory (e.g., C:\Windows\System32 on 32-bit or C:\Windows\Syswow64 on 64-bit), you need to register it. Click "Start" then "Run," type in regsvr32 and then the path to the file e.g., c:\windows\syswow64\mscomct2.ocx, then click OK. If you don't want to go the trouble of doing this, I have included a second Userform in the .dot version of the Student Survey Form template that substitutes a Textbox control for birthday and omits the DateAndTimePicker control.
Use the VBE Insert menu to insert a "Module" and a "Userform."


Right click the frmSurvey object in the Project Explorer and select "View code."

Your code pane should look like the illustration below:

Now we will enter the basic code in the standard code module "modMain" you created that will create and display the Userform. Double click the project module "modMain" and type in or copy and paste the following code:
Sub CallUF() Dim oFrm As frmSurvey Set oFrm = New frmSurvey oFrm.Show Unload oFrm Set oFrm = Nothing lbl_Exit: Exit Sub End Sub
Notes:
1. You can step through a VBA procedure from the VBE using the F8 key. Give it a try. As you step through the code you will see your Userform be created and displayed. Click either "OK" or "Cancel" and you will see it disappear.
2. If you want a little more schooling on building a basic Userform with a more detailed discussion of the code lines that call, initiate, show and ultimately kill the form see my: Custom VBA Message Box
You will now need to enter the remaining controls and set their respective properties (i.e., name, caption, background color, foreground color, font, MultiSelect, MatchEntry, etc.) using the Properties Window, create the event procedures, and expand the processing code to complete the form.
I am not going to step through the construction of each control or the event procedures.
Instead, you can download the complete template (Word 2003 and Word 2007/2010 versions) with all the code from the tips page demo pack link at the end of this tips page.
I will review some of the event procedures and the processing code in the discussion that follows.
You may have noticed that the ListBox and multi-select ListBox in the example form has items displayed and one of the "Gender" option buttons is selected. This is accomplished using the Userform "Initialize" event. This event establishes the conditions in the Userform when it is initially displayed to the user.
The code used to initialize the Student Survey Userform is shown in the pane below. It illustrates how to set the state of an OptionButton control plus several methods for populating o Listbox and Combobox list members.
Private Sub Userform_Initialize()
Dim arrString() As String
With Me
.obUndecided.Value = True
With .LBFavSub
.AddItem "Math"
.AddItem "English"
.AddItem "Science"
.AddItem "Social Studies"
.AddItem "Home Room"
End With
.CBFavTeach.List = Array("Mr. Hardnose", "Ms Toad", "Mrs. Shickleburger", "Mr. Badger")
arrString = Split("Beans and Franks|Pizza|Grinders|Cold Gruel|Grubs", "|")
.CBFavFood.List = arrString
.LBmultisel.List = Split("Football,Basketball,Baseball,Soccer,Tennis,Golf," _
& "Hockey,Gymnastics,Water Polo,Swimming", ",")
End With
lbl_Exit:
Exit Sub
End Sub
The spin buttons are used to increment the value in the age field by 1 each time the spin button control is pressed up or down. The code for this control is shown below. You should see that the upper limit is 120 and the lower limit is 0.
Private Sub SpinButton1_SpinUp() Dim lngAge as Long 'See note On Error GoTo Err_Age lngAge = Me.txtAge If lngAge < 120 Then Me.txtAge = lngAge + 1 End If Exit Sub Err_Age: Me.txtAge = 0 Resume End Sub Private Sub SpinButton1_SpinDown() Dim lngAge as Long 'See note On Error GoTo Err_Age lngAge = Me.txtAge If lngAge > 1 Then Me.txtAge = lngAge - 1 End If Exit Sub Err_Age: Me.txtAge = 0 Resume End Sub
Bonus Tip: Variables with the same name and type used in multiple procedures can be declared once at the object level (i.e., right at the top under the Option Explicit statement)
Students being students, you might want to validate some of the Userform inputs.
Private Sub txtAge_Change()
Dim strSpan As string
If Not IsNumeric(Me.txtAge) Then
If Len(Me.txtAge) > 1 Then
Me.txtAge.Text = Left(Me.txtAge.Text, Len(Me.txtAge.Text) - 1)
Else
Me.txtAge.Text = ""
End If
Exit Sub
End If
If Len(Me.txtAge) > 3 Then
Me.txtAge.Text = Left(Me.txtAge.Text, 3)
End If
If Val(Me.txtAge) > 120 Then
MsgBox "Contact Guinness World Records!!"
Me.txtAge.Text = Left(Me.txtAge.Text, 2)
End If
strSpan = Format(DateAdd("yyyy", -(CDbl(Me.txtAge)), Now), "yyyy")
Me.DTPicker1 = CDate("1/1/" & strSpan)
lbl_Exit:
Exit Sub
End Sub
You might want to validate and format the data entered. The phone number field in the Student Data Form formats the number entered as: (###)-###-####. For more on validating text entries in Userforms, see my: Validate Userform Text Entries.
Private Sub txtPhone_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim strTemp As String
strTemp = Me.txtPhone.Value
If (strTemp Like "(###) ###-####") Then Exit Sub
If (strTemp Like "##########") Then
strTemp = "(" & Left(strTemp, 3) & ") " & Mid(strTemp, 4, 3) & "-" & Right(strTemp, 4)
Me.txtPhone.Value = strTemp
ElseIf (strTemp Like "###-###-####") Then
strTemp = "(" & Left(strTemp, 3) & ") " & Right(strTemp, 8)
Me.txtPhone.Value = strTemp
ElseIf (strTemp Like "### ### ####") Then
strTemp = Replace(strTemp, " ", "-")
strTemp = "(" & Left(strTemp, 3) & ") " & Right(strTemp, 8)
Me.txtPhone.Value = strTemp
ElseIf (strTemp Like "(###)###-####") Then
strTemp = Left(strTemp, 5) & " " & Right(strTemp, 8)
Me.txtPhone.Value = strTemp
Else
If MsgBox("Your entry does not convert to a standard U.S. phone number format. " _
& "Do you want to try again?", vbQuestion + vbYesNo, "Invalid Format") _
= vbYes Then
With Me.txtPhone
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
Cancel = True
Else
Me.txtPhone.Value = strTemp
End If
End If
lbl_Exit:
Exit Sub
End Sub
You might want to ensure that fields are not left blank or comment on a particular entry. You can do this with the "OK" click event procedure in the frmSurvey module as follows:
'The public variable boolProceed is shared with the CallUF procedure and is used to determine if the student processed or canceled the form.
'Place it at the top of the frmSurvey module immediately below the "Option Explicit" statement.
Public boolProceed As Boolean
Private Sub cmdBtnOK_Click()
Select Case ""
Case Me.txtName.Value
MsgBox "Please fill-in your name."
Me.txtName.SetFocus
Exit Sub
Case Me.txtAge.Value
MsgBox "Please fill-in your age."
Me.txtAge.SetFocus
Exit Sub
Case Me.txtAddress.Value
MsgBox "Please fill-in your address."
Me.txtAddress.SetFocus
Exit Sub
Case Me.txtPhone.Value
MsgBox "Please fill-in your phone number."
Me.txtPhone.SetFocus
Exit Sub
End Select
If Me.obUndecided.Value = True Then
MsgBox "You should schedule an appointment with the school counselor", _
vbExclamation + vbOKOnly, "Don't know your gender?"
Exit Sub
End If
'Set value of a public variable declared at the form level." This is used to determine if _
form was processed or if the student canceled.
Me.boolProceed = True
Me.Hide
lbl_Exit:
Exit Sub
End Sub
Now let's shift our attention to the code needed to process the information entered in the Userform and put it in the document. To do this we are going to need a "few" more variables and a "good bit" of additional processing code in the CallUF procedure created earlier. The additional variables and the processing code is shown below:
Sub CallUF()
Dim oFrm As frmSurvey
Dim oVars As Word.Variables
Dim strTemp As String
Dim oRng As Word.Range
Dim i As Long
Dim strMultiSel As String
Set oVars = ActiveDocument.Variables
Set oFrm = New frmSurvey
With oFrm
.Show
If .boolProceed Then
oVars("varName").Value = .txtName
oVars("varAge").Value = .txtAge
"Replace the line breaks entered by the user with line breaks and tabs _
to ensure address entry is properly indented. See notes below.
strTemp = Replace(.txtAddress.Value, Chr(10), Chr(10) + Chr(9))
Set oRng = ActiveDocument.Bookmarks("bmAddress").Range
oRng.Text = strTemp
ActiveDocument.Bookmarks.Add "bmAddress", oRng
oVars("varBirthDay").Value = .DTPicker1
'Define the Gender text
Select Case True
Case .obMale
strTemp = "Male"
Case .obFemale
strTemp = "Female"
Case .obUndecided
strTemp = "Undecided"
End Select
oVars("varGender").Value = strTemp
oVars("varPhone").Value = .txtPhone
'Process student responses (including no response)
If Not IsNull(.LBFavSub.Value) And (.LBFavSub.Value) <> "" Then
oVars("varFavSub").Value = .LBFavSub.Value
Else
oVars("varFavSub").Value = "Not provided."
End If
If .CBFavTeach.Value <> "" Then
oVars("varFavTeach").Value = .CBFavTeach.Value
Else: oVars("varFavTeach").Value = "No response"
End If
If .CBFavFood.Value <> "" Then
oVars("varFavFood").Value = .CBFavFood.Value
Else: oVars("varFavFood").Value = "No response"
End If
'Define the PersItems text string
If .CheckBox1.Value = True Then strTemp = "Cell phone, "
If .CheckBox2.Value = True Then strTemp = strTemp & "Car, "
If .CheckBox3.Value = True Then strTemp = strTemp & "MP3 Player, "
If .CheckBox4.Value = True Then strTemp = strTemp & "Bullwhip."
'Clean up the string text
If Right(strTemp, 2) = ", " Then strTemp = Left(strTemp, Len(strTemp) - 2) & "."
On Error Resume Next
strTemp = Left(strTemp, InStrRev(strTemp, ",") - 1) & " and" & Mid(strTemp, InStrRev(strTemp, ",") + 1)
On Error GoTo 0
If strTemp = "" Then strTemp = "No response"
oVars("varPersItems").Value = strTemp
'Build the multi-select string
strMultiSel = ""
With .LBmultisel
For i = 0 To .ListCount - 1
If .Selected(i) Then
strMultiSel = strMultiSel & .List(i) & ", "
End If
Next i
End With
'Clean up the string text.
If Right(strMultiSel, 2) = ", " Then strMultiSel = Left(strMultiSel, Len(strMultiSel) - 2) & "."
On Error Resume Next
strMultiSel = Left(strMultiSel, InStrRev(strMultiSel, ",") - 1) & " and" & Mid(strMultiSel, InStrRev(strMultiSel, ",") + 1)
On Error GoTo 0
If strMultiSel = "" Then strMultiSel = "No Response"
oVars("varFavSports").Value = strMultiSel
myUpdateFields
Else
MsgBox "Form cancelled by user"
End If
End With
Unload oFrm
Set oFrm = Nothing
Set oVars = Nothing
Set oRng = Nothing
lbl_Exit:
Exit Sub
End Sub
Notes:
1. Notice that it takes two additional steps and lines of code to process the bookmark for the address data. Whenever you place data "in" a bookmark instead of "at" a bookmark you must redefine the bookmark range. This destroys the bookmark and another one with the same name must be added at the redefined range. This may seem like a lot of trouble but it is worth the extra effort.
2. If you elect to use a DocVariable for a multi-line textbox and want to indent the subsequent lines to tab stop you would use the following code: oVar("varAddress").Value = Replace(Me.TextBox1.Text, Chr(10), Chr(9))
In the procedure above we have set the value of several document variables to the value that the user enter entered in the Userform. The DocVariable fields associated with these variables were inserted previously in the template. Those fields now need to be updated to reflect the new variable values. We accomplished this by calling a separate procedure "myUpdateFields" that cycles through each storyrange in the document and updates the fields. This procedure is shown below:
Sub myUpdateFields()
Dim oStyRng As Word.Range
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each oStyRng In ActiveDocument.StoryRanges
Do
oStyRng.Fields.Update
Set oStyRng = oStyRng.NextStoryRange
Loop Until oStyRng Is Nothing
Next
End Sub
To polish the cannonball, DocVariable fields that point to a variable that doesn't exist can look pretty gnarly when the field result is displayed.

To keep our template looking nice we can create and set initial values in each variable with a simple procedure:
Sub Create_Reset_Variables()
With ActiveDocument.Variables
.Item("varName").Value = " "
.Item("varAge").Value = " "
.Item("varAddress").Value = " "
.Item("varBirthday").Value = " "
.Item("varGender").Value = " "
.Item("varPhone").Value = " "
.Item("varFavSub").Value = " "
.Item("varFavTeach").Value = " "
.Item("varFavFood").Value = " "
.Item("varFavSports").Value = " "
.Item("varPersItems").Value = " "
End With
myUpdateFields
lbl_Exit:
Exit Sub
End Sub
Now all we need to do is deploy the Userform when a student creates a new Student Survey Form from the template. This easily accomplished by adding an AutoNew event procedure to the project module "modMain." With this procedure we will create the document variables and display the form each time a new document is created from the template.
Sub AutoNew() Create_Reset_Variables CallUF lbl_Exit: Exit Sub End Sub
See: Installing Macros for instructions on how to set up and use the macros provided in this Microsoft Word Help & Microsoft Word Tips page.
In this section I will provide an example of a template and userform using content controls in the main document which serve as target ranges for the data entered by the user in the userform. These content controls replace the bookmarks/document variable fields demonstrated earlier.
This method has several advantages:
The example presented here was created using Word 2010. It is fully functional in Word 2013. Unfortunately content control checkboxes were not available in Word 2007. Accordingly the portions of the example template dealing with checkboxes will not function and is not available in Word 2007.
The document template and userform are illustrated below. The template consists of various types of content controls in a document restricted for editing. The shaded areas (light yellow) represent the content controls. Each content controls is defined as an editable region in the restricted document. For more on using content controls in forms, see: Create Forms with Content Controls


Each content control in the document is associated with a control in the Userform.
Logic in the Userform and in a custom Document_ContentControlOnChange event work together to ensure that the user is limited to selecting only one "subject" option and up to two "sports" activities.
Logic in the Userform ensures that the user is limited to selecting a maximum of three events in the Userform "Events" listbox and converts and inserts the selected items into a properly formatted text string in the document "Events" content control.
All of the associated code is available in the template you can download from the Userform Demo Pack link below. For more information on mutually exclusive option buttons, see: Mutually Exclusive "Content Control" Option Buttons.
That's it! This concludes this Tips Page. I hope that it gives you a better understanding and appreciation for Userforms. You can download all of the templates used to create this tips page here: Userform Demo Pack
There are several other helpful articles on Userforms in the Word MVP FAQ pages MVP FAQ Userforms or see my: Interactive Userforms and Interactive Userform Checkboxes.
The information, illustrations and code contained in my "Microsoft Word Tips" are provided free and without risk or obligation.
However, the work is mine. If you use it for commercial purposes or benefit from my efforts through income earned or time saved then a donation, however small, will help to ensure the continued availability of this resource.
If you would like to donate, please use the appropriate donate button to access PayPal. Thank you!