Mail Merge - reference a field from parent region in child region

Hi,
is it possible to reference a field from parent region in child region? As in the following sample, where ServiceName from Services region is referenced in ServiceLevels region:

«TableStart:Services»
ServiceName: «ServiceName»
Levels:
«TableStart:ServiceLevels»
ServiceName: «ServiceName»
Level: «Level»
«TableEnd:ServiceLevels»
«TableEnd:Services»

Currently the ServiceName in ServiceLevels region is substituted by an empty string, not by the actual name. Are there any workarounds apart from adding field to child region data source?

Thanks,
Michal

Hi

Thanks for your request. I think, you can achieve this using IMailMergeDatasource:
https://reference.aspose.com/words/net/aspose.words.mailmerging/imailmergedatasource/
Also, we will consider allowing using data from parent region in child regions. Your request has been linked to the appropriate issue. You will be notified as soon as it is resolved.
Best regards.

Could it be achieved using MailMerge.MergeField event? In the event handler, check whether the field belongs to child region. If it doesn’t, search the parent and, if necessary, other ancestor regions to find the proper region for the field. Then read the field value from the datasource from the appropriate record (assuming that the record indices of the currently processed ancestor regions can be determined). I’d appreciate if you could tell me whether such approach is possible to implement because it seems easier to me than the IMailMergeDatasource approach you proposed above.

Hi

Thanks for your request. Yes, you can try using MergeField event to achieve this. But parent DataTable and current record index should be available in MergeField event. In this case, you will be able to get proper data from the parent DataTable.
Best regards.

The following code does almost what I want. The problem is that RecordIndex property returns an index of an element in the currently merged set of child elements, not in the whole data table. If there are several services (parent region) S1, S2, S3 with several clients (child region) S1-C1, S1-C2, S2-C3, S2-C4, S3-C5, the RecordIndex when merging C1, C3 and C5 is 0. How to get the correct index in the clients table?

private DataSet _ds;

private void MailMerge_MergeField(object sender, MergeFieldEventArgs e)
{
    if (e.FieldValue == null)
    {
        string value = FindValue(_ds.Tables[e.TableName].Rows[e.RecordIndex], e.FieldName);
        if (value != null)
        {
            e.Text = value;
        }
    }
}

private string FindValue(DataRow row, string fieldName)
{
    if (row.Table.Columns.Contains(fieldName))
    {
        return (string) row[fieldName];
    }

    foreach(DataRelation relation in row.Table.ParentRelations)
    {
        string value = FindValue(row.GetParentRow(relation), fieldName);
        if (value != null)
        {
            return value;
        }
    }

    return null;
}

Hi

Thanks for your request. I think, you can try using code like the following:

mDataSet = GetData();
// Open template.
Document doc = new Document(@"Test001\in.doc");
// Add MergeField event handler.
doc.MailMerge.MergeField += new MergeFieldEventHandler(MailMerge_MergeField);
// Execute mail merge.
doc.MailMerge.ExecuteWithRegions(mDataSet);
// Save output document.
doc.Save(@"Test001\out.doc");
void MailMerge_MergeField(object sender, MergeFieldEventArgs e)
{
    // Get index of current record if we merge parent region.
    if (e.TableName == "Parent" && e.FieldName == "ID")
        parentRecordIdx = e.RecordIndex;
    // Check if value of the mergefield is null,
    // In this case, try to find value in the parent DataTable.
    if (e.FieldValue == null)
    {
        // Get parent row.
        DataRow parentRow = mDataSet.Tables["Parent"].Rows[parentRecordIdx];
        // Get value from parent row.
        string value = parentRow[e.FieldName].ToString();
        // Set text of the mergefield.
        e.Text = value;
    }
}
private DataSet GetData()
{
    // Create dummy datasource.
    DataTable parent = new DataTable("Parent");
    parent.Columns.Add("ID");
    parent.Rows.Add(new object[]
    {
        "1"
    });
    parent.Rows.Add(new object[]
    {
        "2"
    });
    DataTable child = new DataTable("Child");
    child.Columns.Add("ParentID");
    child.Columns.Add("col1");
    child.Columns.Add("col2");
    child.Rows.Add(new object[]
    {
        "1",
        "val20",
        "val30"
    });
    child.Rows.Add(new object[]
    {
        "2",
        "val21",
        "val31"
    });
    child.Rows.Add(new object[]
    {
        "2",
        "val22",
        "val32"
    });
    DataSet ds = new DataSet();
    ds.Tables.Add(parent);
    ds.Tables.Add(child);
    ds.Relations.Add(parent.Columns["ID"], child.Columns["ParentID"]);
    return ds;
}
private int parentRecordIdx;
private DataSet mDataSet;

I also attached sample template and output document.
Best regards.

The issues you have found earlier (filed as WORDSNET-3276) have been fixed in this Aspose.Words for .NET 17.6 update and this Aspose.Words for Java 17.6 update.

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