Inserting nested fields using VBA

Article contributed by Dave Rado

It is usually best to use ranges  in VBA code, and avoid using selections. However, VBA does not allow you to create nested fields on the fly using ranges.

The best workaround is to store your frequently used nested fields as AutoText entries in an Add-in. The you can insert the Autotext entry using ranges:

Sub InsertNestedPageFieldInHeader()

Dim
MyRange As Range

Set MyRange = ActiveDocument.Sections(1) _
        .Headers(wdHeaderFooterPrimary).Range
MyRange.Collapse wdCollapseEnd

Templates(Options.DefaultFilePath(wdStartupPath) & "\MainAddin.dot") _
        .AutoTextEntries("PagePlus1").Insert _
        Where:=MyRange, RichText:=True

End Sub

However, if you really need to create the field on the fly, you will have to use selections instead of ranges; for example:

Sub InsertHyperLinkFieldWithinMacroButtonField()

Application.ScreenUpdating = False
ActiveWindow.View.ShowFieldCodes = True

Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "HYPERLINK ""https://wordmvp.com/""", PreserveFormatting:=False
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend

Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, _
        PreserveFormatting:=False
Selection.InsertAfter "MacroButton ""FollowLink"""
ActiveWindow.View.ShowFieldCodes = False
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend

Selection.Fields.Update
Application.ScreenUpdating = True

End Sub

Using selections in Headers or Footers is a complete no-no. So if you need to create a nested Headers or Footer field on the fly, create the field in the main document, and cut and paste it into the Headers or Footer:

Sub InsertNestedPageFieldInHeader()

Dim MyRange As Range

Application.ScreenUpdating = False
ActiveWindow.View.ShowFieldCodes = True

'Insert dummy para at end of document
ActiveDocument.Range.InsertAfter vbCr
Set MyRange = ActiveDocument.Range
MyRange.Collapse wdCollapseEnd
MyRange.Select

'Insert nested field
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "PAGE ", PreserveFormatting:=False
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, _
        PreserveFormatting:=False
Selection.TypeText Text:="= "
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.TypeText Text:=" + 1"
Selection.MoveRight Unit:=wdCharacter, Count:=2
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Fields.Update
ActiveWindow.View.ShowFieldCodes = False

'Cut field, delete dummy para mark, and paste field into header
Selection.Cut
ActiveDocument.Paragraphs.Last.Range.Delete

Set MyRange = ActiveDocument.Sections(1) _
        .Headers(wdHeaderFooterPrimary).Range
MyRange.Collapse wdCollapseEnd
MyRange.Paste

Application.ScreenUpdating = True

End Sub