This is code to search for several terms in MS Word. For [a stupid but illustrative] example, if you want to find the next vowel in a .DOC, give this sub arguments a,e,i,o,u. It uses comma as a delimiter, but allows backslash/comma for a literal comma.
I believe this to be reliable code for Word 2000. If improvements, corrections, enhancements are made, the code at the bottom of this thread will be the best to download.
Please note the comments atop code.
This goes atop your normal.dot macros:
Dim sResp$
and this goes anywhere else in your normal.dot macros:
'This is a nonwrapping FORWARD search for "OR" arguments, comma-separated.
'It IGNORES current selection (except to change it when the search succeeds).
'Notice that it uses the static variable sResp$, defined atop this module
'Usage e.g.: Type (without the quotes) "a,e,i,o,u" in the InputBox, and it should go to next vowel
'Also beware that while debugging, is CODE WINDOW is operated on, not the "active document"?
Sub CompoundFind()
Dim iInitSelStart&, iInitSelEnd&, iCommaPos&, iSavPos&, iTrialPos&, iNewPos&, iNewPosLen&
Dim sStr$, bFound As Boolean, bLoopForBkSlash As Boolean
sResp$ = InputBox$("Type multiple ' Or ' Find items, comma separated " _
& Chr(10) & "( Use \, for actual comma) ", "MultiFind", sResp$)
If sResp$ = "" Then Exit Sub
iInitSelStart = Selection.Start: iInitSelEnd = Selection.End 'for ensuing Finds
iNewPos = iInitSelStart 'our target - where we will go when done
iNewPosLen = iInitSelEnd - iInitSelStart + 1
iCommaPos = 1: iSavPos = 1: bFound = False
While iCommaPos > 0 'always do at least one Find
'aha! The next line is the key to working properly. Remove it, and you get bad results
'It would be great if someone could explain what happens when next line is commented
Selection.Start = iInitSelStart + 1: Selection.End = iInitSelStart + 1
iCommaPos = InStr(iSavPos, sResp$, "," 'this or next Instr will decide the Wending
If iSavPos <= Len(sResp$) Then sStr$ = Mid$(sResp$, iSavPos) 'provisional
If iCommaPos > 0 Then 'to restate sStr$ (if iCommaPos reveals a DELIMITING comma)
If iCommaPos = 1 Then bLoopForBkSlash = False Else bLoopForBkSlash = True
While bLoopForBkSlash 'GRR!No exit while.Can't"while Mid$";iCommaPos may be 1
If Not Mid$(sResp$, iCommaPos - 1, 1) = "\" Then bLoopForBkSlash = False
If bLoopForBkSlash Then 'i.e., the Mid$ found it
sResp$ = Left$(sResp$, iCommaPos - 2) + Mid$(sResp$, iCommaPos)
sStr$ = Mid$(sResp$, iSavPos) 'again provisionally in case no commas
iCommaPos = InStr(iCommaPos, sResp$, "," 'not (iCommaPos+1,
If iCommaPos = 0 Then bLoopForBkSlash = False
End If
Wend
If iCommaPos > 0 Then sStr$ = Mid$(sResp$, iSavPos, iCommaPos - iSavPos)
iSavPos = iCommaPos + 1
End If
If sStr$ <> "" Then
With Selection.Find
.Forward = True: .Wrap = wdFindStop: .Execute FindText:=sStr$
End With
End If
' MsgBox "<" + sStr$ + "> " + Str$(Selection.Find.Found)
'Stop
If Selection.Find.Found Then
bFound = True: iTrialPos = Selection.Start
If iNewPos = iInitSelStart Then 'trial's our very first hit - save it
iNewPos = iTrialPos: iNewPosLen = Len(sStr$)
Else 'else iNewPos DID have prior value; update if sooner in file
If iTrialPos < iNewPos Then iNewPos = iTrialPos: iNewPosLen = Len(sStr$)
End If
End If
Selection.Start = iInitSelStart: Selection.End = iInitSelEnd
Wend
If bFound Then Selection.Start = iNewPos: Selection.End = iNewPos + iNewPosLen _
Else MsgBox "Solly, no, Cholly"
End Sub
I believe this to be reliable code for Word 2000. If improvements, corrections, enhancements are made, the code at the bottom of this thread will be the best to download.
Please note the comments atop code.
This goes atop your normal.dot macros:
Dim sResp$
and this goes anywhere else in your normal.dot macros:
'This is a nonwrapping FORWARD search for "OR" arguments, comma-separated.
'It IGNORES current selection (except to change it when the search succeeds).
'Notice that it uses the static variable sResp$, defined atop this module
'Usage e.g.: Type (without the quotes) "a,e,i,o,u" in the InputBox, and it should go to next vowel
'Also beware that while debugging, is CODE WINDOW is operated on, not the "active document"?
Sub CompoundFind()
Dim iInitSelStart&, iInitSelEnd&, iCommaPos&, iSavPos&, iTrialPos&, iNewPos&, iNewPosLen&
Dim sStr$, bFound As Boolean, bLoopForBkSlash As Boolean
sResp$ = InputBox$("Type multiple ' Or ' Find items, comma separated " _
& Chr(10) & "( Use \, for actual comma) ", "MultiFind", sResp$)
If sResp$ = "" Then Exit Sub
iInitSelStart = Selection.Start: iInitSelEnd = Selection.End 'for ensuing Finds
iNewPos = iInitSelStart 'our target - where we will go when done
iNewPosLen = iInitSelEnd - iInitSelStart + 1
iCommaPos = 1: iSavPos = 1: bFound = False
While iCommaPos > 0 'always do at least one Find
'aha! The next line is the key to working properly. Remove it, and you get bad results
'It would be great if someone could explain what happens when next line is commented
Selection.Start = iInitSelStart + 1: Selection.End = iInitSelStart + 1
iCommaPos = InStr(iSavPos, sResp$, "," 'this or next Instr will decide the Wending
If iSavPos <= Len(sResp$) Then sStr$ = Mid$(sResp$, iSavPos) 'provisional
If iCommaPos > 0 Then 'to restate sStr$ (if iCommaPos reveals a DELIMITING comma)
If iCommaPos = 1 Then bLoopForBkSlash = False Else bLoopForBkSlash = True
While bLoopForBkSlash 'GRR!No exit while.Can't"while Mid$";iCommaPos may be 1
If Not Mid$(sResp$, iCommaPos - 1, 1) = "\" Then bLoopForBkSlash = False
If bLoopForBkSlash Then 'i.e., the Mid$ found it
sResp$ = Left$(sResp$, iCommaPos - 2) + Mid$(sResp$, iCommaPos)
sStr$ = Mid$(sResp$, iSavPos) 'again provisionally in case no commas
iCommaPos = InStr(iCommaPos, sResp$, "," 'not (iCommaPos+1,
If iCommaPos = 0 Then bLoopForBkSlash = False
End If
Wend
If iCommaPos > 0 Then sStr$ = Mid$(sResp$, iSavPos, iCommaPos - iSavPos)
iSavPos = iCommaPos + 1
End If
If sStr$ <> "" Then
With Selection.Find
.Forward = True: .Wrap = wdFindStop: .Execute FindText:=sStr$
End With
End If
' MsgBox "<" + sStr$ + "> " + Str$(Selection.Find.Found)
'Stop
If Selection.Find.Found Then
bFound = True: iTrialPos = Selection.Start
If iNewPos = iInitSelStart Then 'trial's our very first hit - save it
iNewPos = iTrialPos: iNewPosLen = Len(sStr$)
Else 'else iNewPos DID have prior value; update if sooner in file
If iTrialPos < iNewPos Then iNewPos = iTrialPos: iNewPosLen = Len(sStr$)
End If
End If
Selection.Start = iInitSelStart: Selection.End = iInitSelEnd
Wend
If bFound Then Selection.Start = iNewPos: Selection.End = iNewPos + iNewPosLen _
Else MsgBox "Solly, no, Cholly"
End Sub