MS Office Forum / Word / Programming / February 2008
Word 2003 search macro
|
|
Thread rating:  |
Alan Stancliff - 22 Feb 2008 23:26 GMT 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
Doug Robbins - Word MVP - 23 Feb 2008 00:18 GMT 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
 Signature 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
> Hi all, > [quoted text clipped - 51 lines] > > Alan Stancliff Greg Maxey - 23 Feb 2008 00:30 GMT 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
 Signature ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Greg Maxey - Word MVP
My web site http://gregmaxey.mvps.org Word MVP web site http://word.mvps.org ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Hi all, > [quoted text clipped - 51 lines] > > Alan Stancliff Jay Freedman - 23 Feb 2008 00:34 GMT >Hi all, > [quoted text clipped - 51 lines] > >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.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
Alan Stancliff - 24 Feb 2008 07:28 GMT 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
Jay Freedman - 24 Feb 2008 17:09 GMT 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.
>Thanks for the information and suggestions to Doug Robbins, Greg Maxey, >and Jay Freedman. I have been able to cobble together something workable [quoted text clipped - 47 lines] > >Alan Stancliff -- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
Alan Stancliff - 24 Feb 2008 22:11 GMT 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
> Hi Alan, > [quoted text clipped - 80 lines] > Microsoft Word MVP FAQ: http://word.mvps.org > Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit. Alan Stancliff - 25 Feb 2008 00:07 GMT 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
|
|
|