none
Merge Field Collection devoid of merge fields in Header/Footer

    Question

  • If I add mail merge data fields into a header on a document and then iterate the merge field collection, the collection does not contain the merge fields I placed in the document header. Why? and where/how can I "get to them" ...

    Wednesday, June 07, 2006 6:59 PM

Answers

  • Thanks for the additional details; I can see where the problem is coming from.

    "this" in C# VSTO-.NET-speak = the VSTO document object, which corresponds in the Word object model roughly to the Document object "ActiveDocument". A Document is comprised of multiple "Stories", or StoryRanges. These include the main document body, headers and footers, footnotes and endnotes, comments, etc.

    By default, when you query the Document object, you're addressing only the main body of the document. In order to pick up other things, you have to explicitly specify the story or the range. Look up the StoryRanges collection in the Word Object Model Help files and you'll see a number of ways you can do this.

    Usually (matter of habit), I do something like this:

    Word.Section sec = this.Sections[1];
                Word.Range rng = sec.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range
    foreach (Word.Field fld in rng.Fields)
    }
       if (fld.Type == Microsoft.Office.Interop.Word.WdFieldType.wdFieldMergeField)
       {
           string dataFieldName = fld.Code.Text.Trim();
        }
    }

    Thursday, June 08, 2006 3:10 PM
    Moderator

All replies

  • You need to give us a bit more information. The code you're trying to use would help. Also

    - version of Word
    - does the document contain more than one section
    - what is the mail merge document type (letter, directory, labels...)

    Thursday, June 08, 2006 7:06 AM
    Moderator
  • You are right Cindy, sorry for the lack of information, here it is:
    Office 2003 Pro using Office 2003 PIAs.
    VS2005 C# Word Template Project
    Running on Win2k, WinXP and WinXP Tablet Ed.

    In my example, I have a blank document that I have connected to a valid Data Source. I then 'view' the header/footer band and position my cusor within that band. From the Insert Merge Field dialog, I select a merge field and insert it into the header band; I then close the band.

    Following that, I drop another merge field (or two) in the main body of the form and save the document out.

    If I have a small bit of .NET code that iterates thru the MailMerge.Fields collection, the only MailMergeField objects contained in that collection are those for the merge fields added in the main body of the document.

    Example:
    foreach (Word.MailMergeField mmf in this.MailMerge.Fields)
    }
       if (mmf.Type == Microsoft.Office.Interop.Word.WdFieldType.wdFieldMergeField)
       {
           string dataFieldName = mmf.Code.Text.Trim();
        }
    }

    The document type for the merge is defined as "Letter". I have verified that the merge works, I am unclear, however, as to why the merge fields in the header are not part of the MailMerge.Fields collection for that document.

    Thank you.

    Thursday, June 08, 2006 1:52 PM
  • Thanks for the additional details; I can see where the problem is coming from.

    "this" in C# VSTO-.NET-speak = the VSTO document object, which corresponds in the Word object model roughly to the Document object "ActiveDocument". A Document is comprised of multiple "Stories", or StoryRanges. These include the main document body, headers and footers, footnotes and endnotes, comments, etc.

    By default, when you query the Document object, you're addressing only the main body of the document. In order to pick up other things, you have to explicitly specify the story or the range. Look up the StoryRanges collection in the Word Object Model Help files and you'll see a number of ways you can do this.

    Usually (matter of habit), I do something like this:

    Word.Section sec = this.Sections[1];
                Word.Range rng = sec.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range
    foreach (Word.Field fld in rng.Fields)
    }
       if (fld.Type == Microsoft.Office.Interop.Word.WdFieldType.wdFieldMergeField)
       {
           string dataFieldName = fld.Code.Text.Trim();
        }
    }

    Thursday, June 08, 2006 3:10 PM
    Moderator
  • I had considered that using "this" meant just the ActiveDocument body and looked to see if the header/footer contained a MergeField collection, and did not see one ... and then thought, surely, if it did not include the Header/Footer merge fields, then those objects should expose MergeField collections of their own ...

    You're explanation makes sense, and now having read it, I understand that using "this.MailMerge.MergeFields" would contain only the document body's Merge Fields, but then, it is my opinion that there should be a means to "access" all MergeFields within the context of "ThisDocument", without having to jump through hoops.

    Regardless, now that you've pointed me in the proper direction, I will go hack out some code and get this puppy going.

    I am marking this as "answered"

    Thank you Cindy.
    Thursday, June 08, 2006 4:59 PM
  • You're welcome :-)

    Yes, it would be nice if one could access all items throughout the document, without having to "walk" the various stories. The UI supports this (Find functionality). MS could certainly program it in as an alternative to individual Story access. This would be a good suggestion for you to make for the VSTO program :-)

    Friday, June 09, 2006 8:13 AM
    Moderator
  •  

    Hello...When I try to access merger fields in the header of a document and try to print the document it just sits in the print queue with a status of spooling and the document does not print.  If the document has no header it prints fine.  Am I missing something, do i need to focus a certian part of the document before printing?  Here is the code below...

     

    Thanks in Advance!!

    Adam

     

    Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();

    //Opens the document in Microsoft Word

    doc = wordApp.Documents.Open(ref path, ref oMissing, ref True, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

     

    Microsoft.Office.Interop.Word.Section sec = doc.Sections[1];

    Microsoft.Office.Interop.Word.Range rng = sec.Headers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;

     

    foreach (Microsoft.Office.Interop.Word.Field myMergeField in rng.Fields)

    {

    if (myMergeField.Type == Microsoft.Office.Interop.Word.WdFieldType.wdFieldMergeField)

    {

    Microsoft.Office.Interop.Word.Range rngFieldCode = myMergeField.Code;

    String fieldText = rngFieldCode.Text;

    Int32 endMerge = fieldText.IndexOf("\\");

    Int32 fieldNameLength = fieldText.Length - endMerge;

    String fieldName = fieldText.Substring(11, endMerge - 11);

    fieldName = fieldName.Trim();

    if (fieldName == "FirstName")

    {

      myMergeField.Select();

      wordApp.Selection.TypeText("FirstName");

    }

     

    wordApp.ActiveDocument.PrintOut(ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

     

    doc.PrintOut(ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

     

     

    doc.Close(ref False, ref oMissing, ref oMissing);

    Thursday, August 23, 2007 3:48 PM