Logo: TechTrax...brought to you by MouseTrax Computing Solutions

Creating Test Forms in Word

by Dian Chapman, MVP, MOS
Skill rating level 8.

More and more often these days, tests are conducted on a computer. From teachers testing their students to employers testing their potential employees. In this article, I'll show you how you can create an automated test form in Word that will not only calculate the user's score, but also keep them from cheating!<wink>

Setting Up the Form

The first thing you should do is type out a list of questions with potential answers. That always seems like the hardest part for me! Not so much coming up with questions and answers, but coming up with decent phony answers that don't sound ridiculous. (And if you've taken any of the TechTrax Assessment Tests, you'll see I still struggle with this ability!<grin>)

So I'll leave the questions and answers to you and I'll show you what I do best—create automated forms.

Before you start designing your form, you'll want to make sure you have gone into Tools/Options/View and turned on some of the visual aids so you can see what's going on in your page. Turn on Field Shading (set to Always), Tabs, Paragraph Markers, Bookmarks, Hidden Text and Text Borders. This will help you see what you are doing right and help you figure out if you have something wacky on the page that might be messing up your alignment. Also make sure you're working in View/Print Layout (or Page Layout if in an older version of Word).

Note! If you'd like more details about setting up the proper view, you can find a link to view my free Word Options lesson from my AutoForms and Beginning VBA video course on the MouseTrax Tech Courses page.

Here's a look at our sample Quiz form. Now let's see how we got here.

Image of sample form with checkbox form fields and an ActiveX command button.

Save Your Template
Open a blank page and click File/Save As and click the dropdown for Save as Type and choose Document Template...so you save this page as a template! You should always create master forms as templates. Then new documents are created from that master.

Tip! Although Word will attempt to save your template in your default template directory, don't let it! You'll be hunting around for hours to find it! Rather, save it to your Desktop. This way you can easily right click it and select Open when you need to work on it as a designer/developer to adjust the look or code. But then you can also easily right click it and choose New when you want to test the form.

Margins
Make sure you've given yourself enough space on the page. If you want to max out your page, but aren't sure what your printer can handle, set all your margins to zero. Then click okay. You'll get a warning to fix the margins. Say yes. That'll force your print driver to use its max settings.

Formatting the Title
Type a title for your quiz. You can then select that text and dress it up quickly by hitting Ctrl/Shift/> to make it a larger font. Then maybe hit Ctrl/B to add bold and hit Ctrl/I to make it italic. While still selected, you can click Format/Borders and Shading and maybe add a border above, as I did. Or maybe add some background shading?

Once you have it the way you want it to look, while still selected, click inside the Style Window and enter a style name and hit the Enter key to accept that name for this style. See the image below if you need help.

You've just created an instant Style! Now if you decide to use this same title style again...maybe for part two of the test...you can easily modify all text using this style. Or maybe you want to save this look? Then click Format/Style/Organizer and pass this style from this doc into your Normal.dot (master template) so you'll have it available for other documents.

Add a Name Form Field
After the title, hit the return and add some text to allow the user to enter their name. I've added a right aligned tab to let me push it over to the right side of the page. Although you can just as easily hit Ctrl/R to set it to right alignment.

Important! Whether you add a name field or some other field, be sure to add one Text form field before the questions. You see, we'll be writing code that will cause the checkboxes for the answers to work like mutually exclusive option buttons (radio buttons). If the first form on the test is a checkbox, that checkbox will become instantly selected when the user opens the test. So to avoid that problem, you need to add some field above the test answers.

After you type some text, such as "Enter your name: ", turn on your Forms toolbar by hitting Alt/V + T and arrow down to select the Forms toolbar. Then, as shown in the image below, click on the Text Form Field to add a spot for the user to type their name once the form is locked.

Adding Your Questions
Now we get to the fun part—dealing with Word's numbering!<evil smirk> Type your first question. Triple click on it to select the entire paragraph. Click Format/Bullets and Numbering/Numbered and choose a numbering style.

Take a look at the image below and notice the boxed markings around the questions. Those are simply the text borders that you turned on via Tools/Options/View. You need to leave room to insert a Frame for the answer checkboxes. But if you hit the Enter key, you'll get the next number, because the enter key will end the current paragraph and start a new one, hence...new numbers.

So here's a little trick (and if you tell anyone I told you to do this...I'll deny it!). Hit Shift/Enter to add soft breaks or line feeds. This will maintain the numbering style and trick Word into thinking you're still typing your first question. That will give you empty lines without adding another number.

When you've moved down a few lines, hit the Enter key to add a hard return. This will stop that numbering and add number 2. Type your second question. Continue down the page like this for all your questions.

Add the Frames
Now you need to add a Frame after each question to hold the checkboxes. This is very important and you cannot use TextBoxes for this! You must use a Frame, because TextBoxes can't hold form fields, i.e., your checkboxes. Frames can. That's probably why you'll find the Frame icon on your Forms toolbar.

Check out the image below for a little further info.

Here you'll see the Insert Frame icon on the Forms toolbar. When you click it, you'll be able to draw out a frame, as you can see I've done near the bottom of the image. Also notice how the frame pushed away the text border to the right for the area in which the frame has been inserted. This is because the default text wrapping for a frame is around. But that's not what we want, because it's too difficult in which to work. We'll fix that in a moment.

First, you'll also want to remove the default border around the frame. Select the frame and click Format/Borders and Shading and choose None.

Notice in the image above, when I select the frame, you can see handles (small black squares) around the selection. If you make the frame too large, you can grab one of those handles and adjust the size of your frame. Try to keep them as consistent as possible just so it's easier to see what's happening on the page. If you make them all different sizes, the page can look cluttered and be hard to decipher what's what!

While the frame is still selected, right click your mouse to display the mini menu (or shortcut menu) and choose Format Frame. I'm not quite sure why this dialog box can make sensible folks get loopy, but it does. People seem to freak out about formatting frames and scream that the frames "jump all over the page." But it's actually pretty straightforward. If you take a moment to think about what it's asking!

Notice in the image of this dialog box below, that I'm selecting None for Text Wrapping. This will cause the text border that was along the right to now neatly move under my frame, as shown in that icon image. Leave the rest of the defaults as shown below. Of course, your settings will vary depending on the size/position of your frame.

Adding Checkboxes
Now you just have to select each frame in turn and, from the Forms toolbar, click on the Checkbox icon to add the necessary checkboxes. After each, add text to represent a possible answer.

You can see that I've now added a third question to the form. Since this frame is active, the border looks a little different as I enter the checkboxes. But also notice how the text border that was along the right has now neatly moved below my new frame...because I set the wrapping to None.

Let's Write Some Code!

Hit Alt/F11 to open the Visual Basic for Applications Editor in Word. If you've never ventured into the Visual Basic Editor (VBE), I'll provide some details here. But this is not a beginner's lesson. If you follow along exactly as I say, it'll work for you. However, if you need further details, you should check out all my other free forms articles, which you can find at www.mousetrax.com/techpage.html#autoforms. And if you want to learn a lot more about VBA programming, you should check out my new AutoForms and Beginning VBA video course. It's an enhanced version of my popular eBook course and contains many hours of information and instructions, as well as lots of tips and tricks as I sit down with you and show you how to write VBA code in Word!

When you enter the VBE, you may default into the Normal.dot template and you won't yet have a code module in your template. As shown in the image below, click Insert/Module to add a new code module to your new template. Be sure you have selected the correct Project in the left Project Window!

Double click on the new Module1 that has been added. This will open a code window so we can get busy.

The first thing you need to add is the term Option Explicit, which will cause Word to point out all your mistakes. This is a good thing. You want to know what you did wrong so you can fix it! Then add the names of the two GLOBAL variables we'll be using. Again, I'm not going to get into deep explanations here...I've already done that in my video course. Or you can look up these terms on the Internet.

Add this code to the top of the module:
Option Explicit
Public gintTotal As Integer
Public gintTestTaken As Integer

Hit the return after the above code and now you'll enter in the code for the checkboxes.

Add this code next:
Sub ExclusiveCheckboxes()

'declare an object as the form field
Dim objField As FormField
'for each checkbox (form field) in this current fame set
'(or range of form fields), set all the values to false
'and loop through to make sure they are all set to false (unchecked)
For Each objField In Selection.Frames(1).Range.FormFields
    objField.CheckBox.Value = False
Next objField
'now set the currently selected checkbox value to true
Selection.FormFields(1).CheckBox.Value = True
End Sub

Note! The red text blocks with apostrophes in front are comments, notes to myself (and you) explaining what the code does. So be sure to pay attention to this info and READ IT! You should also leave it in. It will not interfere with your code and it will help you remember what it does later...after you've forgotten. And you will forget!

Make it Work
To get this code to run, you need to add this macro name into each of the checkbox Run Macro on Entry field in their Options dialog box.

Go back to your form. You can leave the VBE open and just hit Alt/Tab to cycle over to the master template. Double click on every checkbox to open its Options and add the name of this procedure (ExclusiveCheckboxes) into the Entry field for each one.

Note! The biggest mistake users make here is either forgetting to enter the name into one of the fields, or entering it into the Exit field, rather than the Entry field. So pay attention to what you are doing!

Naming Your Checkboxes
Another important step is that you need to rename all the checkboxes. Now I could have told you to go through and do this before, but then you would have had to open the option properties twice. Since you have to go through each one now to add the macro, it's time to also rename each checkbox.

All form fields get a name (bookmark name). However, the default names they get are generic and meaningless. So rather than trying to remember that Textbox1 is QuestionOne_AnswerOne, rename them all and give them meaningful names. The names must start with a letter and must be one word (no spaces). I'd suggest you name them Q1_, Q2_, etc for each question series and then add the same name as the text answer. In other words, if the checkboxes for question 1 are Chicago, Springfield and Bloomington, enter checkbox bookmark names like so: Q1_Chicago, Q1_Springfield, Q1_Bloomington.

Test Your Form
You can now run a quick test to make sure all the checkboxes are working. Click Tools/Protect Document/Forms. Don't bother with a password now! You can also simply click the Lock icon on the forms toolbar.

Then grab your mouse and start clicking around. As you enter a group of checkboxes in a frame, the code sets all the checkboxes to false. But then sets the one you select as true. If you have things working correctly thus far, you should only be able to select one checkbox for each question.

Lots More Code
Now we need to add several additional sub procedures. These routines will handle the calculations. After the user has selected all their answers, they can click the Calculate Score button to see their answer. The score will be entered onto the page. However, a flag will be set in the code so that once the user clicks that button to calculate the score, they will no longer be able to change that score!<hee, hee> They can change all the answers they want. But they won't be able to change the score. They can now only print/save the form. Unless you give them the ability to open the master template again. Each time a New test page is created from the master, the flag is reset to zero. It might be a good idea to advise users of this fact so the wise guys don't click the button at the start and end up with a score of zero (although it'll probably serve them right!<grin>).

Adding an ActiveX Control
However, before we get into adding the rest of the code, you'll notice my form has a button on the page that activates the code to calculate the score. ActiveX controls are similar to Form Fields, but they're more sophisticated and require a little more knowledge to use. They also put a heavier drag on the document, so use them sparingly!

Click View/Toolbars/Control Toolbox to see the ActiveX controls. Be sure that you're also in Design Mode by clicking that Icon first. Then find the spot where you want your button to reside and click on the Command Button icon to add one to your template.

You can now right click on the button and modify the Properties. Change the Caption to change the text on the button. You can also modify the font, as well as the size. Once you have it looking the way you want, double click on the command button to enter the code window for the Click Event for this button. This code will run when the user clicks on the button.

As you can see in the image above, after you double click on the command button, you will be in the ThisDocument code module for your project. That's because the command button is on the actual document. I've renamed the Name Property of my button to cmdCalcTotal. You should always rename all your form fields and controls to meaningful names. But if you decide to leave yours with the default name of CommandButton1, then realize your code procedure will also need to be changed from cmdCalcTotal_Click to CommandButton1_Click.

Add this code to the top of the ThisDocument module:
Option Explicit
Private Sub cmdCalcTotal_Click()
 				
'checks to see if GLOBAL variable "flag"
'has been set to see if user has already
'entered a final score, so the score can't be changed
'otherwise, if var is not set, then proceeds with calc
If gintTestTaken = 1 Then
   MsgBox "Sorry, you have already calculated your score!"
Else

    'calls separate routine to add up totals
    'you can position your cursor inside name 
    'and hit Shift/F2 to jump to that procedure
    'to read that code to see what happens next

    Call CalcScores
 				
    'declares variables for this procedure
    Dim strComments As String
    Dim bkRange As Range
 				
    'quickly calls another routine to unlock form
    'note that you can use the "Call" command or not
    'it doesn't matter, except for how you would enter
    'variables, if we were passing them. When using Call, 
    'any passed vars need to go in parens. That's info only
    'as we're not doing there here!
    ToggleFormLock
        'sets bookmarked location to total score
        ActiveDocument.Bookmarks("TotalScore").Range.Text = gintTotal
    'relocks form
    ToggleFormLock
    'sets the GLOBAL variable flag to 1
    'to show the score cannot be changed!
    gintTestTaken = 1
    'create message for scores
    'this is optional and you'll need to change the 
    'settings for the total score. Since I only have three 
    'questions. If you have more, adjust these numbers or
    'you can comment this code out by putting an apostrophe
    'in front of each line, or just rip it out!
    If gintTotal < 2 Then
        strComments = "not too good!"
    ElseIf gintTotal = 2 Then
        strComments = "average."
    ElseIf gintTotal > 2 Then
        strComments = "perfect!"
    End If
 				
    'concatenate your message with the results
    'note! If you rip out the message above, also change this code!
    MsgBox "Your Total Score was " & gintTotal & ". That's " & strComments
End If

End Sub
Private Sub Document_New()
    'sets both global variables
    '...for total and score fields...
    'to zero so they can run at least once
    gintTotal = 0
    gintTestTaken = 0
End Sub

Again, be sure to read the code, as the explanations are within the code comments!

Now we just need to add two more procedures to the end of the code in Module1. Be sure to hit Ctrl/S to save what you've done so far. Then double click on Module1 and move to the end of the code you have in there now.

Add this code to the bottom of Module1, after the ExclusiveCheckbox code you have there already.
Sub CalcScores()
    Dim objAllChecks As FormField
    Dim strName As String 			
    'this loops through all the document fields, and if they
    'are checkboxes, it captures the bookmark name of the 
    'checkbox and puts it into a string to check it to see if
    'it is a correct answer
    For Each objAllChecks In ActiveDocument.FormFields
        objAllChecks.Select
        If objAllChecks.Type = wdFieldFormCheckBox Then
            strName = objAllChecks.Name
        'DEBUG
           'uncomment the message box below to test and make sure
           'you are getting the correct answer, then comment it
           'out again
           'MsgBox strName

        'you will need to modify the code below to one CASE for every
        'CORRECT answer. If the correct answer is checked to true, 
        'then the GLOBAL variable holding the score will have 1 added
        'to it.
        Select Case strName
          Case "Q1_Springfield"
            If Selection.FormFields(strName).CheckBox.Value = True Then
               gintTotal = gintTotal + 1
            End If
          Case "Q2_7"
            If Selection.FormFields(strName).CheckBox.Value = True Then
               gintTotal = gintTotal + 1
            End If
          Case "Q3_50"
            If Selection.FormFields(strName).CheckBox.Value = True Then
               gintTotal = gintTotal + 1
            End If
          Case Else
          'DEBUG
            'this is also a debugging tool. When you are testing
            'your code, you should make sure the message box below
            'is uncommented to catch any fields that contain typos.
            'if they are not found, it means they don't match the
            'actual field name. A typo could cause an incorrect score!
            'You should only see this for incorrect checkboxes. When
            'run in conjunction with the name message above, you can
            'see the field name and see if it's found or not
            'if a CORRECT answer is not found, you messed up!
            'MsgBox "This incorrect answer was not found"
        End Select
        End If
    Next objAllChecks
End Sub
Sub ToggleFormLock()
  If ActiveDocument.ProtectionType = wdAllowOnlyFormFields Then
     ActiveDocument.Unprotect

     'if a password is used, add the line below after a space above
     'Password:="myPassword"
  Else
     ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True

     'if a password is used, add a comma after
     'the last line and include the line below
     'Password:="myPassword"
  End If
End Sub

Finalize Your Form
That'll just about do it! However, the last item you need to do is add a bookmark on your form so the score knows where to be placed. In the code, I've called the bookmark: TotalScore. To ensure it works right and you don't get an error, type some text to say something like "Your total score: " and then hit Alt/I + K to get to the Bookmark dialog box. Add a bookmark called TotalScore (or change the code if you use another name). Then you're ready to save and lock it up.

Note! I highly suggest you uncomment the two DEBUG message boxes for your testing to make sure you matched up the checkbox names correctly. They will show you the checkbox names and let you know if that name was found or not. All correct answers should be found. Later you can comment them out.

Test your form A LOT! Try all combinations to make sure you don't have any errors. Once you're satisfied that it'll work properly, be sure you clear the fields. You can do this by using the Tools/Protect Document/Forms menu to lock your code rather than just using the Lock icon on the Forms toolbar. In later versions of Word, fields are not cleared with the Lock icon. Only through the menu can you be sure your fields are empty when you save your final version.

You should also add a password now. However, if you do, be sure you modify the ToggleFormLock routine to include the password or you'll get errors. Comments in the code show you where and how to do this. And you can lock the code from viewing in the VBE under the Tools/Project Properties menu. But don't lose the password or you can kiss your code goodbye!

Now you can pass it to those who need to take the test. Make sure that they understand that they must click File/New or right click and choose New to take the test. If they simply open the document, the Document_New event won't fire (since you don't want the form to continually run while you're working on it in designer/developer mode). But if the routines in that event don't fire, the test won't be properly setup to clear the variables, so you can't guarantee the score will be correct.

Have fun! And if you create any cool technical tests, be sure to pass me a copy so I can swipe your questions to use in a future TechTrax Assessment Test. Yes, you'll get the credit as the author!


Be sure to check out Dian's other free forms articles and her Word tech courses. And if you'd like to have Dian build you a custom form or get some personal training for a project you need to complete, see her Consulting page!

Need further help getting your VBA code working right? Join our free VBA support groups. See these links for details: http://groups.yahoo.com/group/Word_VBA/ and/or http://groups.yahoo.com/group/ExcelVBA/.

 

Go up to the top of this page.
This site powered by the Logical Web Publisher™: Content management by Logical Expressions, Inc.