Dynamics CRM 2016为营销列表生成大量Excel文件

时间:2017-03-01 07:45:16

标签: c# excel dynamics-crm dynamics-crm-2016

背景
我们的一位客户将月度信息与发票一起发送给他们的联系人子集。这些联系人首先被添加到营销列表中,并且联系人'那么名称,地址信息和OCR号码 提取。将这些成员导出到Excel文件(因此可以将其发送以进行打印)时,我们的客户甚至在生成文件时遇到了大量问题。一旦我们成功,我们就意识到生成的Excel文件 大小约为550 MB,大约40k行,少于10列的名称和地址信息。过了一会儿,我们发现Dynamics CRM生成了另外160个隐藏列,不包含任何数据。删除 这些列使文件大小降低到更合理的4 MB。这些列在被命名为" processid"之间交替。和"过程"。

导出时不会发生此问题,例如来自高级查找的发票,所以我很想知道Dynamics CRM是否做了一些特别的事情,因为我们在这种情况下在导出时运行插件。

详情
我们的客户使用的流程更详细,如下:

  1. 创建了一个广告系列。此广告系列会获取序列号,即我们生成的唯一ID。
  2. 创建营销列表,并将其与广告系列相关联。
  3. 会员被添加到营销列表中。这些成员还有一个序列号,一个唯一的ID。
  4. 从营销列表表单切换到营销列表成员。
  5. 选择"导出视图",我们已创建的自定义视图。在我的最小代表中,此视图仅包含联系人的完整名称以及生成的OCR"字段。
  6. 触发在邮件联系人检索多个邮件上注册的插件,并根据其序列号加上广告系列的序列号为营销列表的每个成员创建一个OCR编号。然后将其添加到"生成的OCR"字段。
  7. 然后将视图导出到Excel。该插件再次被触发。
  8. 如果导出成功,则生成的文件包含许多空列,标记为" processid"和过程"。

  9. PostContactRetrieveMultiple插件

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


    广告系列扩展(剪切不相关的代码)
    下面使用的OCREngine是我们根据序列号创建OCR号码的工具。联系人和广告系列,以及在支付相应发票时解释创建的数字。

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


    结果
    当导出只有一个成员的营销列表的成员时,该文件只包含一组" processid"和"过程"专栏(见下文)。导出40 000个成员时,它包含80组这些列。 Dynamics CRM中的视图中不存在这些列。

        Complete Name    Generated OCR    processid    processts
        Henric Fröberg   800004450000165
    


    我的问题

    • 为什么要添加这些额外的列?
    • 为什么似乎有 导出的成员数与数量之间的相关性 列添加?
    • 我们可以做些什么来防止这种情况,带来文件大小 出口下降?

    我们正在使用Dynamics CRM 2016内部部署,汇总1(8.1.0.359),但在安装汇总1之前,我们在导出营销列表的Excel文件时遇到了困难。

1 个答案:

答案 0 :(得分:1)

据我们所知,平台中固有的东西可以添加这些额外的列。我们尝试从市场营销列表中导出的成员只使用默认解决方案中的列,并且仍然添加了processidprocessts列。然而,我们能够通过观察两个事实来解决这个问题。

<强>观察

  • 导出期间运行的查询包含一个LinkEntity,除了预期的listmember LinkEntity之外,它还与进程执行外连接。从Advanced Find查看(和导出)营销列表成员时,此LinkEntity不存在。
  • 添加的processidprocessts列的数量与查询的PageInfo.Count属性成反比。

操作
因此,到目前为止,对查询的以下修改似乎正在起作用:

  • 从查询中删除进程LinkEntity
  • 增加PageInfo.Count

<强>代码
这是通过添加PreContactRetrieveMultiple插件来完成的,该插件会相应地修改查询。该插件基本上如下所示:

public class PreContactRetrieveMultiple : CrmPlugin
{
    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"];

            var processQuery = query.LinkEntities.FirstOrDefault(le => le.LinkFromAttributeName == "processid");
            if (processQuery != null)
            {
                query.LinkEntities.Remove(processQuery);
            }

            query.ColumnSet = new ColumnSet(query.ColumnSet.Columns.Distinct().ToArray());
            query.ColumnSet.Columns.Remove("processid");
            query.ColumnSet.Columns.Remove("processts");

            query.PageInfo.Count = 5000;
        }
    }
}

<强>结果
随着PageInfo.Count的增加,这意味着视图将一次加载这5000条记录(而不是常规的50/100/250)。因此,加载页面通常需要一些时间,并且经常会弹出“无响应页面”警告。但是稍等一下,视图就会加载。导出时,processidprocessts仍将显示在文件中,但随着PageInfo.Count的增加,数量要小得多。文件大小现在大大减少,并且对于它包含的数据量更合理。

问题的答案

  • 我不知道为什么要添加这些额外的列。
  • 平台似乎为获取所有数据所需的每次分页添加一对列。
  • 上面显示的插件似乎可以解决问题,减少导出的文件大小。