How to prevent the built-in BrowseNext and RepeatFind commands from creating bad karma for wildcard searches

Article contributed by Claudio Faria, Klaus Linke, Dave Rado and Bill Coan

The following bug is easy to reproduce in Word versions 97 through 2002:

1.

Using Edit + Find, perform a Find operation of any kind.

2.

Use Shift+F4 or Ctrl+PgDn or the Browse button to repeat the last find operation. Continue until you reach the end of  the document, but click No when asked if you want to continue at the start of the document.

3.

Do a wildcard search of any kind from VBA. The search will fail.

Workaround 1: Intercepting the RepeatFind, BrowseNext and BrowsePrev commands

Put the following code into an add-in (or of it's only for your own personal use, you could put it into Normal.dot, if you prefer).

It automatically intercepts the built-in RepeatFind (Shift+F4), BrowseNext (Ctrl+PgDn) and BrowsePrev (Ctrl+PgUp) commands, and prevents the bug from ever rearing its ugly head.

Sub BrowseNext()

Select Case Application.Browser.Target
    Case wdBrowseFind
        With Selection.Find
            .Forward = True
            .Execute Wrap:=wdFindAsk
        End With
    Case Else
        Application.Browser.Next
End Select

End Sub


Sub BrowsePrev()

Select Case Application.Browser.Target
    Case wdBrowseFind
        With
Selection.Find
            .Forward = False
            .Execute Wrap:=wdFindAsk
        End With

    Case Else
        Application.Browser.Previous
End Select

End Sub


Sub RepeatFind()

Select Case Application.Browser.Target
    Case wdBrowseFind
        Selection.Find.Execute Wrap:=wdFindAsk
    Case Else
        WordBasic.ToolsMacro Name:="RepeatFind", Run:=1, Show:=2
End Select

End Sub

  

In Word 2000+, if the browse mode is set to Find, the BrowseNext and BrowsePrev commands themselves invoke the RepeatFind command; so strictly speaking, in those versions of Word, it is only necessary to intercept RepeatFind. But if you want compatibility with Word 97, you need to intercept all three commands, as shown above.

See also:

Flush bad karma from Word's find facility after an unsuccessful wildcard search

Workaround 2: Executing the Find & Replace dialog to clear the bug

The following workaround is included mainly for the sake of completeness (and for those who, for whatever reason, don't want to intercept Word commands). Workaround 1 is far more elegant.

FixWildcardBug macro shown below. 

Sub Test()

 

  Application.ScreenUpdating = False

 

  'Call a routine that removes any previous settings from the find dialog

  Call ClearFindAndReplaceParameters

 

  'Now call the fix

  Call FixWildcardBug

  'Call it a second time just in case (because the SendKeys statement is notoriously flaky)

  Call FixWildcardBug

 

  'Now it's safe to do your wildcard search, e.g.:

  With Selection.Find

    .Text = "(" & ChrW( 8220 ) & ")(*)(" & ChrW( 8221 ) & ")"

    .Replacement.Text = ""

    .Forward = True

    .Wrap = wdFindContinue

    .Format = False

    .MatchCase = False

    .MatchWholeWord = False

    .MatchAllWordForms = False

    .MatchSoundsLike = False

    .MatchWildcards = True

    .Execute

  End With

 

  Call ClearFindAndReplaceParameters

 

  Application.ScreenUpdating = True

 

End Sub


 

Sub FixWildcardBug()

  With Selection.Find

    .Execute MatchWildcards:= True , FindText:= "?"

    Selection.Collapse Direction:=wdCollapseStart

    If Not .Found Then

'Call and execute the Replace dialog - not using the wdDialog constant, _

' which is buggy, but by executing the command button instead

      CommandBars.FindControl(ID:= 313 ).Execute

      SendKeys String:= "{ENTER}" , Wait:= True

      SendKeys String:= "{ESC}" , Wait:= True

    End If

    Selection.Collapse Direction:=wdCollapseStart

    .MatchWildcards = False

    .Text = ""

  End With

End Sub


 

Sub ClearFindAndReplaceParameters()

 

  With Selection.Find

    .ClearFormatting

    .Replacement.ClearFormatting

    .Text = ""

    .Replacement.Text = ""

    .Forward = True

    .Wrap = wdFindStop

    .Format = False

    .MatchCase = False

    .MatchWholeWord = False

    .MatchWildcards = False

    .MatchSoundsLike = False

    .MatchAllWordForms = False

  End With

 

End Sub

Notes regarding Workaround 2

 

Unfortunately, this fix requires you to display the Find and Replace dialog momentarily; and there is no way around this. It only flashes up for an instant and is gone, but Workaround 1 doesn't suffer from this drawback, and also has the major  adavantage that you don't need to run a macro every time you do a wildcard Find & Replace!

 

To get the ID of any CommandBar control, you can use code such as the following:

MsgBox CommandBars("Menu Bar"). Controls("&Edit").Controls("R&eplace...").ID

Executing a CommandBar control using the FindControl method:

CommandBars.FindControl(ID:=313).Execute

... has two advantages over referring to it by name as in:

CommandBars("Menu Bar").Controls("&Edit").Controls("R&eplace...").Execute

1.

If the user has customized Normal.dot (renamed or moved the control), your code will still work

2.

It is language-independent

 

Note for advanced users: Unfortunately, you cannot run the FixWildcardBug macro using the Application.Run method. If you do, the SendKeys statement doesn't work properly, and the Edit + Replace dialog remains open until the user cancels it. So if you want to store the FixWildcardBug macro in an add-in and call it from a different project, you have to set a reference to the add-in in your other project and call your macro, rather than using Application.Run.

Similarly, if you have an add-in containing another procedure that, in turn, calls the FixWildcardBug macro, then you can't run that other procedure from a different  project using Application.Run either; instead, you have to set a reference to the add-in and call the other procedure..

 

Apart from the problem with Application.Run, in English versions of Word this fix works reliably in all situations (as far as we can tell from extensive tests); but apparently, in some other language versions of Word it may not work reliably if you assign your macro to Alt+Ctrl+Anything. So if using non-English versions of Word and if assigning it to a keyboard shortcut, avoid assigning it to Alt+Ctrl. Or just use Method 1! 

See also:

Flush bad karma from Word's find facility after an unsuccessful wildcard search