Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using FormFields in Word Part 2 û Coding with Form Fields

Word FAQ

Using FormFields in Word Part 2 û Coding with Form Fields

by  fumei  Posted    (Edited  )
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()
[color red] æ this updates the AuthorizedBy FormField with the result of InitialChecker
æ allows user to change it[/color red]

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)  [color red]' Fred Flintstone[/color red]
[color red]        ' clear list[/color red]
        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
[color red]        ' display first item in list[/color red]
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(1) [color red] ' Yogi Bear[/color red]
[color red]        ' clear list[/color red]
        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
[color red]        ' display first item in list[/color red]
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(2)  [color red]' Harvey Keitel[/color red]
[color red]        ' clear list[/color red]
        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
[color red]        ' display first item in list[/color red]
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case InitializedList(3) [color red] ' Someone[/color red]
[color red]        ' clear list[/color red]
        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
[color red]        ' display first item in list[/color red]
        ActiveDocument.FormFields("R_Area").DropDown.Value = 1
    Case Else
[color red]    ' in case they enter something you don't like[/color red]
        MsgBox "The entry in the Initial Checker field is not valid." _
        & "  Please check your entry and try again."
  [color red]  ' return back to InitialChecker FormField
    ' note the use of the BOOKMARK object to select the FormField[/color red]
       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()
[color red]' increase total count of fields[/color red]
    intFFCount = intFFCount + 1
    If mFormField.Type = wdFieldFormTextInput Then
[color red]' increase total count of text fields[/color red]
        intTextFFCount = intTextFFCount + 1
        ReDim Preserve TextFormFields(i)
        TextFormFields(i) = mFormField.Name
        i = i + 1
    End If
Next
ReDim Preserve TextFormFields(i)
[color red]  ' may as well use this again[/color red]
i = 0
[color red]  ' loop through array getting field name &
  ' using it to get resulting value[/color red]
For var = 1 To intTextFFCount
    sMessage = sMessage & _
      "Field name:=  " & TextFormFields(i) & "   " & _
      "Value:= " & ActiveDocument.FormFields(TextFormFields(i)).Result & _
        vbCrLf
        i = i + 1
Next
[color red]' display message with:
' total number of fields,
' total number of textboxes
' each textbox name and result[/color red]
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  [color red]' text
        ' checks to see if there is default text
        ' if yes, removes user inout and
        ' reverts to default; if no, removes user input[/color red]
        If myFormField.TextInput.Default <> "" Then
          myFormField.result = myFormField.TextInput.Default
        Else
          myFormField.result = ""
        End If
      Case 71  [color red]' check[/color red]
        myFormField.result = False
      Case 83   [color red]' dropdown[/color red]
        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()
[color red]' 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! [/color red]
Dim aDoc
Dim ThisDoc As Document
Dim i As Integer
Dim lngTotalCount As Long
Dim lngCurNumber As Long
Dim strMessage As String

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

On Error Resume Next

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

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

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!
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top