Hi, I am trying to find every occurence of a merge field in a document and replace it with a value. The code I am using is
Document doc = new Document(“sample.doc”);
DocumentBuilder builder = new DocumentBuilder(doc);
while(builder.moveToMergeField(fieldName)) {
// replace value
}
The builder.moveToMergeField(fieldName) method is not returning ‘false’ and the code is getting stuck in the while loop even though the field only occurs once.
I am using the Java version of the software. Please advise.
Thanks,
Ali
In my tests everything works ok. Please make sure you are not moving the DcoumentBuilder or modifying the document node structure inside the loop. If it is not the case, then please attach your sample document, so that we could reproduce the error.
Best regards,
Hi Vladimir,
I am actually replacing each merge field with more than one other merge field. The example below shows the field being enclosed by 2 other merge fields. But in some cases I will have to replace a merge field with a block of data that will contain text and other mergefields.
while(builder.moveToMergeField(fieldName)) {
insertMergeField(“filterBegin”, “filterBegin”); // Wrap with a filter
insertMergeField(fieldName, fieldName);
insertMergeField(“filterEnd”, “filterEnd”); // Close filter
}
public void insertMergeField(String codeName, String value) throws Exception{
String fieldCode = new StringBuffer(“MERGEFIELD “).append(codeName).append(” \* MERGEFORMAT”).toString();
String fieldValue = new StringBuffer("«").append(value).append("»").toString();
builder.insertField(fieldCode, fieldValue);
}
Thanks,
Ali
Please note that moveToMergeField, as well other DocumentBuilder.moveToXXX methods, is not forward-only. It keeps working while there is at least one merge field with the specified name in the document. This method effectively removes the merge field that it moves to. But as you are recreating this field inside the loop, it means that the loop will never end.
Another approach can help you in this matter - using MailMerge with MergeField event. Here is an example in c#:
public void TestLoopingOverMergeFields()
{
Document doc = TestUtil.Open(@"Doc1.doc");
// add a hadler to MergeField event
doc.MailMerge.MergeField += new MergeFieldEventHandler(MergeFieldHandler2);
doc.MailMerge.Execute(new string[] {"Name"}, new string[] {""});
TestUtil.SaveShow(doc, "Doc1 Out.doc");
}
private void MergeFieldHandler2(object sender, MergeFieldEventArgs e)
{
if (e.FieldValue != null)
{
DocumentBuilder builder = new DocumentBuilder(e.Document);
builder.MoveToMergeField(e.DocumentFieldName);
InsertMergeField(builder, "filterBegin");
InsertMergeField(builder, e.DocumentFieldName);
InsertMergeField(builder, "filterEnd");
}
}
private void InsertMergeField(DocumentBuilder builder, string fieldName)
{
builder.InsertField(string.Format("MERGEFIELD {0} \\* MERGEFORMAT", fieldName), string.Format("«{0}»", fieldName));
}
I have a question before I try this out. Will it work if there is more than one merge field with the same name? Since the event handler is still using MoveToMergeField it seems that we will keep moving to the first occurrence of the field.
Thanks,
Ali
Yes, you are right. MoveToMergeField is inappropriate to use in MergeField event handler. Fortunately, we have a special method made specially for moving to the field that is currently processed in MergeField event. That is DocumentBuilder.MoveToField method. Just substitute
builder.MoveToMergeField(e.DocumentFieldName);
with
builder.MoveToField(e.Field, false);
and everything will work fine after this even for the case when there are multiple occurences of merge fields with the same name in the document.
Best regards,