Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Remove Replicate Paragraph Markers - strange problem! 2

Status
Not open for further replies.

DrSimon

IS-IT--Management
Dec 14, 2001
674
GB
I'm trying to tidy up documents by removing any replicate paragraph markers and have found that the last paragraph marker is non-standard. I'm using Find and Replace and because I don't know how many replicates I'm going to find, I need to use .Found and a Do loop to keep cycling round. See code below.
Code:
Sub Delete_Rep_ParaMarkers()
    Dim Findstr As String
    Dim Char As String
    Dim ReplaceStr As String
    Dim Rng As Range
    Dim Notfound As Boolean
    Set Rng = ActiveDocument.Content
    Char = "^p"       ' Or Chr(13)
    ReplaceStr = Char
    Findstr = "^p^p"  ' Or Chr(13) & Chr(13)
    Notfound = False
    Do Until Notfound
        Rng.Find.ClearFormatting
        Rng.Find.Replacement.ClearFormatting
        With Rng.Find
            .Text = Findstr
            .Replacement.Text = ReplaceStr
            .Forward = True
            .Wrap = wdFindContinue
            .Format = True
            .MatchCase = False
            .MatchWholeWord = False
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
            .Execute Replace:=wdReplaceAll
            If .Found Then
                Notfound = False
            Else
                Notfound = True
            End If
        End With
    Loop
End Sub
This works fine until it encounters a duplicate paragraph marker at the end of the document. In this situation Word 'finds' the duplicate paragraph marker but fails to replace it and so the code above gets stuck in an infinite loop. Try it - the same thing happens in this situation if you use the foreground Find and Replace for ^p^p and ^p respectively(but without the infinite loop!).

The only way I could get round this was by using the code below which keeps looping to see if the 2nd last character is a paragraph marker and delete if it is.
Code:
  Dim Rng As Range
    Dim Dun As Boolean
    
    Dun = False
    Do
        Set Rng = ActiveDocument.Range (Start:=ActiveDocument.Range.End - 2, End:=ActiveDocument.Range.End)
        If Asc(Rng.Characters(1)) = 13 Then
            Rng.Delete
        Else
            Dun = True
        End If
    Loop Until Dun

OK. Having provided both the problems and solution, does anyone know if there is a more elegant way around this? Or are there different arguments to use for the original find and replace?

Thanks in advance.
 
The last paragraph in ANY Word document is "special". It can not - ever - be deleted.

I am not sure what you mean by "replicate paragraph markers", but if you mean empty paragraphs (paragraphs of ONLY the paragraph mark) then this removes them.
Code:
Sub RemoveEmptyParagraphs()
Dim oPara As Paragraph
For Each oPara In ActiveDocument.Paragraphs
   If oPara.Range.Text = Chr(13) Then
      oPara.Range.Delete
   End If
Next
End Sub
It will remove the last paragraph if empty, as long as there is a previous paragraph that is NOT empty.

55,687.00 hours down....
<60 hours to go

tick tick tick tick tick
 
Thanks - much cleaner thinking.
 
Yes, it deals with the actual REAL issue: I want to remove empty paragraphs (paragraphs with just the paragraph mark).

So, it tests every paragraph, and if it is only the paragraph mark, it deletes it.

Done. No find and replace, just what is ACTUALLY required. And you are correct. It is a matter of clear thinking.

N.B. as it stands the code only tests paragraphs in the MainStory. It does not test headers or footers.

55,687.00 hours down....
<60 hours to go

tick tick tick tick tick
 
A more efficient process than Gerry's would be:
Code:
Sub Delete_Rep_ParaMarkers()
With ActiveDocument.Content.Find
  .ClearFormatting
  .Replacement.ClearFormatting
  .Text = "[^13]{1,}"
  .Replacement.Text = "^p"
  .Forward = True
  .Wrap = wdFindContinue
  .MatchWildcards = True
  .Execute Replace:=wdReplaceAll
End With
ActiveDocument.Characters.Last.Delete
End Sub

Cheers
Paul Edstein
[MS MVP - Word]
 
Interesting. I've never seen that syntax "[^13]{1". I assume that [^13] refers to ASCII for CR but what is {1 about? And how does this work? If anything I would have expected {10 implying LF. Also strange that the replacement text is still ^p.

Thanks
Simon
 
Hi Simon,

You are correct in the ^13 represents a CR - but you can't use it as a Replace expression for a paragraph break, hence the ^p.

If you examine the code, you'll see that it's doing a wildcard Find/Replace. In such an operation, the [^13]{1,} tells Word to find any string of 1 or more CR characters (it might have been even more efficient to use [^13]{2,}). See Word's Help file for more details on Wildcard Find/Replace operations.

Cheers
Paul Edstein
[MS MVP - Word]
 
OK understood - that's a different version of what I did. But the code that solves my problem is ActiveDocument.Characters.Last.Delete, so thanks for that.

Now I need to consider which is more appropriate for me. Thanks both of you.
Simon
 
Bottom line is that a native Find/Replace with ReplaceAll (macropod's code) is significantly faster - usually - than a For Each code.

55,687.00 hours down....
<60 hours to go

tick tick tick tick tick
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top