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 / September 2005

Tip: Looking for answers? Try searching our database.

Help with looping a macro

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Fred Goldman - 15 Sep 2005 00:27 GMT
I'm trying to loop this macro until it doesn't find anymore occurences. I
would very much appreciate any help.

Here's the macro:

   Selection.Find.ClearFormatting
   With Selection.Find
       .Text = ",^$"
       .Forward = True
       .Wrap = wdFindContinue
   End With
   Selection.Find.Execute
   Selection.MoveLeft Unit:=wdCharacter, Count:=1
   Selection.MoveRight Unit:=wdCharacter, Count:=1
   Selection.TypeBackspace
   Selection.TypeText Text:=""""
End Sub
Greg Maxey - 15 Sep 2005 01:34 GMT
Fred,

Not sure I follow.  Do you want to replace the literal text ,^$ with the
literal text "^$  ?

Assuming yes.  Test below is a modification of your code.  Test2 is a
replace all method.

Sub Test()

With Selection.Find
 .ClearFormatting
 .Find
 .Text = ",^^$"
 .Forward = True
 .Wrap = wdFindContinue
 Do While .Execute
   With Selection
     .MoveLeft Unit:=wdCharacter, Count:=1
     .MoveRight Unit:=wdCharacter, Count:=1
     .TypeBackspace
     .TypeText Text:=""""
   End With
 Loop
End With
End Sub

Sub Test2()
Dim myRng As Word.Range
Set myRng = ActiveDocument.Content
With myRng.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .Text = ",(^^$)"
 .MatchWildcards = True
 .Replacement.Text = """\1"
 .Execute Replace:=wdReplaceAll
End With

End Sub

Signature

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

> I'm trying to loop this macro until it doesn't find anymore
> occurences. I would very much appreciate any help.
[quoted text clipped - 13 lines]
>    Selection.TypeText Text:=""""
> End Sub
Fred Goldman - 15 Sep 2005 02:33 GMT
Greg,

Thanks a lot!  The first one worked like a charm! What I was actually trying
to do was find every occurence of a comma and any letter right afterwords
(I'm working in Hebrew so it's right to left) and replace the comma with a ".

For example (in English) t,g or g,r I would like to replace with t"g g"r.

You can't put a any character sign in the replace field so I had the macro
replace it manually.

Will Do While .Execute ... Loop work in general when I want to loop any find
macro? Is there any general rule even a beginner can figure out regarding
looping macros (I mean without conditions)?

Thank you!


> Fred,
>
[quoted text clipped - 54 lines]
> >    Selection.TypeText Text:=""""
> > End Sub
Greg Maxey - 15 Sep 2005 03:03 GMT
Fred

Based on  your update, you really don't need a macro at all.   You can use
Edit>Replace>More>Use Wildcards.

Type ,(?) in the find what field
Type "\1 in the replace with field
Click replace all  (Of course always have a backup :-) )

For more on Find and Replace, see:
http://www.gmayor.com/replace_using_wildcards.htm

For your follow-on question you will have to accept that while I am not a
beginnner neither am I a Titan.

I have monkeyed around with Find and Replace code to the point of sweeping
up clumps of hair off the floor in some of my more "quiet moments."  Here is
the fruit of my madness:

'In each example, collapse the range to the end of the found term each time.
'In each example, Wrap is set to wdFindStop
'This prevents a circular loop
Sub ScratchMacro1()
Dim rngstory As Word.Range
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWildcards = False
 .MatchWholeWord = True
 .Wrap = wdFindStop
 .Text = "Apples"
 'Don't bother with .Replacement method just redefine the found range
 While .Execute
   rngstory.Text = .Text
   rngstory.Font.Bold = True
   rngstory.Collapse Direction:=wdCollapseEnd
   ActiveDocument.Indexes.MarkEntry Range:=rngstory, Entry:=.Text
  Wend
End With
End Sub
Sub ScratchMacro2()
Dim rngstory As Word.Range
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWildcards = False
 .MatchWholeWord = True
 .Wrap = wdFindStop
 .Text = "Apples"
 .Replacement.Text = .Text
 .Replacement.Font.Bold = True
 'Loop while found and perform if found (not very clean)
 Do
   .Execute Replace:=wdReplaceOne
   rngstory.Collapse Direction:=wdCollapseEnd
   If .Found Then
     ActiveDocument.Indexes.MarkEntry _
     Range:=rngstory, Entry:=.Text
   End If
 Loop While .Found
End With
End Sub
Sub ScratchMacro3()
Dim rngstory As Word.Range
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWildcards = False
 .MatchWholeWord = True
 .Wrap = wdFindStop
 .Text = "Apples"
 .Replacement.Text = .Text
 .Replacement.Font.Bold = True
 'Find once then enter the loop and perform while found
 .Execute Replace:=wdReplaceOne
 Do While .Found
   rngstory.Collapse Direction:=wdCollapseEnd
   ActiveDocument.Indexes.MarkEntry _
     Range:=rngstory, Entry:=.Text
   .Execute Replace:=wdReplaceOne
 Loop
End With
End Sub
Sub DemonstrationMacro()
Dim rngstory As Word.Range

'ReplaceAll.  Word finds all intances of the .find.text
'and replaces with the replacement text globally as determined
'by .Wrap in fell swoop.
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 '.Wrap = wdFindContinue or wdFindStop doesn't matter
 .MatchWholeWord = True
 .Wrap = wdFindContinue
 .Text = "apples"
 .Replacement.Text = "peaches"
 .Execute Replace:=wdReplaceAll
End With

'ReplaceOne.  In this example .Execute finds and "replaces" the first
'instance of the .find.text. Then enters a Do Loop. The found range
'bounds the found text.  The found text and .Find.Text are different.
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWholeWord = True
 '.Wrap = wdFindStop 'If set routine only finds the first
                     'instance of .Find.Text
 .Wrap = wdFindContinue
 .Text = "peaches"
 .Replacement.Text = "pears"
 .Execute Replace:=wdReplaceOne
  Do While .Found
   rngstory.Select
   'As you can see from the selection the .Find.Text "peaches"
   'is no longer in the found range.  The next .Execute will
   'search from the start of the found range forward looking for
   'the next intance of .Find.Text. If wdFindStop is set,
   '.Execute searches only the found range and will return False.
   .Execute Replace:=wdReplaceOne
 Loop
End With
'ReplaceOne.  In this example .Execute finds and "alters" the first
'instance of the .find.text. Then enters a Do Loop. The text in the
'found range is the same as the .Find.Text. You must use both
'.Wrap and a line of code to collapse the found range to prevent a
'circular loop
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWholeWord = True
 .Wrap = wdFindStop 'Prevents a circular loop
 '.Wrap = wdFindContinue 'Will cause a circular loop
 .Text = "pears"
 .Replacement.Text = "pears"
 .Replacement.Font.Bold = True
 .Execute Replace:=wdReplaceOne
 Do While .Found
   rngstory.Select
   'As you can see from the selection the .Find.Text "pears"
   'is in the found range.  Without additional code, the
   'next .Execute searches from the start of the found range forward.
   'The .Find.Text is immediately found and a circular loop is created.
   rngstory.Collapse Direction:=wdCollapseEnd
   'Collapsing the found range moves the next .Execute starting point
   'past the point causing the cicular loop. The .Execute will search
   'the range of text from the collapse point to the end of the
   'document determined by .Wrap = wdFindStop
   rngstory.Select
   .Execute Replace:=wdReplaceOne
   'It should be clear that since the .Find.Text is only altered and
   '"not changed" using .Wrap = wdFindContinue would also result in
   'a cicular loop.
 Loop
End With

'The next few examples don't use the Replace option at all. Instead
'the found range is processed directly with each .Execute.  .Execute
'without differs 'from .Execute Replace in that the following search
'is perfromed from the end of the previous found range

Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWholeWord = True
 '.Wrap = wdFindContinue 'Causes circular loop will occur because the
                         '.Find.Text is altered but not changed
 .Wrap = wdFindStop
 .Text = "pears"
 While .Execute
   rngstory.Font.Bold = False
   rngstory.Select
   'The next .Execute will automatically collapse the search range
   'to the end of the found range.  It just does :-)
 Wend
End With

'Here the .Find.Text is changed.
Set rngstory = ActiveDocument.Range
With rngstory.Find
 .ClearFormatting
 'Wrap can be either
 '.Wrap = wdFindStop
 '.Wrap = wdFindContinue
 .Replacement.ClearFormatting
 .MatchWholeWord = True
 .Wrap = wdFindContinue
 .Text = "pears"
 While .Execute
   rngstory.Text = "apples"
 Wend
End With
End Sub

Signature

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

> Greg,
>
[quoted text clipped - 79 lines]
>>>    Selection.TypeText Text:=""""
>>> End Sub
Fred Goldman - 15 Sep 2005 12:07 GMT
Thank you very much for your tips. The reason I can't use wildcards is
because I don't want to change commas to " where there is a space afterwards
for example: the little red riding hood, wen,t to lunc,h. Iwould like the
wen,t and lunch ti change to wen"t and lunc"h, but not hood, to change to
hood".

> Fred
>
[quoted text clipped - 281 lines]
> >>>    Selection.TypeText Text:=""""
> >>> End Sub
Helmut Weber - 15 Sep 2005 12:46 GMT
Hi Fred,

maybe the following is sufficient:

Sub Test0023()
Dim oRng As Range
Set oRng = ActiveDocument.Range
ResetSearch
With oRng.Find
  .Text = "(,)([a-zA-Z])"
  .Replacement.Text = Chr$(34) & "\2"
  .MatchWildcards = True
  .Execute Replace:=wdReplaceAll
End With
ResetSearch
End Sub
' ---
Public Sub ResetSearch()
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

Means: a comma followed by any of the letters in square brackets
is being replaced by a " plus that letter.

For left to right writing.

It's kind of hard, to check here, what modifications,
if any, have to made for from right from left writing.

HTH

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"

Greg - 15 Sep 2005 12:53 GMT
Fred,

Wildcard searches are very powerful.  Try find:  ,([! ])
                                                      Replace "\1

That means a commma and any character but a space.  Solves the problem
in your example ;-)
Helmut Weber - 15 Sep 2005 13:32 GMT
Hi Submariner,

>Try find:  ,([! ]) Replace "\1

very tempting. Very probably best, with some luck. ;-)

How about 10,000.67?

Of course, without previous knowledge about the data,
one might suggest a most often working, fast and simple method,
or a slower and more complicated method,
which won't work always either.

Same as with sorting. You never know the fastest method, unless
You analyze the data before and the resources You've got (stack),
which takes some time, too.

Have a nice day!

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"

 
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.