none
Word 2013: How to add new paragraphs, but not before Headings? RRS feed

  • Question

  • Hi all,

    I want to add an empty paragraph previous to each paragraph in a document, except to those paragraphs formatted with a Heading style.

    The purpose is to create margin numbers. So I have to insert new empty paragraphs and apply a style (defining numbered frames). Just the Heading paragraphs have not to get margin numbers.

    Your help would be appreciated.

    Lisa


    Monday, September 21, 2015 7:43 AM

Answers

  • Try:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long
    With ActiveDocument.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If InStr(.Style, "Heading ") <> 1 Then
            If Len(.Range) > 1 Then
              If i = 1 Then
                .Range.InsertBefore vbCr
              ElseIf Len(.Previous.Range.Text) > 1 Then
                .Range.InsertBefore vbCr
              End If
            End If
            .Previous.Style = "SomeStyle"
          End If
        End With
      Next
    End With
    Application.ScreenUpdating = True
    End Sub

    Note that the code doesn't insert empty paragraphs where there already is one and that I've made provision for you to apply your Style.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Monday, September 21, 2015 10:44 AM
  • Hi Lisa,

    You can eliminate the issue with tables and add the ability to run a second time using:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long, Stl As String
    Stl = "MyStyle"
    With ActiveDocument.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If .Range.Information(wdWithInTable) = False Then
            If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then
              If Len(.Range) > 1 Then
                If i = 1 Then
                  .Range.InsertBefore vbCr
                ElseIf Len(.Previous.Range.Text) > 1 Then
                  .Range.InsertBefore vbCr
                End If
              End If
              .Previous.Style = Stl
            End If
          End If
        End With
      Next
    End With
    Application.ScreenUpdating = True
    End Sub

    I could add code to manage the bookmarks issue also, but I expect that would slow the macro down quite a lot.

    As for the addition of frames, the ideal time to do that is where the code applies your Style.


    Cheers
    Paul Edstein
    [MS MVP - Word]




    Monday, September 21, 2015 10:31 PM
  • In that case, try:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim Rng As Range, Doc As Document, BkMk As Bookmark, i As Long
    Const Stl As String = "My Style"
    Set Doc = ActiveDocument
    With Doc.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If .Range.Information(wdWithInTable) = False Then
            If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then
              If Len(.Range) > 1 Then
                If i = 1 Then
                  .Range.InsertBefore vbCr
                ElseIf Len(.Previous.Range.Text) > 1 Then
                  .Range.InsertBefore vbCr
                Else
                  .Range.Start = .Previous.Range.Start
                End If
                For Each BkMk In Doc.Bookmarks
                  If BkMk.Range.Start = .Previous.Range.Start Then
                    Set Rng = BkMk.Range
                    With Rng
                      .Start = .Start + 1
                    End With
                    Doc.Bookmarks.Add Name:=BkMk.Name, Range:=Rng
                  End If
                Next
              End If
              .Previous.Style = Stl
            End If
          End If
        End With
      Next
    End With
    Set Rng = Nothing: Set Doc = Nothing
    Application.ScreenUpdating = True
    End Sub

    Do note, though, that this could take considerably longer to complete processing in a document with many bookmarks.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Tuesday, September 22, 2015 7:54 AM
  • You could change:

    If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then

    to:

    If (InStr(.Style, "Heading ") <> 1) And InStr(.Style, "TOC") <> 1) And (.Style <> Stl) Then

    Toggling the field code display alone won't prevent an extra para being added before the TOC. Nor will it prevent adding such paragraphs before other content that preceded the TOC. In that case you could

    • insert:

    Doc.ActiveWindow.View.ShowFieldCodes = True

    before:

    With Doc.Range

    • insert:

          If .Range.Fields.Count > 0 Then
            If .Range.Fields(1).Type = wdFieldTOC Then Exit Sub
          End If

    before:

          If .Range.Information(wdWithInTable) = False Then

    • insert:

    Doc.ActiveWindow.View.ShowFieldCodes = False

    before:

    Set Rng = Nothing: Set Doc = Nothing


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, September 23, 2015 7:54 AM

All replies

  • Hi Lisa,

    I think we need more context...


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, September 21, 2015 7:54 AM
  • Hi Paul,

    I think we need more context...

    Sorry, the question was sent by mistake when using a newsreader... I have just edited the text.

    --
    Cheers,
    Lisa

    Monday, September 21, 2015 9:45 AM
  • Try:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long
    With ActiveDocument.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If InStr(.Style, "Heading ") <> 1 Then
            If Len(.Range) > 1 Then
              If i = 1 Then
                .Range.InsertBefore vbCr
              ElseIf Len(.Previous.Range.Text) > 1 Then
                .Range.InsertBefore vbCr
              End If
            End If
            .Previous.Style = "SomeStyle"
          End If
        End With
      Next
    End With
    Application.ScreenUpdating = True
    End Sub

    Note that the code doesn't insert empty paragraphs where there already is one and that I've made provision for you to apply your Style.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Monday, September 21, 2015 10:44 AM
  • Hi  Paul,

    Your Code works like a charm, thank you so much :-).

    However, there may be a few problems:
    1. In documents with tables, I will get an error message, and the frames will be inserted not before the last table.
    2. "InsertBefore" in the code means, that a new paragraph will be created from the beginning of an existing paragraph. So, if there is a bookmark, the bookmark will be expanded to the new paragraph.
    3. You cannot run the macro a second time, because the code will not check for existing frames. Therefore, if necessary to add more frames, you have to insert new paragraphs manually and apply the style.

    But for now it is okay. Thanks!

    Lisa
     > Try:


    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long
    With ActiveDocument.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If InStr(.Style, "Heading ") <> 1 Then
            If Len(.Range) > 1 Then
              If i = 1 Then
                .Range.InsertBefore vbCr
              ElseIf Len(.Previous.Range.Text) > 1 Then
                .Range.InsertBefore vbCr
              End If
            End If
            .Previous.Style = "SomeStyle"
          End If
        End With
      Next
    End With
    Application.ScreenUpdating = True
    End Sub

     Note that the code doesn't insert empty paragraphs where there already is one and that I've made provision for you to apply your Style.

    Monday, September 21, 2015 4:05 PM
  • Hi Lisa,

    You can eliminate the issue with tables and add the ability to run a second time using:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long, Stl As String
    Stl = "MyStyle"
    With ActiveDocument.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If .Range.Information(wdWithInTable) = False Then
            If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then
              If Len(.Range) > 1 Then
                If i = 1 Then
                  .Range.InsertBefore vbCr
                ElseIf Len(.Previous.Range.Text) > 1 Then
                  .Range.InsertBefore vbCr
                End If
              End If
              .Previous.Style = Stl
            End If
          End If
        End With
      Next
    End With
    Application.ScreenUpdating = True
    End Sub

    I could add code to manage the bookmarks issue also, but I expect that would slow the macro down quite a lot.

    As for the addition of frames, the ideal time to do that is where the code applies your Style.


    Cheers
    Paul Edstein
    [MS MVP - Word]




    Monday, September 21, 2015 10:31 PM
  • Hi Paul,

    You can eliminate the issue with tables and add the ability to run a second time using:
    [Code]
    I could add code to manage the bookmarks issue also, but I expect that would slow the macro down quite a lot.
    As for the addition of frames, the ideal time to do that is where the code applies your Style.

    The macro works perfectly :-), thank you again.

    The bookmark issue isn't that important. During my tests it was just a problem with user-defined bookmarks. I guess, in some cases it could be a problem with bookmarks created e.g. by cross-references or TOC.
    (As we know, the problem sometimes occur, when users create new paragraphs from the “wrong” place.)


    Cheers,
    Lisa

    Tuesday, September 22, 2015 6:22 AM
  • In that case, try:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim Rng As Range, Doc As Document, BkMk As Bookmark, i As Long
    Const Stl As String = "My Style"
    Set Doc = ActiveDocument
    With Doc.Range
      For i = .Paragraphs.Count To 1 Step -1
        With .Paragraphs(i)
          If .Range.Information(wdWithInTable) = False Then
            If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then
              If Len(.Range) > 1 Then
                If i = 1 Then
                  .Range.InsertBefore vbCr
                ElseIf Len(.Previous.Range.Text) > 1 Then
                  .Range.InsertBefore vbCr
                Else
                  .Range.Start = .Previous.Range.Start
                End If
                For Each BkMk In Doc.Bookmarks
                  If BkMk.Range.Start = .Previous.Range.Start Then
                    Set Rng = BkMk.Range
                    With Rng
                      .Start = .Start + 1
                    End With
                    Doc.Bookmarks.Add Name:=BkMk.Name, Range:=Rng
                  End If
                Next
              End If
              .Previous.Style = Stl
            End If
          End If
        End With
      Next
    End With
    Set Rng = Nothing: Set Doc = Nothing
    Application.ScreenUpdating = True
    End Sub

    Do note, though, that this could take considerably longer to complete processing in a document with many bookmarks.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Tuesday, September 22, 2015 7:54 AM
  • Hi Paul,

    Thank you very much - the code works perfectly! No more requirements.

    [Code]
    Do note, though, that this could take considerably longer to complete processing in a document with many bookmarks.

    I think there will be never lots of bookmarks in a document.

    (Now I am just testing whether it will be more comfortable to show field codes instead of results at the beginning of  the macro, or whether the macro should exclude not only Heading styles but also TOC styles etc. Otherwise also single paragraphs of field results will be numbered. I guess, it would be better to exclude other styles...)


    Have a nice day,
    Lisa

    Wednesday, September 23, 2015 7:17 AM
  • You could change:

    If (InStr(.Style, "Heading ") <> 1) And (.Style <> Stl) Then

    to:

    If (InStr(.Style, "Heading ") <> 1) And InStr(.Style, "TOC") <> 1) And (.Style <> Stl) Then

    Toggling the field code display alone won't prevent an extra para being added before the TOC. Nor will it prevent adding such paragraphs before other content that preceded the TOC. In that case you could

    • insert:

    Doc.ActiveWindow.View.ShowFieldCodes = True

    before:

    With Doc.Range

    • insert:

          If .Range.Fields.Count > 0 Then
            If .Range.Fields(1).Type = wdFieldTOC Then Exit Sub
          End If

    before:

          If .Range.Information(wdWithInTable) = False Then

    • insert:

    Doc.ActiveWindow.View.ShowFieldCodes = False

    before:

    Set Rng = Nothing: Set Doc = Nothing


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, September 23, 2015 7:54 AM