web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :

Supported Record Counter For Microsoft Dynamics CRM 4.0

a33ik Profile Picture a33ik 84,331 Most Valuable Professional
I've already published code of record counter for Microsoft Dynamics CRM 4.0 in this post. Those record counter worked but it had some issues (lookups, advanced finds, form assistant).

I've upgraded the code and now it works perfectly.

UPD: according to comment of Moti Mendelovich to this thread i've one more time updated the code of the plugin and now it works even count of records in fetch response greater then 5000.

Code:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Win32;
using System.Xml;
using Microsoft.Crm.SdkTypeProxy.Metadata;
using Microsoft.Crm.Sdk.Metadata;

namespace RecordCounter
{
public class ExecuteHandler : IPlugin
{

#region IPlugin Members

public void Execute(IPluginExecutionContext context)
{
if (context.Depth != 1) //To calculate count of pages and records another one fetch will be executed
return;//so to avoid infinite loops i need to check the depth of request - if it more then 2 - return

if (context.MessageName == "Execute" && context.InputParameters.Contains("FetchXml"))
{
XmlDocument indoc = new XmlDocument();
indoc.LoadXml((string)context.InputParameters["FetchXml"]);

//Retrieve name of entity to display
string entityName = indoc.SelectSingleNode("//fetch/entity").Attributes["name"].InnerText;

if (entityName == EntityName.savedquery.ToString() ||//To make Advanced Find Work
entityName == EntityName.businessunitnewsarticle.ToString() ||//To make Literature work
entityName == EntityName.resource.ToString() ||//To make Service calendar work
entityName == EntityName.systemuser.ToString() ||//To make Service calendar work
entityName == EntityName.equipment.ToString() ||//To make Service calendar work
entityName == EntityName.asyncoperation.ToString())
return;

//Creation of Metadata service - it will be need for retrieving of main attribute of entity
IMetadataService mservice = context.CreateMetadataService(false);

RetrieveEntityRequest request = new RetrieveEntityRequest();
request.RetrieveAsIfPublished = false;
request.LogicalName = entityName;
request.EntityItems = EntityItems.EntityOnly;
string primaryFieldName = ((RetrieveEntityResponse)mservice.Execute(request)).EntityMetadata.PrimaryField;
//CrmService Creation
ICrmService crmService = context.CreateCrmService(true);

//Count of records by page - for calculation of pages count
int pagecount = int.Parse(indoc.DocumentElement.Attributes["count"].InnerText);

//I remove this attributes for retrieve of all records in current view
indoc.DocumentElement.Attributes.Remove(indoc.DocumentElement.Attributes["count"]);
indoc.DocumentElement.Attributes.Remove(indoc.DocumentElement.Attributes["page"]);

foreach (XmlNode node in indoc.SelectNodes("//fetch/entity/attribute"))
indoc.SelectSingleNode("//fetch/entity").RemoveChild(node);

foreach (XmlNode node in indoc.SelectNodes("//fetch/entity/order"))
indoc.SelectSingleNode("//fetch/entity").RemoveChild(node);

foreach (XmlNode node in indoc.SelectNodes("//fetch/entity/link-entity"))
foreach(XmlNode subnode in node.SelectNodes("./attribute"))
node.RemoveChild(subnode);

XmlAttribute aggrAttr = indoc.CreateAttribute("aggregate");
aggrAttr.Value = "true";
indoc.DocumentElement.Attributes.Append(aggrAttr);

XmlNode field = indoc.CreateNode(XmlNodeType.Element, "attribute", null);

XmlAttribute nameAttr = indoc.CreateAttribute("name");
nameAttr.Value = string.Format("{0}id", (entityName == EntityName.activitypointer.ToString() ? "activity" : entityName));
field.Attributes.Append(nameAttr);

XmlAttribute aggregateAttr = indoc.CreateAttribute("aggregate");
aggregateAttr.Value = "count";
field.Attributes.Append(aggregateAttr);

XmlAttribute aliasAttr = indoc.CreateAttribute("alias");
aliasAttr.Value = "C";
field.Attributes.Append(aliasAttr);

indoc.SelectSingleNode("//fetch/entity").AppendChild(field);

//Xml of full result (without paging)
string fullResult = crmService.Fetch(indoc.OuterXml);

XmlDocument fullResultDocument = new XmlDocument();
fullResultDocument.LoadXml(fullResult);

//Total record count by fetch
int totalRecordCount = int.Parse(fullResultDocument.SelectSingleNode("//resultset/result/C").InnerText);
int totalPageCount = (totalRecordCount / pagecount) + ((totalRecordCount % pagecount) == 0 ? 0 : 1);

string result = string.Format("Total records = {0}, Total pages = {1}", totalRecordCount, totalPageCount);

//Result XML which is the result shown in Grid
XmlDocument outdoc = new XmlDocument();
outdoc.LoadXml((string)context.OutputParameters["FetchXmlResult"]);

//Creation of record which will show totals
XmlNode ResultNodeText = outdoc.CreateNode(XmlNodeType.Element, primaryFieldName, null);
ResultNodeText.InnerText = result;

XmlNode ResultNodeId = outdoc.CreateNode(XmlNodeType.Element, string.Format("{0}id", (entityName == EntityName.activitypointer.ToString() ? "activity" : entityName)), null);
ResultNodeId.InnerText = Guid.Empty.ToString();

XmlNode res = outdoc.CreateNode(XmlNodeType.Element, "result", null);
res.AppendChild(ResultNodeText);
res.AppendChild(ResultNodeId);

XmlNode ResultNodeType;

//Following code repair icon for record counter icon
if (entityName == EntityName.activitypointer.ToString())
{
ResultNodeType = outdoc.CreateNode(XmlNodeType.Element, "activitytypecode", null);
ResultNodeType.InnerText = "4212";
res.AppendChild(ResultNodeType);
}

//This code repair report view
if (entityName == EntityName.report.ToString())
{
ResultNodeType = outdoc.CreateNode(XmlNodeType.Element, "reporttypecode", null);
ResultNodeType.InnerText = "1";
res.AppendChild(ResultNodeType);
}

//Adding record with label of count of pages and records as a first record in recordset
outdoc.SelectSingleNode("//resultset").InsertBefore(res, outdoc.SelectSingleNode("//resultset").FirstChild);
context.OutputParameters["FetchXmlResult"] = outdoc.OuterXml;
}
}

#endregion

}
}


Registration of the step for this plugin:



And screenshots:

Advanced find:



Lookup:



Public and private views:



Quick find:



Form assistant:



Auto resolve lookup view:



Source code you can download here.

This was originally posted here.

Comments

*This post is locked for comments