Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / November 2007

Tip: Looking for answers? Try searching our database.

find&replace text throughout a document

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Nicholas Lim - 18 Nov 2007 12:28 GMT
I am trying to programmatically replace text throughout a document using
string manipulation and complex logic, which may not easily be coded into the
single assignment statement: .Replacement.Text = "xxx"
which doesn't appear to allow multiple procedural string manipulations of
found text (unless I can hook a 'found' event handler which has the found
text in scope?).

First example
I'd like to correct speech recognition errors to change dialogue that starts
with an extra space and uncapitalised: " why?" into: "Why?" without using
ALLCAPS or any font-formatting, instead using UCase or programmatic changing
of the actual letters. Once I can understand how to do this example,
hopefully I can code other requirements. Many thanks!

Code example
The following code works but unfortunately issues the prompt "Word has
reached the end of the document. Do you want to continue searching from the
beginning?" ...which is not practical for contant use.

Sub Macro1()
   ResetSearch
   ' Find any "X pattern
   If Selection.Find.Execute("""^?", 0, 0, 0, 0, 0, 0, 1) = True Then
       Do
         '...and replace by "X
         Selection.Text = UCase(Selection.Text)
       Loop While Selection.Find.Execute("""^?", 0, 0) = True
   End If
End Sub

I don't want to use     Selection.Find.Execute Replace:=wdReplaceAll (with
.Wrap = wdFindContinue) because of the limitations of the single
.Replacement.Text = "xxx" assignment statement.

With my current code approach above, initially setting .Wrap =
wdFindContinue (in ResetSearch sub below) doesn't appear to work.
Used explicitly in the find calls, e.g. Selection.Find.Execute("""^?", 0, 0,
0, 0, 0, 0, 1), results in an infinite loop.

Public Sub ResetSearch()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
End Sub

Many thanks for any help.
Signature

NickL

Doug Robbins - Word MVP - 18 Nov 2007 19:29 GMT
See the article "Finding and replacing characters using wildcards" at:

http://www.word.mvps.org/FAQs/General/UsingWildcards.htm

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

>I am trying to programmatically replace text throughout a document using
> string manipulation and complex logic, which may not easily be coded into
[quoted text clipped - 61 lines]
>
> Many thanks for any help.
Nicholas Lim - 18 Nov 2007 22:18 GMT
Many thanks. Yes, I have tried this approach, using    
 Selection.Find.Execute Replace:=wdReplaceAll
and
 With Selection.Find
 .Text = """ ^?"
 .Replacement.Text = """^&"
and
 applying AllCaps
But the approach has two drawbacks:
1) There is font-level formatting applied all over the document
2)  the .Replacement.Text assignment statement is so restrictive compared to
a series of clear VBA statements that can reference the selected text and use
UCase, Replace, Split etc

Signature

NickL

> See the article "Finding and replacing characters using wildcards" at:
>
[quoted text clipped - 65 lines]
> >
> > Many thanks for any help.
Doug Robbins - Word MVP - 19 Nov 2007 06:08 GMT
Use:

Dim myrange As Range

Selection.HomeKey wdStory
Selection.Find.ClearFormatting
With Selection.Find
   Do While .Execute(findText:=" why?", Forward:=True,
MatchWildcards:=False, _
MatchCase:=True, Wrap:=wdFindStop) = True
       Set myrange = Selection.Range
       With myrange
           .Text = UCase(Mid(.Text, 2, 1)) & Mid(.Text, 3)
       End With
   Loop
End With

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

> Many thanks. Yes, I have tried this approach, using
>  Selection.Find.Execute Replace:=wdReplaceAll
[quoted text clipped - 87 lines]
>> >
>> > Many thanks for any help.
Nicholas Lim - 20 Nov 2007 15:27 GMT
I'm a word VBA macro newbie and didn't know about ranges. Very elegant. Thank
you. Here's your solution generalized, with fix using QuoteDistinguisher to
avoid consequent infinite looping. My outstanding issue is summarized in the
first code comment, in order to avoid:
" why?" said fred.
becoming
"Why?"said fred.
- which is good except for the loss of space after closing quote.
Many thanks for your help.
N

Sub FixDialogue()
   QuoteDistinguisher = "@@@"
   
   'Ensure smart quotes, then change FixDialogue_RemoveLeadingSpace to
process only if opening quote char...???
   FixDialogue_RemoveLeadingSpace
   FixDialogue_ReplaceQuotesToDistinguish (QuoteDistinguisher)
   FixDialogue_MakeInitialCapsFollowingQuote (QuoteDistinguisher)
End Sub
Sub FixDialogue_RemoveLeadingSpace()
   Selection.Find.ClearFormatting
   Selection.Find.Replacement.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
   Selection.Find.Execute Replace:=wdReplaceAll
End Sub
Sub FixDialogue_ReplaceQuotesToDistinguish(QuoteDistinguisher)
   Selection.Find.ClearFormatting
   Selection.Find.Replacement.ClearFormatting
   With Selection.Find
       .Text = """"
       .Replacement.Text = QuoteDistinguisher & """"
       .Forward = True
       .Wrap = wdFindContinue
       .Format = False
       .MatchCase = False
       .MatchWholeWord = False
       .MatchWildcards = False
       .MatchSoundsLike = False
       .MatchAllWordForms = False
   End With
   Selection.Find.Execute Replace:=wdReplaceAll
End Sub
Sub FixDialogue_MakeInitialCapsFollowingQuote(QuoteDistinguisher)
   QDLen = Len(QuoteDistinguisher)
   Dim myrange As Range
   Selection.HomeKey wdStory
   Selection.Find.ClearFormatting
   With Selection.Find
       .Wrap = wdFindStop
       Do While .Execute(findText:=QuoteDistinguisher & """^?", _
                         Forward:=True, _
                         MatchWildcards:=False, _
                         MatchCase:=True) = True
           Set myrange = Selection.Range
           With myrange
               .Text = """" & UCase(Mid(.Text, 2 + QDLen, 1 + QDLen)) &
Mid(.Text, 3 + QDLen)
           End With
       Loop
   End With
End Sub
Signature

NickL

> Use:
>
[quoted text clipped - 104 lines]
> >> >
> >> > Many thanks for any help.
Doug Robbins - Word MVP - 20 Nov 2007 19:39 GMT
I don't understand your code, but if the code I gave you is removing the
trailing space I would modify it as follows:

Set myrange = Selection.Range
       With myrange
           .End = . End - 1
           .Text = UCase(Mid(.Text, 2, 1)) & Mid(.Text, 3)
       End With

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

> I'm a word VBA macro newbie and didn't know about ranges. Very elegant.
> Thank
[quoted text clipped - 190 lines]
>> >> >
>> >> > Many thanks for any help.
Nicholas Lim - 21 Nov 2007 00:09 GMT
Thank you! Apologies, two more questions (!)
Do you have VBA code to find and replace all straight quotes with smart
quotes?
And do you know the chr() values for the smart open and smart closing quotes?

Signature

NickL

> I don't understand your code, but if the code I gave you is removing the
> trailing space I would modify it as follows:
[quoted text clipped - 199 lines]
> >> >> >
> >> >> > Many thanks for any help.
Greg Maxey - 21 Nov 2007 00:40 GMT
Nicholas,

Try:
Sub QuoteStyleToggle()
If Options.AutoFormatAsYouTypeReplaceQuotes = True Then
   If MsgBox("SmartQuotes are on.  Do you want switch to straight quotes?
", _
             vbYesNo, "Quote Style Toggle") = vbYes Then
         Options.AutoFormatAsYouTypeReplaceQuotes = False
         If MsgBox("Do you want to replace existing Smartquotes" _
                   & " with straight quotes?", vbYesNo, "Reformat Quotes")
= vbYes Then
         QuoteChangeFormat
         Else: Exit Sub
         End If
     Else: Exit Sub
   End If

Else
   If MsgBox("Staight quotes are on.  Do you want switch to SmartQuotes? ",
_
             vbYesNo, "Quote Style Toggle") = vbYes Then
         Options.AutoFormatAsYouTypeReplaceQuotes = True
         If MsgBox("Do you want to replace existing straight quotes" _
                   & " with Smartquotes?", vbYesNo, "Reformat Quotes") =
vbYes Then
         QuoteChangeFormat
         Else: Exit Sub
         End If
     Else: Exit Sub
   End If
End If
End Sub
Sub QuoteChangeFormat()
Dim rngStory As Word.Range
For Each rngStory In ActiveDocument.StoryRanges
 Do
   If rngStory.StoryLength >= 2 Then
     With rngStory.Find
       .Text = Chr$(34)
       .Replacement.Text = Chr$(34)
       .Forward = True
       .Wrap = wdFindContinue
       .Format = False
       .Execute Replace:=wdReplaceAll
       .Text = Chr$(39)
       .Replacement.Text = Chr$(39)
       .Forward = True
       .Wrap = wdFindContinue
       .Format = False
       .Execute Replace:=wdReplaceAll
     End With
   End If
   Set rngStory = rngStory.NextStoryRange
 Loop Until rngStory Is Nothing
Next
End Sub

Signature

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Thank you! Apologies, two more questions (!)
> Do you have VBA code to find and replace all straight quotes with
[quoted text clipped - 237 lines]
>>>>>>> --
>>>>>>> NickL
Nicholas Lim - 21 Nov 2007 10:20 GMT
Thank you.
PS Recently, I remember reading the two different chr() values for the smart
open quote and smart closing quote. I can't find the reference now - do you
know what these chr() values are?
PPS could you tell me the find&replace values for:
find: all occasions where two spaces occur in a row
replace by: one space.
Signature

NickL

> Nicholas,
>
[quoted text clipped - 267 lines]
> >>>>>>> wdFindContinue (in ResetSearch sub below) doesn't appear to
> >>>>>>> work. Used explicitly in the find calls, e.g.
Graham Mayor - 21 Nov 2007 12:05 GMT
The smart quoted are chr(145) to (148)
The simplest way to change straight quotes to smart quotes is to autoformat
the document with this setting checked.

Signature

<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor -  Word MVP

My web site www.gmayor.com
Word MVP web site http://word.mvps.org
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>

> Thank you.
> PS Recently, I remember reading the two different chr() values for
[quoted text clipped - 282 lines]
>>>>>>>>> wdFindContinue (in ResetSearch sub below) doesn't appear to
>>>>>>>>> work. Used explicitly in the find calls, e.g.
Helmut Weber - 18 Nov 2007 20:10 GMT
Hi Nicholas,

for that purpose avoid the selection.

"ResetSearch" is from former times,
when I didn't know about ranges.

Sub Test666b()
Dim rDcm As Range
Set rDcm = ActiveDocument.Range
With rDcm.Find
   .Text = " why"
   .MatchCase = True
   .Replacement.Text = "Why"
   .Execute Replace:=wdReplaceAll
   .Text = " what"
   .MatchCase = True
   .Replacement.Text = "What"
   .Execute Replace:=wdReplaceAll
End With
End Sub

HTH

--

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Vista Small Business, Office XP
Nicholas Lim - 18 Nov 2007 22:28 GMT
Many thanks for your reply, but see my reply to Doug...
Signature

NickL

> Hi Nicholas,
>
[quoted text clipped - 27 lines]
>
> Vista Small Business, Office XP
Graham Mayor - 19 Nov 2007 06:01 GMT
It is not easy to see why you want to complicate things when a simple
solution will suffice - unless you are not telling us the whole story?

You cannot use multiple formatting types in the replace string - the only
way to do that is to copy the pre-formatted string to the clipboard then
replace the text with the clipboard content ^c

Signature

<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor -  Word MVP

My web site www.gmayor.com
Word MVP web site http://word.mvps.org
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>

> Many thanks for your reply, but see my reply to Doug...
>
[quoted text clipped - 29 lines]
>>
>> Vista Small Business, Office XP
fumei - 19 Nov 2007 16:54 GMT
Sub SpaceCap()
Dim r As Range
Set r = ActiveDocument.Range
  With r.Find
     .ClearFormatting
     Do While .Execute(FindText:=" why", Forward:=True) = True
        r.Text = LTrim(r.Text)
        r.Text = UCase(Left(r.Text, 1)) & _
              Right(r.Text, Len(r.Text) - 1)
        r.Collapse Direction:=wdCollapseEnd
     Loop
  End With
Set r = Nothing
End Sub

will take " why", and make it "Why", and will retain the individual format of
each.

You could amend it to take an entered search string, or you could amend it to
go through an array of words, like this:

Sub SpaceCap2()
Dim r As Range
Dim myWords()
Dim var

myWords = Array(" why", " who", " what", " where")
Set r = ActiveDocument.Range
For var = 0 To UBound(myWords)
  With r.Find
     .ClearFormatting
     Do While .Execute(FindText:=myWords(var), Forward:=True) = True
        r.Text = LTrim(r.Text)
        r.Text = UCase(Left(r.Text, 1)) & _
              Right(r.Text, Len(r.Text) - 1)
        r.Collapse Direction:=wdCollapseEnd
     Loop
  End With
  Set r = ActiveDocument.Range
Next
Set r = Nothing
End Sub

The code above would go through the document, changing all the " why" to
"Why" - again, retaining format - then resets the r variable to the whole
document,and then processes the next item in the array, " who".  And so on.

I too have to wonder if there is something that is not being mentioned.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.