View Full Version : Restart ListNum field (\s 1) if prior ListNum exists in proceeding paragraph
bstephens
07-10-2011, 04:31 PM
Hi I am using the below macro to do "autonumbering" within a paragraph:
Sub NumberingInParagraphArabic()
    Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "LISTNUM  NumberDefault \l 4", PreserveFormatting:=False
End Sub 
The macro works fine the first time I use it in a paragraph. However, once I use it in a second paragraph, I want it to automatically restart numbering at "(1") instead of restart numbering at the next number in the sequence from the prior paragraph.
In other words, I want the macro to automatically insert"LISTNUM  NumberDefault \l 4 \s 1" in the next paragraph if there is a prior paragraph that uses a LISTNUM field.
I am having trouble constructing a conditional boolean statement (i.e. "LISTNUM is in a prior paragraph") which triggers the code that "\s 1" should be appended. Anyone have input?
Regards,
Brian
Jay Freedman
07-10-2011, 05:18 PM
The logic does get a little complicated. :yes
Recognize that you need to check not just the single preceding paragraph but the entire document up to but not including the Selection's paragraph -- if you have a LISTNUM field in paragraph 1 and you're entering one in paragraph 17, you still need the switch. But if the current run of the macro is for the second or later LISTNUM field in the current paragraph, you don't want the switch even if there are fields in any preceding paragraphs...
Sub NumberingInParagraphArabic()
    Dim code As String
    Dim paraInx As Long
    Dim rg As Range
    Dim fld As Field
    Dim addToCode As Boolean
    
    code = "LISTNUM NumberDefault \l 4"
    addToCode = False
    
    ' find out which paragraph the Selection is in
    Set rg = Selection.Paragraphs(1).Range
    rg.Start = ActiveDocument.Range.Start
    paraInx = rg.Paragraphs.Count
    
    ' If it's in paragraph 1, there is no previous paragraph;
    ' don't add the \s 1 switch.
    If paraInx > 1 Then
       ' If Selection is in any later paragraph, look for a
       ' LISTNUM field anywhere in the earlier part of the doc
       ' (not just the previous paragraph).
       Set rg = ActiveDocument.Paragraphs(paraInx - 1).Range
       rg.Start = ActiveDocument.Range.Start
       For Each fld In rg.Fields
          If fld.Type = wdFieldListNum Then
             addToCode = True
             Exit For  ' as soon as we find one, stop looking
          End If
       Next
       
       ' If this isn't the first LISTNUM field in the paragraph,
       ' don't add the \s 1 switch even if previous paragraphs
       ' have LISTNUM fields.
       If addToCode Then
          For Each fld In Selection.Paragraphs(1).Range.Fields
            If fld.Type = wdFieldListNum Then
               addToCode = False
               Exit For  ' as soon as we find one, stop looking
            End If
          Next
       End If
    End If
    
    If addToCode Then code = code & " \s 1"
    
    Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, _
       Text:=code, preserveformatting:=False
End Sub
bstephens
07-10-2011, 06:31 PM
Jay, thanks for the code! 
Once you add a LISTNUM field the code works great (i.e. numbering restarts at "(1)") for any new LISTNUM fields that are inserted in the paragraphs below, but do you know how to  revise this code so that any LISTNUM fields inserted in a paragraph above (i.e., paragraph 1 is now different and appears earlier in "ActiveDocument.Paragraphs(paraInx - 1).Range") does not trigger the LISTNUM fields in the next applicable paragraph below to renumber from "new paragraph 1"
Example to illustrate, because kind of confusing.
Suppose User runs the macro and first adds numbering within paragraph 5 (5 fields) and then a little later in time, decides to also do numbering within paragraph 10 (5 fields). Now the next day, User decides to add numbering within paragraph 3 (5 fields). RESULT: Paragraph 5 starts with "(6)" instead of "(1)". 
Do you know how I can achieve this logic?: If there is NO LISTNUM field in the current paragraph at all, then insert "LISTNUM NumberDefault \l 4 \s 1", else, if a "LISTNUM NumberDefault \l 4 \s 1" field already exists in the current paragraph, then insert "LISTNUM NumberDefault \l 4".
Jay Freedman
07-11-2011, 04:46 AM
To take care of the situation you described, I added to section starting with the Else statement below:
Sub NumberingInParagraphArabic()
    Dim code As String
    Dim paraInx As Long
    Dim rg As Range
    Dim fld As Field
    Dim addToCode As Boolean
     
    code = "LISTNUM NumberDefault \l 4"
    addToCode = False
     
     ' find out which paragraph the Selection is in
    Set rg = Selection.Paragraphs(1).Range
    rg.Start = ActiveDocument.Range.Start
    paraInx = rg.Paragraphs.Count
     
     ' If it's in paragraph 1, there is no previous paragraph;
     ' don't add the \s 1 switch.
    If paraInx > 1 Then
         ' If Selection is in any later paragraph, look for a
         ' LISTNUM field anywhere in the earlier part of the doc
         ' (not just the previous paragraph).
        Set rg = ActiveDocument.Paragraphs(paraInx - 1).Range
        rg.Start = ActiveDocument.Range.Start
        For Each fld In rg.Fields
            If fld.Type = wdFieldListNum Then
                addToCode = True
                Exit For ' as soon as we find one, stop looking
            End If
        Next
         
         ' If this isn't the first LISTNUM field in the paragraph,
         ' don't add the \s 1 switch even if previous paragraphs
         ' have LISTNUM fields.
        If addToCode Then
            For Each fld In Selection.Paragraphs(1).Range.Fields
                If fld.Type = wdFieldListNum Then
                    addToCode = False
                    Exit For ' as soon as we find one, stop looking
                End If
            Next
        End If
    Else   ' paraInx = 1 (first paragraph)
        ' Always start the (current) first paragraph with
        ' a \s 1 switch.
        addToCode = True
        For Each fld In Selection.Paragraphs(1).Range.Fields
            If fld.Type = wdFieldListNum Then
                addToCode = False
                Exit For ' as soon as we find one, stop looking
            End If
        Next
    End If
     
    If addToCode Then code = code & " \s 1"
     
    Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, _
    Text:=code, preserveformatting:=False
End Sub
There's another situation that may cause a problem for you: If you insert a new LISTNUM field closer to the beginning of a paragraph than a field that already has the \s switch, the numbers will be out of order -- the newly added one won't have the switch. To solve that would take another section of code about the same size as what I've already written; it would be easier just to fix it manually if and when it occurs.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.