sábado, 12 de diciembre de 2009

[Crystal Reports] Usar DataSet Tipado con dos DataTable

 

Introducción 

La finalidad de este articulo es muy puntual e intentara demostrar como hacer uso en un reporte de Crystal un DataSet Tipado que contiene dos DataTable en su interior.

En este caso se necesita listar los contactos de una empresa, pero para ello no solo se debe contar con los datos de los contactos, sino que además se desea enviar en el mismo origen de datos la información de la empresa.

Para esta operación es que se hace uso de un mismo DataSet Tipado, pero este contendrá dos tablas, las cuales serán cargadas de forma independiente, pero todo el conjunto será enviado como DataSource al reporte.

Para la operación se carga del dataset es que se ha creado un método que permite bajo la misma conexión cargar ambas tablas

public static dtoContactosEmpresa GetContactosEmpresa()
{
    dtoContactosEmpresa dtContactosEmpresa = new dtoContactosEmpresa();


    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        #region Cargo Datos Empresa

        string sql = @"SELECT IdEmpresa
                          ,RazonSocial
                          ,Telefono
                          ,Direccion
                          ,CUIT
                      FROM Empresas";

        OleDbCommand command = new OleDbCommand(sql, conn);

        OleDbDataAdapter da = new OleDbDataAdapter(command);

        da.Fill(dtContactosEmpresa, "DatosEmpresa");

        #endregion

        #region Cargo Contactos

        sql = @"SELECT Nombre
                  ,Apellido
                  ,FechaNacimiento
                  ,Localidad
                  ,Calle
                  ,Numero
                  ,Mail
              FROM Contacto";


        command = new OleDbCommand(sql, conn);

        da = new OleDbDataAdapter(command);

        da.Fill(dtContactosEmpresa, "Contactos");

        #endregion

    }

    return dtContactosEmpresa;
}

Es importante remarcar como al hacer el Fill() de los datos se especifica el nombre del datatable donde se quiere volcar la información (líneas 22 y 42)

 

[C#]
[VB.NET]

50 comentarios:

  1. Hola leandro.
    estoy creando un reporte con mas de dos tablas pero en formularios web y me estoy basando en en el ejemplo que publicaste, lo que no entiendo es por que el crystal report usando winform te crea un archivo cs y el crystal report usando webform no lo crea, y nose si sea por eso que al llamarlo en webform no me imprima ningun dato.
    Por tu atencion gracias.
    Saludos...

    ResponderEliminar
  2. Hola Leandro.
    Espero y me puedas ayudar, quiero cargar directamente un crystal report en formato pdf, pero el problema es que me marca un error que me dice "Faltan valores de parámetro".
    el reporte lo cargo desde un procedimiento almacenado y utilizo un parametro en la consulta...
    las linea de codigo que tengo para convertir es la sig:
    reporte.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, true, "MiReporte.rpt");
    Saludos...

    ResponderEliminar
  3. hola Chipujin

    ReportDocument.ExportToHttpResponse Método

    hasta donde puedo ver pareceria estar correcto, quizas el MiReporte.rpt, no deberias definirlo

    algo que no ahs comentado es si este error se produce cuando compilas o en la jecucion cuando pasa por alli

    saludos

    ResponderEliminar
  4. Hola Leandro.
    se produce en la ejecución cuando pasa por allí, y el error que me dice es que "faltan valores de parámetro".
    El código completo que tengo es el siguiente:
    string Folio = Session["Folio"].ToString();
    ReportDocument reporte = new ReportDocument();
    ParameterField pf = new ParameterField();
    ParameterFields pfs = new ParameterFields();
    ParameterDiscreteValue pdv = new ParameterDiscreteValue();

    pf.Name = "@QuejaFolio";
    pdv.Value = Folio;
    pf.CurrentValues.Add(pdv);
    pfs.Add(pf);
    CRVReporteFolio.ParameterFieldInfo = pfs;
    reporte.Load(Server.MapPath(@"CRReporteFolio.rpt"));
    reporte.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, false, "");
    reporte.SetDatabaseLogon("Heri", "heri", @"HERIBERTO-HP\SQLEXPRESS", "ControlQuejas");
    Saludos...

    ResponderEliminar
  5. Oye Leandro como creaste ese Dataset tipado ? veo tu código pero no entiendo unas cosas como de donde salió el dtoContactosEmpresa.cs con un:
    public partial class dtoContactosEmpresa {
    partial class ContactosDataTable //<-- Este de donde salió ? tú lo creaste ?
    {
    }
    }
    Porque cuando yo mando instanciar el mio me marca un error. Además de que en mi dataset solo tengo esto:
    public partial class dsTblComp {

    }
    Y cuando quiero hacer el
    oda.Fill(ds, "MidataTableEnMiDataset"); Me marca el error:
    "La mejor coinicidencia de método sobrecargado es System.Data.Common.DbDataAdapter.Fill" Tiene algunos argumentos no válidos.

    ResponderEliminar
  6. hola Cannibal

    respondi en el foro

    http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/fbfa4189-0add-46ed-bbfb-d916132d183a

    saludos

    ResponderEliminar
  7. Oye Leandro como creaste ese Dataset tipado de tu ejemplo? Fue a través del asistente ? Veo tu código pero no entiendo unas cosas como de donde salió el dtoContactosEmpresa.cs

    Además de que contiene la instancia pero además un ContactosDataTable que no sé de donde sale:
    public partial class dtoContactosEmpresa {
    partial class ContactosDataTable //<-- Este de donde salió ? tú lo creaste ?
    {
    }
    }
    Porque cuando yo mando instanciar el mio me marca un error. Además de que en mi dataset solo tengo esto:
    public partial class dsTblComp {
    }
    Y cuando quiero hacer el
    oda.Fill(ds, "MidataTableEnMiDataset"); Me marca el error:
    "La mejor coinicidencia de método sobrecargado es System.Data.Common.DbDataAdapter.Fill" Tiene algunos argumentos no válidos.

    Me puedes ayudar con esto ? Espero y ya terminar pronto.

    Otra cosa...para usar dataset tipados necesito instalar el cliente de oracle -cosa que no uso- porque se me hace algo muy pesado y además al crear dataset de este tipo la aplicación se vuelve más lenta. Es por eso que no los uso. Tengo otra app donde agregué varios Dataset tipados y era una catástrofe de lentitud. Al menos con oracle. Hay manera de hacer esto que no sea con Datasets tipados ?

    ResponderEliminar
  8. hola leandro oye mira yo uso adodb en mi proyecto ya tengo diseñado mi crystal report lo malo es que no se como en lazar los campos con la tabla ya en lase el dataset y jale los campos al crystal reports pero no me apese ni un dato que sera

    ResponderEliminar
  9. hola LEONARDO

    una pregunta mas alla que uses oledb o algo diferente, has creado un dataset tipado ?

    o sea tienes un .xsd que defina la estructura de tablas (por medio de datatable) y campos
    porque es por medio de estos que enlazas con el reporte

    saludos

    ResponderEliminar
  10. He visto tu post el cual me interesado bastante debido a que he creado una aplicacion en vb.net utilizando como base de datos Mysql y mi problema radica en la creacion de dataset que pueda utilizarlo en los reportes, los cuales no sea hecho por asistente, estoy utilizando como driver de coneccion hacia mysql .net y utilizare crystal reports. necesito de su ayuda, cualquier cosa escribirme a adonys28@gmail.com

    ResponderEliminar
  11. hola Alfredo

    puedes usar sin problemas mysql como origen de datos para cargar dataset tipados ya que cuantas con el conector de ado.net para mysql

    analiza la respuesta que aqui brindo

    http://social.msdn.microsoft.com/Forums/es-ES/netfxes/thread/f36fe79a-c4be-43a5-9743-a28cb16e6cab

    si comparas el codigo que use para cargar los datatable del dataset en este articulo con las clases que se usa en el proveedor de mysql para mysql son practicamente identicas

    saludos

    ResponderEliminar
  12. Sr. Leandro Por favor puede publicar ejemplos de crystal reports con subreportes, embebido , incrustado , es que tengo un problema , he hecho un reporte con 3 store procedure y solo m muestra uno los demas nada, apesar que los he vinculado.. se agradeceria bastante gracias

    ResponderEliminar
  13. Leandro muchas gracias, siempre que puedo trato de encontrar tus ejemplos, son claras y simples de entender.

    ResponderEliminar
  14. Me gustaría saber si hay crystal reports para visual studio 2012
    Si alguien sabes porfa dejo mi correo vajm25@hotmail.com

    ResponderEliminar
  15. hola victor

    sabes que es todo un tema

    hasta donde puede ver aun no hay soporte de Crystal para 2012

    http://social.msdn.microsoft.com/Forums/es/vsrepcrystales/thread/257a2e35-7d59-4581-9c4c-a38387d615fc

    quizas deberias analizar de usar Reporting Service

    saludos

    ResponderEliminar
  16. Hola Leandro

    Tengo una consulta, estoy tratando de crear un reporte con procedimiento almacenado que recibe como parametro dos fechas. Según mi codigo lo cargo a un datatable de un data set. pero al momento de volcarlo al reporte en cristal report me carga en blanco el informe

    Dime si esta es la mejor forma de acuerto a este codigo que te adjunto.


    Sub con_parametros(parametro1 As String, parametro2 As String)

    Dim myData As New DataSet1
    Dim conn As New MySqlConnection("server=xx.xx.xx.xx;user=yyyy;password=zzzz;database=AAAA;port=3306")
    Dim cmd As New MySqlCommand
    Dim myAdapter As New MySqlDataAdapter
    Dim myReport As New ReportDocument
    Dim dt As New DataTable
    dt.TableName = "p_rpt_ausencias"

    Try
    conn.Open()
    'cmd.CommandText = "call p_rpt_ausencias @fInicio, @fFin "
    cmd.CommandText = "call p_rpt_ausencias (" + parametro1 + ", " + parametro2 + " ) "
    cmd.Connection = conn
    myAdapter.SelectCommand = cmd

    myAdapter.Fill(dt)
    ' Para crear el XML de datos
    'myData.WriteXml("C:\dataset.xml", XmlWriteMode.WriteSchema)
    myData.Tables(0).Merge(dt)
    myReport.Load("C:\Users\Hans\Desktop\SGRRHH\SGRRHH\SGRRHHLL\SGRRHHLL\rpt_ausencias.rpt")
    myReport.SetDataSource(myData)
    myViewer.ReportSource = myReport
    myViewer.Refresh()
    Catch ex As Exception
    MessageBox.Show(ex.Message, "El reporte no se pudo crear", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    End Sub

    ResponderEliminar
  17. hola

    para invocar a un procesure no se usa el call, deebrias usar algo como ser

    Dim dt As DataTabla = New DataTable()
    Using conn As New SqlConnection("connectionstring")

    Dim cmd As New SqlCommand("", conn)
    cmd.CommandType = SqlCommandType.StoredProcedure

    cmd.Parameters.AddWithValue("@param1", valor)

    Dim da As New SqlDataAdapter(cmd)
    da.Fill(dt)
    End Using

    es mas si usas un dataset para el reporte cargalo directo, usando

    da.Fill(ds, "nombredatatable")

    asi no tendras que ahcer ningun Merge()


    saludos

    ResponderEliminar
  18. Hola Leandro buenas noches, agradecere que me ayudes ,,tengo un procedimiento almacenado en un tableadapter de un dataset tipado,lo que quiero es pasarle 2 parametros texto para que me filtre en un reporte Crystal Report Viewer..gracias por la atencion

    ResponderEliminar
  19. hola Franky

    podrias extender la funcionalidad del tableadapter para incorporar los parametros

    Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0

    Tutorial 1: Creating a Data Access Layer

    como veras en los articulo un tableadapter se puede agregar o modificar metodos para definir queries propias

    saludos

    ResponderEliminar
  20. Hola Leandro, gracias por tu apoyo con el enlace, alfin logre hacerlo, una consulta mas; porque el crystal reports no cargaba hasta que en el app.config le coloque useLegacyV2RuntimeActivationPolicy="true" en ...esa duda es la que tengo ahora o si es que me dara problemas mas adelante ya que e colocado como comentario la parte de sku=".NETFramework,Version=v4.0"...nuevamente muchas gracias.

    ResponderEliminar
  21. hola Franky

    la verdad es raro, sera que esos reportes los convertiste de un proyecto original en VS 2008 ? si es una conversion de un proyecto 2008 a 2010 puede que eso es lo que hace que necesite es opcion

    sino la verdad no me explico que podra ser

    saludos

    ResponderEliminar
  22. Hola Leandro realice mi reporte y si me da resultado con el dataset pero tengo el problema que cuando abro el form el crystalviewer se tarda en ejecutar la primera ves ya la segunda es rapida eso pasa con cualquiera de mis reportes la primera ves, me podrias ayudar si es que tengo que agregar alguna linea de codigo al inicio para que no pase esto, desde ya te agradesco

    ResponderEliminar
  23. hola Orlando

    es que no se puede evitar, la primera vez siempre va a demorar mas que el resto, porque es la primera ejecucion donde se compila y valida las operaciones

    despues en las siguientes como esta todo cacheado por eso es mas rapido

    quizas poner algun progressbar o manesaje indicando que esta trabajando ayude a indicar que demorara un rato el proceso

    saludos

    ResponderEliminar
  24. Hola Leandro estoy trabajando de la siguiente manera:
    tengo estas 3 consultas de diferentes tablas relacionadas con un campo
    sql = "SELECT sede_name as sede," _
    + "facu_name as facultad,facu_unac as uni_acade,facu_menc as mencion," _
    + "date_format(dage_ano,'%d/%M/%Y') as fecha," _
    + "peri_name as periodo, " _
    + "moda_name as modalidad, " _
    + "seme_name as semestre, " _
    + "asig_name as asignatura,asig_id, " _
    + "doce_name as docente, " _
    + "dage_desc as desc_materia, " _
    + "dage_obge as obj_general, " _
    + "dage_cope as cope_perf_egreso, " _
    + "evtx_name as eval_resultados, " _
    + "auto_sude as subdecano, auto_dica as dir_carrera " _
    + "FROM datos_generales " _
    + "inner join sede on sede_id = dage_sede " _
    + "inner join facultad on facu_id = dage_facu " _
    + "inner join periodo on peri_id = dage_peri " _
    + "inner join modalidad on moda_id = dage_moda " _
    + "inner join semestres on seme_id = dage_seme " _
    + "inner join asignatura on asig_id = dage_asig " _
    + "inner join docente on doce_id = dage_doce " _
    + "inner join evtx on evtx_id = dage_evre " _
    + "inner join autoridades on auto_facu = dage_facu and auto_sede=dage_sede " _
    + "where dage_asig='" + cmbasig.SelectedValue.ToString + "'"
    sql1 = "SELECT hoal_asig,hoal_hora as hora, hoal_lune as lunes, hoal_mart as martes," _
    + "hoal_mier as miercoles, hoal_juev as jueves, " _
    + "hoal_vier as viernes, hoal_saba as sabado " _
    + "FROM datos_generales " _
    + "inner join hoal on hoal_asig = dage_asig " _
    + "where dage_asig='" + cmbasig.SelectedValue.ToString + "'"


    sql3 = sql + ";" + sql1

    y utilizo este proceso para crear un xml

    Dim rptdat_gen As New Reportes("datos_generales", sql3)
    rptdat_gen.CreateXMLFile(Application.StartupPath)


    con estos procesos creo el xml

    Public Sub New(ByVal TableName As String, ByVal SQLstring As String)
    Me.TableName = TableName
    Me.SQLstring = SQLstring
    End Sub
    Public Function GetDataTable() As DataTable
    Dim myDataAdapter As MySqlDataAdapter
    Dim myDataSet As New DataSet
    Dim myDataTable As DataTable
    myDataAdapter = New MySqlDataAdapter(Me.SQLstring, string_coneccion)
    myDataAdapter.Fill(myDataSet, Me.TableName)
    myDataTable = myDataSet.Tables(Me.TableName)
    Return myDataTable
    End Function
    Public Sub CreateXMLFile(ByVal FilePath As String)
    Dim myDataTable As DataTable
    myDataTable = Me.GetDataTable()
    myDataTable.WriteXmlSchema(FilePath & "\" & Me.TableName & ".xml")
    End Sub

    luego llamo para cargar el informe en crystal a

    Private Sub refresh_report()
    Dim rptclientes As New Reportes("datos_generales", sql3)
    Dim rptDoc As ReportDocument = New crpsyllabus
    Dim myDataTable As DataTable = rptclientes.GetDataTable()
    rptDoc.SetDataSource(myDataTable)
    frmipmsill.crvsyllabus.ReportSource = rptDoc
    End Sub

    y solo me carga una tabla, que estoy haciendo mal o como podria mejorarlo, por la atencion de antemano gracias José Antonio

    ResponderEliminar
  25. hola JOSÉ

    que pasa si lanzas los select por separado usando SqlDataAdapter distintos, no veo correcto unir dos SELECT que separas por medio de un punto y coma

    aplica al tecnica que uso en este articulo, ejecuta cada select por separado y los cargas en un mismo datatable

    saludos

    ResponderEliminar
  26. Leandro gracias por tu comentario, le comento que hecho por separado por lo cual he creado uno que se llama datos generales y otro horario pero al hacer la subconsulta o subinforme esta me sale vacía solo con la cabecera de los datos y nada mas y la consulta principal si me presentan los datos, desearía mandar el programa por algún medio que Ud. me podría decir; para que tenga mejor la idea de cual es mi problema adjuntandole la base de datos correspondiente

    ResponderEliminar
  27. hola JOSÉ

    pudiste validar que los datatable que asignas al dataset tipado esten cargados con registros?

    validaste que el database expert de Crystal este relacionando los datatable de forma correcta
    a veces una incorrecta relacion de los datos dentro del reporte crystal puede causar que no se muestren registros

    saludos

    ResponderEliminar
  28. Leandro; te comento, que todo eso lo he hecho ya que lo he realizado paso a paso, y los datos cargan en el cristal las selecciones las relaciones entre la tabla principal y la subtabla tiene relación con el id de la asignatura... esta raro no se como más hacerlo. Saludos José

    ResponderEliminar
  29. hola JOSÉ

    estas validando que los datos esten en secciones diferentes del reporte?

    o sea crear un grupo para poner los datos del primer datatable y el detalle en la seccion de Details

    tambien podrias ver de primero crear el reporte con un solo datatable y ver que funcione, luego agregar el segundo

    al final el DataBase Exprert de crytal pudiste validarlo? esta correcta la relacion

    saludos

    ResponderEliminar
  30. Hola Leandro te comento para ver el paso de la información lo hice en dos reportes por separados y me carga la información, por lo cual en el codigo puedes ver que tengo un refres1 y un refresh con esa informacion los llamo por separado y luego en un sola data y no me funciona, talvez si tienes un poco de tiempo y revisas esos procedimientos a ver si por ahi encuentras algun paso que estoy obviando te agradeceria

    ResponderEliminar
  31. hola Sistemas UCC Cañar

    la verdad no entendi lo que planteas
    pareciera haces referencia a un codigo, pero la verdad no se de cual se trata

    que seria "un sola data" ? apuntas a un solo dataset tipado


    saludos

    ResponderEliminar
  32. Hola tengo un problema lo que pasa es que estoy generando un reporte con crystal reports y visual studio 2012 asp - c# pero el reporte que intento generar es una consulta a dos tablas que se encuentran tipadas en el dataset,
    Si hago la consulta a una tabla me vota datos pero cuando intento hacerla con dos tablas me genera la hoja en blanco con el nombre de los campos lo que tengo es esto

    //la clase de la conexion
    ClassConexion con = new ClassConexion();

    //el dataset tipado anteriormente con las tablas desde asistente
    DataSet1 ds = new DataSet1();

    SqlCommand cons = new SqlCommand("select r.nombre,l.usuario from registro r,login l where l.id_usuario = r.id_usuario and l.usuario = 'pepe'");
    cons.Connection = con.conectar();
    SqlDataAdapter da = new SqlDataAdapter(cons);
    da.Fill(ds,"registro");

    //el informe tiene los campos a mostrar
    Informe3 inf = new Informe3();
    inf.SetDataSource(ds);
    CrystalReportViewer1.ReportSource = inf;
    CrystalReportViewer1.RefreshReport();

    ResponderEliminar
  33. hola Mc Bryan

    en el ejemplo que proporcionas solo veo que cargas un unico datatable del dataset tipado

    para cargar el segundo usas el Fill() como:
    da2.Fill(ds,"nombresegundatabla");

    revisaste el DataBase Expert de Crystal para ver si la relacion entre las tablas que reconoce el reporte estan correctas

    saludos

    ResponderEliminar
  34. Estimado, he seguido tu ejemplo sin problemas, consulta; uno de los datatable posee los datos;
    -nombre1
    -direccion1
    -nombre2
    -direccion2
    Necesito hacer un texto en Crystal que represente:
    "Senor 'nombre1' ubicado en 'direccion1' y el Señor 'nombre2' ubicado en 'direccion2'...Señor 'n'"
    He intentado por medio de una formula la cual contiene un ciclo 'For Next', pero no logro cambiar el indice del campo ({nombre1}(i)). Duda; Como es posible recorrer un datatable en Crystal reports e incrementar el indice, mostrando cada uno de los registros ?.
    agradecería tu ayuda.

    ResponderEliminar
  35. hola Unknown

    si defines este template

    Senor ubicado en

    en el seccion de detalle, pondrias los campos en los lugares de nombre y direccion

    por supuesto se generara uno debajo del otro

    saludos

    ResponderEliminar
  36. Buenos días Leandro,

    estoy peleando para intentar pasarle dos datatables al dataset de Crystal pero no soy capaz de hacerlo, me da el error "El objeto no es ADODB.Record. nombre del parámetro: adodb".

    He publicado un post en el foro de MSDN http://social.msdn.microsoft.com/Forums/es-ES/279c9388-393c-4e3f-95f4-632638c82994/crystal-reports-con-dos-datatables-en-un-dataset?forum=vsrepcrystales pero nadie me contesta, ¿podrías ayudarme por favor?

    Muchas gracias por la labor de ayuda que haces en la red

    ResponderEliminar
  37. hola frikismo

    pero esta programando con .net ?
    porque ese objeto ADODB.Record es de VB6, porque lo usas, deberias descartarlo

    se supone que uses el SqlCommand, SqlDataAdapter, como lo realizo en este articulo

    saludos

    ResponderEliminar
  38. Hola Leandro,

    efectivamente trabajo con .NEt (VS2010).

    Si descargo tu código tal cual, me funciona perfectamente, pero cuando intento adaptarlo a mi programa es cuando me da ese error.

    Yo quiero meterlo todo dentro de un mismo procedimiento porque no me entero muy bien todavía y es cuando me casca el error. La BD de datos con la que trabajo es una de Access 2000, no sé si será por eso. (en realidad trabajo con una bd de MySQL, pero no era capaz de trabajar en Crystal con ella y los paso a una local de Access).

    Si quieres te pego el código a ver si ves algo (si no lo tienes en la entrada del foro de MSDN):

    Private Sub Parametros_Crystal()
    Dim oCnn As New OleDbConnection ' Objeto de conexion a la base de datos
    Dim da_Datos As New OleDbDataAdapter ' Objeto Adaptador para leer datos de la Base de datos

    Dim dt_Eventos As New DataTable ' Datatable para recibir los datos de la base de datos
    Dim cmdExec1 As New OleDbCommand ' Objeto comando para ejecutar sentencias sql
    Dim sbQuery1 As New StringBuilder ' StringBuilder para armar cadenas

    Dim dt_Personal As New DataTable ' Datatable para recibir los datos de la base de datos
    Dim cmdExec2 As New OleDbCommand ' Objeto comando para ejecutar sentencias sql
    Dim sbQuery2 As New StringBuilder ' StringBuilder para armar cadenas



    Try
    oCnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Ruta_Fichero
    oCnn.Open()



    ' EVENTOS ***************
    cmdExec1 = oCnn.CreateCommand
    cmdExec1.Connection = oCnn

    sbQuery1.Append("SELECT ID_Evento ")
    sbQuery1.Append(" ,Fecha ")
    sbQuery1.Append(" ,Dia_Semana ")
    sbQuery1.Append(" ,ID_Empleado ")
    sbQuery1.Append(" ,Hora_Inicio ")
    sbQuery1.Append(" ,Hora_Fin ")
    sbQuery1.Append(" ,Tipo_Evento ")
    sbQuery1.Append(" ,Horas ")
    sbQuery1.Append(" ,Minutos ")
    sbQuery1.Append(" ,Total_Minutos ")
    sbQuery1.Append(" ,Error ")
    sbQuery1.Append(" FROM Eventos ")

    cmdExec1.CommandText = sbQuery1.ToString

    da_Datos = New OleDbDataAdapter(cmdExec1)
    'da_Datos.Fill(dt_Eventos)
    da_Datos.Fill(dt_Eventos, "Eventos") ' versión Tuttini


    ' PERSONAL ***************
    cmdExec2 = oCnn.CreateCommand
    cmdExec2.Connection = oCnn

    sbQuery2.Append("SELECT ID_Empleado ")
    sbQuery2.Append(" ,Nombre ")
    sbQuery2.Append(" ,Apellidos ")
    sbQuery2.Append(" ,Horas_Jornada ")
    sbQuery2.Append(" ,Minutos_Jornada ")
    sbQuery2.Append(" FROM Personal ")

    cmdExec2.CommandText = sbQuery2.ToString

    da_Datos = New OleDbDataAdapter(cmdExec2)
    'da_Datos.Fill(dt_Personal)
    da_Datos.Fill(dt_Eventos, "Personal") ' Versión Tuttini






    Dim CrReport As New CrystalDecisions.CrystalReports.Engine.ReportDocument
    ' Asigno el reporte
    CrReport = New CrystalDecisions.CrystalReports.Engine.ReportDocument()


    Ruta_Reporte = Ruta_Reporte & "\cr_Informe.rpt"



    CrReport.Load(Ruta_Reporte)
    CrReport.SetDataSource(dt_Eventos)
    'CrReport.SetDataSource(dt_Personal)

    crv_Informe.ReportSource = CrReport


    Catch ex As Exception
    MessageBox.Show(ex.ToString, "Mostrando Informe")
    End Try

    End Sub

    ResponderEliminar
  39. hola frikismo

    respondi en el foro

    saludos

    ResponderEliminar
  40. Muchísimas gracias por tu ayuda, los neófitos autodidactas sobrevivimos por gente como tú.


    Un saludo

    ResponderEliminar
  41. Form2 formu2 = new Form2();
    conexionconBD();
    strSQL = "exec ver_art_tod ";
    da = new SqlDataAdapter(strSQL, cn);
    cb = new SqlCommandBuilder(da);
    ds = new DataSet();
    da.Fill(ds, "articulos");
    DataSet dt;
    dt = ds;
    CrystalReport1 cr= new CrystalReport1();
    cr.SetDataSource(dt);
    formu2.crystalReportViewer1.ReportSource = cr;
    formu2.ShowDialog();
    :::::::::::::::::::::::::::::::::
    exec ver_art_tod: es te es un procedimiento almacenado, pero puedes hacerlo con la cunsulta sql "select *from articulos"

    ResponderEliminar
  42. hola Danis

    no entendi, cual es el problema que tienes con esa query ?

    se presenta algun mensaje de error?

    porque usas el "exec" para eejcutar un procedure, esa no es la forma correcta deberias usar un SqlCommand asignando el CommandType

    saludos

    ResponderEliminar
  43. Hola leandro, uso en mi aplicación dataset tipados. Tengo un datagridview que almacena las lineas de una factura. Estoy teniendo problemas a la hora de calcular el total de la factura. Como sería la forma correcta de recorrer el datagridview?
    Lo que me sucede es que cuando quiero borrar una fila se me queda la fila vacia en el datargridview pero no la borra, se queda la fila vacia. Porque sucede esto?
    El calculo del total lo realizo en un backgroundworked tiene esto algo que ver?

    La excepcion que me da es:
    Referencia a objeto no establecida como instancia de un objeto.

    Cuando sucede lo que te he comentado, que al borrar la fila no se borrar y se queda vacia, me da dos exceciones de este tipo, la de la fila ultima por tener la propiedad del dgv AllowUserToAddRows a true y la otra excepcion por la fila que debería de haber borrado y no la borra.

    ResponderEliminar
  44. Te pongo una captura para que veas lo que sucede:

    http://i60.tinypic.com/24w7guw.jpg

    ResponderEliminar
  45. hola Isidro

    partamos de la base que con el backgroudworker no puedes acceder a los controles del form, por lo que me llama la atencion que realices alli alguna operacion

    calcular totales se puede realizar con linq en una unica operacion

    sumar columnas de un datagridview en c#

    saludos

    ResponderEliminar
  46. Hola Leandro, ya he solucionado mi error. He quitado el backgrounworked. Lo que me sucedia es que en la función de calcular el total, hacia una modificación en la tabla. Esto me generaba el evento CellValueChanged y hacia una recursividad a esta función.
    Gracias por contestar.

    ResponderEliminar
  47. Hola Leandro
    Estoy realizando un reporte con un dataset el cual contiene cuatro tablas relacionadas
    rhempleados,rhasistencia,rhDetalleAsistencia,rhtipoasistencia
    respectivamente rhempleados con rhasistencia de una a varios
    rhasistencia con rhDetalleAsistencia de una a varios
    rhDetalleAsistencia con rhtipoasistencia de una a varios

    quiero mostrar un reporte con las asistencias de un empleado en un mes determinado
    a nivel de SQL realizo una consulta y si puedo mostrarlos


    SELECT rhempleados.id, rhempleados.nombres, rhempleados.apellidos, rhDetalleAsistencia.horaMarcada, rhasistencia.fecha, rhtipoasistencia.descripcion
    FROM rhasistencia INNER JOIN
    rhDetalleAsistencia ON rhasistencia.idrhAsistencia = rhDetalleAsistencia.idAsistencia INNER JOIN
    rhtipoasistencia ON rhDetalleAsistencia.idTipoAsistencia = rhtipoasistencia.idrhTipoAsistencia INNER JOIN
    rhempleados ON rhasistencia.idEmpleado = rhempleados.id WHERE rhempleados.id=@idEmpleado and (YEAR(rhasistencia.fecha)=YEAR(@fechaConsultar) and MONTH(rhasistencia.fecha)=month(@fechaConsultar))

    y poniendolos en un datagridview tambien me muestran los datos de forma correcta pero al querer poner en el reporte esos datos me sale el reporte en blanco
    este codigo utilizo para mostrar el reporte



    //consultas
    string empleados = "SELECT * from rhempleados where id='"+unEmpleado.Id.ToString()+"'";
    string asistencias = "SELECT * from rhasistencia";
    string detalleAsistencias = "SELECT * FROM rhDetalleAsistencia where YEAR("+fechaConsulta+")=YEAR(fecha) and MONTH("+fechaConsulta+")=MONTH(fecha)";
    string tipoAsistencias = "SELECT * from rhtipoasistencia";

    //dataset
    dsAsisnteicasMesEmpleados dsAsisnteicasMesEmpleados = new DataSets.dsAsisnteicasMesEmpleados();
    SqlConnection sqlConexion = new SqlConnection(new Conexion().obtenerCadenaConexion);

    //adaptadores
    SqlDataAdapter rhasistencia = new SqlDataAdapter(asistencias, sqlConexion);
    SqlDataAdapter rhDetalleAsistencia = new SqlDataAdapter(detalleAsistencias, sqlConexion);
    SqlDataAdapter rhtipoasistencia = new SqlDataAdapter(tipoAsistencias , sqlConexion);
    SqlDataAdapter sqlDarhEmpleados = new SqlDataAdapter(empleados, sqlConexion);


    sqlDarhEmpleados.Fill(dsAsisnteicasMesEmpleados, "rhEmpleados");
    rhasistencia.Fill(dsAsisnteicasMesEmpleados, "rhasistencia");
    rhDetalleAsistencia.Fill(dsAsisnteicasMesEmpleados, "rhDetalleAsistencia");
    rhtipoasistencia.Fill(dsAsisnteicasMesEmpleados, "rhtipoasistencia");

    //reporte
    rptAsistenciasPorMes rptAsistenciasPorMes = new Reportes.rptAsistenciasPorMes();
    rptAsistenciasPorMes.SetDataSource(dsAsisnteicasMesEmpleados);
    crystalReportViewer1.ReportSource = rptAsistenciasPorMes;

    de antemano gracias!!!!!

    ResponderEliminar
  48. hola Nelson

    si pones un breakpoint en la linea
    rptAsistenciasPorMes.SetDataSource(dsAsisnteicasMesEmpleados);

    y pasas el mouse sobre el dataset puedes validar que contiene registros ? usa la tool de debug para ver los datos

    defines campos del dataset en el .rpt en la seccion de Details del reporte ?

    podrias validar el DataBase Expert del reporte para ver como relaciona las tablas, a veces no respecta bien las relaciones de forma correcta lo cual genera uniones invalidad que impide que se muestre bien la informacion

    saludos

    ResponderEliminar
  49. Hola leandro
    1. si contiene registros
    2. Si estan definidos los campos en la secio detail
    3. Las relaciones si estan correctas

    Estimado Leandro probe las 3 opciones que diste pero me sigue mostrando el reporte vacio de pronto no tendras un ejemplo donde trabajes con unas tres tablas relacionadas asi como el que yo plantee

    Otra cosa haciendolo por medio de un procedimiento almacenado si me funciona pero el problema esque solo me funciona localmente cuando pongo la aplicación en otra maquina tengo que cambiar uno por uno las conexiones del reporte y practicamente diseñarlo nuevamente, existe alguna manera de que esto se pueda hacer por código gracias de antemano

    Saludos de Ecuador

    posdata: te han dicho que te pareces a Hernan Barcos xD (aquel jugador de Racing Club, Liga de Quito entre otros!!!

    ResponderEliminar
  50. hola Leandro buen dia recomiendame algún reporteador para Visual Studio 2017
    muchas gracias

    ResponderEliminar