MS Office Forum / Word / Programming / April 2007
advanced replace - add character to paragraph
|
|
Thread rating:  |
nico - 03 Apr 2007 22:46 GMT Hi,
I'm trying to migrate wikis, and thought Word's Replace might be good (and it is, generally). Want I can't get to work is to make sure that every paragraph that ends in ** should also start with ** (they should be added), while every paragraph that starts with ** should also end with it. Some paragraphs will have two stars both at the beginning and at the end already, while some have it only at the beginning and some only at the end. I don't want to end up with four stars in any place. What's the quickest way to do that? I had tried searching for ^13(\*\*)(*)([!^13])([!\*\*])(^13^13) and replacing this with ^p**\2**^p^p** but it didn't work as expected.
Thanks for any help! Nico
Helmut Weber - 03 Apr 2007 23:49 GMT Hi Nico,
to me, wildcard searches are too complicated.
Sub Test40X() Dim oPrg As Paragraph For Each oPrg In ActiveDocument.Paragraphs With oPrg.Range If Len(.Text) <> 1 Then While .Characters.First = "*" .Characters.First = "" Wend While .Characters.Last.Previous = "*" .Characters.Last.Previous = "" Wend .Characters.First = "**" .Characters.Last.Previous = "**" End If End With Next End Sub
Should be fast enough. There is still room for improvement. The macro skips empty paragraphs and processes the first paragraph, as well, which is always a problem with wildcards, when using chr(13) & something.
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
Karl E. Peterson - 04 Apr 2007 00:12 GMT > Hi Nico, > > to me, wildcard searches are too complicated. Yeah, I hear that.
> Sub Test40X() > Dim oPrg As Paragraph [quoted text clipped - 13 lines] > Next > End Sub Here's another approach that doesn't lean so heavily on the object model:
Sub Test40X() Dim oPrg As Paragraph Dim txt As String For Each oPrg In ActiveDocument.Paragraphs txt = oPrg.Range.Text If Len(txt) >= 2 Then Select Case True Case (Left$(txt, 2) = "**") And (Right$(txt, 2) = "**") ' do nothing Case (Left$(txt, 2) = "**") txt = txt & "**" Case (Right$(txt, 2) = "**") txt = "**" & txt Case Else ' do nothing End Select End If oPrg.Range.Text = txt Next End Sub
 Signature .NET: It's About Trust! http://vfred.mvps.org
Helmut Weber - 04 Apr 2007 01:16 GMT Hi Karl,
>> to me, wildcard searches are too complicated. > >Yeah, I hear that. Not always, but it needs a special talent. So to speak, some like to twist their brain.
>> Sub Test40X() >> Dim oPrg As Paragraph [quoted text clipped - 13 lines] >> Next >> End Sub Results in an endless loop here and now.
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
Helmut Weber - 04 Apr 2007 02:14 GMT Hi Karl,
it's very late here, not to say early in the morning.
It's your code, that loops endlessly, not mine. :-)
Maybe something went wrong with your code when copying and pasting.
Cheers
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
Karl E. Peterson - 04 Apr 2007 02:39 GMT > Hi Karl, > [quoted text clipped - 3 lines] > > Maybe something went wrong with your code when copying and pasting. Well, it was AirCode<tm>, sorry for not posting a warning. I just took your loop, and redid the guts. <g>
 Signature .NET: It's About Trust! http://vfred.mvps.org
nico - 04 Apr 2007 02:18 GMT Hi Karl,
Also couldn't get this one to work. For some reason the oPrg.Range.Text = txt prevents the NEXT loop from working properly, resulting in an endless loop. Otherwise it would seem that this is as close as it gets. Cheers.
> > Hi Nico, > > [quoted text clipped - 42 lines] > Next > End Sub Karl E. Peterson - 04 Apr 2007 02:41 GMT > Also couldn't get this one to work. For some reason the oPrg.Range.Text = > txt prevents the NEXT loop from working properly, resulting in an endless > loop. Otherwise it would seem that this is as close as it gets. Dang! You don't know how often I get away with posting AirCode, either. I'm sorry, but I have no idea why that might be, and as things stand I'm late for supper! If this remains unsolved tommorow, I'll take another look at it.
Good luck!
 Signature .NET: It's About Trust! http://vfred.mvps.org
>>> Hi Nico, >>> [quoted text clipped - 46 lines] >> ..NET: It's About Trust! >> http://vfred.mvps.org Helmut Weber - 04 Apr 2007 13:56 GMT Hi Nico,
my solution was alright, but not for your problem. :-( ;-)
I didn't read the question correctly.
On my and I dare say an Karl's behalf, too. This is what we had in mind.
Sub Test40XX() Dim p As Paragraph Dim s As String ' a string Dim c As Long ' a case Dim r As Range ' a range For Each p In ActiveDocument.Range.Paragraphs With p.Range Set r = p.Range r.End = r.End - 1 r.Select s = r.Text If Left(s, 2) <> "**" And Right(s, 2) <> "**" Then c = 1 If s = "" Then c = 0 ' do nothing If Right(s, 2) = "**" Then c = 2 If Left(s, 2) = "**" Then c = 3 If Left(s, 2) = "**" And Right(s, 2) = "**" Then c = 0 ' do nothing Select Case c Case 1: s = "**" & s & "**" Case 2: s = "**" & s Case 3: s = s & "**" End Select r.Text = s End With Next End Sub
I excluded the paragraph mark from overwriting, as it may lose formatting by the above method.
-- Greetings from Bavaria, Germany Helmut Weber, MVP WordVBA "red.sys" & chr(64) & "t-online.de" Word 2002, Windows 2000 (german versions)
nico - 04 Apr 2007 02:16 GMT Sorry, can't get this one to work. It adds stars to all paragraphs, rather than just to the ones that have ** either in front or at the back (but not both). It also 'swallows' the last character of the text. I've tried for some time to find a way to insert characters, or to change the code so that it would ignore starless paragraphs, but have had no success.
Thanks anyway, I did learn more about VB.
> Hi Nico, > [quoted text clipped - 24 lines] > which is always a problem with wildcards, > when using chr(13) & something. Doug Robbins - Word MVP - 04 Apr 2007 08:07 GMT The following code will do all but put the ** before the first paragraph in the document:
Selection.HomeKey wdStory Selection.Find.ClearFormatting With Selection.Find Do While .Execute(findText:="[!\*]{2}^13", ReplaceWIth:="**^p", MatchWildcards:=True, Forward:=True, Wrap:=wdFindStop) = True Loop End With Selection.HomeKey wdStory Selection.Find.ClearFormatting With Selection.Find Do While .Execute(findText:="^13[!\*]{2}", ReplaceWIth:="^p**", MatchWildcards:=True, Forward:=True, Wrap:=wdFindStop) = True 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
> Hi, > [quoted text clipped - 13 lines] > Thanks for any help! > Nico Klaus Linke - 04 Apr 2007 16:24 GMT To add missing asterisks at the end of paragraphs (that have two at the start):
Find what: (^13\*\*[!^13]@[!\*][!\*])(^13) Replace with: \1**\2
To add missing asterisks at the start of paragraphs (that have two at the end): Find what: (^13)([!\*][!\*][!^13]@\*\*^13) Again, Replace with: \1**\2
According to Helmut, I must have a twist in my brain... <g> Klaus
> Hi, > [quoted text clipped - 13 lines] > Thanks for any help! > Nico Klaus Linke - 04 Apr 2007 16:35 GMT Ouch... You'll have to do the replacements twice.
That's a common problem when you want to want to match both for the start and the end of the paragraph. Because Word widcards have no anchors for the start and end of paragraphs (like the "<" and ">" anchors for the beginning and end of words), you have to match the paragraph mark of the preceeding paragraph. That way, you match more than one paragraph, and will likely miss some. A second run of the wildcard replacement will fix that though, and those 4 replacements will still likely be faster than looping paragraphs.
Anchors for the beginning and end of paragraphs would be very nice to have... especially considering that users don't even easily discover the possible use of ^13 for ^p.
Klaus
Russ - 08 Apr 2007 22:09 GMT > Find what: (^13\*\*[!^13]@[!\*][!\*])(^13) > Replace with: \1**\2 [quoted text clipped - 3 lines] > Find what: (^13)([!\*][!\*][!^13]@\*\*^13) > Again, Replace with: \1**\2
>> Hi, >> [quoted text clipped - 13 lines] >> Thanks for any help! >> Nico
> Ouch... You'll have to do the replacements twice. > [quoted text clipped - 6 lines] > A second run of the wildcard replacement will fix that though, and those 4 > replacements will still likely be faster than looping paragraphs. I agree on the speed issue. However, if there is no paragraph mark at the beginning of the document, the first 'non-empty' paragraph will not be tested. But you could temporarily add a paragraph mark before running the "Finds and Replaces" and delete the temporary mark afterwards. ActiveDocument.Range.InsertBefore vbCr ' Do Finds and Replaces ActiveDocument.Characters(1).Delete
> Anchors for the beginning and end of paragraphs would be very nice to > have... especially considering that users don't even easily discover the > possible use of ^13 for ^p. I agree. I would hope that Microsoft would employ smarter Regular Expressions in a future version of Word. Referenced, newer Regular Expressions VBA code modules might even be used in older versions of Word, if they were referenced via VBA code.
MacWord people should use \n or [\^13] instead of just ^13 in their paragraph mark "Finds".
> Klaus
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
Helmut Weber - 04 Apr 2007 16:36 GMT Hi Klaus,
>According to Helmut, I must have a twist in my brain... sure, one might call it a special talent as well. :-) You may have fun with Excel-formulae, which I am hopeless with.
My last code incloses all paragraphs that have neither leading nor trailing double asteriscs, in asteriscs, too. Still didn't get the question.
I'll be off for playing chess. It's clear and simple.
 Signature Greetings from Bavaria, Germany
Helmut Weber, MVP WordVBA
Win XP, Office 2003 "red.sys" & Chr$(64) & "t-online.de"
nico - 04 Apr 2007 18:06 GMT I won't be able to test and report the results for a while, but be sure that I will come back after Easter. All the best for your holidays, too, and thousand thanks for your help!!
> Hi Klaus, > [quoted text clipped - 9 lines] > > I'll be off for playing chess. It's clear and simple. Klaus Linke - 04 Apr 2007 18:25 GMT Happy holidays!
Klaus
>I won't be able to test and report the results for a while, but be sure >that [quoted text clipped - 14 lines] >> >> I'll be off for playing chess. It's clear and simple.
|
|
|