martes, 28 de julio de 2009

GROUP BY en sharepoint

El problema

¿Es posible hacer una consulta en sharepoint como la que haríamos en SQL?

SELECT SUM(importe) FROM Pedidos GROUP BY Cliente, Producto

La respuesta es NO, al menos en Sharepoint 2007. No he encontrado la forma de hacer un group by en un spquery. La documentación que hay al respecto es un tanto confusa. Existe el tag <GroupBy> en CAML, pero sólo puede ser usado para crear vistas. De hecho las vistas que un usuario puede crear contienen una sección de agrupamiento. Bueno, lo mismo puede hacerse en forma programática, pero sólo para crear una vista, no para hacer un query. Para más información consultar http://msdn.microsoft.com/en-us/library/ms415157.aspx

El work-around

A continuación les muestro una manera de resolver el problema con un work-around. Lo considero work-around, porque es poco práctico y poco escalable, pero será útil en algunas situaciones. Consiste básicamente en realizar la consulta y luego sumar en forma manual.

Ejemplo:


SPWeb web = SPContext.Current.Web;


SPList list = web.Lists["Imputaciones"];



SPQuery query = new SPQuery();

query.ViewFields =

"<FieldRef Name='Importe_x0020_insumido'/>

<FieldRef Name='Importe_x0020_estimado'/>

<FieldRef Name='Importe'/>

<FieldRef Name='Liquidaci_x00f3_n'/>

<FieldRef Name='ContentType'/>";

query.Query =

"<Where>" +

"<Eq>" +

"<FieldRef Name='Proyecto' LookupId='TRUE'/><Value Type='Lookup'>" +

Context.Request["Proyecto"] + "</Value>" +

"</Eq>" +

"</Where>" +

"<OrderBy><FieldRef Name='Title'/></OrderBy>";



SPListItemCollection items = list.GetItems(query);



int sum_equipo_real = 0;


int sum_contra_real = 0;

(...)



foreach (SPListItem imp_item in imp_items)

{


switch (imp_item["Tipo de contenido"].ToString())

{


case
"Horas insumidas" :

if (imp_item["Importe insumido"] != null)

sum_equipo_real += Convert.ToInt32(imp_item["Importe insumido"].ToString()); break;


case
"Horas estimadas" :

if (imp_item["Importe estimado"] != null)

sum_equipo_plan += Convert.ToInt32(imp_item["Importe estimado"].ToString()); break;

(...)

}

}


label_equipo_plan.Text = string.Format("{0:c}", sum_equipo_plan);

label_equipo_real.Text = string.Format("{0:c}", sum_equipo_real);

label_equipo_porc.Text = (sum_equipo_real*100/sum_equipo_plan).ToString() + " %";

label_equipo_desv.Text = string.Format("{0:c}", sum_equipo_plan - sum_equipo_real);


(...)


Como habrán visto, es un poco "manual", pero permite salir del paso. Se aceptan sugerencias. Hasta la próxima.

0 comentarios:

Publicar un comentario en la entrada