Background
One of our customers sends out monthly information together with an invoice to a subset of their contacts. These contacts are first added to a marketing list, and the contacts' names, address information and OCR number is then
extracted. When exporting these members to an Excel file (so it can be sent for printing), our customer has had massive problems to even generate the file. Once we succeeded, we realized that the generated Excel file
is about 550 MB in size, for about 40k rows and less than 10 columns of name and address information. After a while, we figured out that Dynamics CRM generated an additional 160 hidden columns, containing no data. Deleting
these columns brought the file size down to a more reasonable 4 MB. These columns alternated between being named "processid" and "processts".
This problem does not occur when exporting e.g. invoices from advanced find, so I'm curious to know if Dynamics CRM does something special because we're running a plugin at export time in this case.
Details
The flow our customer uses, in more detail, is the following:
- A campaign is created. This campaign gets a sequence number, a unique ID that we generate.
- A marketing list is created, and connected to the campaign.
- Members are added to the marketing list. These members also have a sequence number, a unique ID.
- Switch from the marketing list form to Members of marketing list.
- Selecting the "Export view", a custom view that we've created. In my minimal repro, this view contains only the complete name of the contact plus the "generated OCR" field.
- A plugin, registered on post contact retrieve multiple, is triggered and creates an OCR number for each member of the marketing list, based on their sequence number plus the sequence number of the campaign. This is then added to the "generated OCR" field.
- The view is then exported to Excel. The plugin is triggered once again.
- If the export succeeds, the generated file contains a number of empty columns, labeled "processid" and processts".
The PostContactRetrieveMultiple plugin
protected override void Execute(PluginVars variables)
{
if (variables.Context.InputParameters.Contains("Query") && variables.Context.InputParameters["Query"] is QueryExpression)
{
QueryExpression objQueryExpression = (QueryExpression) variables.Context.InputParameters["Query"];
//Generate and fill the ocr number field when requested
if (objQueryExpression.EntityName == Contact.EntityLogicalName && objQueryExpression.ColumnSet.Columns.Contains("company_generatedocr"))
{
if (objQueryExpression.LinkEntities.Count > 0 && objQueryExpression.LinkEntities.Count(le => le.LinkToEntityName == ListMember.EntityLogicalName) > 0)
{
var contacts = ((EntityCollection)variables.Context.OutputParameters["BusinessEntityCollection"]);
Guid relatedListGuid = (Guid)objQueryExpression.LinkEntities.First(le => le.LinkToEntityName == ListMember.EntityLogicalName).LinkCriteria.Conditions[0].Values[0];
CampaignExtensions.GenerateOcrNumbersForCollection(contacts, relatedListGuid, variables.Dao);
}
}
}
}
The CampaignExtensions (snipped irrelevant code)
The OCREngine used below is our tool for creating OCR numbers based on sequence numbers for e.g. contacts and campaigns, as well as interpreting the created numbers when the corresponding invoice is paid.
public static void GenerateOcrNumbersForCollection(EntityCollection entityCollection, Guid marketingListId, DataAccess dao)
{
var campaignSequenceNumber = GetCampaignSequenceNumberFromList(marketingListId, dao);
foreach (var entity in entityCollection.Entities)
{
string sequenceNumber = entity.GetSequenceValue(dao); //Get the sequence number for the contact
var spec = new OCRSpecification();
spec.DonorNumber = sequenceNumber;
spec.CampaignNumber = campaignSequenceNumber;
entity.Attributes.Add("company_generatedocr", OCREngine.GenerateOCR(spec));
}
}
The result
When exporting members for a marketing list with only one member, the file contains only one set of "processid" and "processts" columns (see below). When exporting 40 000 members, it contains 80 sets of these columns. These columns are not present in the view in Dynamics CRM.
Complete Name Generated OCR processid processts Henric Fröberg 800004450000165
My questions
- Why are these extra columns added?
- Why does there seem to be a correlation between the number of members exported and the number of columns added?
- What can we do to prevent this, to bring the file size of the exports down?
We're using Dynamics CRM 2016 on-premise, rollup 1 (8.1.0.359), but we've had difficulties exporting Excel files for marketing lists before installing rollup 1.