Aspose words - truncate long mail merge fields

Hi,
We have an issue using Aspose word.
The issue is related to Microsoft Word mail merge when Word is supplied with long field names.
Word internally truncates the long field names where necessary before
displaying them to the user to place onto the page. It seems to sometime truncate to 36, 37 or 37 characters. I can’t seem to find a pattern.

During the Mail Merge using aspose I have to truncate the field names as per the workings in MS Word. Could you please update Aspose.Word to handle the truncation of field names as done by MS Word?
This issue was raised in the forums earlier . … please see in the URL:
https://forum.aspose.com/t/bug-long-mail-merge-fields-values-not-appearing-in-output/130640/2

I have also attached some test files.

  1. In first stage we built a template document. The datasource file ‘DataSource-Orig.doc’ was was used to create template merge file ‘Template-Orig.dot’. This was done manually by manually opening a word template and attaching the datasource. Short named MS word merge fields were available in the list of merge fields and added to template document.
  2. However during merging, using Aspose, the ‘Template-Orig.dot’ file with document ‘DataSource-Aspose.doc’, I had to modify \shorten the field names in the ‘DataSource-Aspose.doc’ file for his Aspose merge to work. As mentioned the field names seem to sometime truncate to 36, 37 or 37 characters.
    The output.doc file is result of the aspose merge, which you can see has not been merged properly as some of the fields lengths have not been truncates correctly to match field name in the template.

Thanks,
Rana

Hi
Thanks for your request. Actually, MS Word does not truncate mergefield name, it truncated only field value (displayed text). If you press Alt+F9 you will see that mergefield names are full, but displayed text is truncated.
For example, if you insert mergefield like the following into your document:
{ MERGEFIELD ThisIsVeryLongMergeFieldNameItShouldBeTruncated }
You will see text like this at place of the field, but field name will be still the same as specified in the field code:
«ThisIsVeryLongMergeFieldNameItShouldBeTr»
Best regards,

Hi Andrey,

Thank you for your response.

You are right the field length truncation does not happen when character like spaces are not present in the fieldname.

However it does seem that MS Word is truncating the mail merge field
names when field name contains space(s) and say is about 45 characters
or more in length.

Example use a field with fieldname:

Last Modified Username:FROM Company (Org. Struct.)

After assigning the datasource document to the template, the above field seems to get truncated to:

«Last_Modified_UsernameFROM_Company_Org»

And even hitting ALT+F9 displays the shortened field name
«Last_Modified_UsernameFROM_Company_Org» and not the expected long
fieldname.

Thanks,

Rana

Hi Rana,

Thanks for your request. Each field in MS Word consists of FieldStart, FieldSeparator, FieldEnd nodes and Run nodes, which represent field code and field value (displayed text). So in MS Word document field looks like the following:
[FieldStart] here is field code [FieldSeparator] here is field value [FieldEnd]
During MailMerge process your merge fields will be replaced by values from DataSource. And you will see just these values (inside output document), in your case it’s “Last_Modified_UsernameFROM_Company_Org”.
I use the following code for testing:

// Create data table
DataTable table = new DataTable("Test");
table.Columns.Add("IncClaim_No");
table.Columns.Add("Authorisation_DateFROM_Division_Org_");
table.Columns.Add("Last_Modified_UsernameFROM_Company_Or");
table.Columns.Add("Last_Modified_UsernameFROM_Cost_Centre");
table.Columns.Add("Authorisation_DateFROM_Emergency_Conta");
table.Columns.Add("Address_SearchFROM_Emergency_Contact_");
table.Columns.Add("Authorised_ByFROM_Emergency_Contact_E");
table.Columns.Add("Last_Modified_TimeFROM_Cost_Centre_Or");
// Add some dummy data.
table.Rows.Add(new object[] { "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue", 
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue2", 
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue3",
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue4",
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue5",
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue6",
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue7",
"ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue8" });
Document doc = new Document("Template-Orig.dot");
doc.MailMerge.Execute(table);
doc.Save("out.doc");

The output document is attached.
Best regards,

Hi Andrey,
Thanks for your detailed response.
Let me provide more details as to our issue.
We are a software development company based in Australia. We had been using MS Word mail merge from our applications for quite some time and now we also use Aspose words.

In MS word we have been using long field names like ‘Last Modified Username:FROM Company (Org. Struct.)’. MS word would internally truncate the long field name and would display the truncated field name on the template. However on doing a merge using the longname ‘Last Modified Username:FROM Company (Org. Struct.)’, the MS Word mail merge would still work as MS Word knew how to internally truncate and use the long field name.

Now we also use Aspose.words to merge letter (along with MS Word) and have to use the same templates that have been created earlier. We have to use the field names in the format ‘Last Modified Username:FROM Company (Org. Struct.)’.
During mail merge Aspose words is unable to resolve this to the shortened fieldname like say
’Last_Modified_UsernameFROM_Company_Org’ internally using the same logic as done by MS Word.

Hope I have explained our issue in detail.

Thanks and regards,
Rana

Hi Rana,
Thank you for additional information. I have tried one more time, and still cannot reproduce the problem on my side. Please see the attached documents.

I use the latest version of Aspose.Words 9.4.0 and the following code for testing:

// Create data table
DataTable table = new DataTable("Test");
table.Columns.Add("Inc/Claim No.");
table.Columns.Add("Authorisation Date:FROM Division (Org. Struct.)");
table.Columns.Add("Last Modified Username:FROM Company (Org. Struct.)");
table.Columns.Add("Last Modified Username:FROM Cost Centre (Org. Struct.)");
table.Columns.Add("Authorisation Date:FROM Emergency Contact (Emp)");
table.Columns.Add("Address Search:FROM Emergency Contact (Emp)");
table.Columns.Add("Authorised By:FROM Emergency Contact (Emp)");
table.Columns.Add("Last Modified Time:FROM Cost Centre (Org. Struct.)");
// Add some dummy data.
table.Rows.Add(new object[] { "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue2", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue3", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue4", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue5", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue6", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue7", "ThisIsVeryLongMergeFieldValueThisIsVeryLongMergeFieldValue8" });
Document doc = new Document("Template-Orig_withLongFieldNames.dot");
doc.MailMerge.Execute(table);
doc.Save("out.doc");

The input and the output documents are attached.
Best regards,

Hi Andrey,
Thanks again for your assistance.
I have documented how to replicate the issue using screen-shots in detail. Could you please have a look. Please see attached file ‘Issue-F201.doc’
Thanks and Regards,
Rana

Hi
Thank you for additional information. I see that MS Word uses truncated name format. But I really do not see any reason for that.
Anyways, I think, you can easily resolve the problem yourself. For example, you can try using MappedDataFields:
https://reference.aspose.com/words/net/aspose.words.mailmerging/mailmerge/mappeddatafields/
You can get list of fields in the template and list of columns in your data source and map corresponding fields with the corresponding columns in your data source.
Just a suggestion, maybe you can avoid using such long field names and use short descriptive columns names without whitespaces.
Best regards,

Hi Andrey,
Thanks a lot for your help.

We still have issues cause WordDocument.MailMerge.GetFieldNames collection in the template document does not maintain same order\sequence for the merge fields as per order of fields in the datasource document. So we are having trouble getting the mapping of the long-field-names to the short-field-names. The order of fields in the template document is as per the order in which they are placed onto the word template.

We will look at using short fieldnames in future however we have lots of existing clients using templates which contain these type of long fieldnames. They are using MS Word for mailmerge now and would be using Aspose in future.

Is it possible for Aspose to enhance the Aspose.Words to also also support the mailmerge for these type of long field names (long field names with spaces)?

Thanks and regards,
Rana

Hi
Thanks you for additional information. I suppose this should not be a problem.
Also, I think you should not map one to one because your data source can contain more (or less) columns than number of fields in your template. Also, some particular field can occur several times in your template. So, I think, you should use code like the following to map fields names and column names:

[Test]
public void Test001()
{
    // Create data table - this is our datasource.
    DataTable table = new DataTable("Test");
    table.Columns.Add("Inc/Claim No.");
    table.Columns.Add("Authorisation Date:FROM Division (Org. Struct.)");
    table.Columns.Add("Last Modified Username:FROM Company (Org. Struct.)");
    table.Columns.Add("Last Modified Username:FROM Cost Centre (Org. Struct.)");
    table.Columns.Add("Authorisation Date:FROM Emergency Contact (Emp)");
    table.Columns.Add("Address Search:FROM Emergency Contact (Emp)");
    table.Columns.Add("Authorised By:FROM Emergency Contact (Emp)");
    table.Columns.Add("Last Modified Time:FROM Cost Centre (Org. Struct.)");
    // Add some dummy data.
    table.Rows.Add(new object[] { "Inc/Claim No.",
        "Authorisation Date:FROM Division (Org. Struct.)",
        "Last Modified Username:FROM Company (Org. Struct.)",
        "Last Modified Username:FROM Cost Centre (Org. Struct.)",
        "Authorisation Date:FROM Emergency Contact (Emp)",
        "Address Search:FROM Emergency Contact (Emp)",
        "Authorised By:FROM Emergency Contact (Emp)",
        "Last Modified Time:FROM Cost Centre (Org. Struct.)" });
    // Open template.
    Document doc = new Document(@"Test001\in.dot");
    MapColumnNames(table, doc);
    doc.MailMerge.Execute(table);
    doc.Save(@"Test001\out.doc");
}
private void MapColumnNames(DataTable data, Document doc)
{
    // Get column names from datasource.
    // We will write column names into hashtable, where key is is column name with whitespaces replaced by '_' and removed punctuation marks,
    // and value original column name.
    // We use regular expression to remove all punctuation marks.
    Regex punctuationMarks = new Regex(@"[\!|\.|\?|\;|\,|\:,|\&,|\\,|\/,|\{,|\},|\[,|\],|\(,|\),|\(,|\),|\~,|\#]");
    Hashtable columns = new Hashtable();
    foreach (DataColumn column in data.Columns)
        columns.Add(punctuationMarks.Replace(column.ColumnName, "").Replace(" ", "_"), column.ColumnName);
    // Now get field names from the docuemnt.
    string[] names = doc.MailMerge.GetFieldNames();
    // Avoid duplicated names.
    ArrayList fieldNames = new ArrayList();
    foreach (string name in names)
    {
        if (!fieldNames.Contains(name))
            fieldNames.Add(name);
    }
    // Now we should map field names and column names.
    foreach (DictionaryEntry entry in columns)
    {
        foreach (string name in fieldNames)
        {
            if (entry.Key.ToString().StartsWith(name))
            {
                doc.MailMerge.MappedDataFields.Add(name, entry.Value.ToString());
                fieldNames.Remove(name);
                break;
            }
        }
    }
}

Hope this helps.
Best regards.