Professional Documents
Culture Documents
Hola a todos:
El siguiente articulo pretende mostrar la manera de crear un reporte local usando ReportViewer
y Local Report o Rdlc enlazando su origen datos (DataSource) a una fuente proveniente de una
Lista Genérica de propiedades. Como se que esto puede resultar un tema demasiado
complicado cuando no se tiene experiencia en el manejo de reportes tratare de que el articulo
sea lo mas descriptivo posible y para ello me apoyare en la mayor cantidad de imágenes
posibles, traten de realizar el ejemplo siguiendo el tutorial, si un paso no les queda claro
siéntanse con toda confianza de hacer las consultas necesarias, al final del articulo tendrán el
link de descarga del proyecto de ejemplo.
Los datos los enviaremos desde un formulario simulando ser los datos de una Factura
comercial, que contiene Datos del cliente y los artículos adquiridos.
Bien, comencemos creando un Formulario y arrastrando los controles necesarios hasta obtener
un formulario como este:
Inserte una nueva clase y nómbrela EArticulo, la cual contendrá todas las propiedades de la
entidad Articulo, la clase deberá de quedar con esta estructura:
Código C#:
namespace ReportViewerInvoiceReport_CSharp
{
public class EArticulo
{
public int Numero { get; set; }
public string Upc { get; set; }
public string Descripcion { get; set; }
public decimal Piezas { get; set; }
public decimal Precio { get; set; }
public decimal Importe { get; set; }
}
}
Código Vb.Net:
Public Class EArticulo
Public Property Numero() As Integer
Public Property Upc() As String
Public Property Descripcion() As String
Public Property Piezas() As Decimal
Public Property Precio() As Decimal
Public Property Importe() As Decimal
End Class
Después inserte una nueva clase y nómbrela EFactura, esta clase contendrá todas las
propiedades del encabezado de la factura, la clase deberá de quedar con esta estructura:
Código C#:
using System;
using System.Collections.Generic;
namespace ReportViewerInvoiceReport_CSharp
{
public class EFactura
{
public int Numero { get; set; }
public string Nombre { get; set; }
public string Rfc { get; set; }
public string Direccion { get; set; }
public decimal Subtotal { get; set; }
public decimal Iva { get; set; }
public decimal Total { get; set; }
public DateTime FechaFacturacion { get; set; }
Código Vb.Net:
Imports System.Collections.Generic
Public Class EFactura
Public Property Numero() As Integer
Public Property Nombre() As String
Public Property Rfc() As String
Public Property Direccion() As String
Public Property Subtotal() As Decimal
Public Property Iva() As Decimal
Public Property Total() As Decimal
Public Property FechaFacturacion() As DateTime
End Class
Para poder usar las clases de EFactura para llenar el Encabezado del reporte
y EArticulo para el detalle del mismo, primero debemos de generar el proyecto, para ello
localice el menú Generar –> Generar Solución
Active el cuadro Datos del informe, Menú Ver –>Datos del informe
Establezca el Nombre del conjunto de datos y haga click sobre el botón Nuevo:
Observe que ya tiene una fuente de datos seleccionada, solo haga Click en el botón Aceptar:
Active la regla del informe para ello menú Informe –> Regla
Configure el tamaño del informe, menú Informe –> Propiedades del informe
Un punto muy importante en este paso es tener presente el Ancho o alto del reporte
dependiendo que tipo de orientación se haya elegido, en este caso el ancho es lo que interesa,
considere que tiene un ancho máximo de 21.59 cm. a este espacio le restara el valor total de
los márgenes que son 2.0 cm en total ya que configuro un margen de 0.5 cm, dando un
espacio de trabajo real disponible de 19.59 cm., si en el diseño de nuestro reporte nos
pasamos de este espacio disponible nuestro reporte en lugar de mostrarnos una hoja nos
mostrar ara dos, normalmente la segunda hoja sin o con pocos datos.
Bien, continuemos…
Arrastre tantos Cuadros de texto como se requieran, recuerde que nuestros datos provienen de
una clase, entonces por cada campo-propiedad de la clase tiene que crear un control Cuadro
de texto para poder visualizar el dato…esto de crear un control por cada propiedades de la
clase origen es únicamente para este reporte, en realidad usted puede elegir que datos mostrar
y cuales no.
Recuerde que establecer un nombre a los controles que vayamos utilizando es de vital
importancia porque será en base a este como los identificaremos, en proyectos pequeños tal
vez no tenga problemas si deja los nombres asignados por default pero, en proyectos grandes
esta mala practica nos provocara constantes dolores de cabeza, entonces, nunca olvide
ponerle un nombre a los controles. Considere que el nombre debe de identificar fácilmente al
control al que hace referencia y al dato que contendrá o al cual estará relacionado, en este
caso txtFactura es muy descriptivo, ya que se entiende que es un control textBox o cuadro de
texto y que contendrá el numero de factura.
Para definir el origen del dato que mostrara el control cuadro de texto despliegue el ComboBox
Valor, vera que este estará cargado con las propiedades de las clases las cuales definimos
como fuente de datos, no le será difícil identificar a que clase pertenece cada una ya que al
final podra ver el nombre que le puso al origen de datos.
Desactivar la casilla “Permitir aumentar el alto” puede resultar muy importante para conservar
un buen diseño, tener activada esta casilla permite que el control cambie de tamaño en tiempo
de ejecución adecuándose al tamaño del valor que contiene, modificando con esto el diseño
hasta el punto de generar hojas innecesarias.
En este ejemplo el campo Factura será del tipo numérico por lo cual para conservar un formato
de numero correcto, tendrá que configurar el lenguaje que utilizara el campo, para mi ubicación
(México) la configuración de lenguaje será “es-Mex”, para configurar esta propiedad:
Para abarcar mas sobre el tema de ReportViewer y local report, subamos un poco mas el nivel
de nuestro proyecto agregando parámetros al mismo, esto no siempre es necesario así que en
este articulo solo lo haremos para fines ilustrativos, es decir, para cuando lleguemos a
necesitarlo tendremos el conocimiento disponible de como usarlos.
En el Datos del informe –> Click derecho sobre Parametros –> Agregar parametro:
De nuevo, recuerde que nombrar correctamente a cada control que agregamos es de vital
importancia:
Haga lo mismo para el segundo control agregado, veamos como va nuestro diseño del informe:
Para el detalle del informe, agregue un Tabla arrastrándola desde el cuadro de herramientas,
vaya a las propiedades de la tabla recién agregada, ubique la propiedad DataSetName par
establecer el origen de datos y seleccione Detalle, recuerde que ese fue el nombre que
establecimos al origen de datos:
Agregue las columnas que falten para completar el cuerpo del informe, para ello haga Click
derecho sobre la tabla, Insertar columna, Izquierda o derecha.
Después establezca el valor que mostrara cada columna, para ello tiene dos opciones,
seleccionar el valor desde el icono que vera en la esquina superior derecha de cada celda o ir a
propiedades del cuadro de texto tal cual como lo hizo anteriormente:
Establezca el tamaño de fuente, borde, tipo de dato, lenguaje a utilizar (recuerde lo comentado
anteriormente sobre el formato de numero/moneda)
Una vez echo lo anterior, genere el evento Load del Formulario, para ello puede hacer doble
click sobre la barra de titulo o seleccionar el form y presionar la tecla de función F4, esto abrirá
la caja de propiedades, en la parte superior podrá ver un icono con forma de “rayo” de color
amarillo, haga click sobre el para ver los eventos que implementa el control, después ubique el
Evento que le interese implementar en este caso nos interesa el evento “Load”.
Código C#:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
namespace ReportViewerInvoiceReport_CSharp
{
public partial class FacturaRpt : Form
{
//
//Cree dos listas una para el Encabezado y otra para el
detalle
//
public List<EFactura> Invoice = new List<EFactura>();
public List<EArticulo> Detail = new List<EArticulo>();
//
//Cree las propiedades publicas Titulo y Empresa
//
public string Titulo { get; set; }
public string Empresa { get; set; }
public FacturaRpt()
{
InitializeComponent();
}
//
//Establezcamos la lista como Datasource del informe
//
reportViewer1.LocalReport.DataSources.Add(new
ReportDataSource("Encabezado", Invoice));
reportViewer1.LocalReport.DataSources.Add(new
ReportDataSource("Detalle", Detail));
//
//Enviemos la lista de parametros
//
reportViewer1.LocalReport.SetParameters(parameters);
//
//Hagamos un refresh al reportViewer
//
reportViewer1.RefreshReport();
}
}
}
Código Vb.Net:
Imports Microsoft.Reporting.WinForms
'
'Establezcamos la lista como Datasource del informe
'
ReportViewer1.LocalReport.DataSources.Add(New
ReportDataSource("Encabezado", Invoice))
ReportViewer1.LocalReport.DataSources.Add(New
ReportDataSource("Detalle", Detail))
'
'Enviemos la lista de parametros
'
ReportViewer1.LocalReport.SetParameters(parameters)
'
'Hagamos un refresh al reportViewer
'
ReportViewer1.RefreshReport()
End Sub
End Class
Hagamos lo ultimo que falta, enviar los datos desde el formulario principal:
Código C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace ReportViewerInvoiceReport_CSharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Funcion encargada de llenar el control DataGridView
/// <autor>José Luis García Bautista</autor>
/// </summary>
/// <returns>Una lista generica de la clase artículo</returns>
private static List<EArticulo> FillDgv()
{
//
//Cree una lista generica de la entidad EArticulo
//
List<EArticulo> listaArticulos = new List<EArticulo>();
//
//Instancie la clase EArticulo para agregar datos a la
lista
//
EArticulo item = new EArticulo
{
//Establezca valores a cada una de
las propiedades
Numero = 1,
Upc = "7501020405680",
Descripcion = "Descripción del
artículo 1",
Piezas = 6,
Precio = new decimal(12.50),
Importe = (decimal)(6 * 12.5),
};
//
//Agregamos el Item a la lista
//
listaArticulos.Add(item);
return listaArticulos;
}
//
//Hacemos las sumatorias usando un método de extensión de
Linq
//
decimal sum = FillDgv().Sum(x => x.Importe);
decimal iva = (Math.Round(((sum / 116) * 16), 2));
decimal subtotal = Math.Round(sum - iva, 2);
return rdm.Next();
}
//
//Vamos agregando el Item a la lista del detalle
//
invoice.Detail.Add(article);
}
//
//Creamos una instancia del Formulario que contiene
nuestro
//ReportViewer
//
FacturaRpt frm = new FacturaRpt();
//
//Usamos las propiedades publicas del formulario, aqui es
donde enviamos el valor
//que se mostrara en los parametros creados en el
LocalReport, para este ejemplo
//estamos Seteando los valores directamente pero usted
puede usar algun control
//
frm.Titulo = "Este es un ejemplo de Factura";
frm.Empresa = "Este es un ejemplo del Nombre de la
Empresa";
//
//Recuerde que invoice es una Lista Generica declarada en
el FacturaRtp, es una lista
//porque el origen de datos del LocalReport unicamente
permite ser enlazado a objetos que
//implementen IEnumerable.
//
//Usamos el metod Add porque Invoice es una lista e
invoice es una entidad simple
frm.Invoice.Add(invoice);
//
//Enviamos el detalle de la Factura, como Detail es una
lista e invoide.Details tambien
//es un lista del tipo EArticulo bastara con igualarla
//
frm.Detail = invoice.Detail;
frm.Show();
}
''' <summary>
''' Funcion encargada de llenar el control DataGridView
''' <autor>José Luis García Bautista</autor>
''' </summary>
''' <returns>Una lista generica de la clase artículo</returns>
Private Shared Function FillDgv() As List(Of EArticulo)
'
'Cree una lista generica de la entidad EArticulo
'
Dim listaArticulos As New List(Of EArticulo)()
'
'Instancie la clase EArticulo para agregar datos a la lista
'
'Establezca valores a cada una de las propiedades
Dim item As New EArticulo()
item.Numero = 1
item.Upc = "7501020405680"
item.Descripcion = "Descripción del artículo 1"
item.Piezas = 6
item.Precio = New Decimal(12.5)
item.Importe = CDec(6 * 12.5)
'
'Agregamos el Item a la lista
'
listaArticulos.Add(item)
listaArticulos.Add(item1)
Return listaArticulos
End Function
Return rdm.[Next]()
End Function
'
'Vamos agregando el Item a la lista del detalle
'
invoice.Detail.Add(article)
Next
'
'Creamos una instancia del Formulario que contiene nuestro
'ReportViewer
'
Dim frm As New FacturaRpt()
'
'Usamos las propiedades publicas del formulario, aqui es donde
enviamos el valor
'que se mostrara en los parametros creados en el LocalReport,
para este ejemplo
'estamos Seteando los valores directamente pero usted puede
usar algun control
'
frm.Titulo = "Este es un ejemplo de Factura"
frm.Empresa = "Este es un ejemplo del Nombre de la Empresa"
'
'Recuerde que invoice es una Lista Generica declarada en
FacturaRtp, es una lista
'porque el origen de datos del LocalReport unicamente permite
ser enlazado a objetos que
'implementen IEnumerable.
'
'Usamos el metod Add porque Invoice es una lista e invoice es
una entidad simple
frm.Invoice.Add(invoice)
'
'Enviamos el detalle de la Factura, como Detail es una lista e
invoide.Details tambien
'es un lista del tipo EArticulo bastara con igualarla
'
frm.Detail = invoice.Detail
frm.Show()
End Sub
Presione el botón Imprimir, si siguió al pie de la letra el Articulo tendrá un reporte como este:
Observe, en el reporte el Formato numérico y Módena, al igual que no tenemos hojas de mas
sin datos…
Ahora, exporte el reporte a Pdf y observe que los márgenes están dentro del limite, sin generar
hojas de mas, ni salirse de los márgenes:
Bueno, hemos llegado al final de este tutorial, en un entrega posterior abordaremos las
imágenes en Reportes Locales y utilizaremos una Bd como fuente de datos para nuestro
reporte.
End Class
la función con la que interactuas es DsToReport igual queda a gusto y piachere de cada uno, yo le hice
algunas modificaciones para que te sea más sencillo de entender.
Saludos,
Germán.
----------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
using Microsoft.Reporting.WinForms;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
SqlConnection sql
= newSqlConnection(ConfigurationManager.ConnectionStrings["cnn"].ConnectionString);
SqlDataAdapter da;
SqlCommand cmd;
Datos info;
public Form1() {
InitializeComponent();
da=new SqlDataAdapter();
info=new Datos(); }
y eso es todo ;)