EJEMPLO 4. MATRIZ En este ejemplo vamos a ver la forma de crear matrices de datos en el informe. Las matrices son tablas con el número de columnas variable. Para ello disponemos de una clase, llamada ClaseMatricula, con la definición de la clase y otra, llamada ClaseMatriculas, que devuelve un listado de las mismas. Esta clase devuelve las personas matriculadas de cada universidad en cada estudio. Empezamos creando un nuevo elemento “Web Form” llamado ejer4.aspx. CREAMOS EL INFORME A continuación, vamos a crear el informe (Botón derecho sobre el proyecto y “Agregar nuevo elemento…” de tipo informe. A este elemento le vamos a añadir un nuevo conjunto de datos llamado “DataSetMatriculaciones”. Para añadir el nuevo conjunto de datos hay que darle a la opción añadir de los datos del informe. Una vez añadidos los datos, arrastramos un elemento matriz. Y le arrastramos el dato “PaisUni” en las columnas, el dato “Facultad” en las filas y en datos ponemos “[Count(Nif)]”. Esto creará una tabla con el número de matriculados de cada facultad por país. ENLAZAMOS LOS DATOS Para poder ver el informe en el formulario creado al principio del ejemplo, debemos arrastrar un componente ReportViewer con un ScriptManager. Una vez añadidos, escribimos el siguiente código en el método Page_Load. El código enlaza los datos con el informe y le dice que datos debe mostrar. if(!IsPostBack) { ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add( new ReportDataSource("DataSetMatriculaciones", new ClaseMatriculas().Todos())); ReportViewer1.LocalReport.ReportPath = "Report.rdlc"; ReportViewer1.LocalReport.Refresh(); } El Resultado es el siguiente: Vemos que tenemos los alumnos matriculados en cada facultad por país. GRUPOS PRIMARIOS U SECUNDARIOS Al igual que ocurría en las tablas, podemos agrupar los datos en subgrupos. A estos subgrupos se les denomina grupos secundarios. En el ejemplo vamos a hacer que se nos muestren las universidades de cada país y los estudios de cada facultad. No tenemos más que arrastrar el subgrupo o grupo secundario a la matriz, debajo del grupo primario. El resultado será el siguiente: GRUPOS ADYACENTES Además de grupos primarios y secundarios, podemos crear grupos adyacentes. Estos grupos actúan independientemente de los otros grupos y, dan como resultado, una tabla creada como si hubiésemos creado dos. Para que quede mas claro veamos el ejemplo. Además de la separación de las matriculaciones por país y por universidad, queremos saber los matriculaciones por año. Para crear un grupo adyacente, vamos al menú de grupos y pulsamos sobre la pestaña del grupo “PaisUni”, ya que vamos a crear un grupo adyacente a él. En su menú elegimos “Agregar grupo/Adyacente posterior…” y seleccionamos que agrupe por “Anyo”. Se nos habrá creado el nuevo grupo con el siguiente resultado. Recordar poner “[Count(Nif)]” como dato del nuevo grupo. TOTALES Los totales en las matrices actúan de la misma forma que en las tablas. Se pueden crear totales tanto para los grupos primarios como de los secundarios y los adyacentes. Además se pueden crear totales de los grupos de filas y de los grupos de columnas. En nuestro ejemplo crearemos totales globales tanto en las columnas como en las filas. Para ello solamente agregaremos el total en los grupos primarios y adyacentes. Recordar que para agregar un total hay que seleccionar el grupo en menú inferior de grupos y elegir “Agregar total”. Como resultado tenemos el siguiente: FORTALEZA DE LAS MATRICES La gran fortaleza de las matrices es que crea las filas y las columnas según los datos de la consulta. Por tanto, si variamos los datos, nos variará el resultado sin modificar nuestro informe. Para comprobarlo abrimos la clase ClaseMatriculas. En la parte que crea el listado con todos sus elementos vamos a añadir dos elementos nuevos: lista.Add(new ClaseMatricula() { Nif = "88888880A", NombreCompleto = "Nombre usu71", Facultad = "Derecho", Estudio = "Derecho", Universidad = "UB", PaisUni = "Alemania", Anyo = "2011" }); lista.Add(new ClaseMatricula() { Nif = "88888881A", NombreCompleto = "Nombre usu72", Facultad = "Derecho", Estudio = "Criminologia", Universidad = "UB2", PaisUni = "Alemania", Anyo = "2011" }); Hemos añadido como dato dos alumnos de un nuevo país, en universidades diferentes. Ahora comprobaremos como, al vuelo, se van a crear las nuevas columnas. OCULTAR SUBGRUPO Existe la posibilidad de ocultar un subgrupo según el valor de un determinado parámetro. Para hacerlo, debemos pulsar con el botón derecho sobre el grupo y seleccionar “Propiedades de grupo…”. En la solapa “Visibilidad” podremos hacer que ese grupo no se vea en la matriz. NOTA: En la versión actual de Visual estudio esta opción tiene un bug y no muestra elementos, veamos en el próximo punto como solucionarlo. Observamos que no salen datos para el grupo PaisUni por causa de un bug. VISUALIZACIÓN INTERACTIVA Podemos hacer que un elemento haga que un subgrupo se muestre o no. Vamos a arrastrar un cuadro de texto y hacer que al pincharlo muestro o oculte el subgrupo. Arrastramos un elemento “cuadro de texto” y escribimos en él “Ver/ocultar subgrupo”. Al cuadro de texto le vamos a poner el nombre “TextboxActivar”. Pulsamos botón derecho sobre el subgrupo y seleccionamos “Propiedades de grupo…”. En la solapa “Visibilidad” elegimos lo siguiente: Esto hará que el cuadro de texto active o desactive la visualización del subgrupo. Ahora, si quisiéramos saltarnos el bug y sacar la matriz sin mostrar el subgrupo, podríamos ocultar el cuadro de texto que interacciona con él y se quedaría oculto por defecto. Esto no tiene mucho sentido, pero podríamos pasar un parámetro y ocultarlo o no en función del valor del parámetro. CLASEMATRIZ Una matriz crea sus filas, columnas y datos en función de los datos que contiene el dato que agregamos a los campos de la matriz. Es decir, si le decimos a una matriz que debe de mostrar los países como columnas, solamente funcionará si uno de los datos se llama países. Si quisiéramos que el informe nos muestre otros datos, como por ejemplo los de ClaseVenta, tendríamos que crear otro informe con otra matriz diferente. ¿Cómo podemos hacer que, independientemente del nombre de los campos, se cree una matriz según la sentencia o clase que utilicemos para enlazar los datos? Vamos a crear una clase llamada ClaseMatriz, la cual utilizaremos para crear una matriz genérica y, de esa forma, rellenarla sea cual sean sus datos. public class ClaseMatriz { public string Columna { get; set; } public string Subcolumna { get; set; } public string Fila { get; set; } public string Subfila { get; set; } public string Dato { get; set; } public ClaseMatriz() { Columna = ""; Subcolumna = ""; Fila = ""; Subfila = ""; Dato = ""; } } Ahora haremos un método en ClaseMatriculas y otro en ClaseVentas que devuelva los valores como un listado de ClaseMatriz. Estos métodos deberían de leer los elementos de la base de datos, pero como los datos los tenemos estáticos por el mal funcionamiento de la red del aula, los leeremos del método que los devuelve todos. Así quedará el método de ClaseMatriculas: public List<ClaseMatriz> Matriculas() { List<ClaseMatriz> lista = new List<ClaseMatriz>(); foreach(var mat in Todos()) { lista.Add(new ClaseMatriz() { Columna = mat.PaisUni, Subcolumna = mat.Universidad, Fila = mat.Facultad, Subfila = mat.Estudio, Dato = mat.Nif }); } return lista; } Y así quedará el método de ClaseVentas. public List<ClaseMatriz> Ventas() { List<ClaseMatriz> lista = new List<ClaseMatriz>(); foreach (var mat in Filtrar()) { lista.Add(new ClaseMatriz() { Columna = mat.Pais, Subcolumna = mat.Region, Fila = mat.Categoria, Subfila = mat.Subcategoria, Dato = mat.Total.ToString() }); } return lista; } Ahora crearemos el informe con los nuevos datos. Creamos un informe llamado InformeMatriz.rdlc y agregamos la matriz de tal forma que quede así (al DataSet de los datos les llamaremos DataSetMatriz en el ejemplo): Ahora es el momento de enlazar los datos. Para ello vamos a crear un nuevo elemento “Web Form” con nombre ejeMatriz.aspx y situaremos en el dos botones. La idea es hacer que, dependiendo del botón que pulsemos, se verán unos datos o otros. Además de los dos botones, vamos a agregar un ReportViewer y un ScriptManager. Con las propiedades de los botones les cambiamos su nombre y, pulsando doble click sobre cada uno de ellos, creamos los eventos que se ejecutan al pulsar sobre ellos. Al primer botón le llamaremos Matriculaciones y en su evento Click insertaremos el siguiente código: ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add( new ReportDataSource("DataSetMatriz", new ClaseMatriculas().Matriculas()) ); ReportViewer1.LocalReport.ReportPath = "InformeMatriz.rdlc"; ReportViewer1.LocalReport.Refresh(); Al segundo botón le llamaremos Ventas y su evento Click tendrá el siguiente código: ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add( new ReportDataSource("DataSetMatriz", new ClaseVentas().Ventas())); ReportViewer1.LocalReport.ReportPath = "InformeMatriz.rdlc"; ReportViewer1.LocalReport.Refresh(); PASAR PARÁMETROS CON NOMBRES DE MATRIZ Si nos fijamos en el resultado, nos saldrá el nombre de “filas y “subfilas” en la cabecera de la matriz. Esto se puede quitar, pero vamos a hacer que lo definamos nosotros por parámetro. Agregamos dos nuevos parámetros “Nuevo/parámetro…”). en los “Datos del informe” (Pulsar sobre Vamos a crear dos parámetros con los nombre de “NombreFila” y “NombreSubfila” y que sean del tipo texto. Esos parámetros los arrastramos a la matriz para que se muestren en ella: Ahora solamente nos queda pasar los parámetros desde en evento de los botones. El botón de las matriculaciones quedará así: ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add( new ReportDataSource("DataSetMatriz", new ClaseMatriculas().Matriculas()) ); ReportViewer1.LocalReport.ReportPath = "InformeMatriz.rdlc"; ReportParameter[] parametros = new ReportParameter[2]; parametros[0] = new ReportParameter("NombreFila", "Facultades"); parametros[1] = new ReportParameter("NombreSubfila", "Estudios"); ReportViewer1.LocalReport.SetParameters(parametros); ReportViewer1.LocalReport.Refresh(); Y el evento del segundo botón: ReportViewer1.LocalReport.DataSources.Clear(); ReportViewer1.LocalReport.DataSources.Add( new ReportDataSource("DataSetMatriz", new ClaseVentas().Ventas())); ReportViewer1.LocalReport.ReportPath = "InformeMatriz.rdlc"; ReportParameter[] parametros = new ReportParameter[2]; parametros[0] = new ReportParameter("NombreFila", "Categorias"); parametros[1] = new ReportParameter("NombreSubfila", "Subcategorias"); ReportViewer1.LocalReport.SetParameters(parametros); ReportViewer1.LocalReport.Refresh(); OCULTAR O VISUALIZAR SUBGRUPOS Para practicar lo que hemos aprendido anteriormente, vamos a añadir un elemento que al pulsarlo muestre u oculte un subgrupo. Esta vez, y para darnos cuenta de la potencia de este elemento, vamos a hacer que el propio grupo sea el encargado de mostrar o no su subgrupo. Pulsamos sobre el botón derecho sobre el subgrupo “Subcolumna” y seleccionamos “Propiedades de grupo…”. En la pestaña Visualizar, activamos la opción de activar o desactivar el elemento y seleccionamos el nombre del grupo que va a hacer esta función. Si vemos el resultado, ahora podremos ocultar los subgrupos del grupo que queramos independientemente, sin que se oculten para los demás grupos. También, como hemos explicado anteriormente, podemos ocultar o mostrar en función de un parámetro o valor. Vamos a hacer que para la matriz de matriculaciones inicialmente aparezca el grupo visible y para la de ventas oculto. En la solapa visualizar anterior, deberemos elegir la opción “Mostrar u ocultar en función de una expresión” y, le asignamos la siguiente: =IIf(Parameters!NombreFila.Value = "Facultades", false, true)