Graham Mayor

... helping to ease the lives of Microsoft Word users.

Many people access the material from this web site daily. Most just take what they want and run. That's OK, provided they are not selling on the material as their own; however if your productivity gains from the material you have used, a donation from the money you have saved would help to ensure the continued availability of this resource. Click the appropriate button above to access PayPal.

Automatic Numbering of Documents

Some of the macros featured lower down this page had been available on my old site for a while, but I thought it would be worth integrating the various functions into a simple add-in (for Word versions 2007 to 2016) for those uncomfortable with the use of macros.

The add-in, in DOTM template format, is intended to be filed in the Word startup folder and thus load with Word. If you have not changed the preferred startup folder it can be located (in English language versions of Windows) by typing

%appdata%\Microsoft\Word\Startup

in the Windows Explorer Address bar and pressing Enter.

It provides buttons on the Add-Ins tab of the ribbon which can be used to apply numbering in a variety of formats. The ZIP file contains both the template itself and a self extracting archive file which will attempt to load the template in the default Word Startup folder.

The add-in stores the user's preferences and the current value of the incrementing number in the document variables in the template. This allows the template numbering to be shared between users who have access to the template.

The add-in employs a text content control and a pair of bookmarks to display the number and any associated text in the document. Whenever the process is run, it first checks to establish if that content control is positioned anywhere in the document and if not it will present the following dialog which offers to place the content control and its associated bookmarks at the cursor position.

When first run, the add-in will display a disclaimer text. This will display each time the function is run, until the check box at the bottom of the main dialog is unchecked.

When the dialog is closed the following dialog is displayed.

The dialog displays the next available number (obviously 1 the first time the add-in is run).

There are text boxes to add optional common leading and trailing texts, and you can set the number of digits from the dropdown to any value between 1 and 10, which should be enough to cover most circumstances.

The changes that you add are displayed in orange coloured type across the bottom of the frame that fills the lower part of he userform as you make them, so you can see how the number is going to appear in the document before you enter it.

On the left of the dialog are three radio buttons. These allow the user to insert the number at the current cursor position; to update the number in a document to which a number has already been applied; and to print a batch of incrementing numbered documents.

The number and associated texts are stored in the add-in template for ease of recall for the next numbered document.

The number is inserted in the content control and any associated leading and trailing texts are inserted in the bookmarks placed wither side of the content control; unless the update option is selected, when the number is replaced.

The font and paragraph attributes of the inserted number are dependent upon the format at the cursor position. The add-in does not format the inserted content control and associated texts.

Note: The add-in stores the last number, used which it increments when the function is run. It does not check the number actually last used in a particular document.

When updating old documents, make sure you note the existing number and the next number from the dialog, before making any changes that would affect the sequence.

 

The 'Update Number' option is only available when there is already an appropriate content control, with a number, in the current document.

The variables may be reset to defaults from the ribbon. The variable that holds the next available number however is not reset. This number may be reset either from the button on the ribbon or the button beneath the number in the main dialog. In either case the following dialog is displayed:

Only numbers are accepted in this dialog. Insert anything other than a number and a warning message is displayed and the original number is restored. Enter a 0 in the dialog and it will be changed to 1.

'Print Document' option

Some users may wish to print a batch of otherwise identical numbered documents. The 'Print Document' option allows this.

It works on entirely similar principles to the process to insert a single number, except that it sends the requested number of numbered copies to the printer. There is an option to store the last used number of the batch so the sequence may be continued.

   Click here to download the add-in

 

Inserting a number from an ini file

The method below was inspired by code developed by fellow MVP Doug Robbins and reproduced in a web page he developed for the now defunct MVP FAQ site. The number sequence is stored in an editable text file called Settings.ini which is stored here in the Word startup folder and displayed by a docvariable field inserted in the header by the macro.

For a multi-user system any folder to which all users have read/write access can be used.

Instead of using the Options.DefaultFilePath() you can enter the full path to the file.

The same Settings.ini file can be used to store number sequences for other macros as required.

The macros should be stored in a module in the document template - not in the normal template!

The macro code below will insert an incrementing number and some fixed text at the right side of the document header thus:

Code to change the number and to recycle the number when a document is closed without saving is included.

Note You will find another example of this technique on the vba macro examples page.

 

Option Explicit

Private CertNo As String
Private oHeader As Range
Private oHead As HeaderFooter
Private oField As field
Private sName As String, sPath As String
Private oVars As Variables
Private bProtected As Boolean
Const sFormat As String = "000#"
Const sText As String = "Certificate No. "
Const sPassword As String = "" 'The password to edit the form

Sub AutoNew() 'Add a number when a new document is created
'If the document is a protected form, unprotect it
If ActiveDocument.ProtectionType <> wdNoProtection Then
bProtected = True
ActiveDocument.Unprotect Password:=sPassword
End If
sPath = Options.DefaultFilePath(wdStartupPath) & "\Settings.ini"
Set oVars = ActiveDocument.Variables
CertNo = System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber")
If CertNo = "" Then 'The settings file entry does not exist
CertNo = 1 'So set the start number
Else 'The settings file entry does exist so increment it by 1
CertNo = CertNo + 1
End If
'Define two document variables of the same initial value
oVars("varCertNo").Value = CertNo
oVars("varSaveNo").Value = CertNo
'The number is to be placed in the header on the first page
'so establish which type of header that is.
If ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Exists Then
Set oHeader = ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range
Else
Set oHeader = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range
End If
'Setup the format of the header.
'Note that this will remove any existing header content
'So ensure you include anything else required in the header
'Here we have some fixed text, and assorted formatting that should
'be self evident.
With oHeader
.Text = sText
.Font.name = "Times New Roman"
.Font.Bold = True
.Font.Italic = False
.Font.Size = "16"
.ParagraphFormat.Alignment = wdAlignParagraphRight
.Collapse wdCollapseEnd
'Insert a docvariable field to display the formatted number
.Fields.Add oHeader, wdFieldDocVariable, """varCertNo"" \# " & sFormat, False
.Fields.Update
End With
'Save the number in the INI file
System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber") = CertNo
'If the document was unprotected initially,
' reprotect the document for forms.
If bProtected = True Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:=sPassword
End If
lbl_Exit:
Exit Sub
End Sub

Sub SaveCertificateAs()
sPath = Options.DefaultFilePath(wdStartupPath) & "\Settings.ini"
Set oVars = ActiveDocument.Variables
CertNo = System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber")
If Not ActiveDocument.Path = "" Then
'The document has previously been saved, so resave
ActiveDocument.Save
Else 'The document has not been previously saved, so save it
'In the current document folder with a name including the number
With Dialogs(wdDialogFileSaveAs)
.name = "Certificate " & Format(oVars("varSaveNo"), sFormat)
.Show
End With
End If
'Close the document
ActiveDocument.Close
lbl_Exit:
Exit Sub
End Sub

Sub AutoClose() 'Recycles number if the document was unsaved.'
sPath = Options.DefaultFilePath(wdStartupPath) & "\Settings.ini"
Set oVars = ActiveDocument.Variables
CertNo = System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber")
'Check if the document is unsaved
If ActiveDocument.name Like "Document#*" Then
'Offer the user the opportunity to save
If MsgBox("This Certificate has not been saved." & vbCr & "Do you want to save before closing?", vbYesNo, "MacroSettings") = vbYes Then
With Dialogs(wdDialogFileSaveAs)
.name = "Certificate " & Format(oVars("varSaveNo"), sFormat)
.Show
End With
Else ' Close the document and recycle the number
If CertNo = oVars("varCertNo") Then
MsgBox "The current number " & "will be recycled.", vbOKCancel, "Recycle"
System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber") = CertNo - 1
End If
End If
ActiveDocument.Saved = True
End If
lbl_Exit:
Exit Sub
End Sub

Sub ResetStartNo()
'Reset the number shown in the current document and record 'it as the last used number
sPath = Options.DefaultFilePath(wdStartupPath) & "\Settings.ini"
Set oVars = ActiveDocument.Variables
'Get the current number from the settings file
CertNo = System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber")
'Get the user to input the new number
CertNo = InputBox("Reset certificate number?", "Reset", CertNo)
'Record the input number as a docvariable
oVars("varSaveNo").Value = CertNo
'Save the input number
System.PrivateProfileString(sPath, "MacroSettings", "CertificateNumber") = CertNo
'Set the new number as the displayed variable content
oVars("varCertNo").Value = CertNo
'Update the header
For Each oHead In ActiveDocument.Sections(1).Headers
If oHead.Exists Then
For Each oField In oHead.Range.Fields
oField.Update
Next oField
End If
Next oHead
lbl_Exit:
Exit Sub
End Sub

 

Increment a number in a document each time the document is opened

The previous macro is useful in a template for creating invoices, orders, certificates etc, but you may want to increment a number in a document each time it is opened. One way to do this is to increment a document variable each time the document is opened and display that number in a docvariable field.

Insert the following DOCVARIABLE field in the document where you want the number to appear:
{ DOCVARIABLE VarNum \# "000000" }

Use CTRL+F9 to insert the brackets { } when copying the field code.

The switch \# "000000" is optional and used here to format the number to six digits, with leading zeroes for numbers with fewer digits. (See also http://www.gmayor.com/formatting_word_fields.htm)

Add the following macro to the document (not the Normal template) and save the document as macro enabled (DOTM) format

Sub AutoOpen()
Dim oVars As Variables
Dim bVar As Boolean
Dim lngCount As Long
Set oVars = ActiveDocument.Variables
For Each oVar In ActiveDocument.Variables
If oVar.Name = "varNum" Then
bVar = True
lngCount = oVar.Value + 1
Exit For
End If
Next oVar
If Not bVar Then lngCount = 1
oVars("varNum").Value = lngCount
UpdateAllFields
ActiveDocument.Save
lbl_Exit:
Exit Sub
End Sub

The macro calls a second macro to update the field to show the revised value. This macro (shown below) goes in the same module as the above macro

Private Sub UpdateAllFields()
Dim oStory As Range
For Each oStory In ActiveDocument.StoryRanges
oStory.Fields.Update
If oStory.StoryType <> wdMainTextStory Then
While Not (oStory.NextStoryRange Is Nothing)
Set oStory = oStory.NextStoryRange
oStory.Fields.Update
Wend
End If
Next oStory
Set oStory = Nothing
lbl_Exit:
Exit Sub
End Sub

Each time the document is opened, the macro runs, increments the document variable, displays and saves the change

If you need to change the number, set the value of the document variable 'varNum' as required.

A simple way to do this is to use http://www.gmayor.com/BookmarkandVariableEditor.htm

Note: If you don't know what to do with macro listings see - Installing Macros From Listings

 

 

 

Automatic Numbering

Numbering documents for certificates, invoices, order forms etc.