domingo, 15 de enero de 2012

Generar informes en Visual Studio usando el control ReportViewer

Hola,
en este primer post del 2012 voy a centrarme en explicar cómo generar informes para nuestras aplicaciones o sitios web con los datos que tenemos en la base de datos. Para ello voy a crear un sitio web al que le añadiré el control ReportViewer.  El ejemplo es para C# pero sería igual para Visual Basic ya que las líneas de código son pocas y similares y prácticamente quien sabe programar en Visual Basic no le debe plantear problemas C#. En versiones de Visual Studio anteriores a la 2010 también estaba la alternativa de Crystal Reports, pero tenía el problema de al ser una versión gratuita estaba limitada a que no hubiera más de 5 personas al mismo tiempo generando informes. Ésto en una aplicación de escritorio que no estuviera en red no plantearía problemas, pero en un sitio web colgado en un servidor con miles de conexiones al mismo momento era un poco frustrante. De hecho aún podrías descargar e instalar Crystal Reports para tu Visual Studio ya que existe la versión gratuita. Si te fijas en el instalador verás las 3 letras mágicas por el que ya no viene de serie al instalar Visual Studio 2010 (SAP).
Bueno a lo que iba. Poder hacer informes es una de las cosas más interesantes que se pueden hacer con los datos almacenados en nuestra base de datos. Está bien tener los datos guardados pero esos datos hay que usarlos. Puedes consultar los datos de tus clientes, puedes generar archivos de texto o xml para luego subirlos a un servidor, o por ejemplo puedes usarlos para hacer informes. Cuando digo informes, puedo hablar de informes estadísticos donde se analice la media aritmética, la moda y demás indicadores de la estadística descriptiva para una muestra de datos, informes de análisis de la situación financiera y/o patrimonial de una empresa tipo cuadro de mando integral, informes de notificaciones, o por ejemplo informes tipo facturas emitidas a los proveedores. Este último es muy útil ya que a al tener todas las facturas de ventas en tu base de datos, ya puedes saber si vendes más o menos, puedes saber si una rama de actividad te está generando pérdidas o, ya más propiamente para la gente como yo que se encarga de gestionar la empresa, puedes saber lo que hay que rellenar en las casillas del IVA repercutido del modelo 303. Así doy ideas, ya que automatizarlo todo no es muy difícil si sabes lo que buscas y lógicamente has diseñado correctamente tu base de datos para que haciendo las consultas necesarias obtengas esta información.
Pues bien voy a ver un poco de todo. Voy a explicar cómo crear usando el phpMyAdmin  una base de datos MySQL con una única tabla llamada países. Luego como he dicho voy crear un Sitio Web usando C# que se conectará a esta base de datos y que me mostrará a través del control ReportViewer un informe referente a los habitantes de cada uno de los países que tengo en la base de datos así como un gráfico de barras. A parte el usuario podrá filtrar la información que aparecerá en el informe por el número de habitantes.
Esto es importante: para filtrar los datos se puede hacer de 2 formas. En cualquiera de las 2 formas primero hemos editado el DataSet con el diseñador y hemos añadido una consulta que nos devolverá los países cuya población sea superior a la indicada en el parámetro @valor (guardada con el nombre de FillByGente).
Pues bien si queremos filtrar el informe vía código habría que añadir el siguiente código al evento Click de un botón que en mi ejemplo recibe el nombre de ‘Filtrar’:
    protected void Button1_Click(object sender, EventArgs e)
    {
        datosDataSetTableAdapters.paisesTableAdapter ta = new datosDataSetTableAdapters.paisesTableAdapter();
        datosDataSet.paisesDataTable tabla = new datosDataSet.paisesDataTable();
        ta.FillByGente(tabla, int.Parse(TextBox1.Text));

        ReportViewer1.LocalReport.DataSources.Clear();
        ReportDataSource datasource = new ReportDataSource("DataSet1", (DataTable)tabla);
        ReportViewer1.LocalReport.DataSources.Add(datasource);
        ReportViewer1.LocalReport.Refresh();
    }
Lo único que hace el código es crear un objeto paisesTableAdapter llamado ta y un objeto paisesDataTable llamado tabla (lógicamente la table se llama países). El objeto ta tiene el método creado FillByGente que toma como argumentos el DataTable y el contenido de la caja de texto TextBox1. Gracias a este método FillByGente del TableAdapter rellenamos el DataTable. Pues bien ahora borramos los DataSources que tiene nuestro componente ReportViewer y le añadimos uno nuevo que contiene el DataTable con los datos ya filtrados. Finalmente con el método Refresh() refrescamos los datos.
La segunda alternativa es más sencilla y el único código que habría que usar en el evento Click del botón ‘Filtrar’ es:
 ReportViewer1.LocalReport.Refresh();
Para ello yo utilizaré el origen de datos que se me ha agregado al proyecto llamado ObjectDataSource1 y lo configuraré para que en el método SELECT no me utilice el método GetData() que viene por defecto sino el método GetDataByGente(Int32 valor) que toma como parámetro un Int32 llamado valor que representa la población que el usuario ingresa en la caja de texto TextBox1. Visual Studio esto lo sabe y nos mostrará una pantalla para que le digamos donde se encuentra el origen del parámetro. Seleccionamos en ControlID  el TextBox1, que es el lugar donde el usuario indicará el número habitantes para que se filtre el informe por aquellos países cuyo número de habitantes es mayor o igual al indicado por el usuario en este TextBox1.
Como siempre  cuelgo un vídeo en el que todo quedará más claro.

Bueno en la siguiente entrada colgaré una pequeña aplicación relacionada con temas de impuestos y como una de las opciones de esta aplicación es la de generar pdfs expliaré el proceso de cómo crear pdfs de forma fácil, pero está vez tanto para Visual Basic como para Java, usando iTextSharp e iText.