lunes, 3 de agosto de 2009

Filtros complejos en vistas de sharepoint

Algunas veces necesitamos realizar filtros complejos en vistas de listas, es decir, con información que debe ser leída previamente desde la base de datos. En estos casos una de las soluciones que he encontrado consiste en:

  1. Crear una application page.
  2. Hacer un spquery para obtener la información para armar el filtro
  3. Hacer un redirect a la página que contiene la vista, pasando como parámetros de la URL los filtros:

    .../AllItems.aspx?FilterField1=<>&FilterValue1=< >
    ó
    .../DispForm.aspx?ID=< >

Les dejo un pequeño ejemplo. Espero que les sea útil:

<%@Page language="C#" %>

<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Import Namespace="Microsoft.SharePoint" %>
<% %>

<%
SPWeb yq_web = SPContext.Current.Web;
SPList presup_list = yq_web.Lists["Presupuesto"];
SPQuery presup_query = new
SPQuery();
presup_query.ViewFields = "<FieldRef Name='ID'/>";
presup_query.Query = "<Where>" +
"<Eq>";
if (Context.Request["TipoPresup"] == "Proyecto") presup_query.Query += "<FieldRef Name='Proyecto' LookupId='TRUE'/><Value Type='Lookup'>";
if (Context.Request["TipoPresup"] == "Oferta") presup_query.Query += "<FieldRef Name='Oferta' LookupId='TRUE'/><Value Type='Lookup'>";
presup_query.Query += Context.Request["Proyecto"] + "</Value>" +
"</Eq>" +
"</Where>";

SPListItemCollection presup_items = presup_list.GetItems(presup_query);

if (presup_items.Count == 1)
{
SPListItem presup_id = presup_items[0];
Context.Response.Redirect("/gain/Lists/Presupuesto/DispForm.aspx?ID=" + presup_id["ID"].ToString() + "&Proyecto=" + Context.Request["Proyecto"] + "&TipoPresup=" + Context.Request["TipoPresup"] + "&Tit=" + Context.Request["Tit"] + "&Cons=" + Context.Request["Cons"]);
}
else
{
Context.Response.Redirect("/gain/Lists/Presupuesto/DispForm.aspx?ID=0&Proyecto=" + Context.Request["Proyecto"] + "&TipoPresup=" + Context.Request["TipoPresup"] + "&Tit=" + Context.Request["Tit"] + "&Cons=" + Context.Request["Cons"]);
};
%>

15 comentarios:

¿Cómo se crea una application Page?

Las application pages son páginas ASPX que se almacenan en un directorio especial de sharepoint llamado LAYOUTS. Te dejo un link que explica cómo hacerlo, cualquier duda no dejes de consultar.

http://msdn.microsoft.com/en-us/library/bb418732.aspx

Saludos,
Juan Pablo.-

Entonces desde el menú tendria que llamar a esta página y desde esta página a la de AllItem de la vista.

Así es. Desde el punto de vista del usuario será transparente. Sólo verá la página final.
Saludos.

Este filtro se podria realizar por los permisos que tenga asignado el item de la lista, es decir.El grupo1 tiene permiso para ver sobre el item1. ¿Se podria realizar el filtro sin tener que agregar otra columna (invisible) que fuera el grupo?

No entiendo porque se está realizando este bloque de código.
if (Context.Request["TipoPresup"] .....
¿Como deberia realizar esto para mi aplicación?

Hola Anónimo, respondo a tus consultas:

1) Cómo estás manejando el tema de permisos? Estás utilizando la seguridad de sharepoint a nivel de ítem? Porque se lo estás usando, la seguridad debería ser automática, sin necesidad de filtro.

2) En el ejemplo de este artículo, ese if sirve para armar la consulta a la lista de dos formas distintas dependiendo de un parámetro recibido por URL. Context.Request["TipoPresup"] lee el parámetro de la URL llamado TipoPresup.

Es justo a la solución que habia llegado antes de leer tu respuesta, asignar los premisos a nivel de item.

Muchas Gracias,

Me alegro que hayas llegado a una solución. Saludos.

hola necesito comparar datos de una lista en sharepoint para verificar que el dato que voy a ingresar no este en la listo.... como lo puedo hacer?

Hola! Si ejecutás la consulta con SPQuery como lo mostramos más arriba podrías comparar con la siguiente instrucción (siguiendo el mismo ejemplo):

if (presup_items.Count == 0)

Esto te indicaría que el elemento no existe en la lista y ejecutar el código que necesites.

Saludos, Sebastián.-

Hola, adicionalmente a lo que dice Sebastián, podrías hacer ese control en un evento que se ejecute en el momento que estés creando un registro en una lista. De esta manera el usuario podría recibir un mensaje del tipo "Duplicado" justo en el momento en que crea el registro.

Saludos, Juan Pablo.-

Hola Como estan todos;
tengoo una consulta, es un poco distinta a la tematica, pero igual es a serca de share point.
La situacion es la siguiente: tengo una libreria de datos en ella tengo varios archivos y una carpeta, dentro de esta carpeta tengo otros archivos, pero cuando extraigo los datos de los elementos de la libreria solo me muestra la informacion del los archivos y del la carpeta (pero no de los documentos dentro de la carpeta, muestra solo del primer nivel en la jerarquia), como podria hacer para mostrar la informacion de los documentos que se encuentran dentro de carpetas. uso web services.
Para extraer los datos uso la funcion lists.GetAttachmentCollection("libreria", "");

Gracias de ante mano por la ayuda que se me pueda facilitar

Hola!

No he usado ese webservice en particular, pero fijate en este enlace como lo resuelven:

http://www.sharepointkings.com/2010/05/download-all-documents-recursively-from.html

El detalle está aquí:

xmlQueryOptions.InnerXml = "";

Dime si te ha servido.
Saludos,

Juan Pablo.-

Blogger truncó el código, pero fijate en estas opciones:

ViewAttributes Scope=RecursiveAll
IncludeRootFolder=True

Publicar un comentario en la entrada