×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Microsoft: Office FAQ

Word FAQ

Using FormFields in Word Part 2 û Coding with Form Fields by fumei
Posted: 9 Jul 04

Word Form Fields Part 2 û Coding with Form Fields

This is Part 2 of an FAQ on Using FormFields in Word.  This part covers some sample VBA code that deals with fairly common FormField issues.  First of all, it is important to call attention to a very important point.

Explicit Naming.

When you put a FormField in a document, Word gives it a default name.  The first text FormField is named ôText1ö, the second is named ôText2ö.  The first dropdown Formield is named ôDropDown1ö, the second ôDropDown2ö etc.

If you plan to use even a minor amount of VBA with FormFields, do NOT use the default names.  I know it is a serious pain in the butt to rename them all.  Most people do not bother to rename them.  However, there is this to consider.  Word gives the names dynamically.  In other word, the FormField ôText1ö keeps that name ONLY if it is the first text FormField in the document.  If that FormField is moved, it no longer is named ôText1ö  Any code that points to Text1 (getting a result from it, setting properties), does NOT point to a specific FormField, it only points to the first one.  It you want to make sure your code acts on a specific FormField (and you usually do), then exp-licitly name it.  Once named, you can move it around the document all you want.  Any code pointing to it, by a specific name will always point to it, regardless of where it is.

OK, here is some code.

Code A  Two OnEntry macros resetting properties of the FormField, itself.

What this could be used for.  Version 1 automatically fills in text with the result of another text FormField.  Version 2 fill in a drop down list based on the result of a previous text FormField.


OnEntry Macro - Version 1 Assumptions:
A text FormField named InitialChecker, a text FormField named AuthorizedBy.

CODE

Sub UpdateAllowChanges()
æ this updates the AuthorizedBy FormField with the result of InitialChecker
æ allows user to change it


Dim sPrevious As String
sPrevious = ActiveDocument.FormFields(ôInitialCheckerö).Result
ActiveDocument.FormFields(ôAuthorizedByö).Result = sPrevious
End Sub


OnEntry Macro - Version 2 Assumptions
A text FormField named InitialChecker, a dropdown FormField named R_Area.  This uses Select Case to determine how to fill in the drop down list.

CODE

Sub UpdateR_Area()

Dim InitializedList(3) As String

Dim R_AreaList1(3) As String
Dim R_AreaList2(2) As String
Dim R_AreaList3(4) As String
Dim R_AreaList4(1) As String

Dim var
Dim i As Integer

InitializedList(0) = "Fred Flintstone"
InitializedList(1) = "Yogi Bear"
InitializedList(2) = "Harvey Keitel"
InitializedList(3) = "Someone"


R_AreaList1(0) = " Accounting - Invoice "
R_AreaList1(1) = " Accounting - Billing "
R_AreaList1(2) = " Accounting - Muscle "
R_AreaList1(3) = " Accounting - Bargains "

R_AreaList2(0) = " Management - Top Floor "
R_AreaList2(1) = " Management - Middle Floor "
R_AreaList2(2) = " Management - Wannabe "

R_AreaList3(0) = " Warehouse - San Francisco "
R_AreaList3(1) = " Warehouse - Seattle"
R_AreaList3(2) = " Warehouse - Auckland "
R_AreaList3(3) = " Warehouse - Tuktayuktuk "
R_AreaList3(4) = " Warehouse - No where "

R_AreaList4(0) = " Mars "
R_AreaList4(1) = " Moon "

Select Case ActiveDocument.FormFields("InitialChecker").Result
    Case InitializedList(0)  ' Fred Flintstone
        ' clear list
        ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Clear
        For var = 0 To 4
          ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Add _
            R_AreaList3(i)
          i = i + 1
        Next
        ' display first item in list
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(1) ' Yogi Bear
        ' clear list
        ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Clear
        For var = 0 To 3
          ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Add _
            R_AreaList1(i)
          i = i + 1
        Next
        ' display first item in list
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(2)  ' Harvey Keitel
        ' clear list
        ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Clear
        For var = 0 To 2
          ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Add _
            R_AreaList2(i)
          i = i + 1
        Next
        ' display first item in list
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(3) ' Someone
        ' clear list
        ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Clear
        For var = 0 To 1
          ActiveDocument.FormFields("R_Area").DropDown.ListEntries.Add _
            R_AreaList4(i)
          i = i + 1
        Next
        ' display first item in list
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case Else
    ' in case they enter something you don't like
        MsgBox "The entry in the Initial Checker field is not valid." _
        & "  Please check your entry and try again."
    ' return back to InitialChecker FormField
    ' note the use of the BOOKMARK object to select the FormField

       ActiveDocument.Bookmarks("InitialChecker").Select
End Select
End Sub



Code B:  An OnExit macro that sets a specific value in another FormField,  in this case, disabling it.

Assumptions:  a checkbox named OrderNow, a dropdown named PaymentMethod

CODE

Sub OrderChoice()

If ActiveDocument.FormFields("OrderNow").CheckBox.Value = False Then
    ActiveDocument.FormFields("PaymentMethod").Enabled = False
Else
    ActiveDocument.FormFields("PaymentMethod").Enabled = True
End If
End Sub



Code C
What it could be used for: Counting Formfields, Making an array of a certain Formfield type (Textboxes in this example) and the values for each of that type.

CODE

Sub TextFFArray()

Dim mFormField As FormField
Dim i As Integer
Dim intFFCount As Integer
Dim intTextFFCount As Integer
Dim TextFormFields() As String
Dim sMessage As String
Dim var

For Each mFormField In ActiveDocument.FormFields()
' increase total count of fields
    intFFCount = intFFCount + 1
    If mFormField.Type = wdFieldFormTextInput Then
' increase total count of text fields
        intTextFFCount = intTextFFCount + 1
        ReDim Preserve TextFormFields(i)
        TextFormFields(i) = mFormField.Name
        i = i + 1
    End If
Next
ReDim Preserve TextFormFields(i)
  ' may as well use this again
i = 0
  ' loop through array getting field name &
  ' using it to get resulting value

For var = 1 To intTextFFCount
    sMessage = sMessage & _
      "Field name:=  " & TextFormFields(i) & "   " & _
      "Value:= " & ActiveDocument.FormFields(TextFormFields(i)).Result & _
        vbCrLf
        i = i + 1
Next
' display message with:
' total number of fields,
' total number of textboxes
' each textbox name and result

MsgBox "There are " & intFFCount & " FormFields in this " & _
    "document, including " & intTextFFCount & " textboxes." & _
    vbCrLf & " The contents of those textboxes are:" & vbCrLf & _
    sMessage
End Sub

Code D
What it could be used for:  Clears all FormFields.  Use this as the exit macro on the last field, or as a separate closing macro to the document.  It checks for default text, and if the textbox has default text, it resets the result to that default again.


CODE

Sub ClearAllFormFields()
Dim myFormField As FormField
Dim aDoc As Document
Dim response
Dim msg As String


Set aDoc = ActiveDocument
msg = "Do you want to clear all FormField results?"
response = MsgBox(msg, vbYesNo)
If response = vbYes Then
  For Each myFormField In aDoc.FormFields()
    Select Case myFormField.Type
      Case 70  ' text
        ' checks to see if there is default text
        ' if yes, removes user inout and
        ' reverts to default; if no, removes user input

        If myFormField.TextInput.Default <> "" Then
          myFormField.result = myFormField.TextInput.Default
        Else
          myFormField.result = ""
        End If
      Case 71  ' check
        myFormField.result = False
      Case 83   ' dropdown
        myFormField.DropDown.Value = 1
    End Select
  Next
Else
End If
Set aDoc = Nothing
End Sub


Code E
What this could be used for:   This is an example of looping through a number of files and retrieving data from them.  This example retrieves a piece of information from each document in a folder and calculates an average from the total collected.  It could also be used for picking up strings for FormFields.  Maybe use this in conjunction with the other code above to create an array of text from various files.


CODE

Sub GetAv()
' assumes each file has a FormField named GetAv
' and that FormField has a piece of text that is a number
' Probably should add a error trap (IsNumeric) to ensure
' that content of text FormField is, in fact numeric!

Dim aDoc
Dim ThisDoc As Document
Dim i As Integer
Dim lngTotalCount As Long
Dim lngCurNumber As Long
Dim strMessage As String

  ' this does not have to be hard coded
aDoc = Dir("c:\TempRun\*.DOC")

On Error Resume Next

Do While aDoc <> ""
' open the file and make it document object
   Application.Documents.Open FileName:=aDoc
   Set ThisDoc = ActiveDocument

' get the FormField text and convert to number
    lngCurNumber = CLng(ThisDoc.FormFields("getAv").Result)
    lngTotalCount = lngTotalCount + lngCurNumber
    i = i + 1
' add filename and value to message string
  strMessage = strMessage & _
       ThisDoc.Name & "  " & lngCurNumber & vbCrLf
End If
' close current doc, destroy doc object
     ThisDoc.Close
     Set ThisDoc = Nothing
     aDoc = Dir()
Loop
' display results.  This could be changed, to putting the average
æ (lngTotalCount / i ) into somewhere else.


MsgBox strMessage & vbCrLf & vbCrLf & _
       "Average is: " & lngTotalCount / i
End Sub

Hopefully this FAQ, and these examples, will help you use WordÆs FormFields more efficiently.  There is a lot more you can do with FormFields, this is just a start.

Have fun!

Back to Microsoft: Office FAQ Index
Back to Microsoft: Office Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close