Remove all empty paragraphs from a document
Article contributed by Dave Rado
You can remove most empty paragraphs from a document by doing a wildcard Find & Replace.
Replace: ^13{2,} with ^p, which (in theory – see below) replaces all occurrences of two or more consecutive paragraph marks with one paragraph mark. Or you can run the following macro, which does the same thing:
With Selection.Find
.Text = "^13{2,}"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
(Note that using Find and Replace is dramatically faster than cycling through the Paragraphs collection).
However, you can't use Find & Replace to delete the first or last paragraph in the document, if they are empty. To delete them you would need to add the following code to the above macro:
Dim MyRange
As Range
Set MyRange = ActiveDocument.Paragraphs(1).Range
If MyRange.Text = vbCr Then MyRange.Delete
Set MyRange = ActiveDocument.Paragraphs.Last.Range
If MyRange.Text = vbCr Then MyRange.Delete
In addition, you can't use Find & Replace to delete the paragraph immediately preceding or following any tables, if these are empty. You would need to add the following code to the macro if you want them deleted – but be careful; if two tables are separated only by an empty paragraph, the following code will merge them into one table, which may or may not be the result you wanted:1
Dim oTable As Table,
MyRange As Range
For Each oTable In ActiveDocument.Tables
#If VBA6 Then
'The following
is only compiled and run if Word 2000 or 2002 is in use
'It speeds up the table and your code
oTable.AllowAutoFit = False
#End If
'Set a range to the para following the current table
Set MyRange = oTable.Range
MyRange.Collapse wdCollapseEnd
'if para after table empty, delete it
If
MyRange.Paragraphs(1).Range.Text = vbCr Then
MyRange.Paragraphs(1).Range.Delete
End If
'Set a range to the para preceding the
current table
Set MyRange =
oTable.Range
MyRange.Collapse wdCollapseStart
MyRange.Move wdParagraph, -1
'if para before table empty, delete it
If
MyRange.Paragraphs(1).Range.Text = vbCr Then
MyRange.Paragraphs(1).Range.Delete
End If
Next oTable
You also can't use Find & Replace to delete the first or last paragraph in a table cell, if empty. If the user inserted an empty paragraph at the start or end of a table cell (in order to simulate “space before paragraph” or “space after paragraph”), you have to use something like the following to remove those empty paragraphs:
Dim oTable As Table,
oCell As Cell,
MyRange As Range
For Each oTable In ActiveDocument.Tables
'Using oCell.Next to cycle through
table cells is much quicker
' in long tables than using For Each oCell
Set oCell =
oTable.Range.Cells(1)
For Counter = 1
To
oTable.Range.Cells.Count
If
Len(oCell.Range.Text) > 2 And _
oCell.Range.Characters(1).Text = vbCr Then
'if cell is NOT blank, but it starts with a blank paragraph, delete the blank
para
'Note that a
blank cell contains 2 characters;
'a paragraph
mark and an end of cell marker
oCell.Range.Characters(1).Delete
End If
If
Len(oCell.Range.Text) > 2 And _
Asc(Right$(oCell.Range.Text, 3)) = 13 Then
'if cell is NOT blank, but it ends with a blank paragraph, delete the blank para
Set
MyRange = oCell.Range
MyRange.MoveEnd Unit:=wdCharacter, Count:=-1
MyRange.Characters.Last.Delete
End If
Set
oCell = oCell.Next
Next Counter
Next oTable
So the complete macro would look like this:
Sub DeleteEmptyParas()
Dim MyRange As Range, oTable
As Table, oCell As Cell
With Selection.Find
.Text = "^13{2,}"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
Set MyRange = ActiveDocument.Paragraphs(1).Range
If MyRange.Text = vbCr Then MyRange.Delete
Set MyRange = ActiveDocument.Paragraphs.Last.Range
If MyRange.Text = vbCr Then MyRange.Delete
For Each oTable In ActiveDocument.Tables
#If VBA6 Then
'The following
is only compiled and run if Word 2000 or 2002 is in use
'It speeds up the table and
your code
oTable.AllowAutoFit =
False
#End If
'Set a range to the para following the current table
Set MyRange = oTable.Range
MyRange.Collapse wdCollapseEnd
'if para after table empty, delete it
If
MyRange.Paragraphs(1).Range.Text = vbCr Then
MyRange.Paragraphs(1).Range.Delete
End If
'Set a range to the para preceding the
current table
Set MyRange =
oTable.Range
MyRange.Collapse wdCollapseStart
MyRange.Move wdParagraph, -1
'if para before table empty, delete it
If
MyRange.Paragraphs(1).Range.Text = vbCr Then
MyRange.Paragraphs(1).Range.Delete
End If
Next oTable
End Sub
__________________
You could modify the macro to cater for that; for example, if my formatting macro finds a blank paragraph separating two tables, it applies the Heading 1 style to that paragraph and inserts the text: “Heading text needs to go here” at that point; and at the end of the macro, a message box is displayed (when appropriate) warning the user that they need to type meaningful heading text at those places, and explaining how to find them. However, the code to do that is beyond the scope of this article. |