|
|
|
 |
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.
You can fix the bug using the 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
|