De modo que obtengamos el siguiente código:
Agregar: ScriptManager, el cual es necesario para el control visor de informes. Entonces en la página rptProductosAgotadosYPorAgotarse.aspx tenemos que agregar el siguiente código:
También vamos a editar las propiedades del vi sor de informes de modo que nos quede de la siguiente manera:
Hemos denominado a nuestro control Visor de Informes como rvProductos y especificado
un
ancho
y
alto.
Y
es
necesario
especificar
la
propiedad
SizeToReportContent a True para que el visor se adapte al bloque o división que lo contiene.
Si volvemos a ejecutar la aplicación y damos click en el botón consultar del reporte que estamos construyendo, obtendremos lo siguiente:
38
7) Crear DataTable Usaremos el archivo DataSet creado en el reporte anterior, se muestra un área de diseño, en el cual añadiremos otro DataTable, que serán las fuentes de datos que alimentarán el reporte. Para esto, hacer click derecho en el área de diseño, click en la opción: Add / DataTable, cambiar el nombre DataTable1 por: dtProductosStockMinimoActual. Es necesario agregar los campos del DataTable, que representaran a las columnas que devuelve una instrucción select o las columnas de un conjunto de registros que devuelve un procedimiento almacenado, para ello, presionar CTRL + L, para agregar una nueva columna, o hacer click derecho sobre el DataTable y escoger: ADD / Column y escribir el nombre de la columna. Al seleccionar una columna se puede editar sus propiedades en el panel de propiedades, una de sus propiedades es: DataType, que nos indica el tipo de dato de la columna, por defecto es String, y hay que tener cuidado de indicar el tipo adecuado de la columna cuando estas sean numéricas y se vaya a realizar cálculos sobre dichas columnas. Entonces, el DataTable debe quedar de la siguiente manera:
8) Crear Reporte RDLC Click derecho sobre carpeta Productos (ubicada dentro de la capeta Reportes), Opción Agregar Nuevo Item. En la parte derecha, seleccionamos Reporting y en la parte izquierda Report. Esta opción nos permitirá crear un reporte en blanco desde cero. A continuación, indicamos un nombre para el Reporte: rptProductosAgotadosYPorAgotarse.rdlc.
39
Agregar una cabecera y un Pié de Página al informe. En la cabecera colocar un título: Listado de Productos por Grupo, insertar una imagen a la izquierda de la cabecera y a la derecha de la cabecera colocar: Fecha, Hora y Usuario logeado tal como se explicó en el Reporte anterior. En el pié de página colocar el Número de Página actual del Número de Páginas Totales.
En el cuerpo del informe hacer click derecho, opción Insert y hacer click en Table.
40
9) Insertar primera tabla y configurar primer dataset para productos agotados Antes de insertar la tabla aparecerá un modal donde nos pedirá configurar las propiedades del dataset. El nombre de nuestra primera fuente de datos será: dsProductosAgotados y en Data source escogeremos: dsProductos y en datasets disponibles escogeremos el datatable: dtProductosStockMinimoActual. Click en OK.
41
Mover la tabla a la parte superior del cuerpo del informe, click en la primera celda de la segunda fila y escoger el campo de la fuente de datos al que se asociará, en este caso: DescripcionProducto, y así con las demás columnas, darle los colores y formatos adecuados de modo que quede como en la siguiente imagen.
Cambiarle el color de fondo: Background Color: #4c68a2, Color: White, Font Weight: Bold.
10) Insertar segunda tabla y configurar segundo dataset para productos no agotados Click derecho en el cuerpo del informe, click en Tabla. Sin embargo ahora ya no nos muestra el modal para configurar el dataset. Entonces, hay que agregar explícitamente el dataset y luego asociarlo a la tabla. Para esto, tenemos que tener visible el panel de Report Data (si no está visible habilitarlo desde el menú Vista, la última opción: ReportData). Click derecho sobre la opción: Datasets, tal como se muestra en la figura, click en Add Dataset…
42
Nos muestra un modal donde tenemos que especificar un nombre para nuestro dataset, en este caso será: dsProductosPorAgotarse, el DataSource es: dsProducto y en dataset disponibles escogemos el dtProductosStockMinimoActual (el mismo que se seleccionó para la primera tabla). En ambas tablas se mostrará la misma estructura de campos, solo variará los registros de productos, según pertenezcan a un grupo u otro. Como veremos en un paso posterior, tenemos dos dataset que será alimentados por código al utilizar dos datatables que se alimenten de 2 procedimientos almacenados respectivamente.
43
Darle el formato adecuado a la segunda tabla en cuanto color de fondo, color de letra y negrita. Luego se tiene que seleccionar toda la segunda tabla y asociarlo a un dataset, entonces, luego de seleccionarlo en las propiedades, escoger: DatasetName y se nos va a mostrar los dos Dataset que tenemos, pero para la segunda tabal escogeremos:
dsProductosPorAgotarse. En la siguiente imagen se ilustra el proceso.
Luego asociar cada columna de la segunda tabla con la columna de interés del dsProductosPorAgotarse.
11) Trabajar en la vista de código de: rptProductosAgotadosYPorAgotarse.aspx Es necesario obtener los datos que se mostrarán en el reporte, y estos datos los encontramos en la Base de Datos que pueden descargar del enlace: https://www.dropbox.com/s/fxackytddtahikg/bkReportesMVC?dl=0
44
En el método Page_Load debemos codificar lo siguiente:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Int32? idGrupoProducto = Convert.ToInt32(Request.QueryString["idGrupoProducto"]); String nombreGrupoProducto = Convert.ToString(Request.QueryString["nombreGrupoProducto"]); SqlConnection cnn = null; try { cnn = new SqlConnection(Models.DalConexion.ObtenerCadenaConexion()); cnn.Open(); SqlDataAdapter adaptador = new SqlDataAdapter(); System.Data.DataSet ds = new System.Data.DataSet(); SqlCommand comando = new SqlCommand("spr_ReporteProductoPorGrupo", cnn); comando.CommandType = System.Data.CommandType.StoredProcedure; comando.Parameters.Add(new SqlParameter("IdGrupoProducto", idGrupoProducto==-1 ? null : idGrupoProducto)); adaptador.SelectCommand = comando; adaptador.Fill(ds); ReportParameter[] parametros = new ReportParameter[2]; parametros[0] = new ReportParameter("Param_NombreGrupo", idGrupoProducto == -1 ? "TODOS LOS GRUPOS" : "GRUPO: " + nombreGrupoProducto, false); parametros[1] = new ReportParameter("Param_UsuarioLogeado", "Usuario: " + Convert.ToString(Session["nombreUsuario"]), false); rvProductos.LocalReport.ReportPath = "Reportes/Productos/rptProductosPorGrupo.rdlc"; rvProductos.LocalReport.DataSources.Add(new ReportDataSource ("dsProductos", ds.Tables[0])); rvProductos.LocalReport.SetParameters(parametros); rvProductos.LocalReport.Refresh(); } catch(Exception ex){ } finally{ if (cnn != null) cnn.Close(); } } }
Se coloca ¡IsPostBack para asegurarnos que se llama al reporte la primera vez que se carga la página. DalConexion es una clase que se debe crear en la Carpeta Models y tiene un método estático que permite obtener la cadena de conexión. public class DalConexion { public static String ObtenerCadenaConexion(){
45
return @"Data Source=INROES\SQLSERVER2008R2; Initial Catalog=ReportesMVC_Logistica; uid=sa; pwd=sqlserver2008"; } }
Los datos que necesitamos los obtendremos a través de la ejecución del procedimiento almacenado: spr_ReporteProductoPorGrupo. Contiene lo siguiente:
CREATE procedure [dbo].[spr_ReporteProductoPorGrupo] @IdGrupoProducto int=null AS SELECT P.Descripcion as 'DescripcionProducto', M.Descripcion as 'Marca', G.Descripcion as 'GrupoProducto', StockActual, PrecioVenta FROM Producto P left join Marca M on P.IdMarca = M.IdMarca left join GrupoProducto G on P.IdGrupoProducto = G.IdGrupoProducto WHERE @IdGrupoProducto is null OR (@IdGrupoProducto is not null and @IdGrupoProducto = G.IdGrupoProducto) order by P.IdGrupoProducto, P.IdMarca, P.Descripcion GO
Desde javascript se nos envía como parámetros a través de la url: el Id del Grupo seleccionado y el nombre del grupo seleccionado. Los cuales son capturados en la Página aspx de la siguiente manera: Request.QueryString[ "idGrupoProducto"] y Request.QueryString["nombreGrupoProducto"] respectivamente. El id del Grupo es
enviado como parámetro al procedimiento almacenado, tal como se muestra en el código. Además el nombre del grupo de productos es mostrado en la cabecera del reporte, para ello se tiene que haber creado un parámetro con el nombre: NombreGrupo, el que ha sido asociado a una caja de texto colocado en la cabera y cuyo valor es establecido desde el código con el parámetro que recibe vía url.
En la línea:
rvProductos.LocalReport.ReportPath= Reportes/Productos/ ”
rptProductosPorGrupo.rdlc ; ”
Se especifica la ruta del reporte que se visualizará en el Report viewer: rvProductos.
En la línea: rvProductos.LocalReport.DataSources.Add(new ReportDataSource ( dsProductos , ds.Tables[0])); “
”
Se especifica el nombre del datasource que alimentará el reporte y como segundo parámetro el datatable que contiene esos datos, en este caso hacemos referencia al primer datatable del dataset ds que líneas arriba llenamos.
Luego actualizamos el reporte con la instrucción: rvProductos.LocalReport.Refresh();
46
12) Hasta acá el reporte debe quedar de la siguiente manera:
13) Agrupando Filas Por Marca
http://dotnetawesome.com/mvc/microsoft-report-in-mvc-4
https://www.youtube.com/watch?v=gRvUVsZxMLc
http://dotnetawesome.com/mvc/microsoft-report-in-mvc-4
https://www.youtube.com/watch?v=gRvUVsZxMLc
http://dotnetawesome.blogspot.com/2013/09/microsoft-report-in-mvc-4.html
https://www.youtube.com/watch?v=2q42e7UGssc
47