lunes, 19 de octubre de 2009

Contador de registros y páginas

El funcionamiento de las vistas y las búsquedas avanzadas permite a los usuarios de forma muy sencilla acceder a la información almacenada en el CRM.
A pesar de su sencillez, tiene una carencia importante y que casi siempre preguntan los usuarios finales: "¿Cómo sé cuantos registros totales me devuelve una vista?".
Existe una forma de facilitar la vida a los usuarios, creando un Plugin que se dispare recoja cuando se ejecute una vista (FetchXml) y que añada un registro como resultado en la primera posición, que nos dé esa información. Realmente será un registro "simulado" que permitirá al usuario saber fácilmente cuantos registros hay en una consulta. La idea la he recogido del Blog de a33ik.
El código siguiente muestra un contador de registros y páginas para las Cuentas y Contactos:

public void Execute(IPluginExecutionContext context)
{
if (context.Depth != 1) return;

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

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

if (entityName != EntityName.account.ToString() && entityName != EntityName.contact.ToString()) return; //solo para cuentas y contactos

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;

ICrmService crmService = context.CreateCrmService(true);

int pagecount = int.Parse(indoc.DocumentElement.Attributes["count"].InnerText);

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 con el resultado (sin paginación)
string fullResult = crmService.Fetch(indoc.OuterXml);

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

//registros por 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 de registros = {0}, Total de Páginas = {1}", totalRecordCount, totalPageCount);

//XML de Resultado que se muestra en el Grid
XmlDocument outdoc = new XmlDocument();
outdoc.LoadXml((string)context.OutputParameters["FetchXmlResult"]);

//Creacion del registro que muestra los totales
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);

//Añadir en registro con la etiqueta del contador de páginas y registros como primer registro en el recordset
outdoc.SelectSingleNode("//resultset").InsertBefore(res, outdoc.SelectSingleNode("//resultset").FirstChild);
context.OutputParameters["FetchXmlResult"] = outdoc.OuterXml;
}


La dll se puede descargar de aquí: RecordCounter y se debe registrar de la siguiente forma:


esto se verá de la siguiente forma:


espero les sirva...

un saludo

No hay comentarios:

Publicar un comentario