domingo, 27 de octubre de 2013

ReportViewer y Rdlc, ejemplo Factura (Base de datos)

Hola a todos:

Este articulo es la continuación de : ReportViewer y Rdlc, ejemplo Factura (datos fijos) a si que si aun no lee ese articulo deberá de hacerlo antes de continuar con este, ya que aprovecharemos el diseño que ya tenemos creado, únicamente modificaremos el código existente en el Form1 que es el encargado de enviar los datos al Rdlc y  para extender el articulo tomaremos los datos de una Base de datos que para fines ilustrativos se hará uso de una Bd SqlCompact.

Antes de continuar descargue el proyecto de ejemplo y agregue una Base de datos Sqlcompact si no sabe como agregar una Bd sqlCompact sírvase de leer este articulo:

Agregar una Base de datos SqlCompact a un proyecto de Visual Studio

Agregue tres tablas con las siguientes características:

Tabla Articulo, contendrá toda la información de los artículos:
b1

Tabla Factura, contendrá los datos del encabezado de factura, el Id de la tabla será del tipo Identity autoincrementable, este campo representara el numero consecutivo de factura:
b2

Tabla DetalleFactura, será la tabla que conservara la relación entre la tabla Factura y Artículo, la importancia de esta tabla es que nos evita duplicar información al momento de crear un factura, ya que el Encabezado de la factura se almacena en la tabla Factura, y el detalle de la factura almacenara la relación de la factura con los artículos.
b3

Una vez que tengamos las tablas agreguemos algunos datos de ejemplo, puede descargar y estos datos aquí.

Después de que creamos las tablas y les insertamos estos datos de ejemplo, vayamos a lo que nos interesa, la codificación de nuestra aplicación.

Vaya al proyecto de Vs y agregue una nueva Clase. llámela DataAccess, esta clase será la encargada de hacer la comunicación de nuestra aplicación con la Base de datos y contendrá una función leerá y retornara información de nuestras tablas, simulando ser la capa de Acceso a Datos de una arquitectura en capas.
Recuerde agregar las referencias a los ensamblados System.Data.SqlCe y System.Configuration, si agrego una base de datos ya existente.

Dentro de la clase DataAccess crearemos una función que será la encargada de hacer la solicitud de la factura a nuestra Base de datos, quedando de la siguiente manera:

Código C#:
using System;
using System.Data.SqlServerCe;
using System.Configuration;

namespace ReportViewerInvoiceReport_CSharp
{
    public class DataAccess
    {
        /// <summary>
        /// Función encargada de hacer la solictud de información de una Factura a la base de datos
        /// </summary>
        /// <Autor>José Luis García Bautista</Autor>
        /// <param name="invoicenumber">Número de factura solicitada</param>
        /// <returns>Una instancia simple de EFactura</returns>
        public static EFactura GetFactura(int invoicenumber)
        {
            //
            //Instanciamos la clase Efactura
            //
            EFactura invoice = new EFactura();
            //
            //Abrimos la cadena de conexión, leyendoe el archivo de configuración
            //Recuerde siempre encerrar en un bloque Using la cadena de conexión para asegurar liberar
            //recuersos despues de terminar la ejecución
            //
            using (SqlCeConnection cnx = new SqlCeConnection(ConfigurationManager.ConnectionStrings["connString"].ToString()))
            {
                //
                //Abrimos la cadena de conexión
                //
                cnx.Open();
                //
                //Creamos una constante, a la cual le asignaremos nuestra consulta Sql parametrizada
                //
                const string sqlAction = @"SELECT F.Numero, F.Cliente, F.Rfc, F.Direccion, F.FechaFacturacion,  
                                                D.NumeroArticulo, A.Upc, A.Descripcion, A.Precio, D.Piezas, ROUND(A.Precio * D.Piezas, 2) AS Importe
                                         FROM Factura F
                                              INNER JOIN DetalleFactura D ON F.Numero = D.NumeroFactura
                                              INNER JOIN Articulo A ON D.NumeroArticulo = A.Numero
                                         WHERE F.Numero = @numFactura";
                //
                //Creamos nuestro comando, asignandole nuestra consulta y la conexión
                //
                using (SqlCeCommand cmd = new SqlCeCommand(sqlAction, cnx))
                {
                    //
                    //Asignamos los parametros y sus valores
                    //
                    cmd.Parameters.AddWithValue("@numFactura", invoicenumber);
                    //
                    //Creamos nuestro objeto DataReader encargada de atrapar el resultado de la ejecución de la consulta
                    //
                    SqlCeDataReader dataReader = cmd.ExecuteReader();
                    //
                    //si nuestro comando devolvio informacion, entonces nuestro DataReader contendra estos datos
                    //
                    while (dataReader.Read())
                    {
                        //
                        //Vamos asignando valores a nuestras propiedades contenidas en la instancia de EFactura
                        //tomando los valores de los campos del DataReader...
                        //
                        invoice.Numero = Convert.ToInt32(dataReader["Numero"]);
                        invoice.Nombre = Convert.ToString(dataReader["Cliente"]);
                        invoice.Rfc = Convert.ToString(dataReader["Rfc"]);
                        invoice.Direccion = Convert.ToString(dataReader["Direccion"]);
                        invoice.FechaFacturacion = Convert.ToDateTime(dataReader["FechaFacturacion"]);
                        //
                        //Creamos una instancia de EArticulo, recuerde que dentro de nuestra clase EFactura tenemos
                        //lista generica de EArticulo llamado Detail, Detail como su nombre lo indica sera la encargada de
                        //almacenar la lista de articulos que conformán el detalle de la factura, asi que crearemos una instancia
                        //de esta clase para poder agregarla a la lista
                        //
                        EArticulo articulo = new EArticulo();
                        articulo.Numero = Convert.ToInt32(dataReader["NumeroArticulo"]);
                        articulo.Upc = Convert.ToString(dataReader["Upc"]);
                        articulo.Descripcion = Convert.ToString(dataReader["Descripcion"]);
                        articulo.Precio = Convert.ToDecimal(dataReader["Precio"]);
                        articulo.Piezas = Convert.ToDecimal(dataReader["Piezas"]);
                        articulo.Importe = Convert.ToDecimal(dataReader["Importe"]);
                        invoice.Detail.Add(articulo);
                    }
                }
            }
            //
            //Por ultimo devolvemos la instancia de Efactura
            //
            return invoice;
        }

    }
}

Código Vb.Net:
Imports System.Data.SqlServerCe
Imports System.Configuration

Public Class DataAccess

    ''' <summary>
    ''' Función encargada de hacer la solictud de información de una Factura a la base de datos
    ''' </summary>
    ''' <Autor>José Luis García Bautista</Autor>
    ''' <param name="invoicenumber">Número de factura solicitada</param>
    ''' <returns>Una instancia simple de EFactura</returns>
    Public Shared Function GetFactura(invoicenumber As Integer) As EFactura
        '
        'Instanciamos la clase Efactura
        '
        Dim invoice As New EFactura()
        '
        'Abrimos la cadena de conexión, leyendoe el archivo de configuración
        'Recuerde siempre encerrar en un bloque Using la cadena de conexión para asegurar liberar
        'recuersos despues de terminar la ejecución
        '
        Using cnx As New SqlCeConnection(ConfigurationManager.ConnectionStrings("connString").ToString())
            '
            'Abrimos la cadena de conexión
            '
            cnx.Open()
            '
            'Creamos una constante, a la cual le asignaremos nuestra consulta Sql parametrizada
            '
            Const sqlAction As String = "SELECT F.Numero, F.Cliente, F.Rfc, F.Direccion, F.FechaFacturacion, " _
                                             & "D.NumeroArticulo, A.Upc, A.Descripcion, A.Precio, D.Piezas, " _
                                             & "ROUND(A.Precio * D.Piezas, 2) AS Importe " _
                                      & "FROM Factura F INNER JOIN DetalleFactura D ON F.Numero = D.NumeroFactura " _
                                      & "               INNER JOIN Articulo A ON D.NumeroArticulo = A.Numero " _
                                      & "WHERE F.Numero = @numFactura"
            '
            'Creamos nuestro comando, asignandole nuestra consulta y la conexión
            '
            Using cmd As New SqlCeCommand(sqlAction, cnx)
                '
                'Asignamos los parametros y sus valores
                '
                cmd.Parameters.AddWithValue("@numFactura", invoicenumber)
                '
                'Creamos nuestro objeto DataReader encargada de atrapar el resultado de la ejecución de la consulta
                '
                Dim dataReader As SqlCeDataReader = cmd.ExecuteReader()
                '
                'si nuestro comando devolvio informacion, entonces nuestro DataReader contendra estos datos
                '
                While dataReader.Read()
                    '
                    'Vamos asignando valores a nuestras propiedades contenidas en la instancia de EFactura
                    'tomando los valores de los campos del DataReader...
                    '
                    invoice.Numero = Convert.ToInt32(dataReader("Numero"))
                    invoice.Nombre = Convert.ToString(dataReader("Cliente"))
                    invoice.Rfc = Convert.ToString(dataReader("Rfc"))
                    invoice.Direccion = Convert.ToString(dataReader("Direccion"))
                    invoice.FechaFacturacion = Convert.ToDateTime(dataReader("FechaFacturacion"))
                    '
                    'Creamos una instancia de EArticulo, recuerde que dentro de nuestra clase EFactura tenemos
                    'lista generica de EArticulo llamado Detail, Detail como su nombre lo indica sera la encargada de
                    'almacenar la lista de articulos que conformán el detalle de la factura, asi que crearemos una instancia
                    'de esta clase para poder agregarla a la lista
                    '
                    Dim articulo As New EArticulo()
                    articulo.Numero = Convert.ToInt32(dataReader("NumeroArticulo"))
                    articulo.Upc = Convert.ToString(dataReader("Upc"))
                    articulo.Descripcion = Convert.ToString(dataReader("Descripcion"))
                    articulo.Precio = Convert.ToDecimal(dataReader("Precio"))
                    articulo.Piezas = Convert.ToDecimal(dataReader("Piezas"))
                    articulo.Importe = Convert.ToDecimal(dataReader("Importe"))
                    invoice.Detail.Add(articulo)
                End While
            End Using
        End Using
        '
        'Por ultimo devolvemos la instancia de Efactura
        '
        Return invoice
    End Function

End Class

Después de haber creado la función dentro de nuestra clase de acceso a datos, vayamos a crear la codificación para nuestro Formulario encargado de enviar los datos al Rdlc, hablo de nuestro form1, esta clase será la única que sufrirá cambios con respecto al articulo anterior, por favor remplace las líneas de código por estas existentes por las siguiente:

Código C#:
using System;
using System.Linq;
using System.Windows.Forms;

namespace ReportViewerInvoiceReport_CSharp
{
    public partial class Form1 : Form
    {
        //
        //Creamos la instancia de la clase Efactura
        //
        EFactura _factura = new EFactura();

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Función encargada de recuperar de la Base de datos la informacion de una Factura
        /// </summary>
        /// <Autor>José Luis García Bautista </Autor>
        /// <param name="invoiceNumber">Número de factura solicitada</param>
        private void FillDgv(int invoiceNumber)
        {
            try
            {
                //
                //Establecemo el valor de la instancia de la clase EFactura, el valor devuelto por la funcion GetFactura
                //de la clase DataAccess, recuerde que GetFactura devuelve un tipo EFactura.
                //
                _factura = DataAccess.GetFactura(invoiceNumber);

                //
                //Preguntamos si _factura contiene items en su detalle, si no contiene detalle, informamos
                //al usuario y nos salimos del método...
                //
                if (_factura.Detail.Count == 0)
                {
                    MessageBox.Show("La factura solicitada no existe", "Factura", MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                    return;
                }
                //
                //Si llegamos a este punto de ejecucion, significa que nuestra factura es valida
                //
                //Asignamos valores a los controles
                //
                txtnumero.Text = Convert.ToString(_factura.Numero);
                txtnombre.Text = _factura.Nombre;
                txtrfc.Text = _factura.Rfc;
                txtdireccion.Text = _factura.Direccion;
                dtpfecha.Value = _factura.FechaFacturacion;

                //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 usando la instancia EFactura / Detail
                //que previamente asignamos el valor devuelto por GetFactura
                //
                dgvdetalle.DataSource = _factura.Detail;
                //
                //Mapeamos las propiedades de la clase EArticulo, contenido en Efactura 
                //
                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
                //como tenemos un objeto Efactura que dentro contiene una coleccion de tipo Earticulo y este objeto
                //tiene dentro la propiedad Importe que es lo que nos interesa sumar. Entonces
                //hacemos la sumatoria usando este objeto
                //
                decimal sum = _factura.Detail.Sum(x => x.Importe);
                //
                //Obtenemos el Iva (para los que no sean de México, el Iva es el Impuesto al Valor Agregado)
                //
                decimal iva = (Math.Round(((sum / 116) * 16), 2));
                //
                //Obtenemos el Subtotal
                //
                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);
            }
            catch (Exception e)
            {
                MessageBox.Show(String.Format("Error: {0}", e.Message), "Error inesperado", MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            }
        }

        private void InvoiceGenerate()
        {
            //
            //Hamos los calculos de Total, Iva y Subtotal usando el objeto EFactura
            //
            _factura.Total = _factura.Detail.Sum(x => x.Importe);
            _factura.Iva = Math.Round(((_factura.Total/116)*16), 2);
            _factura.Subtotal = Math.Round((_factura.Total - _factura.Iva), 2);
            
            //
            //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 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(_factura);
            //
            //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 = _factura.Detail;
            frm.Show();
        }

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

        private void txtnumero_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter & !string.IsNullOrWhiteSpace(txtnumero.Text)) FillDgv(Convert.ToInt32(txtnumero.Text));
        }
    }
}

Código Vb.Net:
Public Class Form1
    '
    'Creamos la instancia de la clase Efactura
    '
    Dim _factura As New EFactura()


    ''' <summary>
    ''' Función encargada de recuperar de la Base de datos la informacion de una Factura
    ''' </summary>
    ''' <Autor>José Luis García Bautista </Autor>
    ''' <param name="invoiceNumber">Número de factura solicitada</param>
    Private Sub FillDgv(invoiceNumber As Integer)
        Try
            '
            'Establecemo el valor de la instancia de la clase EFactura, el valor devuelto por la funcion GetFactura
            'de la clase DataAccess, recuerde que GetFactura devuelve un tipo EFactura.
            '
            _factura = DataAccess.GetFactura(invoiceNumber)

            '
            'Preguntamos si _factura contiene items en su detalle, si no contiene detalle, informamos
            'al usuario y nos salimos del método...
            '
            If _factura.Detail.Count = 0 Then
                MessageBox.Show("La factura solicitada no existe", "Factura", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return
            End If
            '
            'Si llegamos a este punto de ejecucion, significa que nuestra factura es valida
            '
            'Asignamos valores a los controles
            '
            txtnumero.Text = Convert.ToString(_factura.Numero)
            txtnombre.Text = _factura.Nombre
            txtrfc.Text = _factura.Rfc
            txtdireccion.Text = _factura.Direccion
            dtpfecha.Value = _factura.FechaFacturacion

            '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 usando la instancia EFactura / Detail
            'que previamente asignamos el valor devuelto por GetFactura
            '
            dgvdetalle.DataSource = _factura.Detail
            '
            'Mapeamos las propiedades de la clase EArticulo, contenido en Efactura 
            '
            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
            'como tenemos un objeto Efactura que dentro contiene una coleccion de tipo Earticulo y este objeto
            'tiene dentro la propiedad Importe que es lo que nos interesa sumar. Entonces
            'hacemos la sumatoria usando este objeto
            '
            Dim sum As Decimal = _factura.Detail.Sum(Function(x) x.Importe)
            '
            'Obtenemos el Iva (para los que no sean de México, el Iva es el Impuesto al Valor Agregado)
            '
            Dim iva As Decimal = (Math.Round(((sum / 116) * 16), 2))
            '
            'Obtenemos el Subtotal
            '
            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)
        Catch e As Exception
            MessageBox.Show([String].Format("Error: {0}", e.Message), "Error inesperado", MessageBoxButtons.OK, MessageBoxIcon.[Error])
        End Try
    End Sub

    Private Sub InvoiceGenerate()
        '
        'Hamos los calculos de Total, Iva y Subtotal usando el objeto EFactura
        '
        _factura.Total = _factura.Detail.Sum(Function(x) x.Importe)
        _factura.Iva = Math.Round(((_factura.Total / 116) * 16), 2)
        _factura.Subtotal = Math.Round((_factura.Total - _factura.Iva), 2)

        '
        '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(_factura)
        '
        '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 = _factura.Detail
        frm.Show()
    End Sub

    Private Sub btnImprimir_Click(sender As System.Object, e As System.EventArgs) Handles btnImprimir.Click
        InvoiceGenerate()
    End Sub

    Private Sub txtnumero_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles txtnumero.KeyDown
        If e.KeyData = Keys.Enter And Not String.IsNullOrWhiteSpace(txtnumero.Text) Then
            FillDgv(Convert.ToInt32(txtnumero.Text))
        End If
    End Sub
End Class

Por ultimo nos queda probar nuestro reporte, genere el proyecto, ejecútelo, ponga un numero de factura de 1 al 5 (recuerde que solo insertamos 5 facturas de ejemplo), con el cursor en el TextBox número presione “Enter”, si hicimos las cosas con forme el articulo tendremos un formulario cargado con datos como este:

2

Ahora, presione el botón imprimir para ver nuestro reporte:
3

Listo, hemos terminado con nuestro reporte, recuerde que no siempre las cosas salen a la primera así que si algún punto no le quedo claro pues a leer de nuevo, si tiene algunas dudas siéntase con toda la confianza de hacer las preguntas pertinentes.

Por ultimo

En este articulo de ejemplo usamos una Base de datos SqlCe por la facilidad que brinda para agregarlo al proyecto, así que usamos todos los objetos de Ado.Net para manejo de Bases de datos propios para este motor, si usted cuenta con otra base de datos, recuerde que tiene que cambiar estos objetos, para ser mas claros hablo de cambiar:

SqlCeConnection por :
  • Access: OleDbConnection
  • SqlServer: SqlConnection
  • MySql : MySqlConnection
  • Sqllite : SQlLiteConnection
SqlCeCommand por:
  • Access: OleDbCommand
  • SqlServer: SqlCommand
  • MySql : MySqlCommand
  • Sqllite : SQlLiteCommand
y SqlCeDataReader  por:
  • Access: OleDataReader
  • SqlServer: SqlDataReader
  • MySql : MySqlDataReader
  • Sqllite : SQlLiteDataReader
Dicho todo lo anterior, nos leemos a la próxima

Saludos desde Monterrey, Nuevo León México!
Ejemplo C#
Ejemplo Vb.Net

Nota: El proyecto fue desarrollado en Vs2010 Ultimate usando una Bd SqlCe v3.5 y Framework 4.0

53 comentarios:

  1. estaba buscando esto hace mucho, gracias .!!! probando codigo! =D

    ResponderEliminar
  2. Hola Alexis:

    Me alegro que el artículo haya sido de utilidad para tu proposito, la idea del blog es tratar de dar una eplicacion sobre como resolver los problemas mas comunes que nos topamos cuando espezamos en el mundo del Desarrollo de Software, intentando siempre dar una clara explicacion.

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

    ResponderEliminar
  3. Hola José Luis, descargue el proyecto ya solucione lo de la conexión instale el sqlcompact 4.0 agregue la referencia y se soluciono los errores de conexión que tenía, pero a la hora de hacer la búsqueda del registro no me esta fucionando pq tu db fue creda en una version anterior a la que uso, ese es el problema que tengo, la solución sería actualizar la db que esta en el proyecto, pero ese es el problema como acualizarla?

    ResponderEliminar
  4. Hola José Luis, tu ejemplo esta interesante pero así como lo muestras esta fácil pero en un caso real que se trabaja con mas de cuatro tablas para poder mostrar un reporte de factura va cambiando el escenario.

    ResponderEliminar
  5. Hola Pedro:

    Un gusto que estés visitando mi blog y que el articulo sea de tu interés, lo que mencionas que "así como lo muestro esta fácil" te comento que esa precisamente es la idea del artículo, que sea fácil para que los Párvulos .Net puedan digerir la información y el método sin meterse en tantos lios, el grado de complejidad lo irán estableciendo ustedes al momento de adaptar este ejemplo a sus proyectos personales, que como has de saber cada proyecto tiene sus peculiaridades.

    No olvides compartir el articulo y suscribirte al blog!

    ResponderEliminar
  6. Hola, Soy Uriel y estoy haciendo un proyecto similar, y probando el código, al momento de insertar datos a la base de datos y volverlo a probar , cuando creo la vista en precio no me da lo que esta ne la base de datos, creo es algo en el dataaccess para que haga bien la relación.

    ResponderEliminar
    Respuestas
    1. Hola Uriel:

      Si desde el SqlManagement puedes los datos de las tablas entoncones no es problema de la BD pero si podria ser problema de tu cadena de conexion valida a que Bd estas apuntando...normalmente cuando creas una Bd SqlCompact este se agrega en la carpeta donde se almacenan las clases pero crea una copia en el bin\debug, para trabajar sobre el...entonces tu debes de validar que tu cadena este aputando al archivo que esta en bin\debug...espero te sirva

      Eliminar
  7. Hola José,

    Segui el tutorial paso a paso para poder hacer unos reportes en C# que necesito, sin embargo al momento de compilar me arroja los siguientes errores:

    Error 1 El nombre de tipo 'Clase' no existe en el tipo 'Proyecto.Proyecto'

    La línea de error es la siguiente:
    this.EEmpleadoBindingSource.DataSource = typeof(MenuPrincipal.EEmpleado);

    Me puedes orientar como corregir este error. Tengo visual studio 2012

    Gracias.
    Atte. Isai

    ResponderEliminar
    Respuestas
    1. Ya lo corregí José. Gracias excelente tutorial.

      Saludos

      Eliminar
  8. Hola Jose Luis que buen tutorial, solo tengo una duda como puedo hacer que funcione el codigo con una BD hecha en Acces 2010.

    Mil Gracias.....

    ResponderEliminar
  9. Excelente tutorial, en verdad es de gran ayuda, gracias!

    ResponderEliminar
    Respuestas
    1. Hola Julio:

      Gracias por tus comentarios. Puedes apoyar al blog uniéndote o haciendo Click sobre los anuncios que aquí se muestran.

      Saludos

      Eliminar
  10. El link de visual basic no funciona :(

    ResponderEliminar
  11. El link de visual basic no funciona :(

    ResponderEliminar
  12. El link de visual basic no funciona :(

    ResponderEliminar
    Respuestas
    1. Hola Yanibel:

      Enviame tu correo por medio de formulario de contacto y te hago llegar el link de descarga.

      Saludos

      Eliminar
  13. Estimado...me puede enviar el link d descarga del visual basic, no funciona el link que dejo.

    gracias..

    saludos.

    ResponderEliminar
  14. SAludos el link de vb no funciona

    ResponderEliminar
  15. ahi te mando mi correo arismendy_clarinet@hotmail.com, otra cosa no tiene por ahi un ejemplo pero que no sea utilizando clases para los reportes

    ResponderEliminar
  16. Muchas gracias por esta ayuda, les queria preguntar si tienen algun ejemplo de hacer un reporte utilizando subreportes, pero pasando parametros desde el reporte principal al subreporte para filtrar los datos.

    Muchas gracias.

    ResponderEliminar
    Respuestas
    1. Hola Carlos.

      Lamentablemente no tengo ningún ejemplo usando SubReportes pero me da gusto que a ti también te haya sido útil el articulo.

      Saludos

      Eliminar
  17. Buen día José Luis te agradezco subas nuevamente el proyecto me aparece que el link esta caido.

    Saludos desde Colombia.

    ResponderEliminar
  18. Hola, porfavor los links que pusiste no se pueden descargar el proyecto. espero puedas ponerlos de nuevo

    ResponderEliminar
  19. puedes pasarme el programa porfavor

    ResponderEliminar
  20. podrias porfavor compartir el link de descarga gumdam2017@gmail.com

    ResponderEliminar
  21. Hola prodrias ayudarme en este tema estoy trancado con un reporte, podrias compartir el link del ejemplo en vb.net ya que el link se encuentra roto mi correo es alberod.rodriguez@gmail.com me seria de gran ayuda

    ResponderEliminar
  22. podria subir los links del proyecto en c#

    ResponderEliminar
    Respuestas
    1. Hola Alejandra, dentro de los comentarios del post podrás encontrar los links de descarga, sin embargo aquí lo tienes adjunto también, espero te sea de utilidad.


      https://1drv.ms/f/s!AiQ176xmckvhgT91In4-j9jobQbW

      Eliminar
  23. Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar
  24. Que tal.
    Estoy tratando de hacer un reporte desde VS 2017 Profesional, en MVC 5 ASP.Net, ¿alguna idea si se puede implementar el reporte rdlc? ya que no eh encontrado algo que funcione de este modo. De antemano, muchas gracias.

    ResponderEliminar
    Respuestas
    1. Hola, claro, tengo un ejemplo en ASP MVC Este fin de semana comparto el artículo...

      Saludos

      Eliminar
    2. Si se puede embeber una pagina aspx con reportviewer y que guarde en pdf en ASP.NET MVC 5, de hecho se puede programar en MVC 5 sin EF, con ADO.NET

      Eliminar
  25. Hola Jose Luis , estoy intentando hacer tu ejemplo pero no me sale, puedo darte mi correo para que me envies tu proyecto hecho en visual basic ya que los links de descarga no funcionan.

    ResponderEliminar
  26. Mi correo es abantojava@gmail.com o jesua8java@hotmail.com

    ResponderEliminar
  27. Hola Jose Luis... Ante todo muchas gracias por compartir tus conocimientos.
    Me interesa el código fuente del ejemplo en vb pero no funciona el link de descarga. ¿Me lo podrías enviar a mi correo?
    mi dirección es franciscohernandezn@gmail.com

    ResponderEliminar
  28. Hola:

    Tendríamos que ver la imagen para darnos una idea de que campos te refieres...

    Saludos

    ResponderEliminar
  29. Hola José Luis, te consulto aquí ya que en los foros de MSDN no he tenido respuestas.
    Tengo una aplicación que por su nivel de confidencialidad no puede exponer la cadena de conexión en por ejemplo, un app.config. Por tal motivo he desarrollado un pequeño conector con sql donde almaceno los datos del servidor en un xml encriptado. Estos datos los puedo modificar en tiempo de ejecución sin problemas. El tema viene a la hora de los reportes..
    Necesito generar un solo reporte, donde tengo que mostrar resultados de 20 tablas relacionadas por un id.
    Ya tengo el procedimiento en el sql y funciona bien. El problema es que no entiendo aun, como mostrar esos datos en el reporte sin tener que crear un app.config...
    He intentado pasar los datos con parámetros, pero es imposible ya que para enviarlos tendría que tenerlos todos en el form1, y en este form1 solo tengo los datos del "producto" llamemosle..
    No se si hasta aquí soy lo suficientemente claro con mi consulta...

    Estoy leyendo sobre crear DSN de sistema con la conexión para que no exista intervención del usuario, pero no encuentro mucha info y los ejemplos que he visto no los he podido portar a vb.net 2015.
    Desde ya agradezco cualquier ayuda que me puedas brindar.
    Saludos cordiales.

    ResponderEliminar
    Respuestas
    1. Hola: pero al final ese xml es muy similar al app.config que también es otro xml, lo que sugeriría es que encriptes la cadena de conexión y desencriptes cuando lo requieras desde código.

      Eliminar
    2. En efecto, es otro xml. El tema es que no entiendo aun en que momento desencriptar un app.config, me explico?
      No se como maneja la aplicación el app.config...
      Enrique Montejo me acaba de pasar un ejemplo para crear un DSN de sistema, pero no lo crea, ni en 32 ni en 64 bits...
      Estoy mas que perdido...

      Eliminar
    3. Sencillo, tienes que generar código que encriptes y desencripte, mañana con gusto cargo un ejemplo. Tu cadena de conexión nunca será legible para el usuario a simple vista.

      Me alegra que Enrique Montejo siga respondiendo no existe mejor persona que el para este tipo de situaciones .

      Saludos

      Eliminar
    4. Hola José, si, por suerte responde! te dejo el hilo donde soluciono el tema de los DSN https://social.msdn.microsoft.com/Forums/es-ES/9bbd2dca-a003-424c-8155-37a63debf4a6/crear-dsn-de-sistema?forum=vbes
      Si puedes compartirme un ejemplo de encriptación y des.. del app.config sería un gustaso estudiarlo y ponerlo en práctica!
      Saludos

      Eliminar
  30. No se puede descargar el ejemplo.

    ResponderEliminar
  31. Hola José, te agradezco si podrías enviarme los ejemplos de reportviewer a matiasperonetto@gmail.com

    Saludos!

    ResponderEliminar
  32. Buenas me puedes pasar los ejemplos de reportviewer christenorio3274@gmail.com

    ResponderEliminar
  33. Hola, muy bueno el tutorial. No puedo descargar el ejemplo en vb.net. Podrias enviarmelo, o pasarme un link para descargarlo a anbidan@gmail.com. Muchas gracias.

    ResponderEliminar
  34. Hola José Luis agradecería si me enviaras los ejemplos de ReportViewer, a ganselmofranciaco@gmail.com

    ResponderEliminar
  35. al correo de ganselmofrancisco@gmail.com

    ResponderEliminar
  36. Como haces para hacer los calculos en el reporte? yo tengo algo similar en el form tengo esos calculos pero yo quiero me salgan tambien en el reportViewer, como es?

    ResponderEliminar
  37. mi correo es cartagena6519@hotmail.com
    te agradezco la atención.

    ResponderEliminar
  38. buenos días bendiciones, José Luis, me gustaría poder estar en comunicación con usted por lo tanto le pido el favor de envíame su correo y así estar comunicándome.
    mi correo es: cartagena6519@hotmail.com
    whatsapp 3002547259
    gracias.

    ResponderEliminar
  39. Hola estimado, seria tan amable de pasarme los ejemplos (con imagenes del paso a paso) ya que las imagenes me sale como si hubiesen sido eliminadas. Desde ya muchas gracias, mi correo es: lemosfranco005@gmail.com

    ResponderEliminar

Deja un comentario si el articulo fue de utilidad.