View Full Version : Updating all field codes in doc with >1 section break
bstephens
07-19-2010, 07:51 PM
Hi, I am having a difficult time trying to write a macro that efficiently updates all the fields in a document (both in the body of the document and in the header and footer) in a document which has multiple section breaks.
I don't want to use the print-preview trick because I don't want my users losing their current editing position on the document.
I tried various code on the internet, and it worked except that it only worked as to the first section break.
I came up with the following code that seems to update all the field codes in the header and footer in multiple section breaks, but it doesn't seem to work in the body of the document.
Does anyone know how to edit this code so that, in addition to updating the field codes in the header and footer in each section break of a document, it will also do any field codes in the body?
'Updates All Fields in a Document
Sub UpdateAllFields()
Dim section As section
Dim myRange As Range
Dim myHF As HeaderFooter
'Loop through the header/footer for each section to update the header/footer of sections after section 1.
For Each section In ActiveDocument.Sections
    For Each myHF In section.Headers
    Set myRange = myHF.Range
        For Each aField In myRange.Fields
                aField.Update
        Next aField
    Next myHF
    For Each myHF In section.Footers
        Set myRange = myHF.Range
        For Each aField In myRange.Fields
                aField.Update
        Next aField
    Next myHF
Next section
End Sub 
Also, is this code efficient?  I noted that where there is a table of contents it seems like the saves are really slowed down.
Appreciate any input on achieving updates in the body, or if there is a way to make this code more efficient.
Best, 
-Brian
Tinbendr
07-19-2010, 08:09 PM
Try using StoryRanges
Sub LoopStoryRanges()
'http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm
Dim rngStory As Range
  Dim lngJunk As Long
  'Fix the skipped blank Header/Footer problem as provided by Peter Hewett
  lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType
  'Iterate through all story types in the current document
  For Each rngStory In ActiveDocument.StoryRanges
    'Iterate through all linked stories
    Do
      With rngStory
        .Fields.Update
      End With
      'Get next linked story (if any)
      Set rngStory = rngStory.NextStoryRange
    Loop Until rngStory Is Nothing
  Next
End Sub
bstephens
07-19-2010, 08:26 PM
Tinbendr, I tried that code, and it worked for a filename field code in the header/footer in a document with two sections (updated in Section 1 and in Section 2), but I couldn't get it to update a filename field code in the body (field code did NOT update in Section 1 or Section 2 of the body).
What could I be missing here?  Anyone else able to verify that Tinbendr's code works as described in my original post?
Tinbendr
07-20-2010, 05:13 AM
This article (http://www.vbaexpress.com/kb/getarticle.php?kb_id=459) is in the KB entries.  Other messages refering to this article seem to indicate that it worked.
bstephens
07-20-2010, 10:28 AM
Thanks for the input tinbendr, I tried the following code, and it updates the header/footer in section 1 (but not any subsequent sections), it also updates the body in section 1 and any subsequent sections.  
Anyone know how to rewrite it so it updates the header/footer in section 1 and any subsequent sections and also the body in section 1 and any subsequent sections?
 
Here is the code as referenced by tinbendr:
Option Explicit 
 
 'This one updates all the fields in the document:
Sub UpdateALL() 
    Dim oStory As Object 
    Dim oToc As Object 
     
     'exit if no document is open
    If Documents.Count = 0 Then Exit Sub 
    Application.ScreenUpdating = False 
     
    For Each oStory In ActiveDocument.StoryRanges 
        oStory.Fields.Update 'update fields in all stories
    Next oStory 
     
    For Each oToc In ActiveDocument.TablesOfContents 
        oToc.Update 'update TOC's
    Next oToc 
     
    Application.ScreenUpdating = True 
End Sub
bstephens
07-20-2010, 10:31 AM
OK, so I came up with the following two macros that, when combined, accomplish what I was after:
'Updates All Fields in multiple sections of a Document
Sub UpdateAllFields()
UpdateBodyFields
Dim section As section
Dim myRange As Range
Dim myHF As HeaderFooter
'exit if no document is open
If Documents.Count = 0 Then Exit Sub
Application.ScreenUpdating = False
'Loop through the header/footer for each section to update the header/footer of sections after section 1.
For Each section In ActiveDocument.Sections
    For Each myHF In section.Headers
    Set myRange = myHF.Range
        For Each aField In myRange.Fields
                aField.Update
        Next aField
    Next myHF
    For Each myHF In section.Footers
        Set myRange = myHF.Range
        For Each aField In myRange.Fields
                aField.Update
        Next aField
    Next myHF
Next section
End Sub
'Updates Fields in the body of the document
Sub UpdateBodyFields()
    Dim oStory As Object
    Dim oToc As Object
     
     'exit if no document is open
    If Documents.Count = 0 Then Exit Sub
    Application.ScreenUpdating = False
     
    For Each oStory In ActiveDocument.StoryRanges
        oStory.Fields.Update 'update fields in all stories
    Next oStory
     
    For Each oToc In ActiveDocument.TablesOfContents
        oToc.Update 'update TOC's
    Next oToc
     
    Application.ScreenUpdating = True
End Sub 
I have linked the two above procedures to the "AutoOpen" procedure as follows:
Sub AutoOpen()
UpdateAllFields
End Sub 
and to re-purposed "Save" and "SaveAs" commands as follows:
'REPURPOSED SAVE COMMAND - Automatically updates the field upon a file SAVE event
Sub FileSave()
    ActiveDocument.Save
    UpdateAllFields
End Sub
'Callback for FileSave onAction
Sub rxFileSave_repurpose(control As IRibbonControl, ByRef cancelDefault)
    Call FileSave
End Sub
'REPURPOSED SAVEAS COMMAND - Automatically updates the field upon a file SAVEAS event
Sub FileSaveAs()
    Application.Dialogs(wdDialogFileSaveAs).Show
    UpdateAllFields
End Sub
'Callback for FileSaveAs onAction
Sub rxFileSaveAs_repurpose(control As IRibbonControl, ByRef cancelDefault)
    Call FileSaveAs
End Sub 
This seems to accomplish my objective of always having fields (in multiple sections, and in header/footer and body) automatically updated for users in the event they (1) save the file with a new name in word, or (2) open a file after renaming it in windows explorer.
I wish I could find a more efficient way, but my skills are pretty basic.  Would appreciate any input on making this more efficient.
 
Best,
Brian
fumei
07-21-2010, 10:49 AM
I am a bit confused with the reported difficulties.  The basic field updating should not be affected by Sections at all.  In fact, I can not duplicate this.  In any case, some suggestions:
        For Each myHF In section.Headers 
            Set myRange = myHF.Range 
             
            For Each aField In myRange.Fields 
                aField.Update 
            Next aField 
             
        Next myHF 
can be written as:
        For Each myHF In ActiveDocument.Sections.Headers 
            For Each aField In myHF.Range.Fields 
                aField.Update 
            Next aField      
        Next myHF 
There is no need to set a range object.
I would be careful about using syntax like:
    Dim section As section 
It is never a good idea to name a variable the same as a reserved word.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.