Hi
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Thank you for additional information. I created a simple example for you. Hope it could be useful. Here is code:
DataSet ds = GetData();
// Open template.
Document doc = new Document(@"Test001\in.doc");
// Add MergeField event handler.
// It will allowus to change table formatign upon mail merge process.
doc.MailMerge.MergeField += new MergeFieldEventHandler(MailMerge_MergeField);
// Execute mail merge with regions.
doc.MailMerge.ExecuteWithRegions(ds);
// Save output document.
doc.Save(@"Test001\out.doc");
doc.Save(@"Test001\out.pdf");
=====================================================================
void MailMerge_MergeField(object sender, MergeFieldEventArgs e)
{
if (e.FieldName == "StartDate")
{
startDate = (DateTime) e.FieldValue;
}
else if (e.FieldName == "EndDate")
{
DateTime endDate = (DateTime) e.FieldValue;
int duration = endDate.Month - startDate.Month;
// If duration is greater then we should merge cells.
// Get cell where the currrent mergefield is located.
Cell refCell = (Cell) e.Field.Start.GetAncestor(NodeType.Cell);
if (refCell != null)
{
// Merge cells.
refCell.CellFormat.HorizontalMerge = CellMerge.First;
for (int i = 0; i < duration; i++)
{
if (refCell.NextSibling != null)
{
refCell = (Cell) refCell.NextSibling;
refCell.CellFormat.HorizontalMerge = CellMerge.Previous;
}
}
// We should also merge other cells in row.
refCell = (Cell) refCell.NextSibling;
if (refCell != null)
{
refCell.CellFormat.HorizontalMerge = CellMerge.First;
while (refCell.NextSibling != null)
{
refCell = (Cell) refCell.NextSibling;
refCell.CellFormat.HorizontalMerge = CellMerge.Previous;
}
}
}
}
}
private DateTime startDate;
private DataSet GetData()
{
// Prepare dummy data.
DataSet ds = new DataSet();
int numberOfSites = 3;
DataTable sites = new DataTable("Sites");
sites.Columns.Add("SiteId");
sites.Columns.Add("SiteName");
for (int i = 0; i < numberOfSites; i++)
sites.Rows.Add(new object[] {i, string.Format("site_{0}", i)});
ds.Tables.Add(sites);
DataTable programs = new DataTable("Programs");
programs.Columns.Add("SiteId");
programs.Columns.Add("ProgId");
programs.Columns.Add("ProgName");
programs.Columns.Add("StartDate", typeof (DateTime));
programs.Columns.Add("EndDate", typeof (DateTime));
// In the template we have one region per month.
// So in our datasource we also should have one table per month.
// You can achieve the same usingstored proc.
Random rnd = new Random();
for (int month = 1; month <= 12; month++)
{
DataTable monthData = programs.Clone();
monthData.TableName = month.ToString();
for (int siteId = 0; siteId < numberOfSites; siteId++)
{
int numberOfPrograms = rnd.Next(1, 4);
for (int j = 0; j < numberOfPrograms; j++)
{
int endMonth = rnd.Next(month, 12);
monthData.Rows.Add(new object[]
{
siteId, string.Format("{0}{1}", siteId, j),
string.Format("Prog_{0}_{1}", siteId, j),
new DateTime(2010, month, 1), new DateTime(2010, endMonth, 1)
});
}
}
ds.Tables.Add(monthData);
ds.Relations.Add(sites.Columns["SiteId"], monthData.Columns["SiteId"]);
}
return ds;
}
Sample template and output documents are attached.
Best regards.