Mixed usage of MailMerge.Execute and MailMerge.ExecuteWithRegions

Hi,We are trying to perform a mailmerge on a document in which we want to have ‘normal’ merge fields and also repeatable regions. I have found that fieldsbetween a start/end table are only parsed when they we call ExecuteWithRegions; And that fields that are not placed between a start/end are only parsed when calling de normal Execute.

We wish to give our users ‘total freedom’ in creating their templates so I tried to combine both techniques with the following code.

internal void ParseDocument(Document subject, DataSet DataSource)
{
foreach (DataTable table in DataSource.Tables)
{
subject.MailMerge.Execute(table);
}
subject.MailMerge.ExecuteWithRegions(DataSource);

}
The problem with this is that each call to ‘Execute’ will duplicate the entire orignal document.
So in if we have a template with one page and a dataset with 5 tables, the end result is a document with 5 pages.
It does not seem to matter whether there are actual mergefields in the document or not.
It also does not seem to matter in which order (Execute/executeWithRegions) we call the methods, the result is the same.
Strangely enough, if one of the ‘regionized’ tables contain more than one row, each row is correctly shown within its’ region.
The ONLY problem is that the entire document is duplicated for every table in the dataset.

Is there a way that I can prevent the additional copies being made?
Everything else seems to work fine.

Tanks, Bas.

Hi Wouter,


Thanks for your inquiry. Please note that it is by design, your whole MailMerger document template will be repeated for each data row in the data source and every repeated copy is populated again by ExecuteWithRegions process. May be in your case you can simply use Nested MailMerge with regions:
http://www.aspose.com/documentation/.net-components/aspose.words-for-.net/howto-use-nested-mail-merge-regions.html

Moreover, could you please attach your input template document here for testing? I will investigate the scenario further and provide you more information.

Best Regards,

I have suppied the (very basic version of) the template and a serialized dataset.
The code we use is already mentioned above.

The typical scenario would be that we have a dataset with 8 to 14 tables.
Some of these tables have multiple rows.
Every column in the dataset will have a unique name.

The idea is that the end user can build a template that only uses a little start/end region-declarions as possible, which means only for the tables that will have multiple rows., and only in the portion of the template that needs repeating.

We could easily achieve this if not every call to execute would duplicate the template.
(I noticed that multiple calls to ExecuteWithRegion does not exhibit this behaviour.)
I appreciate that this behaviour is by design, but it is really in conflict with our design goals.

Ideally we would be able to set a property before the second call, this would then not interfere with anyones existing production code.

Thank you for your time,
bas.

Hi there,


Thanks for this additional information.

Could you clarify how you would like an output document to look for simple mail merge (using MailMerge.Execute) if there was more than one data row for a field in the document? This situation would cause a repeat of the document which would be the correct behavior, so it’s unclear how you would like the document to look.

If you data table only ever has one record for the fields in the document then you might be able to avoid the document restarting. Instead of passing the entire data table to be merged, you could try iterating through each column in the data table and mail merging each column name and corresponding value manually by calling Execute.

Thanks,

Hi
Wouter,


Thanks for the additional information. I think, after preprocessing your input data source, you can achieve what you need by using the following code snippet:

Document doc = new
Document(@“c:\test</span>Polis Aansprakelijkheidsverzekering (PP).docx”);

DataSet ds = new
DataSet();
ds.ReadXml(@“c:\test\data.xml”);

Hashtable keyValuePairs = new Hashtable();
foreach (DataTable
dt in ds.Tables)
{
if (dt.Rows.Count == 1)
{
foreach
(
DataColumn column in
dt.Columns)
{
if
(!keyValuePairs.ContainsKey(column.ColumnName))
{
keyValuePairs.Add(column.ColumnName, dt.Rows[0][column].ToString());
}
}
}
}

string[] fieldNames= new string[keyValuePairs.Count];
string[] values= new string[keyValuePairs.Count];

keyValuePairs.Keys.CopyTo(fieldNames,
0);
keyValuePairs.Values.CopyTo(values,0);

doc.MailMerge.Execute(fieldNames,
values);
doc.MailMerge.ExecuteWithRegions(ds);

doc.Save(@“c:\test\out.docx”);

I hope, this will help.

Best Regards,

Hi,

I had forgotten to mention that we are not performing a typical mailmerge,
in which a single dataset will create multiple copies (for example for printing) of a template. The document that we wish to create is used to report the endresult of a (request)process and will always be limited to a single instance of the template.

Based on the code you provided I think you must have already guessed this because is does produce the desired result. *big smile*

I did change the datatype of the values-parameter to object[] so I do not have to handle null/DbNull values.

Thank you for your help.

Hi Wouter,


Thanks for your feedback. It is perfect that you managed to achieve what you were looking for. If we can help you with anything else, please feel free to ask.

Best Regards,