We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

MailMerge - Skip a Merge Field that shouldn't be merged

Hello,
Our software allows a client to choose how they want to map the merge fields found in their document to the data fields that we provide. They have the option of leaving one of their fields unmapped and we would like to leave it untouched in the merged document in case that they need it for Mail Merging outside of our software.

I have implemented the latest mail merging process described in release 9.2 because the some of the data that can be merged are tables of data. I have followed your documentation: “Insert a Document into another Document” in order to insert a table of data into my merged document

I have found that the method implementing the IFieldMergingCallback (MailMergeHandler) is called for each MergeField found in the document regardless of the String() of MergeField names that I pass in.
Here’s part of my code to help with my explanation. Attached is a sample template I am using. It contains 3 Word Merge Fields: FirstName, LastName & UnknownTag.

When I run the following code it will replace FirstName with “George”, LastName with “Washington” and UnknownTag with “”.

I want to skip the UnknownTag altogether, no replacing, no erasing. Setting the FieldMergingArgs to Nothing or “” does not accomplish this.

Snippet

 Dim theFields As String() = New String() {“FirstName”, “LastName”}
Dim theFieldValues As String() = New String() {“George”, “Washington”}
theDocument.MailMerge.FieldMergingCallback = New MailMergeHandler()
theDocument.MailMerge.Execute(theFields, theFieldValues)

Hi Aaron,

Thanks for the inquiry. Yes you are right, the FieldMerging method is being called for every field, not just for the ones being merged. You can ensure that any field that is not actually being merged is skipped by checking if FieldMergingArgs.FieldValue is equal to null in the FieldMerging method.

If you are still having troubles could you please post your MailMergeHandler class here and we will take a closer look for you.

Thanks,

Hi Adam,
Thank you for your response. I am able to skip the insertion my “document” whenever e.FieldValue is Nothing, but it doesn’t solve my problem because it still replaces my Merge Field in the document with Nothing. I really need a way to leave the Merge Field in question untouched.
Here is the code I am using for the IFieldMergingCallback.

Public Class MailMergeHandler
Implements IFieldMergingCallback

Private Sub IFieldMergingCallback_FieldMerging(ByVal e As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
Dim builder As New DocumentBuilder(e.Document)
builder.MoveToMergeField(e.DocumentFieldName)
Dim para As Paragraph = builder.CurrentParagraph

'Create a generic “document” just for this example
Dim subDoc As New Document()
Dim p As Paragraph = New Paragraph(subDoc)
p.Runs.Add(New Run(subDoc, e.FieldValue))
subDoc.FirstSection.Body.Paragraphs.Add§

If e.FieldValue IsNot Nothing Then
InsertDocument(para, subDoc)
If (Not para.HasChildNodes) OrElse String.IsNullOrEmpty(para.ToTxt.Trim()) Then para.Remove()
End If
e.Text = Nothing
End Sub

Private Sub ImageFieldMerging(ByVal args As ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging
’ Do nothing.
End Sub
End Class

Hi Aaron,

Thanks for posting your code. Taking a quick look, maybe try moving e.Text = Nothing inside the If e.FieldValue IsNot Nothing if statment code. This should then leave any field completely untouched if there is no field value to insert thus should not change it in anyway.

I haven't tested this though, if it does not work then please tell me and I will look into it further for you

Thanks,

Adam,
I double checked what you recommended just to be sure, but what I expected to happen, happened. The arg e.Text is equal to Nothing when the method is called so it really doesn’t matter where I place that statement. I could be wrong on this one, but it appears that that line of code is more for reassurance than anything else and is not needed i my code sample.

Thanks,
-Aaron

Hi Aaron,

Thanks for the additional information. I just checked, and you are right it does not make a difference. It appears that the default behaviour for the DocumentBuilder to move to a mergefield involves it removing the field as well. This is why even the unmerged field is being removed in the code.

To fix this you can either check if e.FieldValue is not null before calling builder.MoveToMergeField(e.DocumentFieldName)

or you can specify the DocumentBuilder not to remove the field by using this overload of the MoveToMergeField method: builder.MoveToMergeField(e.DocumentFieldName, False, False)

and then overwrite the field when you insert your custom content. Most likely the first option is the easiest.

If you have any further questions please feel free to ask.

Thanks,

Adam,
While I’m satisfied with the solution for the immediate problem, I still need to differentiate between a field I specified to have
replaced with Nothing/Blank and remove the field as compared to a field
that I did not specify and want left alone.
Here’s an updated sample of what I mean. See the attached template.
In this case I do want to replace “UnknownTag” with Nothing and remove the Merge Field tag.
I do not want to touch “UnknownTag2”. With the method of checking e.FieldValue below I skip over both UnknownTags and both are left in the document.

 Dim theFields As String() = New String() {“FirstName”, “LastName”, “UnknownTag”}
Dim theFieldValues As String() = New String() {“George”, “Washington”, Nothing}
theDocument.MailMerge.FieldMergingCallback = New MailMergeHandler()
theDocument.MailMerge.Execute(theFields, theFieldValues)


    Private Sub IFieldMergingCallback_FieldMerging(ByVal e As FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
Dim builder As New DocumentBuilder(e.Document)
If e.FieldValue IsNot Nothing Then
builder.MoveToMergeField(e.DocumentFieldName)
Dim para As Paragraph = builder.CurrentParagraph

'Create a generic “document” just for this example
Dim subDoc As New Document()
Dim p As Paragraph = New Paragraph(subDoc)
p.Runs.Add(New Run(subDoc, String.Format("|{0}|", e.FieldValue)))
subDoc.FirstSection.Body.Paragraphs.Add§


InsertDocument(para, subDoc)
If (Not para.HasChildNodes) OrElse String.IsNullOrEmpty(para.ToTxt.Trim()) Then para.Remove()
e.Text = Nothing
End If
End Sub

Hi Aaron,

Thanks for this additonal information. If I understand you correctly then the code above does actually do excatly what you are looking for. I cannot reproduce the issue on my side. After merging with the code above the third field is removed and the fourth is retained intact. I have attached the output.

It seems this is what should happen as the third field will be replaced with an empty string and the field will dissapear while the fourth will be left untouched as set out in the code above.

If I misunderstood what you were trying to achieve could you please clarify further

Thanks,

Hi Adam,
I’m not sure what happened or maybe I missed something, but yet it does appear to be working the way I need it to. We will see for sure once I get the code implemented into project, but I’m sure it will be fine.

Thanks for your help!
-Aaron