Use of TableStart and TableEnd merge fields within an IF merge field

I have been trying to use TableStart and TableEnd repeaters within an IF merge field in a Word document and have come across a series of issues without finding a working solution.

When I try to run the following the attached document through the following code, it manages to process the document but leaves the if statement in place and doesn’t remove it, as would have been expected.

public void TestRun()
{
    var baseDict = new SortedDictionary<string, string>();
    baseDict.Add("Test1", "Test Value 1");
    baseDict.Add("Test2", "Test Value 2");
    baseDict.Add("Test3", "Test Value 3");
    baseDict.Add("Test4", "Test Value 4");

    DataSet ds = new DataSet();
    DataTable dt = new DataTable("test");
    var testpk = dt.Columns.Add("Id", Type.GetType("System.Int32"));
    dt.Columns.Add("TestHeader", Type.GetType("System.String"));
    dt.Columns.Add("TestField", Type.GetType("System.String"));
    dt.Constraints.Add(new UniqueConstraint("PK_testId", testpk, true));
    dt.Rows.Add(1, "Test Section 1", @"This is the first test section of this document.
        This will test if we can split the row into paragraphs.");
    dt.Rows.Add(2, "Test Section 2", "This is the second test section of this document.");
    dt.Rows.Add(3, "Test Section 3", "No rows within this test.");

    var dt2 = new DataTable("testSub");
    var subpk = dt2.Columns.Add("Id", Type.GetType("System.Int32"));
    var fk = dt2.Columns.Add("fkId", Type.GetType("System.Int32"));
    dt2.Columns.Add("Text", Type.GetType("System.String"));
    dt2.Constraints.Add(new UniqueConstraint("PK_testSubId", subpk, true));
    dt2.Constraints.Add(new ForeignKeyConstraint("FK_testId_testSubFKId", testpk, fk));
    dt2.Rows.Add(1, 1, "Test Row 1");
    dt2.Rows.Add(2, 1, "Test Row 2");
    dt2.Rows.Add(3, 2, "Test Row 3");
    dt2.Rows.Add(4, 2, "Test Row 4");

    ds.Tables.Add(dt);
    ds.Tables.Add(dt2);
    ds.Relations.Add(new DataRelation("Rel_test_testSub", ds.Tables["Test"].Columns["Id"], ds.Tables["testSub"].Columns["fkId"]));

    Document doc = new Document(@"FOREACH Test.docx");
    var cn = doc.ChildNodes;

    doc.MailMerge.Execute(baseDict.Keys.ToArray(), baseDict.Values.ToArray());
    doc.Save(@"FOREACH Test Step 1.docx");

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

    doc.MailMerge.UseNonMergeFields = true;
    doc.MailMerge.ExecuteWithRegions(ds);
    doc.MailMerge.Execute(new string[] { }, new string[] { });

    doc.Save(@"FOREACH Test After.docx");
}

However, when I add the RemoveContainingFields option before the original execute, the if statement is processed, but instead of keeping the mergefields as mergefields, it converts them all to string representations of them, including carats.

Not only that, when the TableStart is on the same line as the IF statement, the entire line (if and all) gets reproduced and fails to process properly.

I’ve tried moving the TableStart and TableEnd tags outside the IF and process it, but the IF statement still fails to be processed even though the non-repeater merge fields seem to be handled.

The nearest I’ve got to it processing is if the TableStart is within the IF statement, but the TableEnd is outside. When the IF’s conditional is true, the statement actually seems to process and it runs through. However, when it is false, the whole thing falls over again due to the mismatched TableEnd.

Is there a correct way to get this processing? Can IF statements and TableStart/End work together?

This has been tested with the latest version of Aspose.Word for .net (v 16.8.0).

Hi Glen,

Thanks for your inquiry. We have tested the scenario using latest version of Aspose.Words for .NET 16.10.0 and have not found any issue with output. Please use Aspose.Words for .NET 16.10.0. We have attached the output document with this post for your kind reference.

You are using MailMerge.CleanupOptions correctly in the shared code. Please use MailMerge.CleanupOptions property before the last call of mail merge to get the desired output.

Hi Tazir,

Thank you for your quick response. However, I’m still concerned that the IF merge field is still there after the process has been complete with both Executes and an ExecuteWithRegions, I’d have thought that it would have been resolved and reduced down to just the true or false clause as per Word’s processing. Should the IF statement still be there, and is there a way to resolve it properly?

Thanks,
Glen.

Hi Glen,

Thanks for your inquiry. Please call Document.UpdateField and FieldsHelper.ConvertFieldsToStaticText methods before saving the document to get the desired output. Please get the code of FieldsHelper class from Aspose.Words for .NET examples repository at GitHub. Hope this helps you.

Document doc = new Document(MyDir + @"FOREACH+test.docx");
var cn = doc.ChildNodes;
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveUnusedFields;
doc.MailMerge.Execute(baseDict.Keys.ToArray(), baseDict.Values.ToArray());
doc.Save(MyDir + @"FOREACH Test Step 1.docx");
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveUnusedFields;
doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveUnusedRegions;
doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveContainingFields;
doc.MailMerge.CleanupOptions |= MailMergeCleanupOptions.RemoveStaticFields;
doc.MailMerge.ExecuteWithRegions(ds);
doc.UpdateFields();
FieldsHelper.ConvertFieldsToStaticText(doc, FieldType.FieldIf);
doc.Save(MyDir + @"Out v16.10.0.docx");