Word 2003 search macro

A

Alan Stancliff

Hi all,

In Word 2003, it is possible to write a VBA macro that searches for a
string, positions the cursor at the string found, deletes the string,
leaving the cursor where the string had been located. Such code might
look like this:

Selection.Find.ClearFormatting
With Selection.Find
.Text = "searchstring"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Delete Unit:=wdCharacter, Count:=1

However, if the string is not found, the macro deletes the character the
cursor is resting on at the beginning of the search.

What I want to know is if there is a way to test if the string is not
found, so that another action can be taken.

Such code might look like this:

Selection.Find.ClearFormatting
' on not found, go to label NoSuchStringExists
With Selection.Find
.Text = "searchstring"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Delete Unit:=wdCharacter, Count:=1
Exit Sub

NoSuchStringExists:
MsgBox "Sorry, I could not find this string"

Regards,

Alan Stancliff
 
D

Doug Robbins - Word MVP

Use:

Dim Found As Boolean
Found = False
Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find
Do While .Execute(findText:="SearchString", Forward:=True, _
MatchWildcards:=False, MatchCase:=True, Wrap:=wdFindStop) = True
Found = True
Selection.Delete
Loop
End With
If Found = False Then
MsgBox "SearchString does not appear in the document."
End If


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP
 
G

Greg Maxey

Alan,

If you must use Selection then use something like this:

Sub Scratchmacro()
Selection.Find.ClearFormatting
With Selection.Find
.Text = "searchstring"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
If Selection.Find.Execute Then
Selection.Delete Unit:=wdCharacter, Count:=1
Else
MsgBox "String not found"
End If
End Sub

If you would rather use a range then use something like this:

Sub ScratchmacroII()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
.ClearFormatting
.Text = "searchstring"
If .Execute
oRng.Delete
Else
MsgBox "String not found"
End If
End With
End Sub


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org~~~~~~~~~~~~~~~~~~~~~~~~~~
 
J

Jay Freedman

Hi all,

In Word 2003, it is possible to write a VBA macro that searches for a
string, positions the cursor at the string found, deletes the string,
leaving the cursor where the string had been located. Such code might
look like this:

Selection.Find.ClearFormatting
With Selection.Find
.Text = "searchstring"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Delete Unit:=wdCharacter, Count:=1

However, if the string is not found, the macro deletes the character the
cursor is resting on at the beginning of the search.

What I want to know is if there is a way to test if the string is not
found, so that another action can be taken.

Such code might look like this:

Selection.Find.ClearFormatting
' on not found, go to label NoSuchStringExists
With Selection.Find
.Text = "searchstring"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.Delete Unit:=wdCharacter, Count:=1
Exit Sub

NoSuchStringExists:
MsgBox "Sorry, I could not find this string"

Regards,

Alan Stancliff


The .Execute method returns a boolean result, True if it found what you asked
for and False if not. So you can write the end of the macro like this:

If Selection.Find.Execute Then
Selection.Delete Unit:=wdCharacter, Count:=1
Else
MsgBox "Sorry, I could not find this string"
End If

By the bye, I don't understand why you have Unit:=wdCharacter, Count:=1 in the
Delete statement.
 
A

Alan Stancliff

Thanks for the information and suggestions to Doug Robbins, Greg Maxey,
and Jay Freedman. I have been able to cobble together something workable
for me.

Jay asks:
"By the bye, I don't understand why you have Unit:=wdCharacter, Count:=1
in the Delete statement."

Jay, this is going to sound a bit weird.

I am a medical transcriptionist, and the doctors sometimes have a bit of
canned speech to put in, something like boilerplate text or Word's text
insert. These are called "normals" in our industry. There will be places
in it for us to fill in information. For example, a sentence might be
something like "we prepped the patient's ____ side" and we put in left
or right. By convention, stemming back years ago when all medical
transcriptionists used WordPerfect, a jump code of two question marks
was used, like this ??. An insert may have half a dozen or more of these
goodies.

Yes, I know about bookmarks. WordPerfect had bookmarks too. But we have
to work with what our employer gives us.

There is a macro attached to a shortcut key that searches for these
"jump marks." Recently, our hospital changed transcription software
vendors, and the old vendor had a macro that searched for the jump mark,
deleted it, and left the cursor where it had been. If there was no jump
mark, the cursor did not move.

The new vendor's macro simply searches for the jump mark but does not
delete it. And if one tries to record a macro that jumps to the jump
mark and deletes it, the conundrum is what you would expect. If the
search failed, the macro deletes the one character under the cursor. To
have a macro that actually does what we need, it must be written instead
of recorded because the logic of the task dictates there must be some
sort conditional branching...if found, do this, if not, do that.

Because of your and the others' kind assistance, I was able to make a
macro that performed much more as I wished.

I hope this answer was not too long-winded. But you did ask. When I
posed the question, I tried to make it more general so the answer would
be more generally helpful to others browsing this forum, and it was a
good learning experience for me.

Thanks again to those who answered my question. This forum is a
wonderful resource for those of us just beginning to figure out VBA.

Regards,

Alan Stancliff
 
J

Jay Freedman

Hi Alan,

Thanks for the explanation. Working around the weird limitations of third-party
software is always "fun".

But the point of my question -- I should have been more explicit the first time
-- is that

Selection.Delete Unit:=wdCharacter, Count:=1

does exactly the same thing as

Selection.Delete

regardless of the number of characters in the selection. Now that you know how
to limit the deletion to occur only when the jump mark is found, you don't need
the Unit:=wdCharacter, Count:=1 part any more (if in fact you ever did need it).

I understand that it doesn't make much (or possibly any) difference to you,
because you know the history. But someday, somebody else may have to do some
maintenance on your system of macros, or maybe they'll be converting the macros
to another language in an external solution like VSTO, and they may not have an
extensive knowledge of VBA. Then that extra verbiage may make them think that
you intended to delete only one character from the Selection instead of the
whole Selection, and that could introduce a bug that's easily avoidable by doing
the right thing now.
 
A

Alan Stancliff

Hi Jay,

Thanks for the feedback.

You wrote:
"But the point of my question -- I should have been more explicit the
first time -- is that

Selection.Delete Unit:=wdCharacter, Count:=1

does exactly the same thing as

Selection.Delete

regardless of the number of characters in the selection. Now that you
know how to limit the deletion to occur only when the jump mark is
found, you don't need the Unit:=wdCharacter, Count:=1 part any more (if
in fact you ever did need it)."

No Jay, I had not realized that point at all. Thanks for pointing it out
to me.

You also wrote:
"I understand that it doesn't make much (or possibly any) difference to
you, because you know the history. But someday, somebody else may have
to do some maintenance on your system of macros, or maybe they'll be
converting the macros to another language in an external solution like
VSTO, and they may not have an extensive knowledge of VBA. "

Those are very good points. Besides, elegant is always better.

I share my macros with anyone who wants them at work, and some have
tried to hack some of my macros. That's why I comment them so
extensively, and I also put links to this forum and other places I swipe
bits of code from, as well as books and articles I refer to. I really am
a beginner at this and appreciate all the help I can get.

Regards,

Alan Stancliff
 
A

Alan Stancliff

Here's how the code eventually ended up:

Sub FindJumpCode()
' For source of ideas for this code,
' please visit the Microsoft URL
'
' http://www.microsoft.com/communities/
'newsgroups/en-us/default.aspx?dg=
'microsoft.public.word.vba.
'general&tid=1df9ba00-
'79e5-421b-9ffd-6cacec9d4f1d&cat=
'en_US_eb67b351-9403-4888-a42c-
'b2b58efec0aa&lang=en&cr=US&sloc=en-us&m=1&p=1
'
'That's all one url, and you'll need to
'remove the carriage returns in Notepad and
'paste it into thy browser.
'
Selection.Find.ClearFormatting
With Selection.Find
.Text = "??"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
If Selection.Find.Execute Then
Selection.Delete ' Unit:=wdCharacter, Count:=1
Else
MsgBox "No Jump Code"
End If
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top