During the merge process, when the MailMerge TX Text Control .NET Server for ASP.NET
DocumentServer Namespace
MailMerge Class
The MailMerge class is a .NET component that can be used to effortlessly merge template documents with database content in .NET projects, such as ASP.NET web applications, web services or Windows services.
class merges JSON or other data into templates, field names are matched against available columns of data in the data source. Hierarchical data structures are merged into repeating merge blocks on the basis of their names.

Mail merge describes the process of creating documents based on templates containing static content and variable elements that are merged from different data sources.

Data Source

To understand the motivation behind the task of renaming hierarchical names in a template, we need to understand the logical structure of the data source and the template. A typical hierarchical data source is shown in the following diagram.

Data Source

The following screenshot shows a template that accesses fields in different ways.

Data Source

Accessing Child Tables

company_name comes directly from the root table, while the address comes from a child table. These fields can be accessed using dot notation. For example, to access the street, the merge field name is address.street.

The Contacts part contains a merge block (shown in red below) to list all contacts. A merge block repeats all elements that are part of the block based on the data for that block. In this case, the block includes a soft break and the tab character so that all contacts are listed at the same indent position:

Sample template

The following animation shows the header section before the merge process and after the merge process:

Sample template

Repeating Blocks

The detail section lists all orders and their articles. Therefore, two nested merge blocks are inserted. The outer block repeats the orders objects and the inner block lists all articles:

Sample template

As can be seen in the following animation, the outer block is getting repeated 2 times based on the actual data in the given JSON. The inner table row is defined as the nested block articles and contains all line items:

Sample template

Renaming Hierarchical Values

If the data source is changed, the merge block names and any fields that use dot notation with these changed names must be updated to match the new data source. In the user interface, this can be done by using the dialog that is provided.

Renaming UI

However, this can be automated by programmatically changing the names when hundreds or thousands of templates are changed.

There are two steps that are required to change the name of a table:

  • Change the name of merge blocks.
  • Change the included table names of merge fields.

Merge blocks are essentially SubTextParts TX Text Control .NET Server for ASP.NET
TXTextControl Namespace
SubTextPart Class
A SubTextPart object represents a user-defined part of a TX Text Control document.
with a special prefix txmb_.

private static void RenameMergeBlocks(SubTextPartCollection subTextParts,
string oldColumnName,
string newColumnName)
{
// iterate through all SubTextParts
foreach (SubTextPart subTextPart in subTextParts)
{
// check if the SubTextPart is a merge block
if (subTextPart.Name == "txmb_" + oldColumnName)
{
// rename the SubTextPart
subTextPart.Name = "txmb_" + newColumnName;
}
}
}
view raw test.cs hosted with ❤ by GitHub

So we can just loop through all the SubTextParts and change the name after the prefix.

For merge fields, we do essentially the same thing, replacing the full string of the name. This will also refactor fields that contain a table name using dot notation.

private static void RenameMergeFields(ApplicationFieldCollection applicationFields,
string oldColumnName,
string newColumnName)
{
// iterate through all ApplicationFields
foreach (ApplicationField applicationField in applicationFields)
{
// check if the ApplicationField is a merge field and contains the old column name
if (applicationField.TypeName == "MERGEFIELD" &&
applicationField.Name.Contains(oldColumnName))
{
// create a new MergeField object and replace the old column name with the new column name
MergeField mergeField = new MergeField(applicationField);
mergeField.Name = mergeField.Name.Replace(oldColumnName, newColumnName);
}
}
}
view raw test.cs hosted with ❤ by GitHub

The complete helper class is shown below:

using TXTextControl.DocumentServer.Fields;
namespace TXTextControl.DocumentServer.DataSources
{
public static class Refactor
{
public static void RenameDataColumn(TextControl textControl,
string oldColumnName,
string newColumnName)
{
// iterate through all TextParts
foreach (TextPartBase textPart in textControl.TextParts)
{
RenameMergeBlocks(textPart.SubTextParts, oldColumnName, newColumnName);
RenameMergeFields(textPart.ApplicationFields, oldColumnName, newColumnName);
}
}
private static void RenameMergeBlocks(SubTextPartCollection subTextParts,
string oldColumnName,
string newColumnName)
{
// iterate through all SubTextParts
foreach (SubTextPart subTextPart in subTextParts)
{
// check if the SubTextPart is a merge block
if (subTextPart.Name == "txmb_" + oldColumnName)
{
// rename the SubTextPart
subTextPart.Name = "txmb_" + newColumnName;
}
}
}
private static void RenameMergeFields(ApplicationFieldCollection applicationFields,
string oldColumnName,
string newColumnName)
{
// iterate through all ApplicationFields
foreach (ApplicationField applicationField in applicationFields)
{
// check if the ApplicationField is a merge field and contains the old column name
if (applicationField.TypeName == "MERGEFIELD" &&
applicationField.Name.Contains(oldColumnName))
{
// create a new MergeField object and replace the old column name with the new column name
MergeField mergeField = new MergeField(applicationField);
mergeField.Name = mergeField.Name.Replace(oldColumnName, newColumnName);
}
}
}
}
}
view raw test.cs hosted with ❤ by GitHub

To change all merge blocks and field names from Sales_SalesOrderDetail to New_SalesOrderDetail, the following call can be used by passing the strings and an instance of ServerTextControl TX Text Control .NET Server for ASP.NET
TXTextControl Namespace
ServerTextControl Class
The ServerTextControl class implements a component that provide high-level text processing features for server-based applications.
to the RenameDataColumn method.

TXTextControl.DocumentServer.DataSources.Refactor.RenameDataColumn(
textControl1, "Sales_SalesOrderDetail", "New_Sales_SalesOrderDetail");
view raw test.cs hosted with ❤ by GitHub