[How To] Reporting Services sin IIS y sin servidor de informes
Desde que abrí mi primer post sobre Reporting Services (hace ya un tiempo), he tenido muchos comentarios. Muchos me han ayudado a investigar cosas que no había usado nunca de Reporting y otros al escribirme como lo habían hecho, me ayudaron a saber algo más acerca de esta tecnología.
Algunas dudas, han sido como trabajar con informes sin tener que utilizar un servidor de informes, como pasarle a un informe de este tipo parámetros o como trabajar con el dataset de este.
El otro día (bueno, ya hace unos cuantos) estuve con el amigo Alberto viendo algunos problemillas que tenía con Reporting y después de ver entre los dos como tratar con este tipo de informes, me decidí a postearlo para la comunidad. Aunque desde que lo hicimos, ha pasado un poco de tiempo :P.
Lo primero, creamos un nuevo proyecto de tipo Windows Forms, luego agregamos un control ReportViewer(1). Este lo podemos encontrar en la caja de herramientas en la parte de datos.
Luego, ajustamos el control a nuestro gusto o en nuestra interfaz, y en la pestaña superior derecha, podemos seleccionar crear un nuevo informe(2).
Al crear un informe de esta forma, nos crea un archivo dentro del a aplicación con extensión .RDLC. Esto nos indica que este informe es de tipo local, por lo que diseñar es casi igual que cuando creamos uno de tipo servidor.
La diferencia principal de uno y otro es que en el de tipo local, no podemos ver, escribir y retocar la fuente de datos como lo hacíamos en el de tipo servidor. Con lo que no podremos pasarle parámetros de la misma forma y ni con todas las otras ventajas. Tampoco trae la vista de preview, pero da igual porque con ejecutar este formulario veremos nuestro informe.
Aunque parece una desventaja, no siempre se necesita o se puede montar un servidor de IIS para ello. Y no por ello significa que no podamos trabajar cómodamente con fuentes de datos en nuestro informe.
Ahora para paliar los problemas de esta forma de trabajar, voy añadirle yo mi propia fuente de datos. Esta tiene que tener los mismos campos que se le pasan al informe para que no nos muestre error. Eso sí, una aclaración, si ponemos más campos de la cuenta no pasará nada, si ponemos campos de menos nos dará un error al cargar el informe.
Para utilizar el ejemplo de prueba que podéis descargar desde aquí, he utilizado la base de datos AventureWorks y en concreto la tabla Production.Product.
Cuando agregamos un nuevo informe al proyecto, este nos pide una fuente de datos y una/s tabla/as. Con esto nos creará una dataset que vinculado al informe, automáticamente vinculará al evento Load al crearlo, junto con otra línea que refresca el report. Estas líneas las quitaremos del evento por estas otras:
DataSet ds = new DataSet();
using (SqlConnection conexion =
new SqlConnection("Nuestra conexión a la base de datos"))
{
using (SqlDataAdapter da =
new SqlDataAdapter("Select top (1) * from production.product", conexion))
{
da.Fill(ds);
}
}
// Eliminamos las fuentes de datos para no crear una nueva. Si tenemos más, con
// recorrerlas nos basta
this.reportViewer1.LocalReport.DataSources.RemoveAt(0);
// Creamos un nuevo datasource para nuestro informe y le
// pasamos la tabla con los datos que queremos que se muestre.
ReportDataSource datasource =
new ReportDataSource ("AdventureWorksDataSet_Product", ds.Tables[0]);
// Agregamos el datasource.
this.reportViewer1.LocalReport.DataSources.Add(datasource);
// Refrescamos el informe.
this.reportViewer1.RefreshReport();
Bueno, lo que hacemos es traernos nuestro dataset con los datos que queremos para nuestro informe, luego borramos la asociación entre el informe y el dataset. Con esto nos evitamos que haya dos fuentes de datos, una la que ya hay al cargar el informe y otra la que agregaremos luego. Bueno, pues después tan sólo tenemos que crear una nueva fuente de datos con el dataset y agregarla al informe.
Por último se refresca el report y listo, ya tenemos nuestro informe listo para ejecutarse. Por último decir que este trozo de código, no tiene porque ir en el evento Load de nuestra aplicación, sino que se puede llamar desde cualquier otro evento o método. Con esto y nuestra imaginación, podemos hacer SQLs personalizadas y añadirles cuantos parámetros creemos oportunos :D.
Para poder trabajar con algunos objetos, necesitaremos importar el siguiente espacio de nombres: using Microsoft.Reporting.WinForms;
Espero que os sea de utilidad.
Un Saludo