Search code examples
c#templatesword-automationmergefield

C# - Replace mergefield inside IfField


I use a Word document as a template as following:

Hello my name is {MERGEFIELD Name /*MERGEFORMAT}
{IF {MERGEFIELD Gender /*MERGEFORMAT} = "M" 
"Your gender is {MERGEFIELD Gender /*MERGEFORMAT}" ""}

My C# program looks like :

Microsoft.Office.Interop.Word.Document documentWord = application.Documents.Open(myWordTemplate);
//Gender and Name are dynamic fields for the example
var myDynamicFields = dbContext.MyFields.All();
foreach (Microsoft.Office.Interop.Word.Field field in documentWord.Fields)
{
    foreach (var item in myDynamicFields)
    {
          //Search for a "Name" or "Gender" field
          if (field.Code.Text.Contains(item.Key))
          {
               field.Select();
               text = item.Value + " ";
               application.Selection.TypeText(text);

               break;
          }
     }       
}

So, my problem is that my code detects 2 Mergefield only : the Name MergeField and the field if. I'd like to replace the Mergefield Gender in the field if. How can I do this?


Solution

  • The reason your code is not working is because the field code of the If field also contains the merge field. So the Select and TypeText is getting rid of the If field, with its MergeField, thus no Mergefield to find when the loop repeats.

    Better is to check the Field.Type property. I also took the liberty of optimizing your code a bit so that you don't need to actually display the field codes.

    Using a Range object, you can set the Range's TextRetrievalMode to include the field codes, so that they don't need to be displayed. My code sample sets the field's Range to another Range object, deletes the field, then writes to that Range.

    (Since I don't have access to your database info, the code below needs to be tweaked, but I'm sure that's no problem for you. I've left your code in comments, as well as your comment, so that you can orient yourself.)

    Word.Range rngDocBody = doc.Content;
    Word.Range rngField = null;
    rngDocBody.TextRetrievalMode.IncludeFieldCodes = true;
    foreach (Word.Field field in rngDocBody.Fields)
    {
            //Search for a "Name" or "Gender" field
            if (field.Type == Word.WdFieldType.wdFieldMergeField)
            {
                rngField = field.Result;
                //field.Select();
                //doc.Application.Selection.TypeText("X");
                field.Delete();
                rngField.Text = "X";
               // break;
            }
    }