PDA

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.