Few issues with Nested Mail Merging

Hello Aspose,

Recently I have become a heavy user of Aspose.words for dot net.
Now playing with a big nested mail merging functionality. I have few hick ups achieving the complete functionality.
I have moderate level of success in achieving the basic functionality and proved that it will work for our corporate need.

I will appreciate if you help me with the issues I have, we have full support license from you.

  1. Page Numbers: When I do the nested mail merging the output document page numbers follows the previous page. Which is not neat, every set of pages merged will have to start from page number 1. Which now is not happening. By default word offers this functionality only when you introduce new section breaks, which of course aspose does not like in nested mail merging. Even if I introduce a section break after the closing tag, the page number starts from 1 but that section is appended to the end of the mail merged toilet roll, which i can understand as it is outside the nested tag. In a nutshell I need an option to introduce next page section breaks so that the page number starts from 1 again in every merge.

  2. Headers: Like the issue 1, the merged toilet roll document loses the first page header. I would like the merge to retain the first page headers in every first page of the set of pages merged. At the moment it only shows the header and the footer in the first page of the entire roll of pages. Like the issue 1, this issue is also something to do with introducing a new page section break between merges I believe.

  3. Conditional Fields: My current template has some conditional fields which after the word merging is done has to be removed, which it is still currently shown when I press ALT+F9 in the merged document. I also had issues with unused merge fields with logic which I removed using the setting “doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveUnusedFields” which is okish. Can you provide a option to deal with this to hide the logic behind the conditional fields?

Can you please help me address these issues, I think we have a heavy use for your tool replacing the regular method of doing things. I can provide further information if you think it speeds up resolving the issue.

Help is very much appreciated.

Regards,
Ram Natarajan

Hi Ram,

Thank you for considering Aspose.Words. Regarding restarting page numbers and displaying first page headers/footers, you can achieve this by using the following code after the mail merge is completed.

foreach (Section sec in doc.Sections)
{
    sec.PageSetup.RestartPageNumbering = true;
    sec.PageSetup.PageStartingNumber = 1;
    sec.PageSetup.DifferentFirstPageHeaderFooter = true;
}

Regarding removing conditional as well unused fields, please specify clean-up options as follows:

doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveUnusedFields
| MailMergeCleanupOptions.RemoveContainingFields;

I hope, this helps.

Best regards,

Hi Awais,

Thanks for your reply.

For the page number and the header issue your suggestion did not work as the template has only one defined section as that’s how Aspose like for the nested tag to be formed.
Your option is coming back with no difference in both page numbers and the header.

Here is the simple structure of how the tags are formed:

«TableStart:IPSClaimCase»
Inside a table row here is the nested region formed:
«TableStart:ClaimEntry»
«LenderName»
«CRef»
«Status»
«CompPayAmountPaid»
«TableEnd:ClaimEntry»
«TableEnd:IPSClaimCase»

Again, the finished merged document will come out only with one section, reason aspose expects the tags and the nested tags to be inside only one section.

And about the second suggestion please give me VB.net option for it.

Regards,
Ram

Also found the bitwise operator for your second suggestion like below for VB.net:

ReturnDocument.MailMerge.CleanupOptions = Reporting.MailMergeCleanupOptions.RemoveUnusedFields Xor Reporting.MailMergeCleanupOptions.RemoveContainingFields

But this actually when done before merging the document completely removes the conditional logic and throws an exception saying one of the book mark is not found anymore. In a nutshell the second option did not work either.

Regards,
Ram

Hi Ram,

Thanks for the additional information.

To ensure a timely and accurate response, it would be great if you please create a standalone (runnable) simple console application that helps us reproduce your problem on our end and attach it here for testing. As soon as you get this simple application ready, we’ll start further investigation into your issue and provide you code to achieve what you’re looking for. Also, please attach the template Word document and output document showing the undesired behavior here for testing.

Secondly, instead of “Xor” please try using the “Or” operator. Please read more details about how MailMergeCleanupOptions work in the following link:
https://docs.aspose.com/words/net/clean-up-before-or-during-mail-merge/

Best regards,

Hi Awais,

Thanks for your reply.
When i said I tried ‘Xor’ sorry I didn’t mention I also tried ‘Or’ and found it not working.
I have a small stand alone console app ready for you but I don’t want it to be available to download. Please send me you email address so that I can send the zip file. Have created a small app that has an xml source read through the dataset and mail merged and spit out in the //bin/Debug folder. All the issues that i have mentioned above still exists in this sample application.

Regards,
Ram

Hi Awais,

I have sent the console application as requested to your email address.
Please do the need full and let me know if you need further information.

Thanks,
Ram

Hi Ram,

Thanks for your inquiry. Please try executing the following code to achieve what you’re looking for:

Module Main
Sub Main()
Dim license As New Aspose.Words.License()
license.SetLicense("Aspose.Words.lic")
Dim ReturnDocument As Document = New Document("AsposeSampleTemplate.docx")
Dim builder As DocumentBuilder = New DocumentBuilder(ReturnDocument)
ReturnDocument.FirstSection.Body.LastParagraph.Runs(0).Remove()
Dim fieldNames() As String = ReturnDocument.MailMerge.GetFieldNames()
Dim ds As New DataSet()
ds.ReadXml("AsposeSampleXML.xml")
ReturnDocument.MailMerge.FieldMergingCallback = New HandleMergeFields()
ReturnDocument.MailMerge.CleanupOptions = Reporting.MailMergeCleanupOptions.RemoveContainingFields Or Reporting.MailMergeCleanupOptions.RemoveUnusedFields
ReturnDocument.MailMerge.ExecuteWithRegions(ds)
For Each bm As Bookmark In ReturnDocument.Range.Bookmarks
If bm.Name.StartsWith("_HiddenBM_") Then
builder.MoveToBookmark(bm.Name, False, True)
builder.InsertBreak(BreakType.SectionBreakNewPage)
End If
Next
For Each sec As Section In ReturnDocument.Sections
sec.PageSetup.RestartPageNumbering = True
sec.PageSetup.PageStartingNumber = 1
If sec.Body.Paragraphs.Count = 1 Then
sec.Remove()
End If
Next
For Each bm As Bookmark In ReturnDocument.Range.Bookmarks
If bm.Name.StartsWith("_HiddenBM_") Then
bm.Remove()
End If
Next
ReturnDocument.Save("AsposeSampleOutput.docx", SaveFormat.Docx)
End Sub
Public Class HandleMergeFields : Implements IFieldMergingCallback
Public Sub FieldMerging(ByVal args As Aspose.Words.Reporting.FieldMergingArgs) Implements IFieldMergingCallback.FieldMerging
If mBuilder Is Nothing Then
mBuilder = New DocumentBuilder(args.Document)
End If
If args.FieldName.Equals("TaxPaid") Then
Dim parenTab As Table = args.Field.Start.GetAncestor(NodeType.Table)
If (parenTab IsNot Nothing) Then
Dim para As Paragraph = parenTab.NextSibling
mBuilder.MoveTo(para)
mBuilder.StartBookmark("_HiddenBM_" & mBookmarkIdx)
mBuilder.EndBookmark("_HiddenBM_" & mBookmarkIdx)
mBookmarkIdx = (mBookmarkIdx + 1)
End If
End If
End Sub
Public Sub ImageFieldMerging1(ByVal args As Aspose.Words.Reporting.ImageFieldMergingArgs) Implements IFieldMergingCallback.ImageFieldMerging
' Do nothing.
End Sub
Private mBuilder As DocumentBuilder
Private mBookmarkIdx As Integer
End Class
End Module

I hope, this helps.

Best regards,

Hi Awais,

Thank for your reply I very much appreciate it.
I have mainly good news and one hick up on removing the conditional fields.
Your suggestion has solved the pager and the header issue which definitely was a deal breaker, which is now solved and out of the way.

But removing the conditional fields with the “Or” operator throws me an exception (cannot find a bookmark). So my question is is there a way to remove all book marks, conditional fields and merge fields from a aspose document after the merging is done (this is a default word behavior in normal mail merging)?

This really helps. And a five star for you solving the other issues.

Regards,
Ram

Hi Ram,

Thanks for your feedback. I was not able to reproduce this exception when using Aspose.Words for .NET 14.1.0 on my side. I would suggest you please upgrade to the latest version of Aspose.Words for .NET 14.1.0 from the following link:
https://releases.aspose.com/words/net

Secondly, you can simply use the following line of code to remove all bookmarks from the document.

ReturnDocument.Range.Bookmarks.Clear()

Best regards,

Hi Awais,

Finally this option works with no side effects.

ReturnDocument.MailMerge.CleanupOptions = Reporting.MailMergeCleanupOptions.RemoveContainingFields Or Reporting.MailMergeCleanupOptions.RemoveStaticFields

Good one mate.

Thanks for your help,

Regards,
Ram

Hi Ram,

Its great you were able to find what you were looking for. Please let us know any time you have any further queries.

Best regards,

Hi Awais,

One more question: how to achieve the nested mail merging by sending dataset directly from stored procedure instead of preparing nested XML and read to a dataset. How to set a relation ship of the parent table and the nested table in the query results?
I am trying something like this:

CurrentDataSet.Tables(0).TableName = "IPSClaimCase"
CurrentDataSet.Tables(1).TableName = "IPSClaimEntry"
ReturnDocument.MailMerge.ExecuteWithRegions(CurrentDataSet)

Help is appreciated.

Regards,
Ram

Never mind Awais,

I have found the way of setting relationship using .net functionality like below and it works.

CurrentDataSet.Tables(0).TableName = "IPSClaimCase"
CurrentDataSet.Tables(1).TableName = "IPSClaimEntry"
CurrentDataSet.Relations.Add("ClaimEntries", CurrentDataSet.Tables("IPSClaimCase").Columns("UniqueKey"), CurrentDataSet.Tables("IPSClaimEntry").Columns("UniqueKey"))
ReturnDocument.MailMerge.ExecuteWithRegions(CurrentDataSet)

Regards,
Ram

Hi Ram,

Thanks for your inquiry. Please also refer to the following article for details:

How to Set up Relations for use in Nested Mail Merge with Regions

Please let us know if we can be of any further assistance.

Best regards,

Thanks Awais,
But I have managed to make it work already.
But I have one more for you,
In nested mail merging how can i set merge fields (without using a StyleRef field) in the header and footer?
If I manually set a merge field in the header that is getting ignored after the nested merge is done, which makes sense as the parent tags are made in the content not the header.
Can you please advise how to I can achieve it or make the header and the footer a part inside the parent tag?

Thanks,
Ram

Hi Ram,

Thanks for your inquiry. I think, you can make use of SET and REF fields i.e. during mail merge assign a new text to a bookmark using SET field and then afterwards using REF field insert the text marked by bookmark in header/footer area. I hope, this helps.

Best regards,

Hi Awais,

Using a SET field in the content with in the region and refer them from header and the footer is not the option we wanted. We don’t want to be displaying the field that we want in the header in the main content. We would basically like to do the nested mail merging and on top of that would like to set merge fields in the header or footer which I am not able to achieve now.

This is very important to get sorted. If this is a success Aspose.words will be adapted to a huge product and potential to be used in future projects too.

If you can release a version that supports what is needed which will be great.

Many thanks,
Ram

Hi Ram,

Thanks for your inquiry. In your case, after performing a mail merge with regions operation using MailMerge.ExecuteWithRegions method you need to simply perform a simple mail merge operation using MailMerge.Execute method. This will place values in mergefields in headers/footers and in any mergefield(s) outside the nested region. I hope, this helps.

Best regards,