|
|
The information in this website is provided without risk or
obligation and free of charge. However, if you have benefitted
from my efforts here and would like to make a contribution to
help me continue and maintain this work then any donation will
be greatly appreciated. Please click the adjacent button to
access PayPal. Thank you.
|
|
I love Word fields. They are a semi-advanced
Word feature and with the exception of VBA, I think that they are the most powerful
and useful feature in the application.
But this Microsoft Word Help & Tips page isn't about
fields. It is about macros designed for working with
the field collection (e.g. deleting fields, updating fields, etc.). I also
wanted to use this page to post what I consider a brilliant method for creating
nested fields using VBA as shown to me by a regular Word newsgroup contributor,
Dave Lett. |
|
Deleting fields.
1. There is no "pure" VBA
equivalent of the User Interface Edit>Replace method for globallly deleting
all fields througout a document. With VBA you can accomplish the same
objective, but you must cycle through each of the various StoryRanges of the
document (e.g., main text story, first page header story, primary header
story, etc.). Given that handicap, either of the following two macros can be used to
delete all of the fields throughout a document: |
|
Sub DeleteAllFields1()
Dim pRange As Word.Range
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
ActiveWindow.View.ShowFieldCodes = True
For Each pRange In ActiveDocument.StoryRanges
Do
With pRange.Find
.Text = "^d"
.Replacement.Text = ""
.Execute
Replace:=wdReplaceAll
End With
Set pRange = pRange.NextStoryRange
Loop Until pRange Is Nothing
Next
ActiveWindow.View.ShowFieldCodes = False
End Sub Sub DeleteAllFields2()
Dim pRange As Word.Range
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each pRange In ActiveDocument.StoryRanges
Do
With pRange.Fields
While .Count
> 0
.Item(1).Delete
Wend
End With
Set pRange = pRange.NextStoryRange
Loop Until pRange Is Nothing
Next
End Sub |
|
2. Let's say that you only want to delete a particular type of
field. Again, VBA can accomplish the same objective as the Edit>Replace dialog,
but it must slog its way through every storyrange (it is a pretty fast
slog). For example,
let's delete all {Page} fields: |
Sub DeleteSpecificFields()
Dim pRange As Word.Range
Dim oFld As Word.Field
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each pRange In ActiveDocument.StoryRanges
Do
For Each oFld In pRange.Fields
Select Case oFld.Type
Case wdFieldPage
oFld.Delete
Case Else
'Do nothing
End Select
Next
Set pRange = pRange.NextStoryRange
Loop Until pRange Is Nothing
Next
End Sub |
|
3. Now let's say that you want to delete a particular type of field
in the footers only. For this situation, the
Edit>Replace dialog begins to fall short and you can achieve better
results
using VBA. For example, we want to deleted { Author } fields from
even page footers only. |
|
Sub
DeleteSpecificFieldsInSpecifStoryRange()
Dim pRange As Word.Range
Dim oFld As Field
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each pRange In ActiveDocument.StoryRanges
Do
Select Case pRange.StoryType
Case wdEvenPagesFooterStory
For Each oFld
In pRange.Fields
Select Case oFld.Type
Case wdFieldAuthor
oFld.Delete
Case Else
'Do nothing
End Select
Next
Case Else
'Do Nothing
End Select
Set pRange = pRange.NextStoryRange
Loop Until pRange is Nothing
Next
End Sub |
Updating (also Unlinking,
Locking, or Unlocking) fields in the field collection.
1.
With minor modification to the fields provided above, you can update all or any specified fields with a macro. The
macro below can be used to update all fields. |
Sub myUpdateFields()
Dim rngStory As Word.Range
Dim oShp As Word.Shape
For Each rngStory In ActiveDocument.StoryRanges
Do
On Error Resume Next
rngStory.Fields.Update
Select Case rngStory.StoryType
Case 6, 7, 8,
9, 10, 11
If rngStory.ShapeRange.Count > 0 Then
For Each oShp In rngStory.ShapeRange
If oShp.TextFrame.HasText Then
oShp.TextFrame.TextRange.Fields.Update
End If
Next oShp
End If
Case Else
'Do Nothing
End Select
On Error GoTo 0
'Get next linked story (if any)
Set rngStory =
rngStory.NextStoryRange
Loop Until rngStory Is Nothing
Next rngStory
End Sub
Note: I have assigned this
macro to the F9 function key. Anytime I want to udate all fields I
simply press F9. |
|
2. The principle command in the above code is "pRange.Fields.Update." By
simply changing this line, you can unlink, lock or unlock all fields.
For example, substituting "pRange.Fields.Update" with the following line
will unlink all the fields in a document:
pRange.Fields.Unlink
3. To go a little deeper, lets say that we only want to unlink certain
DOCPROPERTY fields that use a uniquen DOCPROPERTY identifier.
For example, we have fields like {DOCPROPERTY Title}, {DOCPROPERTY Author},
etc. dispersed throughout a document and we only want to unlink all of the {DOCPROPERTY
Title} field. To do this we have to look at the field code itself.
Like this:
Sub UnlinkSpecificFields()
Dim pRange As Word.Range
Dim oFld As Word.Field
Dim iLink As Long
iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each pRange In ActiveDocument.StoryRanges
Do
For Each oFld In pRange.Fields
Select Case
oFld.Type
Case wdFieldDocProperty
If InStr(oFld.Code.Text, "Title") Then
oFld.Unlink
End If
Case Else
'Do nothing
End Select
Next
Set pRange = pRange.NextStoryRange
Loop Until pRange Is Nothing
Next
End Sub |
Finally, I wanted to use this page to post what I consider
a crown jewel of VBA code for inserting nested fields in a document.
For this example the objective is to create a nested conditional field to display the page
number on all pages excluding the first page (i.e., { IF { PAGE } =
"1"""{ PAGE}}) |
Public Sub ConstructFieldsWithVBA2()
Dim oRng As Range
Dim oFooterRng1 As Range
Dim oFooterRng2 As Range
Set oRng = ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary).Range
With oRng
.Text = "IF PAGE = ""1""""""PAGE"
Set oFooterRng1 = .Duplicate
Set oFooterRng2 = .Duplicate
End With
'Insert the field code around the complete expression
fInsertFields2 oFooterRng1, "IF PAGE = ""1""""""PAGE"
'Insert the field code around the Page expressions
fInsertFields2 oFooterRng2, "PAGE"
oRng.Fields.Update
ActiveWindow.View.ShowFieldCodes = False
End Sub
Public Sub fInsertFields2(oRng As Range, Optional sText As String)
With oRng
'Find the expression and add a
field around it
With .Find
.Text = sText
.MatchCase = True
While .Execute
oRng.Fields.Add oRng, wdFieldEmpty, , False
oRng.Collapse
wdCollapseEnd
Wend
End With
End With
End Sub |
|
These are just a few examples of using macros to work with Word field
collection. I hope you find them useful. |
|
Need help applying macros? See fellow MVP Graham
Mayor's
Guide for
Installing Macros |
|
|
Looking for something else?
|
|
|
|