Hello there,
I am trying to run MailMerge.ExecuteWithRegions against IMailMergeDataSource object but
it seems there is some issue with my data source that I am not able to catch.
Here is the code snipper where I am calling .MailMerge.ExecuteWithRegions():
private void ExecuteMailMerge()
{
string[] mergeFields = objTemplateDocument.MailMerge.GetFieldNames();
if (mergeFields.Count() > 0)
{
AddParentMergeRegion();
objTemplateDocument.MailMerge.MergeField += new MergeFieldEventHandler(MailMerge_MergeField);
objTemplateDocument.MailMerge.MergeImageField += new MergeImageFieldEventHandler(MailMerge_MergeImageField);
PropertyMailMergeDataSource mmPropertyDataSource = new PropertyMailMergeDataSource(“Properties”);
string[] mergeFieldsProperty = mergeFields.Where(x => (x.StartsWith(“P”) || x.StartsWith(“Z”) || x.StartsWith(“T”) || x.StartsWith(“Image:”) || x.Equals(“APPLICANTS”) || x.Equals(“VENDORS”)) && !x.StartsWith(“TableStart:”) && !x.StartsWith(“TableEnd:”)).ToArray();
for (int i = 0; i < mergeFieldsProperty.Count(); i++)
{
if (mergeFieldsProperty[i].StartsWith(“Image:”))
mergeFieldsProperty[i] = mergeFieldsProperty[i].Substring(6);
}
foreach (IPropertyTransaction objProperty in propertyList)
{
mmPropertyDataSource.AddItem(new object[] { objProperty }, mergeFieldsProperty, null);
}
ClientsMailMergeDataSource mmDataSource = new ClientsMailMergeDataSource(clientList, mmPropertyDataSource);
objTemplateDocument.MailMerge.ExecuteWithRegions(mmDataSource);
}
}
private void AddParentMergeRegion()
{
DocumentBuilder docBuilder = new DocumentBuilder(objTemplateDocument);
docBuilder.MoveToDocumentStart();
docBuilder.ParagraphFormat.PageBreakBefore = true;
docBuilder.InsertField(“MERGEFIELD TableStart:Template”, “«TableStart:Template»”);
docBuilder.MoveToDocumentEnd();
docBuilder.InsertField(“MERGEFIELD TableEnd:Template”, “«TableEnd:Template»”);
}
Please note that I am adding top level TableStart and TableEnd at run-time.
The child region “Properties” needs to be replicated for all the properties for each client.
I have attached following files for your reference:
- Input Document (Applicant Properties.docx)
- ClientsMailMergeDataSource.cs (Main Data Source file)
- PropertyMailMergeDataSource.cs (Child Region Data Source file)
Could you please guide me what I am missing in running the mail merge.
Thank you!
Hi Nutan,
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thanks for your request. Why do you think that there is some problem with your mail merge data sources? Could you please describe your problem more specifically?
Also, please create a simple application, which will allow me to reproduce the problem on my side.
Best regards.
Thanks for your reply Alexey.
I am thinking so because I am not getting merged document as an output i.e. output document is same as my source document.
Can you please verify if my source document is correct to have TableStart:Template and TableEnd:Template which I am adding to the document at run-time?
Thank you!
Hi Nutan,
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thanks for your request. Your document seems to be correct. I tested it using the following simple example and all works fine.
// Open template.
Document doc = new Document(@"Test001\in.docx");
// Execute mail merge with regions.
doc.MailMerge.ExecuteWithRegions(GetData());
// Save output document.
doc.Save(@"Test001\out.doc");
======================================================================
///
/// Returns dummy datasource, which contaion two tables with parent-child relationships.
/// The first table name is "Template", the child table name is "PROPERTIES".
///
private static DataSet GetData()
{
DataSet ds = new DataSet();
// Create two tables and add them into the data set.
DataTable parent = new DataTable("Template");
parent.Columns.Add("id");
parent.Columns.Add("ATITLE");
parent.Columns.Add("ASURNAME");
DataTable child = new DataTable("PROPERTIES");
child.Columns.Add("parnetId"); // this column is needed to create relationshoip between tables.
child.Columns.Add("PSTREETNAME");
child.Columns.Add("PVILLAGE");
child.Columns.Add("PPROPERTYTITLE");
child.Columns.Add("PPROPERTYACCOMMODATION");
child.Columns.Add("PASKINGPRICE");
child.Columns.Add("PREFERENCE");
// Add tables into the data set and add relationship.
ds.Tables.Add(parent);
ds.Tables.Add(child);
ds.Relations.Add(parent.Columns["id"], child.Columns["parnetId"]);
// Structure of our datasource is ready. Let's add some dummy data.
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
parent.Rows.Add(new object[] { i, string.Format("ATITLE#{0}", i), string.Format("ASURNAME#{0}", i) });
for (int j = 0; j < rnd.Next(1, 15); j++)
{
child.Rows.Add(new object[] { i, string.Format("PSTREETNAME {0} {1}", i, j),
"PVILLAGE", "PPROPERTYTITLE", "PPROPERTYACCOMMODATION",
"PASKINGPRICE", "PREFERENCE" });
}
}
return ds;
}
Best regards.
Thanks for the detailed code Alexey.
Yes, the mail merge run fine against your parent-child table data source.
However when I run against my data source, it is same… I don’t get any mail merge document
I have attached demo code with this post along with input file.
Both the data sources Parent+child implements IMailMergeDataSource.
Could you please have a look and let me know what I am missing.
Thank you!
Any update on this?
Hi Nutan,
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thank you for additional information. The template was not filled with data, because you missed to specify table name of ClientsMailMergeDataSourceDemo. Here is snippet of your code:
public class ClientsMailMergeDataSourceDemo : IMailMergeDataSource
{
// Code here
// ....................................
string IMailMergeDataSource.TableName
{
get
{
return "";
}
}
}
Also, you repeat the problem described here:
Best regards.
Hey Alexey,
Thanks for pointing that out. Good one!
All running fine.