none
problem using VBA to update custom fields in Word 2010 RRS feed

  • Question

  • I have created a custom field in a Word 2010 document (ReportDate) which is static, and is repeated throughout the document in both the main body as well as multiple headers.  I'm trying to create VBA code that updates the fields in both the main body as well as the headers, and have used two different approaches.  (Both code samples were borrowed from examples posted on the Internet.)  I've created a Quick Links button and keyboard shortcut (Alt-U), but I can't resolve this issue - which needs to be resolved before I add more code.

    Code example 1 (originally for Word 2007 by Petar Miljkovic [http://development.meritsolutions.com/matters/using-fields-properties-word-2007-documents/]):

    Sub UpdateCustomProperties()
    If ActiveWindow.View.SplitSpecial = wdPaneNone Then
    ActiveWindow.ActivePane.View.Type = wdNormalView
    Else
    ActiveWindow.View.Type = wdNormalView
    End If
    Selection.WholeStory
    Selection.Fields.Update
    If ActiveWindow.View.SplitSpecial = wdPaneNone Then
    ActiveWindow.ActivePane.View.Type = wdPrintView
    Else
    ActiveWindow.View.Type = wdPrintView
    End If
    End Sub

    Code example 2 (by Shauna Kelly) [http://msdn.microsoft.com/en-us/library/ff604039]:

    Sub UpdateCustomProperties()
    Dim doc As Document
    Set doc = ActiveDocument

    Dim sRange As Range
    Dim sField As Field

    For Each sRange In doc.StoryRanges
    For Each sField In sRange.Fields
    sField.Update
    Next sField
    Next sRange

    End Sub

    I prefer Shauna's code (sorry, Petar.)  While both routines will update the ReportDate fields within the document body, they won't update theReportDate fields within the headers.  What am I missing?



    Thursday, August 4, 2011 10:48 PM

Answers

  • Tony,

    I don't have the sample document but I thought my:

    Dim lngJunk As Long
    lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType

    would have handled the situation.  Are you saying that should be:

    Dim oRngJunk As Word.Range
    Set oRngJunk = ActiveDocument.Sections(1).Headers(1).Range  ??

     

     


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm
    Saturday, August 6, 2011 6:59 PM
  • Sorry, Greg. I hadn't looked at your code! I had just registered that it was making the point about Shapes and didn't spot that the necessary extra line had slipped in there unannounced! The explicit reference to the Header Range for potentially non-existent Headers is what is required - and your version is as good as mine.
     
    I knew some things in this area were a mess, but I hadn't realised quite how many pitfalls there were in this type of process; Jay (Freedman) has pointed out that the issue causng the problem in this case is mentioned in http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm (at the end of "Step 1")
     

    Enjoy,
    Tony
    www.WordArticles.com
    Sunday, August 7, 2011 8:24 AM

All replies

  • Sub UpdateCustomProperties()
      Dim doc As Document
      Dim sRange As Range
      Dim sField As Field
      Set doc = ActiveDocument
      For Each sRange In doc.StoryRanges
        For Each sField In sRange.Fields
          sField.Update
        Next sField
        Do While Not sRange.NextStoryRange Is Nothing
          Set sRange = sRange.NextStoryRange
          For Each sField In sRange.Fields
            sField.Update
          Next sField
        Loop
      Next sRange
    End Sub
    

    Does the above version work better?
    Regards, Hans Vogelaar
    Thursday, August 4, 2011 11:37 PM
  • Hello,

    It seems there's a problem in Word 2010, see Fields.Update is called twice for primary header/footer fields in VBA macros on Word 2010.


    Regards from Belarus (GMT + 2),

    Andrei Smolin
    Add-in Express Team Leader
    Friday, August 5, 2011 6:55 AM
  • Multiple updates would work, even if inefficiently. The supposed problem here is that a 'static' field is not being updated. The code in use shoud update and I would be interested in a few more details of exactly what  the problem is.
     

    Enjoy,
    Tony
    www.WordArticles.com
    Friday, August 5, 2011 8:09 AM
  • Hans -

    Thanks for the effort - but no joy.  Your code updates the custom fields that are in the document body, but still does not update any of the occurrences of the custom field (ReportDate) in the document headers.  I really suspect it's a problem with Word itself, as Andrei Smolin and Tony Jollans have suggested.  I'd be happy to send a copy of the document for you to play with - but our corporate policies don't permit me to simply post the document to everyone.  I found Tony's email through his web site, and will send him an abbreviated version of the document and the .dotm file that contains the code - assuming he wants to see it all.  I will email him shortly to "discuss."

    The document is an engineering report with report cover, cover letter, TOC, report body, and appendices.  Each section (except the appendices) has its own header (primarily due to page numbering), and the document also has footnotes in the report body.  When I refer to the field as 'static' I mean that it is text that the user specifies and is not automatically updated by Word.  While the field I am currently working with (ReportDate) is a date, the custom field is defined as 'text' type.  The text could be almost anything, although clearly my intent is for this field to contain a date.  (Once I resolve this problem, I plan to extend this code to 4 or 5 other custom fields and create an input dialog.)

    Friday, August 5, 2011 3:31 PM
  • I really like mapping content controls to CustomXMLParts. You can map multiple controls to any one CustomXMLPart node. If you update mapped CC text, you update the node, and you update all the other CCs that are mapped to the same node. Once you've done the mapping, you don't even need your VBA code again. You can have mapped CCs in autotext, too. 
    
    Content Controls trigger document events. You could give your "static" control a tag like "super"<tag>, and give all the reference controls a name like "baby"<tag>. When you leave the CC, you can get the tag of that CC (via the event procedure)-- if it's prefixed "baby," don't do anything. If it's prefixed "super," then update all the CCs with the "baby" prefix and the same <tag>.
    



    I iterate through the sections, and reference each section's footers property. 
    
    For each targetCC in Activedocument.sections(x).Footers(wdheaderfooterprimary).Range.ContentControls

    Friday, August 5, 2011 7:42 PM
  • If the field in the header is in a shape then the codes used previously don't work.  Try:

     

    Public Sub UpdateAllFields()
    Dim rngStory As Word.Range
    Dim lngJunk As Long
    Dim oShp As Shape
    lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType
    For Each rngStory In ActiveDocument.StoryRanges
      'Iterate through all linked stories
      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
            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
    End Sub


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm
    Friday, August 5, 2011 8:33 PM
  • I have replied directly to John, but for the benefit of all ...
     
    John's document did not have any Headers in Section 1, and this caused the various Header Stories not to exist, and not to be in the Collection that was being walked. There is no fault and no blame to lay (except, perhaps, at Microsoft's door) - this is something that can happen.
     
    Hans' code is more complete that the other offerings, although Greg's point about Shapes is important in the general case. But, in this case, and the general case, none of them are guaranteed to work unless the Header Stories can be included.
     
    From very limited testing it appears that explicit reference to the Range of the non-existant Headers is sufficient to whip Word into line and adding a line like this at the start of any of the procedures appears to make them work:
     
        Set A_variable = ActiveDocument.Sections(1).Headers(1).Range
     
     

    Enjoy,
    Tony
    www.WordArticles.com
    Saturday, August 6, 2011 4:00 PM
  • Tony,

    I don't have the sample document but I thought my:

    Dim lngJunk As Long
    lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType

    would have handled the situation.  Are you saying that should be:

    Dim oRngJunk As Word.Range
    Set oRngJunk = ActiveDocument.Sections(1).Headers(1).Range  ??

     

     


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm
    Saturday, August 6, 2011 6:59 PM
  • Sorry, Greg. I hadn't looked at your code! I had just registered that it was making the point about Shapes and didn't spot that the necessary extra line had slipped in there unannounced! The explicit reference to the Header Range for potentially non-existent Headers is what is required - and your version is as good as mine.
     
    I knew some things in this area were a mess, but I hadn't realised quite how many pitfalls there were in this type of process; Jay (Freedman) has pointed out that the issue causng the problem in this case is mentioned in http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm (at the end of "Step 1")
     

    Enjoy,
    Tony
    www.WordArticles.com
    Sunday, August 7, 2011 8:24 AM