jueves, 10 de octubre de 2013

ReportViewer y Rdlc, ejemplo Factura (datos fijos)

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:
dgvReportViewer

Agregue un segundo formulario, llámelo FacturaRpt.cs este contendrá el control ReportViewer al cual enlazaremos el LocalReport, asi que agregue uno arrastrándolo desde el cuadro de herramientas.

l19

Agregue un LocalReport, deje el nombre default:

newItem

newReport

Ahora, crearemos las clases contenedoras de las entidades, recuerde que una entidad esta compuesta por campos y propiedades.

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; }

        //Creamos una lista con una nueva Instancia de la clase Articulo
        //esta lista contendra el detalle de la factura
        public List<EArticulo> Detail = new List<EArticulo>();
    }
}

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

    'Creamos una lista con una nueva Instancia de la clase Articulo
    'esta lista contendra el detalle de la factura
    Public Detail As New List(Of EArticulo)()

End Class

Configurar el Reporte del informe “Report1.rdlc”

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

 Establecer la fuente de datos del Reporte

Active el cuadro Datos del informe, Menú Ver –>Datos del informe

dataSet

Establezca el Nombre del conjunto de datos y haga click sobre el botón Nuevo:

dataS1

Seleccione Objeto y haga Click sobre el botón Siguiente:

 obje

Seleccione la clase EFactura, recuerde que esta clase contiene las propiedades para el encabezado de la factura y haga Click sobre el botón Finalizar (Si no hubiera generado el proyecto estas clases no estarían visibles, así que si no las ve por favor cierre la ventana y genere la solución):

 sele

Observe que ya tiene una fuente de datos seleccionada, solo haga Click en el botón Aceptar:

l1

Bien, ya tiene una Fuente de datos configurada:

l2

Siga los mismos pasos para agregar la fuente de datos para el detalle del reporte solo que ahora seleccionara la clase EArticulo, al final tendrá un resultado como el siguiente:

l3

Configurar tamaño y encabezado del informe

Active la regla del informe para ello menú Informe –> Regla

Configure el tamaño del informe, menú Informe –> Propiedades del informe

l4

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…

Agregue un encabezado de reporte, menú Informe –> Agregar encabezado de pagina

Active el cuadro de herramientas, menú Ver –> Cuadro de herramientas:

l5

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.

Configurar control cuadro de texto:

Click derecho sobre el control cuadro de texto que deseemos configurar:

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.

l10

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.

l6

l7

l8

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:

  Seleccione el control cuadro de texto –> Presione F4:

l9

Si no hiciera esto, un formato numérico podría no mostrarse correctamente por ejemplo la cantidad Mil doscientos cincuenta y seis con cincuenta y seis decimales en México será 1,256.56 pero en España se escribiría de esta manera 1.256,56. Esta configuración debemos de hacerla aun si en la clase Main de nuestro proyecto hayamos definido un lenguaje de manera predeterminada.

Agregar parámetros al Reporte:

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:

l11

De nuevo, recuerde que nombrar correctamente a cada control que agregamos es de vital importancia:

l12

Agregue un  nuevo parámetro y nómbrelo parametroEmpresa.

l13

Ahora, arrastre dos controles Cuadro de texto al informe, y vaya a las propiedades para configurar el valor a mostrar:

l14

Haga lo mismo para el segundo control agregado, veamos como va nuestro diseño del informe:

l15

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:

l16

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:

l17

Establezca el tamaño de fuente, borde, tipo de dato, lenguaje a utilizar (recuerde lo comentado anteriormente sobre el formato de numero/moneda)

¿Como va nuestro diseño de informe?

l18

Si tienen un resultado como este, pueden dar su tarea por terminada en cuanto al diseño del informe si aun no lo logran, todo es cuestión que revisen como configurar un control TextBox o cuadro de texto como gusten llamarlo y ponerse a ver Alineación, tipo de fuente, borde, relleno, etc…

Hasta aquí daremos por terminado nuestro diseño, ahora vayamos a:

Establecer una Lista Genérica como DataSource de un local report:

Ubique el Formulario contenedor del ReportViewer llamado FacturaRpt, seleccione el icono superior derecho del reportViewer –> Seleccione el local report que utilizaremos (el único que hemos diseñado)

l20

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”.

Copie y pegue el siguiente código:

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();
        }

        private void FacturaRpt_Load(object sender, EventArgs e)
        {
            //Limpiemos el DataSource del informe
            reportViewer1.LocalReport.DataSources.Clear();
            //
            //Establezcamos los parámetros que enviaremos al reporte
            //recuerde que son dos para el titulo del reporte y para el nombre de la empresa
            //
            ReportParameter[] parameters = new ReportParameter[2];
            parameters[0] = new ReportParameter("parameterTitulo", Titulo);
            parameters[1] = new ReportParameter("parameterEmpresa", Empresa);

            //
            //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

Public Class FacturaRpt
    '
    'Cree dos listas una para el Encabezado y otra para el detalle
    '
    Public Invoice As New List(Of EFactura)()
    Public Detail As New List(Of EArticulo)()
    '
    'Cree las propiedades publicas Titulo y Empresa
    '
    Public Property Titulo() As String
    Public Property Empresa() As String

    Private Sub FacturaRpt_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        'Limpiemos el DataSource del informe
        ReportViewer1.LocalReport.DataSources.Clear()
        '
        'Establezcamos los parametros que enviaremos al reporte
        'recuerde que son dos para el titulo del reporte y para el nombre de la empresa
        '
        Dim parameters As ReportParameter() = New ReportParameter(1) {}
        parameters(0) = New ReportParameter("parameterTitulo", Titulo)
        parameters(1) = New ReportParameter("parameterEmpresa", Empresa)

        '
        '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:

Genere el Evento load del Formulario principal,

VsEvent

Después de generado el evento trate de seguir estas líneas de código, escriba linea por linea si copia y pega será mas complicado que comprenda (suponiendo que su experiencia en desarrollo no es amplia):


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);

            EArticulo item1 = new EArticulo
                                 {
                                     Numero = 2,
                                     Upc = "7501040805610",
                                     Descripcion = "Descripción del artículo 2",
                                     Piezas = 3,
                                     Precio = new decimal(22.50),
                                     Importe = (decimal)(3 * 22.5),
                                 };
            listaArticulos.Add(item1);

            EArticulo item2 = new EArticulo
            {
                Numero = 3,
                Upc = "0412200805610",
                Descripcion = "Descripción del artículo 3",
                Piezas = 20,
                Precio = new decimal(52.80),
                Importe = (decimal)(20 * 52.80),
            };
            listaArticulos.Add(item2);

            return listaArticulos;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //
            //La funcion GenerateNumber() se utiliza unicamente para generar un Número
            //aleatorio que simulara ser el numerod e factura
            txtnumero.Text = GenerateNumber().ToString();

            //Establecemos la propiedad AutoGenerateColumns en False para evitar que se agreguen
            //nuevas columnas a la derecha de las que creamos en tiempo de diseño.
            //
            dgvdetalle.AutoGenerateColumns = false;
            //
            //Establecemos el DataSource del control DataGridView
            //
            dgvdetalle.DataSource = FillDgv();
            //
            //Mapeamos las propiedades de la clase devuelta por la Funcion FillDgv()
            //recuerde que esta funcion devuelve una lista del tipo EArticulo
            //
            dgvdetalle.Columns["columnNumero"].DataPropertyName = "Numero";
            dgvdetalle.Columns["columnUpc"].DataPropertyName = "Upc";
            dgvdetalle.Columns["columnDescripcion"].DataPropertyName = "Descripcion";
            dgvdetalle.Columns["columnPiezas"].DataPropertyName = "Piezas";
            dgvdetalle.Columns["columnPrecio"].DataPropertyName = "Precio";
            dgvdetalle.Columns["columnImporte"].DataPropertyName = "Importe";

            //
            //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);

            txttotal.Text = Convert.ToString(Math.Round(sum, 2));
            txtiva.Text = Convert.ToString(iva);
            txtsubtotal.Text = Convert.ToString(subtotal);
        }

        private static int GenerateNumber()
        {
            Random rdm = new Random();

            return rdm.Next();
        }


        private void InvoiceGenerate()
        {
            //
            //Hacemos una instancia de la clase EFactura para
            //llenarla con los valores contenidos en los controles del Formulario
            EFactura invoice = new EFactura();
            invoice.Numero = Convert.ToInt32(txtnumero.Text);
            invoice.Nombre = txtnombre.Text;
            invoice.Rfc = txtrfc.Text;
            invoice.Direccion = txtdireccion.Text;
            invoice.FechaFacturacion = dtpfecha.Value.Date;
            invoice.Subtotal = Convert.ToDecimal(txtsubtotal.Text);
            invoice.Iva = Convert.ToDecimal(txtiva.Text);
            invoice.Total = Convert.ToDecimal(txttotal.Text);

            //Recorremos los Rows existentes actualmente en el control DataGridView
            //para asignar los datos a las propiedades
            foreach (DataGridViewRow row in dgvdetalle.Rows)
            {
                EArticulo article = new EArticulo();
                //
                //Vamos tomando los valores de las celdas del row que estamos 
                //recorriendo actualmente y asignamos su valor a la propiedad de la clase intanciada
                //
                article.Numero = Convert.ToInt32(row.Cells["columnNumero"].Value);
                article.Upc = Convert.ToString(row.Cells["columnUpc"].Value);
                article.Descripcion = Convert.ToString(row.Cells["columnDescripcion"].Value);
                article.Piezas = Convert.ToDecimal(row.Cells["columnPiezas"].Value);
                article.Precio = Convert.ToDecimal(row.Cells["columnPrecio"].Value);
                article.Importe = Convert.ToDecimal(row.Cells["columnImporte"].Value);

                //
                //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();
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            InvoiceGenerate();
        }
    }
}

Código Vb.Net:
Public Class Form1

    ''' <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)

        Dim item1 As New EArticulo()
        item1.Numero = 2
        item1.Upc = "7501040805610"
        item1.Descripcion = "Descripción del artículo 2"
        item1.Piezas = 3
        item1.Precio = New Decimal(22.5)
        item1.Importe = CDec(3 * 22.5)

        listaArticulos.Add(item1)

        Dim item2 As New EArticulo()
        item2.Numero = 3
        item2.Upc = "0412200805610"
        item2.Descripcion = "Descripción del artículo 3"
        item2.Piezas = 20
        item2.Precio = New Decimal(52.8)
        item2.Importe = CDec(20 * 52.8)
        listaArticulos.Add(item2)

        Return listaArticulos
    End Function


    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        '
        'La funcion GenerateNumber() se utiliza unicamente para generar un Número
        'aleatorio que simulara ser el numerod e factura
        txtnumero.Text = GenerateNumber().ToString()

        'Establecemos la propiedad AutoGenerateColumns en False para evitar que se agreguen
        'nuevas columnas a la derecha de las que creamos en tiempo de diseño.
        '
        dgvdetalle.AutoGenerateColumns = False
        '
        'Establecemos el DataSource del control DataGridView
        '
        dgvdetalle.DataSource = FillDgv()
        '
        'Mapeamos las propiedades de la clase devuelta por la Funcion FillDgv()
        'recuerde que esta funcion devuelve una lista del tipo EArticulo
        '
        dgvdetalle.Columns("columnNumero").DataPropertyName = "Numero"
        dgvdetalle.Columns("columnUpc").DataPropertyName = "Upc"
        dgvdetalle.Columns("columnDescripcion").DataPropertyName = "Descripcion"
        dgvdetalle.Columns("columnPiezas").DataPropertyName = "Piezas"
        dgvdetalle.Columns("columnPrecio").DataPropertyName = "Precio"
        dgvdetalle.Columns("columnImporte").DataPropertyName = "Importe"
        '
        'Hacemos las sumatorias usando un método de extensión de Linq
        '
        Dim sum As Decimal = FillDgv().Sum(Function(x) x.Importe)
        Dim iva As Decimal = (Math.Round(((sum / 116) * 16), 2))
        Dim subtotal As Decimal = Math.Round(sum - iva, 2)

        txttotal.Text = Convert.ToString(Math.Round(sum, 2))
        txtiva.Text = Convert.ToString(iva)
        txtsubtotal.Text = Convert.ToString(subtotal)
    End Sub

    Private Shared Function GenerateNumber() As Integer
        Dim rdm As New Random()

        Return rdm.[Next]()
    End Function

    Private Sub InvoiceGenerate()
        '
        'Hacemos una instancia de la clase EFactura para
        'llenarla con los valores contenidos en los controles del Formulario
        Dim invoice As New EFactura()
        invoice.Numero = Convert.ToInt32(txtnumero.Text)
        invoice.Nombre = txtnombre.Text
        invoice.Rfc = txtrfc.Text
        invoice.Direccion = txtdireccion.Text
        invoice.FechaFacturacion = dtpfecha.Value.[Date]
        invoice.Subtotal = Convert.ToDecimal(txtsubtotal.Text)
        invoice.Iva = Convert.ToDecimal(txtiva.Text)
        invoice.Total = Convert.ToDecimal(txttotal.Text)

        'Recorremos los Rows existentes actualmente en el control DataGridView
        'para asignar los datos a las propiedades
        For Each row As DataGridViewRow In dgvdetalle.Rows
            Dim article As New EArticulo()
            '
            'Vamos tomando los valores de las celdas del row que estamos 
            'recorriendo actualmente y asignamos su valor a la propiedad de la clase intanciada
            '
            article.Numero = Convert.ToInt32(row.Cells("columnNumero").Value)
            article.Upc = Convert.ToString(row.Cells("columnUpc").Value)
            article.Descripcion = Convert.ToString(row.Cells("columnDescripcion").Value)
            article.Piezas = Convert.ToDecimal(row.Cells("columnPiezas").Value)
            article.Precio = Convert.ToDecimal(row.Cells("columnPrecio").Value)
            article.Importe = Convert.ToDecimal(row.Cells("columnImporte").Value)

            '
            '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

    Private Sub btnImprimir_Click(sender As System.Object, e As System.EventArgs) Handles btnImprimir.Click
        InvoiceGenerate()
    End Sub
End Class
Ahora solo queda probar nuestra aplicación:

Llenamos los datos:
l21

Presione el botón Imprimir, si siguió al pie de la letra el Articulo tendrá un reporte como este:

l22

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:

l23

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.

Saludos desde Monterrey, Nuevo León México!

Ejemplo C#
Ejemplo Vb.Net
Nota: El proyecto fue desarrollado en Vs2010 Ultímate usando Framework 4.0

210 comentarios:

  1. Hola Jose Luis muy interesante tu aporte. Yo quiero hacer algo muy parecido pero con un DataReader y con formularios donde el usuario de iformacion como filros y al darle aceptar le mande los reportes, aunque mis conocimientos aun son pocos por que stoy entrando a programar en C# ando buscando información y poder lograrlo. Saludos

    ResponderEliminar
  2. Hola:
    Me alegro que te haya gustado y espero se haya sido de utilidad, con el tema del DataReader si te animas a usar listas genéricas (que de echo deberías de ir despegándote del DataTable) seria prácticamente lo mismo lo unico que cambia es la manera de llenar la fuente de datos, pero todo lo demas que se a visto en este articulo seguiria igual...espero pronto poder subir un articulo sobre el tema que planteas para aclararte mas el panorama....

    Saludos

    ResponderEliminar
    Respuestas
    1. Hola jose
      una pregunta que tal si tengo 3 tablas
      estudiante(cod_est, nombre, fechanac, foto)
      padres (cod_pad, nombre)
      disciplina (cod_dis, cod_est, cod_pad, descripción, fechafalta)
      la pregunta es como hacer un reportin con c# en el que se pueda visualizar en el reporte (al, momento de la impresión) el campo foto de la tabla eestudiante.

      osea que se pueda ver las descripciones disciplinarias de cada estudiante con sus respectivas foto
      si me ayudas te lo agradecería no se como hacerlo

      Eliminar
    2. Hola Jose muchas gracias por tu proyecto, pero puedo pedirte algo mas el como poner en letras el monto y que sea con centimos gracias

      Eliminar
  3. Esta muy bueno, yo hago algo parecido, peeero, tengo los detalles, y para el encabezado necesito, los datos del presupuesto, para eso tengo una funcion que me devuelve una entidad con las propiedades. El problema es que no me aparece como una opcion cuando elijo el origen de datos, solo aparecen las funciones que devulven listas

    ResponderEliminar
  4. Hola Germán:

    Me da gusto que te haya gustado el articulo y ojala te haya servido para tu propósito, con respecto a lo que comentas, en el mismo articulo explico del porque únicamente puedes enlazar objetos del tipo List<> y es que necesitas objetos que implementen Ienumerable, esto es así tanto si usas un DataTable como si usas Generic list ya que ambos lo implementan, pero esto no es problema, crea el DataSource de tu encabezado normalmente y asignas una lista, no le veo problema; la otra opción aunque no tan elegante seria que para los encabezados insertaras Parámetros para asignarle valores desde las propiedades de tu entidad simple sin mas ni mas.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
  5. interesante tu aporte. ... yo hago un reporte similar pero desde mi base de datos, esta todo super. Pero yo necesito generar el reporte sin vista previa es decir imprimir desde un botón sin mostrar el reporte por favor alguna idea???

    ResponderEliminar
    Respuestas
    1. Hola Carmen:

      La verdad no veo porque hacer esto que deseas y complicarte la vida, si el reportviewer no te quita mucho tiempo pero, bueno tus razones has de tener:

      La verdad nunca lo he intentado pero aqui tienes un tutorial del propio Microsoft, espero te sea de utilidad;

      http://msdn.microsoft.com/es-es/library/ms252091.aspx

      Eliminar
    2. tiene que crear un visor en donde se lo asines al boton de vista previa... y al visor le asginas los datos para el reporte esta sencillo

      Eliminar
    3. tiene que crear un visor en donde se lo asines al boton de vista previa... y al visor le asginas los datos para el reporte esta sencillo

      Eliminar
    4. Yo necesito hacer lo mismo ya que estoy diseñando el recibo de un punto de venta y quiero que la cajera que opera el spoftware no le de click al boton imprimir del reportviewer, que salga directo.

      Eliminar
    5. Yo necesito hacer lo mismo ya que estoy diseñando el recibo de un punto de venta y quiero que la cajera que opera el spoftware no le de click al boton imprimir del reportviewer, que salga directo.

      Eliminar
  6. Donde se debe colocar los ensamblados cuando se agregan a un reporte .rdlc cuando uno esta trabajando con el Business Intelligent Development Estudio y cuando uno publica en reporting services es necesario colocar estos ensamblados en una ruta esecifica dependiendo si se esta depurando o en un ambiente de publicación. Estoy migrando mis reportes para que no sean remotos sino locales y me esta saliendo un error de que no encuentra el ensamblado, donde lo debería agregar??

    ResponderEliminar
  7. Excelente tutorial José Luis.
    Estoy haciendo un pequeño programa para pasar las facturas electrónicas de xml a pdf y me ayudó mucho.
    Me surgió un curioso problema que te quiero comentar.
    Creé una clase parecida a tu EArticulo y de ella instancio un objeto llamado linea.
    Creé una colección generica de objetos "linea", llamada "lineas"
    Como tengo que leer del xml, y no se cuantas lineas tiene la factura, creé un bucle dentro del cual se llena el objeto "linea" y a continuación se añade a la colección "lineas" con el método add.
    De momento todo bien. El problema aparece al llenar la colección, porque la llena con tres elementos iguales a la última linea (la factura que leí, tiene tres lineas distintas). Depuré el codigo paso por paso y llegué a la conclusión de que el problema estaba en que el método add, al añadir un objeto a la colección lo hace "por referencia", es decir, lo que almacena es un puntero hacia el objeto "linea". Al cambiar el valor del objeto en el bucle siguiente, se cambian automáticamente los datos ya almacenados, y al final, todos los elementos de la colección son iguales.
    Como solución provisional, instancio el objeto "linea" justo antes de entrar al bucle y lo destruyo con nothing al terminar de añadir el objeto a la colección. Así funciona bien, pero debe haber alguna otra solución mas "elegante" ¿no?




    ResponderEliminar
  8. Vaya, mi comentario salió como "Unknown"
    Me llamo Oscar González

    ResponderEliminar
  9. Hola:
    Me da muchos gusto que el tutorial haya sido de utilidad para tus propósitos, muchas gracias por tus comentarios y gracias también por tomarte el tiempo de hacerlo, eso motiva a seguir compartiendo conocimiento.

    En relación a tu caso, seria cuestión de ver como es que lo estas haciendo a simple vista no logro ver la dimensión del problema ni una posible solución.

    Si te es posible mándame tu correo por medio del formulario de contacto y vemos como poder resolverlo...tal tu también podrías ayudarme con un tema sobre facturación que estoy enfrentando actualmente.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
    Respuestas
    1. Hola José Luis.
      Al contrario, gracias a gente como tu, que comparte sus conocimientos, podemos aprender algo los demas.
      Te envié mi email, aunque no creo poder ayudarte mucho, porque yo no me dedico a la programación. Trabajo en algo que no tiene nada que ver, y en mis ratos libres, que no son muchos, hago algún programita sencillo.
      Comenté aquí este problema, porque me pareció que que con el se entiende muy bien lo de los tipos de datos (por valor y por referencia), ademas de que le encontré una utilidad que no conocía al método de crear objetos en dos lineas (en una línea se define el objeto y en otra se crea).

      Abusando un poco de tu amabilidad, te comento que ya estoy terminando el programa para pasar de xml a pdf,pero estoy un poco atorado con el asunto del qrcode.
      Ya se como generarlo, y consigo verlo en cualquier formulario, pero no en el informe.
      Intenté poner una imagen y que la carge desde una ruta local (C:\qrcode.jpg por ejemplo)
      tambien intenté crear una propiedad en una clase en la que se guarde la imagen y pasarsela al informe igual que los demas datos, pero nunca me sale la imagen.Me sale un icono pequeño, como de imagen rota.
      No se si estoy guardando mal la imagen, o no referencio bien la ruta con las expresiones...
      Si sabes como poner una imagen variable en un informe, telo agradecería mucho.

      Saludos
      Oscar Gonzalez

      Eliminar
  10. Saludos, tengo una duda, como se puede mandar a impresión tu reporte sin ver el formulario de vista previa ??

    ResponderEliminar
  11. Hola:
    Me hubiera gustado que mencionaras tu nombre para saber a quien me dirijo...

    En relación a tu pregunta te comento que no he tenido la necesidad de hacerlo, pero te dejo este Link donde se menciona como hacer esto que deseas:

    http://social.msdn.microsoft.com/Forums/en-US/57692388-f234-4cc0-9b55-4899a0c7e0b5/printing-a-rdlc-directly-to-a-printer

    Y este otro del propio Msdn con un ejemplo bastante claro:
    http://msdn.microsoft.com/en-us/library/ms252091(VS.80).aspx

    ResponderEliminar
  12. Excelente tutorial, Jose Luis, me va a servir de mucho, pues estaba luchando con los reportes

    ResponderEliminar
  13. Hola Santos:

    Que gusto que el articulo sea de utilidad, cuando empece con el tema de los reportes la verdad me costo mucho comprenderlos sobre todo porque los tutoriales que encontraba o estaban en ingles y no eran claros o estaban en español y tampoco estaban completos y cuando estas comenzando y desconoces tantas cosas, un paso sin mencionar manda todo lo demás a la basura porque resulta estresante andar adivinando.

    No dudes en compartir el articulo y suscribirte al blog si lo deseas, muy pronto subiré mas artículos.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
  14. LORENA URIBE OSORIO6 de febrero de 2014, 9:55

    HOLA JOSE LUIS, EXCELENTE EXPLICACIÓN MUCHISIMAS GRACIAS POR COMPARTIR TUS CONOCIMIENTOS, ME SIRVIO MUCHISIMO.

    ResponderEliminar
  15. Hola José Luis, excelente tutorial, muy bien explicado, es lo que tanto andaba buscando, muchas gracias por la información. saludos.

    ResponderEliminar
  16. Hola:
    Lorena, muchas gracias por tus comentarios, la idea fue esa precisamente ofrecer un manual completo, como el que me hubiera gustado a mi encontrar en su momento. Tenemos temas pendientes que subir los cuales no se han podido lograr por falta de tiempo pero, espero pronto poder subirlos.

    No dudes en compartir el link y suscribirte al blog.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
  17. Hola "Anonimos":

    Me hubiera gustado que publicaran su nombre para asi dirigirme a ustedes por su nombre. Gracias por sus comentarios motivan a seguir publicando.

    No duden en compartir el link y suscribirse al blog.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
  18. brother tengo un problema con el proyecto que isistes yo estoy en visual studio 2013 y me dice en esta parte lo siguiente cuando lo escribo y lo termino dice
    incoherencia de accesibilidad ; es menos accesible que en el campo

    public List Detail = new List();

    ayudame por favor

    mi nombre es Vladimir Martinez mi email es vladimirmartinez_2@hotmail.com

    ResponderEliminar
  19. Esto es lo que me dice no se si me puedes ayudar es con los dos con Invoice y detail me sale este error ayudarme por favor que es mi ultimo ejercicio please

    Error 1 Incoherencia de accesibilidad: el tipo de campo 'System.Collections.Generic.List' es menos accesible que el campo 'ReportViewerInvoiceReport_CSharp.FacturaRpt.invoice' C:\Users\Keiry\Documents\Visual Studio 2013\Projects\ReportViewerInvoiceReport_CSharp\ReportViewerInvoiceReport_CSharp\FacturaRpt.cs 20 35 ReportViewerInvoiceReport_CSharp

    ResponderEliminar
    Respuestas
    1. tengo el mismo problema, no se como resolverlo
      ayudenme

      Eliminar
    2. Anonimo sabes cual es el problema y como lo solucione El codigo de mi amigo esta bueno y funciona exactamente original

      el problema se da por que en la clase tu no le as puesto public por eso da el problema solo la declarastes predetermidamente que solo es class

      pero en realidad es public class factura esto es un ejemplo

      Cualquier duda avisa a mi amigo y que me escriba para poderte ayudar Estamos a las ordenes de todos

      gracias

      Eliminar
    3. Mandamelo a mi correo subilo en skyDriver para verlo y me mandas a mi correo vladimirmartinez_2@hotmail.com o al ing.martinezchavez@gmail.com

      Eliminar
  20. Muy buen POST. Solo una pregunta: Se puede realizar igual en ASP.NET MVC?

    ResponderEliminar
    Respuestas
    1. Hola Dovannys:

      Gracias por tu comentario, lamentablemente no tengo experiencia aun en ambientes web así que no sabría decirte si aplica o no aplica.

      Eliminar
  21. Anonimo sabes cual es el problema y como lo solucione El codigo de mi amigo esta bueno y funciona exactamente original

    el problema se da por que en la clase tu no le as puesto public por eso da el problema solo la declarastes predetermidamente que solo es class

    pero en realidad es public class factura esto es un ejemplo

    Cualquier duda avisa a mi amigo y que me escriba para poderte ayudar Estamos a las ordenes de todos

    gracias

    ResponderEliminar
    Respuestas
    1. Hola Vladimir:

      Muchas gracias por interesarte en el artículo y me alegro que te haya sido de utilidad, también muchas gracias por compartir tu experiencia con el usuario "Anonimo" que espero lo haya solucionado con tu aporte.

      Generemos conocimiento entre todos!

      No olvides compartir el artículo y suscribirte al blog, próximamente subiré otros artículos que podrían ser de tu interés!

      Eliminar
  22. Solo tengo una palabra para ti. Gracias

    ResponderEliminar
    Respuestas
    1. Hola Edy:

      Muchas gracias por tu comentario, me alegro que el articulo te haya sido de utilidad.

      No olvides suscribirte al blog, esto es un motivante para seguir publicando.

      Eliminar
  23. Hola Excelente Articulo. Amigo tengo una duda, estoy haciendo un informe donde tiene campos estaticos es decir no es una lista o tabla indeteminada de datos, digamos es un informe estilo factura donde tiene un numero fijo de datos, este informe solo tiene dos paginas, donde relleno los campos de estas paginas de acuerdo a la consulta a la base de datos. el problema que tengo es que necesito poder tener esas dos paginas en diseño en el archivo rdlc, pero por mas que he buscado solo puedo tener una, y necesito poder diseñar la segunda. agradezco la ayuda que me puedas dar.

    ResponderEliminar
    Respuestas
    1. Hola Luis:
      Lamentablemente esto que quieres hacer aun no lo he logado, lo intente varias veces pero al pareces esto no es posible, no obstante te dejo este link probablemente te de alguna idea:

      http://msdn.microsoft.com/en-us/library/ms251701(v=vs.90).aspx

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
    2. Muchas gracias, de todas formas me toca seguir investigando, por que es necesario para lo que necesito hacer.

      Eliminar
  24. HOLA AMIGO MUY BUEN APORTE AGRADESCO MUCHO YA QUE EXPLICAS TODO BIEN ... CHIDO AMIGO MUCHAS GRACIAS.

    ResponderEliminar
    Respuestas
    1. Hola Anónimo:
      Muchas gracias por tus comentarios, no olvides compartir el enlace para que mas gentes se sirvan de este articulo.

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  25. Hola, muy bueno tu aporte, pero intente hacerlo y cuando quiero agregar los objetos en el reporte (origen de datos ) no me aparecen... probé guardando, ejecutando el código, cerrando y volviéndolo a abrir y tampoco...

    ResponderEliminar
    Respuestas
    1. Hola Agustina:
      Creo que no leíste bien el articulo, o te pasaste por alto esta parte:

      {...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...}

      Prueba con eso y me comentas como te va!

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  26. Hola!
    Hola!

    He intentado de mil maneras que se autoimprima el reporte. Pero no hay manera. Ni siguiendo las instrucciones de Microsoft.
    Alguien sabe cómo hacerlo?
    Muchas gracias!

    ResponderEliminar
  27. Hola Jose Luis

    Me pareció muy útil este tutorial, estoy haciendo algo parecido pero con orígenes de datos dinámicos
    y estoy llenando el report viewer manualmente ya q mis procedimientos tardan demasiado y por cuestiones de timeout lo tengo que hacer manualmente y no me carga absolutamente nada
    este es mi código si pudieras ayudar te agradecería mucho

    SqlDataAdapter sqlAdaptador;
    SqlConnection sqlConexion = new SqlConnection();
    DataSet dt = new DataSet();
    try
    {
    sqlConexion.ConnectionString = ConfigurationManager.ConnectionStrings["IMArk"].ConnectionString;
    sqlConexion.Open();

    sqlAdaptador = new SqlDataAdapter(sConsulta, sqlConexion);
    sqlAdaptador.SelectCommand.CommandTimeout = 0;
    sqlAdaptador.Fill(dt);
    Microsoft.Reporting.WinForms.ReportDataSource rds = new Microsoft.Reporting.WinForms.ReportDataSource("Datos", dt.Tables[0]);

    reportViewer1.LocalReport.ReportPath = "ReportTop100.rdlc";
    // reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("DataSetInformeFidelizacion", dt.Tables[0]));
    reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("Datos", dt.Tables[0]));

    reportViewer1.Refresh();

    }
    catch (Exception ex)
    {

    }

    ResponderEliminar
  28. Ya era hora de que alguien creara un blog para problemas con ReportViewer.
    Soy nuevo en esto y me gustaria hacer una pregunta que me trae loco.
    Resulta que tengo un report y dentro de este tengo otro report. Quiero pasarle unos parametros del primer report al segundo pero cuando los defino me llegan al segundo report a null y no me muestra la informacion.
    Los parametros son campos de la clase he probado a escribir directamente un texto y si aparecen en el subreport pero si es un campo de la clase no va.

    Espero que alguien pueda ayudarme con este problema.
    Gracias.

    ResponderEliminar
  29. Excelente aporte!!! me ha funcionado de maravillas al enlazarlo a un objeto de un servicio web.
    Un saludo desde www.systemdeveloper.info

    ResponderEliminar
  30. Necesito que por cada registro en la darse de dato mostrar una pagina de reporte rdlc. Necesito hacer una combinación de correspondencia

    ResponderEliminar
  31. Buenas, en primer lugar enhorabuena por el articulo!

    Estoy realizando un programa en C# el cual maneja una base de datos sqlite para almacenar datos de clientes, proveedores, distribuidores, etc!
    El programa tiene como fin visualizar un informe el cual recoge dos recetas en un mismo folio!
    Mi problema es que necesito hacer una plantilla para una receta y pasarle un List de una clase que tengo al igual que tu, y que muestre doble esa receta! No se si me he explicado, pero haber si me pueden ayudar, gracias.

    ResponderEliminar
  32. hola, me gusto mucho el tutorial, solo que tengo un problema, me marca un error, me dice que "dgvdetalle" no esta declarado, y en efecto busco en el código, pero no encuentro en que momento se declara "dgvdetalle". ojalá me pudieras ayudar muchas gracias.

    ResponderEliminar
    Respuestas
    1. Hola Jgarale:
      El dgvDetalle fue agregado al proyecto en tiempo de diseño, descarga el codigo que se ofrece mas abajo esta disponible tanto para C# como para Vb.Net..

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  33. hola, se me pasó mencionar que estoy usando visual basic 2010

    ResponderEliminar
  34. hola, perdón que oso, jajaja... ya me di cuenta que asi se llama el datagridview muchas gracias. saludos

    ResponderEliminar
  35. Gracias por el tuto,me sirvio mucho :)

    ResponderEliminar
  36. Hola, muy buen tutorial, me podrías ayudar con la siguiente línea
    reportViewer1.LocalReport.SetParameters(parameters);
    Me marca el siguiente error
    No se controló Microsoft.Reporting.WinForms.LocalProcessingException
    Gracias

    ResponderEliminar
    Respuestas
    1. Me surgió el mismo error como le dio solución??

      Eliminar
    2. Hola Brianda Uriarte:

      Analiza este articulo, ahi se mencionan las posibles soluciones a la excepction que estas obteniendo:

      http://stackoverflow.com/questions/6297282/how-to-fix-the-bug-local-processing-exception-was-unhandled-when-passing-paramet

      Si esta es la solución no olvides comentarnos.

      Eliminar
  37. Wuju!!!! ya encontré el error (el nombre del cuadro de texto de los parametros los tenía incorrectos).

    Saludos.

    ResponderEliminar
  38. Esto es la solución QRcode, veo, espero poder ayudarle a:'descargar ejemplo qrcode en visual c#.net






    ResponderEliminar
  39. Esto es la solución QRcode, veo, espero poder ayudarle a: descargar ejemplo qrcode en visual c#.net

    ResponderEliminar
    Respuestas
    1. Hola Anónimo:

      Seria interesante conocer tu nombre para saber a quien agradecerle el aporte del BarCode, usare la Dll para mostrar como poner una imagen en un RDLC...

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  40. Excelente tutorial Compadre!! Me salvaste la vida...
    Gracias!!!

    ResponderEliminar
  41. Hola Ralex:

    Me alegro que te haya servido el articulo.

    Saludos desde Monterrey, Nuevo León, México!

    ResponderEliminar
  42. Excelente tutorial! Muchas gracias porque la verdad que no he encontrado nada ni la mitad de bueno. Únicamente tengo un problema, he seguido todo el tutorial pero cuando relleno los datos y pulso Imprimir, me aparece el reportviewer vacío. He comprobado que tiene asociado el report1.rdlc pero aún así nada de nada :'( ¿Alguna idea? Gracias nuevamente, un saludo.

    ResponderEliminar
    Respuestas
    1. Hola de nuevo, me respondo con la solución a mí mismo, le había puesto otro nombre a los parámetros y no intersectaba el error de que no se podía cargar porque el nombre del parámetro Title pasado no existía ;-D Ahora todo perfecto! Muchísimas gracias.

      Eliminar
    2. Hola iván:

      Gracias por tus comentarios, lamentablemente no tengo acceso al blog desde el trabajo y solo veo los comentarios hasta tarde, lamento no haber podido asistirte y me alegro que hayas encontrado la solución por ti mismo.

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  43. Muy Buen aporte.
    Tengo un Reporte(R1) que contiene campos con hypervinculos que abren un reporte(R2), Quisera saber como hacer para que al Exportar el R1 a Excel ,no se Creen los Hypervinculos..
    Agradecería si alguien me ayuda con este tema,Estoy usando C#2012

    ResponderEliminar
  44. Gran aporte.
    Pero no se si me puedas ayudar... lo que quiero es mostrar imágenes ( las cuales pueden cambiar registro a registro ). lo único que he logrado es que muestre solo una (la primera) pero las demás se repiten. Las imágenes y los textos a mostrar están guardadas dentro de los objetos del List<>.
    Gracias !!

    ResponderEliminar
  45. Muchas gracias José Luis García Bautista, de verdad lo buscaba desde hace mucho tiempo, siempre encontraba como hacerlo pero usando el asistente, ahora sé como hacerlo manualmente, que es lo que me interesa. Estoy haciendo una aplicación que debe conectarse a una bd que se encuentra en otro equipo y luego de un pago debe general un recibo el cual se debe guardar o imprimir. Me has ayudado muchísimo, en serio, ahora mismo me pondré a adaptarlo a mi necesidad.

    ResponderEliminar
  46. EXCELENTE APORTE:
    pero tengo una dua o ayuda sobre tu programa,que en ves de tener dato fijo en el datagriw tener texbo que llenen el datagriw para haci hacer reporte de vario detalle no de dato fijo

    ResponderEliminar
    Respuestas
    1. Hola: recuerda que la finalidad del artículo es mostrar como utilizar un LocalReport, sus controles, parámetros y como enlazar su DataSource a una lista genérica de objetos. El origen de los datos no importa puesto que podría ser cualquiera.

      Lo que sugieres o deseas ver no es nada complicado bastará con que unas otro artículo de este blog (en donde hablo de como llenar un control DataGridView usando dos técnicas distintas) a este proyecto y listo! Tendrás el proyecto que deseas.

      Si tienes alguna otra duda Siéntete libre de externarla

      Saludos
      J. Luis

      Eliminar
  47. Buenos dias Jose Luis
    Muy interesante el aporte, de todas maneras tengo un pequeño problema (aparte de que estoy comenzando y mis conocimientos son limitados). He ociado letra a letra tu proyecto y al imprimir report en blanco. He bajado tu proyecto, imprimir y report en blanco.... No hay errores no hay nada. Tendra algo que ver que sea Visual Studio 2013???.
    Gracias por adelantado por echarme una mano. Tengo que terminar un pequeño programa que necesita imprimir y aquí estoy esperando como agua de mayo..

    Sldos

    ResponderEliminar
    Respuestas
    1. Hola EDTA:

      Si migraste la aplicación directamente probablemente haya alguna incompatibilidad en algún fragmento de código o en el mismo Rdlc.

      Te recomiendo que en lugar de bajar el reporte, intentes hacerlo tu desde cero en tu Visual Studio 2013 siguiendo paso a paso este articulo, si aun si tienes dudas o problemas con gusto podemos revisarlo uno a uno...

      Espero poder ayudado un poco en la resolución de tu problema.

      Saludos
      J. Luis

      Eliminar
  48. Hola Jose Luis:
    Tengo un problema dentro del report ya que me imprime una hoja demas q tiene solo el encabezado, espero puedas ayudarme

    ResponderEliminar
    Respuestas
    1. Hola Alvin:
      Analiza por favor lo que comentó en la sección. "Configurar tamaño y encabezado del informe" ahí encontrarás el motivo del porque se te esta presentando esta situación.

      Saludos

      Eliminar
    2. como siempre tienes la razon, jaja q cabeza la mia, gracias por tu ayuda, y una consulta mas por favor, quisiera insertar una imagen de un codigo qr por cada factura, lo q no logro hacer es que la imagen cambie automaticamente para cada factura o reporte ya q el codigo qr tiene datos unicos por factura, agradezco de antemano tu ayuda.

      Eliminar
    3. Para el tema de la imagen QR tienes que agregar un objeto Imagen (si mal no recuerdo se llama así) después en las propiedades de dicho objeto seleccionarías una opción que dice Origen de base de datos y lo que le enviarías en seria un arreglo lo Bytes dicho arreglo de bytes seria la imagen del QR descompuesto en bytes :-D, si eres paciente te prometo que para el Sábado subo un articulo que hable sobre los codigo QR en reportes locales...

      Saludos

      Eliminar
  49. como puedo crear un un reporte a partir de un dataset que lllene por codigo mediante una consulta a la base de datos, ejemplo: dim dsDatos as Dataset = getDatos() // funcion que me trae un dataset de una consulta a la base de datos

    ResponderEliminar
    Respuestas
    1. Hola: La primer sugerencia es que dejes de pensar en DataSet porque ya noves usan o no deberían de usarse, la segunda busca dentro de los artículos del blog ahí encontraras un artículo con nombre similar a este, ahí hablo sobre comí traer datos de una base de datos y como se enlaza al DataSource de un LocalReport.

      Si el artículo es de tu agrado considera unirte al blog o Compartir el artículo.

      Eliminar
    2. Este proyecto está para ser descargado?

      Eliminar
    3. Hola Karim:

      Claro, todos los articulos aqui creados tiene el proyecto disponible para su descarga, en caso de que en alguno de ellos no lo encuentres por favor hasmelo saber para reparar el link.

      Te dejo el link del articulo que comente en mi respuesta anterior:
      http://joseluisgarciab.blogspot.mx/2013/10/reportviewer-y-rdlc-ejemplo-factura.html

      o búscalo por nombre:
      ReportViewer y Rdlc, ejemplo Factura (Base de datos)

      Ahí podrás encontrar como enlazar el DataSource del LocalReport a una base de datos.

      Saludos

      Eliminar
    4. Este proyecto donde lo puedo descargar?

      Eliminar
  50. Te complicas demasiado, y confundes al resto, esto lo solucionabas con un Array de @parametros

    ResponderEliminar
    Respuestas
    1. Hola Pablo Ruffo Claure:

      Me da gusto que visites el blog (aunque sea por curiosidad), en relación a tu comentario, permiteme responder con varias puntos:

      1. Seria bueno que extendieras tu aportación, comentas que lo solucionarías con un array de parámetros, pero no comentas que arreglarías, si el paso de dos parámetros al encabezado del reporte o quizás apuntes a llenar un reporte con un array de parámetros.

      2. Seria bueno que nos compartieras tu solución al "problema", recuerda que el objetivo de este blog es que expandamos el conocimiento, no solo yo si no el resto de la gente que diariamente acude a el buscando guías para realizar sus actividades, al compartir, ganamos todos.

      3. En el titulo del articulo se menciona que se tratara sobre listas genéricas, que hoy por hoy forman parte de la médula de la programación orientada a objetos y son mil veces mas potentes que un simple array.

      4. Me gustaría también nos comentaras que parte del articulo te provoca confusión, seguramente alguien mas del blog podría expandir la explicación para ayudarte a comprender el articulo y sus objetivos o si es necesario crear un nuevo articulo donde se evite crear la confusión que hoy te provoca, recuerda que el nombre del blog es "Parvulos .Net" y si alguien no comprende del todo los temas aquí tratados entonces seguramente hay algo que cambiar.

      Saludos desde Monterrey, Nuevo León, México!

      Eliminar
  51. Hola estoy de acuerdo con lo que dice José Luis la creación de este blog es con la finalidad de compartir el conocimiento, no de tirar la piedra y esconderse.
    Aparte que se enseña la creación de reporte, se esta enseñado a usar listas genericas fuertemente tipadas, la cual tiene un mejor performance que un array.

    ResponderEliminar
  52. Hola, gracias por este tutorial, me ha servido de ayuda.

    Pero ahora me surge una duda: si por ejemplo necesito imprimir todas las facturas de un mes (o de un año), ¿cómo podría hacer para unir todas estas facturas en un único informe de manera que se puedan visualizar en el reportviewer como un único documento y además así se podrían imprimir todas de una vez?.

    Muchas gracias.

    ResponderEliminar
  53. excelente amigo un capo te felicito muy bien explicado

    ResponderEliminar
    Respuestas
    1. Gracias Gustavo la idea era no confundir a los Párvulos sobre cómo usar estos controles y clases.

      Saludos

      Eliminar
  54. Gracias por su aporte amigo buen tutorial!!!!! saludos

    ResponderEliminar
  55. MUCHISIMAS GRACIAS AMIGO FUNCIONA A LA PERFECCION MEJOR EXPLICADO NO PUEDE ESTAR...!

    ResponderEliminar
  56. Hola! Muy buen aporte! Muchas gracias! Quería consultar si alguien sabe porque puede ser que si yo tengo un reporte, similar a este, que es de una factura se repita el pie de pagina en otras dos hojas más sin que hubiese detalles, ya que hago una validación para que carguen justo los que entrar en una pagina A4. Si alguien sabe como resolverlo se lo agradecería mucho. Saludos

    ResponderEliminar
    Respuestas
    1. Hola Noelia:
      Una disculpa por responder hasta ahora, si supieras la cantidad de trabajo que tengo encima.

      El problema que te es sucediendo es por la altura de tu reporte, muchas veces no consideramos los margenes, los pie de paginas etc, en nuestro tamaño total.

      Prueba reduciendo el tamaño de estos y veras como corriges tu problema.

      Gracias por visitar Parvulos .Net

      Eliminar
  57. Muy buen aporte, Jose Luis, me sirvio mucho, le realice unos cambios y me funciona perfecto, tienes algun blog donde publiques tus aportes? si es asi me gustaria saber, ya que explicas muy bien

    ResponderEliminar
    Respuestas
    1. Hola Kloz:

      Gracias por visita Parvulos .Net, me da gusto que el articulo te haya sido de utilidad para tus propósitos, no olvides darnos un voto y compartir el articulo.

      Si estas interesado en recibir nuevos artículos podrías unirte al blog sin problemas.

      Eliminar
  58. hola tienes algun video de paso con el Código Vb.Net: de este tutorial ?
    gracias hermano

    ResponderEliminar
  59. hola

    EN: Agrege un segundo formulario, llámelo FacturaRpt.cs este contendrá el control ReportViewer al cual
    enlazaremos el LocalReport,

    en vb.studio 2013 con el Código Vb.Net:
    no encuentro : ReportViewer o LocalReport , ya los busque en elegir elementos o en componentes .net framerwork o componentes com pero no los localizo ?

    de antemao muchas gracias por la ayuda

    ResponderEliminar
  60. Buenos días a todos, me sumo a todos aquellos "Agradecidos" por este gran aporte, así que muchas gracias Jose Luis.

    Planteo el problema que tengo:

    Trabajo con VS 2013 y tengo un reporte que utiliza como dataset un objeto Cotizacion, el cual a su vez tiene una propiedad cliente de tipo Cliente, la cual contiene los datos del mismo. El reporte visualiza sin problemas los datos de la Cotizacion, pero no me muestra los datos de la propiedad cliente. Entiendo que se debe a que la propiedad NO es de tipo primitiva, sino un objeto. Puede alguien decirme como puedo mostrar los datos de esta propiedad?

    Gracias anticipadas y saludos.

    ResponderEliminar
    Respuestas
    1. Hola Kelvis:

      Desafortunadamente el RDLC no permite entidades complejas como fuente de datos, por lo cual tendras que crear una fuente de datos por cada objeto que desees mostrar y tendras que cargar cada uno por separado...de otra forma no podras hacerlo.

      Gracias por visitar Parvulos .Net, no olvides apoyar al blog visitando nuestros anuncios.

      Saludos

      Eliminar
  61. Buenas tardes Jose Luis, muchas gracias por la solución. lo he hecho como indicaste y funciona correctamente.

    Ahora estoy intentando imprimir una factura en un punto de venta, con una impresora BIXOLON SRP 275 que utiliza rollo de papel continuo. Lo primero es que se debe imprimir directamente (sin mostrar la vista preliminar) y lo segundo es que la altura del papel debe ser dinámica, es decir, determinada por la cantidad de lineas de detalle a imprimir. He visto algunos ejemplos creando una imagen de la factura, pero hasta el momento ninguno me ha funcionado.

    Agradecería cualquier comentario que pudiera arrojarme un poco de luz al respecto. Un saludo.

    ResponderEliminar
    Respuestas
    1. Hola Kelvis:

      Que bueno que te haya servido el consejo, mira en relacion a imprimir sin vista preliminar me he encontrado con esta documentacion y ejemplo en la propia libreria de MSDN pero la verdad nunca la he implementado pero te dejo este Link donde se menciona como hacer esto que deseas:

      http://social.msdn.microsoft.com/Forums/en-US/57692388-f234-4cc0-9b55-4899a0c7e0b5/printing-a-rdlc-directly-to-a-printer

      Y este otro del propio Msdn con un ejemplo bastante claro:
      http://msdn.microsoft.com/en-us/library/ms252091(VS.80).aspx

      En relación al tamaño del reporte esto realmente no importara porque al igual que se puede generar un reporte de 1 hoja se puede crear uno de 10 y mientras tengas papel este se imprimirá sin problemas, solo ojo con la configuración del pie de pagina para que no repita por cada hoja que genere.

      Saludos

      Eliminar
  62. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
    Respuestas
    1. Hola Alexis, es extraño esto que mencionas ahora mismo ingrese desde una computadora de la oficina y si puedo descargar los archivos...

      Saludos

      Eliminar
  63. buenas tardes José Luis García Bautista me gusaria que me proporcionaras tu proyecto debido a qeu no lo puedo descargar desde tu publicacion en c# no se si ya no lo tines disponible o el link se ha caido me seria de gran utilidad tu proyecto mi corre es bennigton21@gmail.com

    ResponderEliminar
    Respuestas
    1. ya sea en ese correo o en este jbennignos@hotmail.com

      Eliminar
    2. Hola:
      intenta descargarlo desde aqui:

      http://1drv.ms/1Bmelcu

      Eliminar
  64. gracias me servira de mucho para mi proyecto

    ResponderEliminar
  65. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  66. Excelente aporte, no cabe duda, muy bien explicado, esto me servira para realizar etiquetas.

    ResponderEliminar
  67. Buenas tardes, gracias por tu aporte me sirvio mucho ya que los reportes los tenia pensado realizar con SQL Server Business Intelligence, e integralos a mi proyecto. Al igual por que me diste una idea de como no usar un dataset en si y usar las clases para poder pasar la informacion al reporte sin la necesidad de los dataset.

    De antemano gracias y saludos.

    Reynosa Tamps.

    ResponderEliminar
  68. Hola Jose Luis he hecho todo desde 0 cero en visual basic.net con visual estudio 2013 sin embargo me indica al emitir el reporte no se ha proporcionado ninguna instancia de origen de datos para el origen de datos 'encabezado' me podrias ayudar con este inconveniente?

    ResponderEliminar
  69. Hola Jose Luis he hecho todo desde 0 cero en visual basic.net con visual estudio 2013 sin embargo me indica al emitir el reporte no se ha proporcionado ninguna instancia de origen de datos para el origen de datos 'encabezado' me podrias ayudar con este inconveniente?

    ResponderEliminar
  70. Hola Jose Luis, me sirvió muchisimo este tutotial. Aprovecho para preguntarte si hay alguna forma para incluir en el reporte Rich Text puesto que no he logrado hacerlos. Muchas gracias.

    ResponderEliminar
  71. Hola Jose Luis. Me fue de mucha utilidad este tutorial. Ahora mi duda es si es que puedo hacer que un report obtenga Datos De Varios Procedimientos almacenados. Osea Me explico varios datos de diferentes tablas. y cada tabla en el caso tendria un procedimiento almacenado. Y que al Generar el report me salga el resumen de todas las tablas en un solo report

    ResponderEliminar
  72. Hola, muchas gracias, tu artículo me ha sevido de mucho, estoy trabajando en un pequeño proyecto para generar reportes con dotos contenidos en un archivo de texto, y me ha ayudado mucho tu publicacion, ya se como obtener los datos del archivo y visualizarlos en el reporte, pero tengo un problema, mi reporte necesita de una portada con un buen diseño grafico, eso lo puedo hacer facilmente con las erramientas que contiene en diseñador de reportes, pero ademas de eso quiero que mi informe tenga paginas de contenido diferentes a la portada, necesito saber como puedo controlar la cantidad de paginas que va a tener. Me puedes ayudar por favor?
    Mi nombre es Yusimy Barrios Frómeta

    ResponderEliminar
    Respuestas
    1. Hola Yusimy:

      Lo siento, esto que solicitas los desconozco pero seria un buen aporte de tu parte compartir el conocimiento si descubres como lograrlo.

      Saludos

      Eliminar
  73. Revisando tu ejemplo se explica muy bien. Hay alguna forma de agregar una imagen por ejemplo el logo de la empresa que emite la factura en el report viewer. Yo lo hice con el datareport del viejo vb pero tratando con este control no. Esto porque los datos que carga van relacionados a datos de una tabla. Gracias.

    ResponderEliminar
    Respuestas
    1. Hola Denis:

      Po ravor revisa el articulo:

      http://joseluisgarciab.blogspot.mx/2015/11/reportviewer-y-rdlc-ejemplo-factura.html

      Ahi explico como hacer esto que deseas.

      Saludos

      Eliminar
  74. Gracias por tu colaboración. Todo el proceso es entendible pero estoy usando VB 2010 pero en mis plantillas no tengo el informe formulario o el Reporting. He descargado el Report Viewer de Microsoft y agregado en la Referencia. Sin embargo no puedo agregar esa plantilla para poder usarla y asociarla al report viewer. He buzeado en Google y ayuda msdn pero no lo he logrado. Te agradezco si me podrías indicar algún link para poder agregar dicha plantilla.
    Gracias por tu aporte.

    ResponderEliminar
  75. Hola Jose Luis, muy buen post, te felicito por tu dedicación!
    Te queria consultar un inconveniente que se me presentó. He agregado un origen de datos al Reporte, en otro proyecto para asociarle los campos y salió de maravilla. Luego, creo una clase nueva dentro del mismo proyecto y no me aparece en Conjuntos de datos disponibles. Recompile la solucion y todos los proyectos, a que se puede deber el inconveniente? Muchas gracias

    ResponderEliminar
  76. Una consulta,Estoy haciendo registro de factura con bd real, quiero editar y cambiar detalle de factura, digamos que el cliente registra una cantidad de articulos, y sucede que quiere editar y eliminar ciertos articulos del detalle y agregar otros articulos,como puedo hacer para que se actualice en la bd?,porfa alguna sugerencia

    ResponderEliminar
    Respuestas
    1. Hola:

      Podrías mostrar el detalle en un DataGridview como lo muestra el ejemplo, para esto lo que yo recomendaría es que cargaras toda la información en un lista de clases, despues para poder eliminar un item del detalle bastara con que selecciones el Row y presiones una tecla "Supr" por ejemplo, en la programacion de la tecla tendras que tomar el Row seleccionado actualmente y tomar la cell correspondiente al Id del elemento, y solo hacer un simple Remove de la lista, este elemento podrias guardarlo en otra lista para despues enviar la lista y que te elimine todos los elementos contenidos en el de la base de datos, y seria todo para la eliminacion de registros....

      Si tienes mas dudas puedes contactarme por el formulario de contacto.

      Eliminar
  77. Amigo, buenas tardes! lei tu explicacion, segui tus pasos (Con datos distintos claro), y al compilar, al momento que se van a imprimir los datos en el DataGrid me lanza el siguiente error:

    "error referencia a objeto no establecida como instancia de un objeto"

    Las lineas donde se detiene todo es el siguiente:

    DataHelper.AutoGenerateColumns = False
    DataHelper.DataSource = RegistrarArticulos()
    ERROR -->DataHelper.Columns("ColumnCodigo").DataPropertyName = "Codigo"***
    DataHelper.Columns("ColumnProducto").DataPropertyName = "Producto"
    DataHelper.Columns("ColumnModelo").DataPropertyName = "Modelo"
    DataHelper.Columns("ColumnPrecio").DataPropertyName = "Precio"
    DataHelper.Columns("ColumnCantidad").DataPropertyName = "Cantidad"
    DataHelper.Columns("ColumnSubtotal").DataPropertyName = "Subtotal"
    DataHelper.Columns("ColumnComentario").DataPropertyName ="Comentario"

    ¿Podrias decirme a que se debe esto y que debo hacer?

    ResponderEliminar
    Respuestas
    1. Amigo ya pude resolver!, resulta ser que le habia puesto mal el nombre de la columna de mi datagrid! Ahora tengo otro problemita... cuando le doy a imprimir informe me suelta que no he elegido ningun origen de datos... Porq saldra eso?

      Eliminar
    2. Hola Dan:

      Recuerda que en el evento Load del formulario que contiene el reportviewer tienes que asignar los objetos con datos.

      Revisa esa parte seguramente ahí esta tu error.

      Saludos

      Eliminar
    3. Este comentario ha sido eliminado por el autor.

      Eliminar
    4. Jose gracias por tu ayuda!! acabe de revisar donde me dijiste y tenias razón, escribi mal el nombre del primer ReportDataSource al momento de añadirla a los otros DataSources.. Tu post me sirvio demasiado!! me guie excelente, claro, añadiendo mis necesidades y que fuese dinámico... Gracias!!!

      Eliminar
  78. Hola José Luis, me parece excelente el tutorial, he seguido paso a paso tu explicación con windows form, pero cuando realizo los pasos en asp.net 4.0 al momento de elegir el Origen de Datos no me aparece la opción Objeto, no quiero utilizar DataSet, me podrías ayudar en ello.
    Gracias mil

    ResponderEliminar
  79. Una pregunta Jose Luis. Yo tengo unas hojas de factura con el logo y demás y he realizado un informe para que se adecúe cada elemento en el hueco correspondiente de la hoja. Tengo un elemento con el total de la factura que va casi abajo pegado a la derecha de la hoja, pero dependiendo del número de items que vayan en el detalle de la factura se me mueve. ¿Hay alguna posibilidad de fijar en una posición concreta un campo de texto? Independientemente del resto del informe?
    Un saludo y gracias.

    ResponderEliminar
    Respuestas
    1. Encontraste la solución tengo el mismo problema que no encuentro una solución.

      Eliminar
  80. Muchas Gracias por sus aportes, un cordial saludo!

    ResponderEliminar
  81. como hago para controlar el boton imprimir...

    ResponderEliminar
  82. Me ha gustado mucho como lo has explicado, necesitaba un programa para hacer facturas, ya que el anterior no me termina de convencer, a ver que tal me va con este

    ResponderEliminar
  83. Hola Jose Luis, soy Christián Hevia
    estoy trabajando hace poco con SSRS, no es específicamente de facturación, son reportes idénticos que tengo que sacar de Crystal Reports... Tienes algún tutorial de agrupaciones y subtotales. Si tienes algún correo te puedo mostrar los problemas que he tenido y la información que hay en internet no me ha servido de nada.

    Que estés bien

    ResponderEliminar
  84. Una consulta con respecto al ancho de la pagina que siempre tengo problemas, mencionas 21.59 y descuentas 2 por el total de margenes, pienso que solo debes descontar uno para el ancho, puedes aclararme mejor este tema.
    Gracias por tu articulo

    ResponderEliminar
  85. Amigo buenos dias me puedes enviar el ejemplo a mi correo lsandovalramos@hotmail.comn el enlace no fucniona. mil gracias

    ResponderEliminar
  86. hola amigo me puedes enviar tu ejemplo a mi correo: jeanpier29.12@gmail.com

    el enlace esta roto. gracias por enseñarnos. me es util esto

    ResponderEliminar
  87. hola, muy aporte.
    me podrás enviar el ejemplo en VB.net por favor al correo: abe_rodriguez@hotmail.com
    muchas gracias.

    ResponderEliminar
  88. José Luis, muy bueno tu Post la verdad es de muchísima utilidad, podrías enviarme el código a mi correo?? marcelo_a_medina@hotmail.com o pasarme un nuevo link el de la página esta roto. Un Abrazo.

    ResponderEliminar
  89. hola luis, queria felicitarte, como puedo generar el pdf mas de una vez

    ResponderEliminar
  90. Hola buenas tardes, sabes como agregar 10 tablas diferentes en un reporte ?

    ResponderEliminar
  91. puedes compartir el link de descarga gumdam2017@gmail.com

    ResponderEliminar
  92. Podrias compartirme el link para descarga c#, te agradezco grovdex@hotmail.com

    ResponderEliminar
  93. Podrias compartirme el link para descarga c#, te agradezco grovdex@hotmail.com

    ResponderEliminar
  94. hola el enlace esta roto ya no existe para realizae la descarga. podrias compartir el enlace de descarga en c# y VB a mi correo tobissf@gmail.com
    te agradesco gracias..!!

    ResponderEliminar
  95. Hola, que buen tema muy sencillo pero muy disiente, busque por internet y no encontré algo parecido. felicitaciones, me ayudo mucho.

    ResponderEliminar
  96. Hola, excelente articulo, tengo problemas al tratar de descargarlo, el enlace esta roto o ya no existe, podrías compartirme tu código en VB? mi correo es cgilf@hotmail.com
    De antemano, gracias

    ResponderEliminar
    Respuestas
    1. Hola:

      Descarga el ejemplo que requieras desde este link:

      https://1drv.ms/f/s!AiQ176xmckvhlC8le4cLm3CHVhx5

      Saludos

      Eliminar
  97. Hola,

    Necesito hacerlo con C#, me podrias compartir el proyecto.

    samolinab@gmail.com

    Gracias, Saludos!

    ResponderEliminar
    Respuestas
    1. Hola:

      Descarga el ejemplo que requieras desde este link:

      https://1drv.ms/f/s!AiQ176xmckvhlC8le4cLm3CHVhx5

      Saludos

      Eliminar
  98. Buenas tardes José Luis! Tengo un inconveniente, al seleccionar la clase que quiero que sea el origen de tos y presionar "Finalizar", vuelve a la pantalla anterior pero no me muestra ningún Dataset ni DataSource; a qué se puede deber esto?

    Desde ya muchas gracias! Saludos!
    Natalia

    ResponderEliminar
    Respuestas
    1. Hola: Prueba compilando la solución y luego volviendo a definir estos orígenes de datos muchas veces las clases no son accesibles porque no forman parte del ensamblado... Comentas tus resultados.

      Saludos

      Eliminar
  99. Ya lo solucione.. había creado mal la clase...

    ResponderEliminar
  100. Hola José Luis! Gracias por la respuesta anterior, lo pude solucionar como comenté corrigiendo la forma de declarar las propiedades en la clase... Ahora tengo otro problema, yahe creado el reporte y al momento de presionar el botón Imprimir me sale el suiguiente error "Se ha producido un error durante el procesamiento local de informes.".. He estado leyendo al respecto pero no doy con la solución indicada, podrias ayudarme con esto? Aclaro que no estoy los datos para mostrar en el informe, en mi caso, se toman de la base de datos, SqlServer en este caso.

    Desde ya muchas gracias! saludos!
    Natalia

    ResponderEliminar
  101. Hola, excelente tutorial!! estoy creando una factura que en el detalle tiene definido 10 lineas como máximo, si el total de lineas del detalle supera el total de lineas definidos 20 lineas por ejemplo, debería generar otra factura con las otras 10 lineas, como lo hago para generar otra factura manteniendo el encabezado y el pie de la factura con las 10 lineas restantes?

    ResponderEliminar
  102. Jose Luis, Aquí tengo el problema en mas detalle.

    https://social.msdn.microsoft.com/Forums/es-ES/acea259c-d8c1-46cd-8c78-18a3ed49d0f0/multiples-hojas-de-factura-en-report-designer?forum=xnaes

    ResponderEliminar
  103. Buenas tardes una consulta he logrado hacer todo lo que indica el tutorial pero me sale un error, que dice: Error al procesar el informe. Detalle. por favor que estaré haciendo mal..
    muchas gracias

    ResponderEliminar
  104. Hola buenas noches!! Estuve leyendo el tuto y necesitaría que subas una actualización como hacer todo eso conectado a base de datos (SQL Server 2014), todo lo otro esta bueno como la estética y pasar el link para vb.net que esta caído. Gracias

    ResponderEliminar
  105. hace unos dias revisando un informe veo que esta mal.. lo quiero volver hacer.. en primer lugar creo el objeto de datos. luego diseño un informe nuevo y cuando el asistente me indica el origen de datos.. selecciono este objeto.. y en los detalles del objeto en vez de mostrarte los datos de los campos correspondiente me muestra -___ en nombre de campo : "ClearBeforeFill" y en nombre de tipo: "System.Bollean". tenes idea de porque me hace esto?? no se que mas hacer

    ResponderEliminar
  106. Muchas gracias por tu aporte José Luis. Tengo una duda horrible yo quiero hacer un reporte tal cual como tu lo haces tomando valores de la propiedades de una clase(objeto) pero al correr no aparecen los valores de las expresiones me imagino que me falta código para que actualize un valor. Te agradezco mucho que me ayudes

    ResponderEliminar
  107. nítido.. gracias por tu dedicación... solo quería preguntarte como le hago si no quiero la vista previa.. sino que al hacer clic en el botón se vaya de una vez a la impresora?

    ResponderEliminar
    Respuestas
    1. Creo eso no es posible. Oh se programa para que se visualice o para que se descargue en algún formato (xml, pdf, etc) sin visualizar. Para imprimir eso ya es un extra que el visor muestra para que te permita realizar dicha función una vez realizado el reporte.

      Eliminar
    2. El mismo autor de este blog comentó la siguiente url:

      http://msdn.microsoft.com/es-es/library/ms252091.aspx

      Trata sobre: Imprimir un informe local sin vista previa

      Ojalá y sirva.

      Eliminar
  108. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  109. hola buenas tardes.

    Una consulta yo tengo una solución en visual basic. con un datasource y dataset ya creado y con un obejto creado tipo tableadapter. con su estructura y consultas sql de varias tablas para armar el informe.

    como se diseña y cual es la sintaxis en este caso? se deber parametrizar cada campo manual o se puede traer directamente el table adapter con sus campos previamente seleccionados sin tener que declararlos de a uno?

    es decir crear una variable que contenga el table adapter con toda la consulta de varias tablas y me muestre el reporte en

    ResponderEliminar
  110. Como puedo hacer esto mismo en un proyecto de ASP.Net en modelo MVC 4 y 5, ya que no puedo agregar un form, gracias de antemano, saludos.

    ResponderEliminar
  111. Hago lo mismo desde un proyecto por capas, pero cuando me debe cargar los datos no me los carga, aparece simplemente vació(en blanco), a que se puede deber ?

    ResponderEliminar
  112. Amigo muchisimas pero muchisimas gracias por este valiosisimo aporte! me ha ayudado mucho, estaba buscando informacion para realizar informes pero realmente no daba con algo didactico, hasta que te lei. Lo de este articulo lo adapte a una aplicacion donde uso entity framework con mySql en wpf. gracias nuevamente!

    ResponderEliminar
  113. Muy buen aporte, pero tengo una duda, los totales se van moviendo de posicion de acuerdo a la cantidad de items que contiene la tabla. Como hago para que los totales se mantengan en una posicion fija siempre independientemente de que la tabla tengo 2, 3, 4 o equis productos.

    ResponderEliminar
  114. Gracias excelente aporte, yo soy un principiante y lo entendí todo perfecto, gracias. No cambies de método. Saludos

    ResponderEliminar
  115. excelente, donde puedo descargarlo ya no funciona el link.

    ResponderEliminar
  116. Hola José Luis.... Un abrazo a la distancia, y agradecerte por tu gran aporte me saco de dudas de gran manera.... gracias

    ResponderEliminar
  117. me dice que el vinculo no funciona. :\

    ResponderEliminar
  118. Buenos dias amigo, me da un crashed al momento de añadir un origen de datos tengo visual studio 2017, ayuda por favor

    ResponderEliminar
    Respuestas
    1. Hola:

      Puedes proporcionarnos mas informacion sobre tu problema, como que tipo de error recibes.

      Eliminar
    2. Instalo "Microsoft Rdlc Report Designer for Visual Studio" posteriormente le doy a crear nuevo, se crea sin problemas pero cuando se trato de enlazar un nuevo conjunto de datos todo el programa de visual studio se congela y tengo que forzar a en finalizar tarea para abrir visual studio nuevamente y no pasa de allí es un error, ayuda por favor

      Eliminar
  119. hola, estoy siguiendo el tutorial pero cuando veo las propiedades del textbox en el parámetro valor aparece en blanco, sin embargo en el origen de datos si veo las dos clases me puedes apoyar en esto

    ResponderEliminar
    Respuestas
    1. Hola Christian:

      Francamente no logro entender del todo lo que platicas, podrías regalarme una explicación con mas detalles de ser posible mencionarme a que control en especifico te refieres...

      Recuerda también que para poder ver los propiedades de una clase como fuente de datos, tienes que compilar la aplicación antes de que querer utilizarlos (esto lo digo al aire, ya que no estoy seguro si es este el problema que tienes).

      Saludos

      Eliminar
  120. Hola Jose muchas gracias por tu proyecto, pero puedo pedirte algo mas el como poner en letras el monto y que sea con centimos gracias

    ResponderEliminar
    Respuestas
    1. Hola:

      Existe una clase utilizada para eso, aplicas la conversión de números a letras desde el código C# y solo envías el valor al Report.RDLC.

      Escribeme por medio del formulario de contacto y te paso la clase...

      Eliminar
    2. Mi correo es imvt@msn.com te lo voy agrader mucho por favor gracias

      Eliminar
    3. Hola:

      Te envíe la clase y dos lineas de código para que veas como se implementa y usa, es sencillo.

      Espero te sea de utilidad.

      Saludos

      Eliminar
  121. Hola, tengo mi programa, tengo una ventana con un formulario para llenar con datos sobre un contrato, necesito que al darle clic a guardar, me guarde los datos en la base (esto ya lo tengo listo) y que me imprima los datos que se van a guardar, pero no necesito generar una vista, tampoco guardar la vista en la base, y el problema mayor, estoy trabajando con SQLite y no tengo ni idea de cómo hacerlo, soy nuevo en esto de C#....¿alguna ayuda? Muchas Gracias.

    ResponderEliminar
  122. Buenas noches
    Los línks de descarga ya no funcionan puede habilitarlos de nuevo

    ResponderEliminar
  123. Excelente articulo. Lastima que los link de descarga no funcionan. Saludos y muchas gracias

    ResponderEliminar
  124. Maestro !!! Gracias por tu tiempo.

    ResponderEliminar
  125. Buen artículo, quisiera poder acceder a la descarga del proyecto en c#, ya no está disponible. Muy agradecido de antemano.

    ResponderEliminar
  126. HOLA A TODOS DESGRACIADAMEBTE NO HAY MANERA DE DESCARGAR EL EJEMPLO DE LA FACTURA EN VB ME PODRIAS ENVIAR LA COPIA A MI CORREO POR FAVOR canadianimperialfoods@gmail.com@gmail.com gracias estoy en canada

    ResponderEliminar
  127. Hola soy David Navarro, en Visual Studio 2017 no encuentro el menú Generar al cual se refiere la explicación. No logro ver las clases creadas porque no puedo hacer el paso de Generar Proyecto.
    Estoy haciendo el ejemplo con el lenguaje Visual Basic.
    Agradezco puedan indicarme como encontrar este menú.
    Gracias!!!

    ResponderEliminar
  128. Soy David Navarro, la letra pide menú Generar y luego Generar Solución. Esto no lo encuentro en Visual Studio 2017. Estoy trancado ahí x este simple inconveniente. No veo las clases creadas. Gracias José Luis x este gran aporte!!!

    ResponderEliminar
  129. Estoy igual, no puedo encontrar el menú "Generar" y "Generar solución" en VS 2017

    ResponderEliminar
  130. Mi problema se ha resuelto cambiando la aplicacion a 32bits en vez de 64 bits (X86)


    :-(

    ResponderEliminar
    Respuestas
    1. Hola me podrías pasar el proyecto por favor
      Gracias por tu atencion

      Eliminar
  131. Hola buenos días los links de descarga del proyecto están caído, me podrías pasar un nuevo link por favor y muy buen tutorial gracias

    ResponderEliminar
  132. Muchas gracias José Luis. Lamentablemente los links están caídos, me los podrías enviar a fernandogastonpuig@gmail.com?

    Mucha gracias.

    ResponderEliminar

Deja un comentario si el articulo fue de utilidad.