Restarting list numbering using VBA

Article contributed by Margaret Aldis

with code from John McGhie and Steve Hudson

This article provides details of how to restart list numbering by using VBA code to manipulate the list format, and discusses the workarounds needed to cope with the inherent problems of this method (and of the Restart Numbering command method). For other methods of restarting list numbering, see How to restart style-based numbering.

Using this macro code to apply the restart marker is the equivalent of using the Restart Numbering command, which was not available before Word 2002.

Macros to restart numbering

The following macro will restart list numbering on the first item of a selected list:

Public Sub RestartListNumbering(Optional Scope As Range)

'(c) 1999-2004 Word Heretic steve@wordheretic.com

' Everyone has permission to redistribute and use this code at will,

' providing the (c) notice is left intact.

'Restarts list numbering, 97-XP, all list implementations

 

Dim KillScope As Boolean

 

If Scope Is Nothing Then

       Set Scope = Selection.Range

       KillScope = True

End If

 

'Use first listpara

 

With Scope.ListParagraphs

If .Count > 0 Then

With .Item(1).Range.ListFormat

.ApplyListTemplate .ListTemplate, False

End With

End If

End With

 

'Destroy our objects

 

If KillScope Then Set Scope = Nothing

End Sub

This method can be used in combination with applying numbering using styles. For example, the following code formats the selected paragraphs as a complete list, including applying the restart to the first item and special spacing for the final item.

Sub ListNumber()

' Macro created by John McGhie from an idea by Steve Hudson

With Selection.Paragraphs

.Style = "List Number"

With .First.Range.ListFormat

.ApplyListTemplate .ListTemplate, False

End With

With .Last

.KeepWithNext = False

.SpaceAfter = 10

End With

End With

End Sub

Note that the code steers clear of the ListGalleries collection and works directly with the current ListTemplate, thus avoiding any unwanted changes to styles and list template linking. However, like the built-in RestartNumbering command available from the user interface, it still applies the numbering as direct formatting, and creates a 'restart marker'.

For more information on the Word object model for list formatting, see the Word VBA Help for the List, ListFormat and ListTemplate objects.

Problems and workarounds

There are two basic problems with applying a restart using the code above or the Restart Numbering command:

Steve Hudson has produced a number of macros to address these and other problems - in particular his RestartListsAfterHeadings macro solves the problem of lost restarts by recreating them based on the document outline structure. Another strategy would be to mark the restarted paragraphs in some way, so that after they are reset to style or pasted the restarts can be reinstated. The following code illustrates a possible approach to this.

The first macro finds all items numbered 1 for the List Number style and marks them with a temporary bookmark. This code could be run before copying text containing lists to the clipboard, and before any change to the style. If the paste is to be to a different document, similar code would need to be run there (using a distinct bookmark sequence).

Public Sub MarkRestarts()

' Sample code to mark restarted List Number paragraphs

Dim ListItem As Paragraph

Dim n As Integer ' bookmark id

n = 1

For Each ListItem In ActiveDocument.ListParagraphs

If ListItem.Style = _

ActiveDocument.Styles(wdStyleListNumber).NameLocal Then

If ListItem.Range.ListFormat.ListValue = 1 Then

ActiveDocument.Bookmarks.Add "restart" & n, _ ListItem.Range

n = n + 1

End If

End If

Next ListItem

End Sub

 

Even if the source list loses its restart, it will retain the bookmark, which allows the restart to be reapplied as follows:

Public Sub ReapplyRestarts()

' Sample macro to reapply restarts lost by a copy and paste

Dim aBookmark As Bookmark

Dim RestartPoint As Range

For Each aBookmark In ActiveDocument.Bookmarks

If aBookmark.Name Like "restart*" Then ' it's a restart point

Set RestartPoint = aBookmark.Range

RestartPoint.Collapse wdCollapseEnd

RestartPoint.MoveEnd unit:=wdCharacter, Count:=-1

With RestartPoint.ListFormat

.ApplyListTemplate .ListTemplate, ContinuePreviousList:=False

End With

aBookmark.Delete

End If

Next aBookmark

End Sub

 

After a paste into a different document, or an update to the style, you would need first to reset the paragraph formatting, so as to reapply the correct numbering scheme for the current document, and then reapply the restarts which will have been lost on the reset. The final example illustrates this.

Public Sub ReapplyLists()

' Sample macro to correct errors after paste

' to another document and style changes

 

Dim aPara As Paragraph

Dim aBookmark As Bookmark

Dim StyleName As String

Dim RestartPoint As Range

 

' reset the paragraph formatting of the style if the paragraph

' should be numbered in this document

For Each aPara In ActiveDocument.Paragraphs

StyleName = aPara.Style

If ActiveDocument.Styles(StyleName).ListLevelNumber > 0 Then

aPara.Reset

End If

Next aPara

 

' reapply restarts to bookmarked paragraphs and tidy up

For Each aBookmark In ActiveDocument.Bookmarks

If aBookmark.Name Like "restart*" Then ' it's a restart

Set RestartPoint = aBookmark.Range

RestartPoint.Collapse wdCollapseEnd

RestartPoint.MoveEnd unit:=wdCharacter, Count:=-1

With RestartPoint.ListFormat

.ApplyListTemplate .ListTemplate, _

 ContinuePreviousList:=False

End With

aBookmark.Delete

End If

Next aBookmark

End Sub