Products Technologies Demo Docs Blog Support Company

Renaming Merge Blocks and Merge Fields Programmatically in C#

This article shows how to programmatically rename merge blocks and merge fields in a document using TX Text Control .NET for Windows Forms, WPF, and ASP.NET. It implements a helper class that can be used to rename merge blocks and merge fields in a document.

Renaming Merge Blocks and Merge Fields Programmatically in C#

During the merge process, when the MailMerge 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 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;
         }
     }
 }

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);
         }
     }
 }

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);
                }
            }
        }
    }
}

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 to the RenameDataColumn method.

TXTextControl.DocumentServer.DataSources.Refactor.RenameDataColumn(
    textControl1, "Sales_SalesOrderDetail", "New_Sales_SalesOrderDetail");

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Related Posts

ASP.NETWindows FormsWPF

MailMerge: Data Structures Explained with a Sample Template and JSON Data

The MailMerge class is used to merge JSON data into templates including merge fields and repeating merge blocks. This article gives an overview of the data structure based on a sample template…


ASP.NETWindows FormsWPF

TX Text Control 33.0 SP3 is Now Available: What's New in the Latest Version

TX Text Control 33.0 Service Pack 3 is now available, offering important updates and bug fixes for all platforms. If you use TX Text Control in your document processing applications, this service…


ASP.NETWindows FormsWPF

TX Text Control 33.0 SP2 is Now Available: What's New in the Latest Version

TX Text Control 33.0 Service Pack 2 is now available, offering important updates and bug fixes for all platforms. If you use TX Text Control in your document processing applications, this service…


ASP.NETWindows FormsWPF

Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format

Maintaining the integrity and functionality of documents throughout their lifecycle is paramount. TX Text Control provides a robust ecosystem that focuses on preserving documents in their internal…


ActiveXASP.NETWindows Forms

Expert Implementation Services for Legacy System Modernization

We are happy to officially announce our partnership with Quality Bytes, a specialized integration company with extensive experience in modernizing legacy systems with TX Text Control technologies.