25 abril 2013

Convertir QueryExpression a FetchXml

- Cuando realizamos consultas mediante RetrieveMultiple en CRM 2011, resulta más óptimo enviar como parámetro la consulta construida en FetchXml que en QueryExpression, podemos comprobar estos resultados comparando los tiempos de respuesta mediante StopWatch

- Una ventaja significativa de utilizar FetchXml en nuestras consultas es además el soporte a funciones de agrupación y agregados, por ejemplo 'AVG' o 'SUM'

- En caso de tener la consulta ya construida en QueryExpression, podemos hacer uso del mensaje QueryExpressionToFetchXmlRequest para recuperar la consulta enviada en QueryBase en forma de FetchXml

- En este ejemplo tenemos la siguiente consulta en QueryExpression:

QueryExpression query_exp = new QueryExpression();
query_exp.EntityName = ServiceAppointment.EntityLogicalName;
query_exp.ColumnSet = new ColumnSet(new string[] { "actualstart", "subject" });

ConditionExpression c_owner = new ConditionExpression("ownerid", 
    ConditionOperator.EqualUserId);

ConditionExpression c_state_Open = new ConditionExpression("statecode", 
    ConditionOperator.Equal, (int)ServiceAppointmentState.Open);
ConditionExpression c_state_Scheduled = new ConditionExpression("statecode", 
    ConditionOperator.Equal, (int)ServiceAppointmentState.Scheduled);

FilterExpression f_sa_state = new FilterExpression(LogicalOperator.Or);
f_sa_state.Conditions.AddRange(new ConditionExpression[] 
    { c_state_Open, c_state_Scheduled });

ConditionExpression c_actualend = new ConditionExpression("actualend", 
ConditionOperator.Between, new object[] { new DateTime(2012, 6, 1), 
    new DateTime(2013, 6, 1) });

FilterExpression f_sa = new FilterExpression(LogicalOperator.And);
f_sa.AddCondition(c_actualend);
f_sa.AddFilter(f_sa_state);

ConditionExpression c_state_Active = new ConditionExpression("statecode", 
    ConditionOperator.Equal, (int)AccountState.Active);
FilterExpression f_account = new FilterExpression(LogicalOperator.And);
f_account.AddCondition(c_state_Active);

LinkEntity link_activity_pointer = new LinkEntity();
link_activity_pointer.LinkFromEntityName = ServiceAppointment.EntityLogicalName;
link_activity_pointer.LinkFromAttributeName = "activityid";
link_activity_pointer.LinkToEntityName = ActivityParty.EntityLogicalName;
link_activity_pointer.LinkToAttributeName = "activityid";

LinkEntity link_account = new LinkEntity();
link_account.LinkFromEntityName = ActivityParty.EntityLogicalName;
link_account.LinkFromAttributeName = "partyid";
link_account.LinkToEntityName = Account.EntityLogicalName;
link_account.LinkToAttributeName = "accountid";
link_account.LinkCriteria = f_account;

link_activity_pointer.LinkEntities.Add(link_account);

query_exp.Criteria = f_sa;

query_exp.LinkEntities.Add(link_activity_pointer);

EntityCollection svcApps = CrmSvc.RetrieveMultiple(query_exp);


- Para obtener el equivalente a la consulta en FetchXml añadiremos las siguientes líneas de código al programa:

QueryExpressionToFetchXmlRequest convert_request = new QueryExpressionToFetchXmlRequest();
convert_request.Query = query_exp;
QueryExpressionToFetchXmlResponse convert_response = 
    (QueryExpressionToFetchXmlResponse)CrmSvc.Execute(convert_request);
Console.WriteLine(convert_response.FetchXml);


- El resultado indentado de la cadena devuelta por la respuesta es el siguiente




Desde Innovar Tecnologías esperamos que este documento les sea de ayuda en su desarrollo

09 abril 2013

Despliegue de campos Listbox

- Los tipos de datos para campos disponibles en CRM no incluyen tipo de dato list box para marcado de múltiples opciones. Pero es posible desplegar esta funcionalidad mediante scripts en el formulario

- En este ejemplo vamos a generar una lista de múltiple selección para un campo denominado 'Productos de interés' en la entidad Account


- El despliegue incluye los siguientes componentes

- Un campo option set para dinamizar los valores incluidos en la lista

- Un web resource js para desplegar el listbox en el formulario

- Un campo multilínea para almacenar las opciones marcadas en valores separados por coma


- El código en el evento onLoad del formulario para desplegar la lista es el siguiente:

function displayList(optionSet) {

    var allProducts = optionSet.getOptions();

    var tdProducts = document.getElementById('new_productosinteres_d');
    tdProducts.innerHTML = "";
    listProducts = "<div style='overflow-y:auto; height:200px;'>";
    listProducts += "<table>";

    for (var i = 1; i < allProducts.length; i++) {

        listProducts += "<tr><td width='20px'>";
        listProducts += "<input width='20px' 
            + onclick='addProduct(this)' id='product_" + i 
            + "' type='checkbox' value='" + allProducts[i].text + "'>";
        listProducts += "</td><td>";
        listProducts += "<label for='product_" + i + "'>" 
            + allProducts[i].text + "</label>";
        listProducts += "</td></tr>";
    }

    listProducts += "</table></div>";

    tdProducts.innerHTML += listProducts;
}


- Y el código de control para completar el campo multilínea a continuación:

function addProduct(item) {

    var selectedProducts = Xrm.Page.getAttribute("new_productosinteres").getValue();

    if (item.checked) {

        Xrm.Page.getAttribute("new_productosinteres").setValue(selectedProducts
            + "," + item.value);
    }
    else {

        selectedProducts = selectedProducts.replace("," + item.value, "");
        Xrm.Page.getAttribute("new_productosinteres").setValue(selectedProducts);
    }
}


El resultado es el siguiente




Desde Innovar Tecnologías esperamos que este documento les sea de ayuda en su desarrollo