The Find and Replacement Objects

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Among the most frequently used commands in the Word user interface are the Find and Replace commands on the Edit menu. These commands let you specify the criteria for what you want to locate. They are both really the same thing, with the Replace command's functionality being just an extension of the Find command's functionality. In fact, you might have noticed that Find, Replace, and Go To appear on different tabs of the same dialog box — the Find and Replace dialog box.

Much of the VBA code you write in Word involves finding or replacing something in a document. There are several techniques you can use to locate text or other elements in a document, for example, using the GoTo method or the Select method. Typically, you use the Find object to loop through a document looking for some specific text, formatting, or style. To specify what you want to use to replace the item you found, you use the Replacement object, which you can access by using the Replacement property of the Find object.

The Find object is available from both the Selection object and the Range object; however, it behaves differently depending on whether it is used from the Selection object or the Range object. Searching for text by using the Find object is one of those situations where the Selection and Range objects can be used together to accomplish more than either object can its own.

The following list describes differences between the behavior of the Range object and the Selection object when you are searching for an item in a document:

  • When you are using the Selection object, your search criteria are applied only against the currently selected text.

  • When you are using the Selection object, if an item matching the search criteria is found, the selection changes to highlight the found item, as illustrated by the following example, which uses the Find object to search within the currently selected text:

    With Selection.Find
       .ClearFormatting
       strFindText = InputBox("Enter the text you want to find.", _
          "Find Text")
       If Len(strFindText) = 0 Then Exit Sub
       .Text = strFindText
       If .Execute = True Then
          MsgBox "'" & Selection.Text & "'" _
             & " was found and is now highlighted."
       Else
          MsgBox "The text could not be located."
       End If
    End With
    
  • When you are using the Find object off of the Range object, the definition of the Range object changes when an item matching the search criteria is found. Failing to account for this change in the definition of the Range object can cause all kinds of debugging headaches. The following code sample illustrates how the Range object is redefined:

    Dim rngText      As Word.Range
    Dim strToFind    As String
    
    Set rngText = ActiveDocument.Paragraphs(3).Range
    With rngText.Find
       .ClearFormatting
       strToFind = InputBox("Enter the text you want to find.", _
          "Find Text")
       If Len(strToFind) = 0 Then Exit Sub
       .Text = strToFind
       If .Execute = True Then
          MsgBox "'" & strToFind & "'" & " was found. " _
             & "As a result, the Range object has been " _
             & "redefined and now covers the text: " _
             & rngText.Text
       Else
          MsgBox "The text could not be located."
       End If
    End With
    

Regardless of whether you are using the Find object with the Range object or the Selection object, you must account for the changes that occur to the object when the search is successful. Because the object itself might point to different text each time the search is successful, you might have to account for this and you might also have to keep track of your original object so that you can return to it when the search has been completed.

Specifying and Clearing Search Criteria

You specify the criteria for a search by setting properties of the Find object. There are two ways to set these properties. You can set individual properties of the Find object and then use the Execute method without arguments. You can also set the properties of the Find object by using the arguments of the Execute method. The following two examples execute identical searches:

' Example 1: Using properties to specify search criteria.
With Selection.Find
   .ClearFormatting
   .Forward = True
   .Wrap = wdFindContinue
   .Text = strToFind
   .Execute
End With

' Example 2: Using Execute method arguments to specify search criteria.
With Selection.Find
   .ClearFormatting
   .Execute FindText:=strToFind, _
      Forward:=True, Wrap:=wdFindContinue
End With

The Find object's search criteria are cumulative, which means that unless you clear out the criteria from a previous search, new criteria are added to the criteria used in the previous search. You should get in the habit of always using the ClearFormatting method to remove formatting from the criteria from a previous search before specifying the criteria for a new search. The Find object and the Replacement object each has its own ClearFormatting method. When you are performing a find and replace operation, you must use the ClearFormatting method of both objects, as illustrated in the following example:

With Selection.Find
   .ClearFormatting
   .Text = strToFind
   With .Replacement
      .ClearFormatting
      .Text = strReplaceWith
   End With
   .Execute Replace:=wdReplaceAll
End With

Finding All Instances of the Search Criteria

When you use the Execute method as shown in the preceding examples, the search stops at the first item that matches the specified criteria. To locate all items that match the specified criteria, use the Execute method inside a loop, as shown in the following example:

Public Sub SearchAndReturnExample()
   ' This procedure shows how to use the Execute method inside
   ' a loop to locate multiple instances of specified text.
   Dim rngOriginalSelection     As Word.Range
   Dim colFoundItems            As New Collection
   Dim rngCurrent               As Word.Range
   Dim strSearchFor             As String
   Dim intFindCounter           As Integer
   
   If (Selection.Words.Count > 1) = True Or _
         (Selection.Type = wdSelectionIP) = True Then
      MsgBox "Please select a single word or part or a word. " _
         & "This procedure will search the active document for " _
         & "additional instances of the selected text."
         Exit Sub
   End If
   
   Set rngOriginalSelection = Selection.Range
   strSearchFor = Selection.Text
   
   ' Call custom procedure that moves the insertion point to the
   ' start of the document.
   Call GoToStartOfDoc
   
   With Selection.Find
      .ClearFormatting
      .Forward = True
      .Wrap = wdFindContinue
      .Text = strSearchFor
      .Execute
      Do While .Found = True
         intFindCounter = intFindCounter + 1
         colFoundItems.Add Selection.Range, CStr(intFindCounter)
         .Execute
      Loop
   End With
   
   rngOriginalSelection.Select
   
   If MsgBox("There are " & intFindCounter & " instances of '" _
         & rngOriginalSelection & "' in this document." & vbCrLf & vbCrLf _
         & "Would you like to loop through and display all instances?", _
         vbYesNo) = vbYes Then
      intFindCounter = 1
      For Each rngCurrent In colFoundItems
         rngCurrent.Select
         MsgBox "This is instance #" & intFindCounter
         intFindCounter = intFindCounter + 1
      Next rngCurrent
   End If
   
   rngOriginalSelection.Select
End Sub

The preceding example also illustrates how to use a Collection object to store the matching items as Range objects. In this example, the user is given the option of viewing all matching items, but you could use the same technique to work with the found items as a group.

Replacing Text or Other Items

To replace one item with another, you must specify a setting for the Replace argument of the Execute method. You can specify the replacement item by using either the Text property of the Replacement object or the ReplaceWith argument of the Execute method. To delete an item by using this technique, use a zero-length string ("") as the replacement item. The following example replaces all instances of the text specified by the strFind argument with the text specified in the strReplace argument:

Sub ReplaceText(strFind As String, _
                strReplace As String)
   Application.ScreenUpdating = False
   ActiveDocument.Content.Select
   With Selection.Find
      .ClearFormatting
      .Forward = True
      .Wrap = wdFindContinue
      .Execute FindText:=strFind, _
         Replace:=wdReplaceAll, ReplaceWith:=strReplace
   End With
End Sub

In most cases, when you finish a search operation, you should return the selection (or the insertion point if there was no previous selection) to where it was when the search began. You do this by saving the state of the Selection object before you begin a search, and then restoring it when the search is completed, as shown in the following example:

Sub SimpleRestoreSelectionExample()
   Dim rngStartMarker      As Word.Range
   Dim strToFind           As String

   Set rngStartMarker = Selection.Range
   strToFind = InputBox("Enter the text to find.", "Find Text")
   With Selection.Find
      .ClearFormatting
      .Text = strToFind
      If .Execute = True Then
         MsgBox "'" & strToFind & "'" & " was found and is " _
            & "currently highlighted. Click OK to restore your " _
            & "original selection."
      Else
         MsgBox "'" & strToFind & "'" & " was not found."
      End If
   End With
   rngStartMarker.Select
End Sub

See Also

Working with Microsoft Word Objects | Working with Document Content | The Range Object | The Selection Object | The Selection Object vs. the Range Object | Working with Bookmarks