MergeFieldEventHandler doesn't work for ExecuteWithRegions after Execute- and vice-versa

MergeFieldEventHandler doesn’t work with ExecuteWithRegions after use with Execute, and vice-versa. For example:

// Setup mail merge event handler & document builder to do the custom work.
doc.MailMerge.MergeField += new MergeFieldEventHandler(MergeFieldProcess);
mBuilder = new DocumentBuilder(doc);

// Do the standard merge without regions.
foreach(string name in tablesToExecute)
{
    currentTable = ds.Tables[name];
    doc.MailMerge.Execute(ds.Tables[name]);
}
// Do the merge with regions.
foreach(string name in tablesToExecuteWithRegions)
{
    currentTable = ds.Tables[name];
    doc.MailMerge.ExecuteWithRegions(ds.Tables[name]);
}

In this case, MergeFieldProcess is called for Execute, but not for ExecuteWithRegions. If I do my ExecuteWithRegions first, then do Execute, same problem but reversed. I’ve tried setting up the event handler again and reinitializing the DocumentBuilder a second time, but that doesn’t work either.

Am I doing something wrong? Does anyone have a solution / workaround to this problem?

Thanks!!!

This message was posted using Aspose.Live 2 Forum

Hi

Thanks for your request. Most likely, some of tables in your DataSet have columns with the same names. In this case, when you execute simple mail merge or mail merge with regions all fields in your template are filled so there is nothing to fill, when you call mail merge second time and that is why MergeField event handler is not called. Also, as I can see, your template does not contain any merge fields outside regions. So what is purpose to call simple mail merge if regions should be filled?
I tried to reproduce the same using simple template (see the attachment). As you can see merge fields inside region and merge field outside the region have different names. Here is code used for testing:

public void Test001()
{
    // Create dummy datasource.
    DataTable table = new DataTable("myTable");
    table.Columns.Add("col1");
    table.Columns.Add("col2");
    table.Columns.Add("col3");
    for (int i = 0; i <10; i++)
        table.Rows.Add(new object[]
        {
            "test",
            "test1",
            "test2"
        });
    // Open tamplate
    Document doc = new Document(@"Test001\in.doc");
    // Add MergeField event handler.
    doc.MailMerge.MergeField += MailMerge_MergeField;
    // Execute simple mail merge
    doc.MailMerge.Execute(new string[]
    {
        "test",
        "test1"
    }, new object[]
    {
        "value",
        "value1"
    });
    // Execute mail merge with regions.
    doc.MailMerge.ExecuteWithRegions(table);
    // Save output document.
    doc.Save(@"Test001\out.doc");
}
void MailMerge_MergeField(object sender, MergeFieldEventArgs e)
{
    // Just write for which of mergefield event handler is called.
    Console.WriteLine(e.FieldName);
}

Hope this helps.
Best regards.

Sorry for the delayed response, I was out of the office.

My dataset did not have any duplicate fields. There are still unmerged region merge fields when I call ExecuteWithRegions. My template didn’t have merge fields outside of regions, but I wouldn’t think that calling a regular merge would hurt anything.

I created a simpler test case of my own, and after playing around with code some, I’ve found that the MergeFieldEventHandler fires for both if I do ExecuteWithRegions first, and then Execute. If I switch it to do Execute first and then ExecuteWithRegions, the event handler doesn’t fire for ExecuteWithRegions.

Below is the code, and attached is my template. Note the Nunit Asserts. The second Assert fails, unless I switch the ExcecuteWithRegions call to be first. Please tell me why the order matters in this test case. I suspect there is something else going on here that may rear its ugly head elsewhere if I am unable to understand and fix it. Thanks!

private DataTable currentTable;
private DocumentBuilder mBuilder;
private bool withRegions;
private int fieldsProcessedWithoutRegions;
private int fieldsProcessedWithRegions;

[Test, Ignore("For now…")]
public void MergeBugTest()
{

    fieldsProcessedWithoutRegions = 0;
    fieldsProcessedWithRegions = 0;

    // Create tables.
    DataTable tb1 = new DataTable("SellerSignators");
    tb1.Columns.Add("signator_name", typeof(string));
    tb1.Columns.Add("signator_title", typeof(string));
    tb1.Columns.Add("signator_date", typeof(DateTime));
    DataRow tb1row1 = tb1.NewRow();
    tb1row1["signator_name"] = "John Doe";
    tb1row1["Signator_title"] = "Director";
    tb1row1["signator_date"] = DateTime.Today;
    tb1.Rows.Add(tb1row1);

    DataTable tb2 = new DataTable("BuyerSignators");
    tb2.Columns.Add("signator_name", typeof(string));
    tb2.Columns.Add("signator_title", typeof(string));
    tb2.Columns.Add("signator_date", typeof(DateTime));
    DataRow tb2row1 = tb2.NewRow();
    tb2row1["signator_name"] = "Jane Smith";
    tb2row1["Signator_title"] = "President";
    tb2row1["signator_date"] = DateTime.Today;
    tb2.Rows.Add(tb2row1);

    DataTable tb3 = new DataTable("Simple");
    tb3.Columns.Add("todays_date", typeof(DateTime));
    DataRow tb3row1 = tb3.NewRow();
    tb3row1["todays_date"] = DateTime.Now;
    tb3.Rows.Add(tb3row1);

    DataSet ds = new DataSet();
    ds.Tables.Add(tb1);
    ds.Tables.Add(tb2);
    ds.Tables.Add(tb3);

    Document doc = new Document(@"c:\files\junk\MergeTestTemplate.doc");
    mBuilder = new DocumentBuilder(doc);

    doc.MailMerge.MergeField += MergeFieldProcess;

    // Merge without regions.
    withRegions = false;
    currentTable = tb3;
    doc.MailMerge.Execute(tb3);

    // Merge with regions.
    withRegions = true;
    currentTable = tb1;
    doc.MailMerge.ExecuteWithRegions(tb1);
    currentTable = tb2;
    doc.MailMerge.ExecuteWithRegions(tb2);

    doc.Save(@"c:\files\junk\MergeTestResult.doc");

    Assert.IsTrue(fieldsProcessedWithoutRegions> 0);
    Assert.IsTrue(fieldsProcessedWithRegions> 0);

}

private void MergeFieldProcess(object sender, MergeFieldEventArgs e)
{

    if (e.FieldName.EndsWith("_dtos"))
    {
        // Look for the field name, without the "!", in the current table.
        string fieldName = e.FieldName.Replace("_dtos", "");

        if (currentTable.Columns.Contains(fieldName))
        {
            DataRow row = currentTable.Rows[e.RecordIndex];
            DateTime dtm = Convert.ToDateTime(row[fieldName]);
            string dateString = " ";
            if (dtm != DateTime.MinValue)
            {
                dateString = dtm.ToString("dddd, MMMM dd, yyyy", DateTimeFormatInfo.InvariantInfo);
            }

            // Write out the text.
            mBuilder.MoveToMergeField(e.FieldName);
            mBuilder.Write(dateString);
        }

    }

    if (withRegions)
    {
        fieldsProcessedWithRegions++;
    }
    else
    {
        fieldsProcessedWithoutRegions++;
    }
}

Hi

Thank you for additional information. I managed to reproduce the problem on my side. Your request has been linked to the appropriate issue. You will be notified as soon as it is resolved.
Best regards.

The issues you have found earlier (filed as 14463) have been fixed in this update.

This message was posted using Notification2Forum from Downloads module by aspose.notifier.