Principales respuestas
Recorrer una List e imprimir con Crystal Reports

Pregunta
-
Buenas tardes, otra vez yo con problemas, sigo aprendiendo mucho desde este espacio. Un usuario me plantea poder imprimir varios recibos juntos, voy a compartir un poco de codigo:
Public Class FormRecibos
Private Sub FormRecibos_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim objreporte As New ReciboSocio
For Each item As CCIyS.Entidades.Recibo In FormSocios.ListaRecibos
objreporte.SetParameterValue("NombreSocio", item.NombreSocio)
objreporte.SetParameterValue("DomicilioSocio", item.DireccionSocio)
objreporte.SetParameterValue("MesRecibo", item.Descripcion)
objreporte.SetParameterValue("ImporteCuota", item.Importe)
objreporte.SetParameterValue("FechaRecibo", item.FechaRecibo)
objreporte.SetParameterValue("NumeroRecibo", item.NumeroRecibo)
CrystalReportViewer1.ReportSource = objreporte
Next
End Sub
End ClassEste código proviene directamente del form donde tengo el Crystal Reports. Dentro de el instancio un objeto de tipo .rpt, recorro una lista que traigo desde otro form, donde tengo almacenado todos los recibos que debo imprimir.
Si el usuario solo selecciona un recibo del datagridView, la lista tendrá un solo objeto, por ende este código funciona a la perfección.
El tema es cuando el usuario selecciona varios recibos, solo imprime por Crystal Reports el ultimo objeto de la lista.
Saludos.
Respuestas
-
Hola:
El orden aseguir para crystal reports es mas o menos asi.
1.-Crear el fichero RPT con los campos de base de datos, campos de formula, campos de parametro y sus grupos etc.
2.-Cargar dicho fichero RPT con los datos (Datatable, Lista, variables, etc).
3.-Cargar el CrystalReportViever con el fichero RPT con sus datos cargados.Tiene que ser un codigo parecido a esto (varia segun la fuente de datos, en este ejemplo es manual pero lo logico sea que este en una BD)
Public Class FrmLista
Private Sub FrmLista_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Lista As New List(Of Cliente)
Lista.Add(New Cliente("PEPE", "PEREZ", "MARTINEZ"))
Lista.Add(New Cliente("LOLY", "ATXA", "RUIZ"))
Lista.Add(New Cliente("MANUEL", "GARCIA", "LOPEZ"))
Lista.Add(New Cliente("SARA", "REY", "CONDE"))
'
Try
Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT
' Cargar el objeto informe en el ReportDocument
Me.rdInforme.Load(lsFicheroRPT)
'Usa la lista como fuente de dados para el informe
Me.rdInforme.SetDataSource(Lista)
' cargar el ReportDocument en el CrystalReportViewer
Me.crvInforme.ReportSource = Me.rdInforme
Catch ex As Exception
MessageBox.Show("Alguna cosa ha errado, verifique... : " & ex.Message)
End Try
Me.WindowState = FormWindowState.Maximized
End Sub
End Class
Un saludo desde Bilbo
Carlos- Propuesto como respuesta Carlos_Ruiz_M jueves, 30 de mayo de 2019 13:52
- Marcado como respuesta ggomez115 miércoles, 5 de junio de 2019 16:12
-
Hola:
Esta formaTry
' instanciar el objeto informe
Dim oRptPrueba As New CRLista()
oRptPrueba.SetDataSource(Lista)
' cargar el informe en el control visualizador
Me.crvInforme.ReportSource = oRptPrueba
Catch ex As Exception
MessageBox.Show(ex.Message)
End TryY esta otraTry
Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT
' Cargar el objeto informe en el ReportDocument
Me.rdInforme.Load(lsFicheroRPT)
Me.rdInforme.SetDataSource(Lista)
' cargar el ReportDocument en el CrystalReportViewer
Me.crvInforme.ReportSource = Me.rdInforme
Catch ex As Exception
MessageBox.Show("Alguna cosa ha errado, verifique... : " & ex.Message)
End Try
El resultado es exactamente el mismo.A primera vista la primera opcion necesita menos lineas de codigo y NO necesita el control rdInforme (Es un ReportDocument). Vease la siguiente imagen
La ventaja de usar el ReportDocument es que se obtiene una mayor flexibilidad a la hora de manipular el contenido del informe por codigo.
En cuanto al problema que se te presenta, parece ser que esta en el datatable (o lo que sea) con la que cargas el datasource del fichero RPT.
Es condicion necesaria que la fuente de datos tenga todos los campos que tiene el fichero RPTUn saludo desde Bilbo
Carlos- Propuesto como respuesta Tonatiuh AbregoModerator martes, 4 de junio de 2019 14:16
- Marcado como respuesta Tonatiuh AbregoModerator martes, 4 de junio de 2019 15:20
Todas las respuestas
-
Hola
Gracias por levantar tu consulta en los foros de MSDN. Con respecto a la misma, te hago la recomendación de ingresar al siguiente enlace en donde puedes encontrar una posible solución para tu problema.
https://social.msdn.microsoft.com/Forums/es-ES/aef72dd5-600f-4867-a3d5-a18f9c87057a/imprimir-verticalmente-crystal-reports?forum=vbes
https://social.msdn.microsoft.com/Forums/es-ES/205d2376-64b3-4e78-b42a-97b31be3665c/recorrer-listview-para-llenar-dataset?forum=vcses
Gracias por usar los foros de MSDN.
Carlos Ruiz
____Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.
Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.
Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.- Propuesto como respuesta Carlos_Ruiz_M miércoles, 29 de mayo de 2019 21:29
-
-
Buenas tardes, estuve leyendo los post que me recomendaste. Uno de ellos trabaja con un DataSet enlazado al crystalReportsViewer. Si es necesario podria cambiar mi codigo para probar de hacerlo asi, pero mi ejemplo es algo mas simple. Tengo un form, con un crystalReportViewer, tengo un archivo .rpt que tiene forma de recibo, con variables que seran completadas al momento de instanciar el reporte.rpt, el resto del codigo es simplemente esto:
Public Class FormRecibos
Private Sub FormRecibos_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim objreporte As New ReciboSocio
For Each item As CCIyS.Entidades.Recibo In FormSocios.ListaRecibosobjreporte.SetParameterValue("NombreSocio", item.NombreSocio)
objreporte.SetParameterValue("DomicilioSocio", item.DireccionSocio)
objreporte.SetParameterValue("MesRecibo", item.Descripcion)
objreporte.SetParameterValue("ImporteCuota", item.Importe)
objreporte.SetParameterValue("FechaRecibo", item.FechaRecibo)
objreporte.SetParameterValue("NumeroRecibo", item.NumeroRecibo)
CrystalReportViewer1.ReportSource = objreporte
Next
End Sub
End ClassDe otro form (esto ya es indiferente) traigo una lista ya completa, recorro esta lista con for each asignando a las variables del archivo ReciboSocio.rpt sus valores y luego generando el ReportSource.
Lo que hace este código es solo imprimir el ultimo registro de la lista. Es como que va sobreescribiendo siempre el mismo ReportSource, y al final solo se ve el ultimo. Debe haber alguna manera aquí mismo, sin tener que tocar tanto código de que por cada registro de la lista imprima un ReportSource, generando así la misma cantidad de hojas para imprimir, como registros tenga la lista.
Saludos.
-
Hola:
El orden aseguir para crystal reports es mas o menos asi.
1.-Crear el fichero RPT con los campos de base de datos, campos de formula, campos de parametro y sus grupos etc.
2.-Cargar dicho fichero RPT con los datos (Datatable, Lista, variables, etc).
3.-Cargar el CrystalReportViever con el fichero RPT con sus datos cargados.Tiene que ser un codigo parecido a esto (varia segun la fuente de datos, en este ejemplo es manual pero lo logico sea que este en una BD)
Public Class FrmLista
Private Sub FrmLista_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Lista As New List(Of Cliente)
Lista.Add(New Cliente("PEPE", "PEREZ", "MARTINEZ"))
Lista.Add(New Cliente("LOLY", "ATXA", "RUIZ"))
Lista.Add(New Cliente("MANUEL", "GARCIA", "LOPEZ"))
Lista.Add(New Cliente("SARA", "REY", "CONDE"))
'
Try
Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT
' Cargar el objeto informe en el ReportDocument
Me.rdInforme.Load(lsFicheroRPT)
'Usa la lista como fuente de dados para el informe
Me.rdInforme.SetDataSource(Lista)
' cargar el ReportDocument en el CrystalReportViewer
Me.crvInforme.ReportSource = Me.rdInforme
Catch ex As Exception
MessageBox.Show("Alguna cosa ha errado, verifique... : " & ex.Message)
End Try
Me.WindowState = FormWindowState.Maximized
End Sub
End Class
Un saludo desde Bilbo
Carlos- Propuesto como respuesta Carlos_Ruiz_M jueves, 30 de mayo de 2019 13:52
- Marcado como respuesta ggomez115 miércoles, 5 de junio de 2019 16:12
-
-
Buenas tardes, estimado ando de vuelta por aquí, para sacarme algunas dudas. Hay fragmentos de tu código que no entiendo. Sacando la carga de la lista (esta se carga a través de la interacción entre el usuario y la BD)
.. Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT..
Esta variable string que le asignas como valor la ruta del archivo .rpt es necesaria? Consulto porque mi archivo .rpt esta dentro del proyecto.
..Me.rdInforme.Load(lsFicheroRPT)..
Esta variable rdInforme de que tipo es? Porque no la estas inicializando dentro de tu codigo, directamente la estas utilizando, y le estas asignando la ruta del archivo .rpt como parametro.
No seria esto similar a hacer: Dim MiReporte as new MiReporte.rpt?? Suponiendo que esto es un SI, si hago estoestaría haciendo un trabajo similar a tu código:
Dim Reporte as new ReciboSocio 'este es el archivo .rpt incluido dentro del proyecto
Reporte.SetDataSource(FormSocios.ListaRecibos) 'la lista viene cargada desde otro form
CrystalReportViewer1.ReportSource = Reporte
Con este codigo, arroja el siguiente error:
Dice el informe no tiene tablas.
Saludos Guille.
-
Hola:
Esta formaTry
' instanciar el objeto informe
Dim oRptPrueba As New CRLista()
oRptPrueba.SetDataSource(Lista)
' cargar el informe en el control visualizador
Me.crvInforme.ReportSource = oRptPrueba
Catch ex As Exception
MessageBox.Show(ex.Message)
End TryY esta otraTry
Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT
' Cargar el objeto informe en el ReportDocument
Me.rdInforme.Load(lsFicheroRPT)
Me.rdInforme.SetDataSource(Lista)
' cargar el ReportDocument en el CrystalReportViewer
Me.crvInforme.ReportSource = Me.rdInforme
Catch ex As Exception
MessageBox.Show("Alguna cosa ha errado, verifique... : " & ex.Message)
End Try
El resultado es exactamente el mismo.A primera vista la primera opcion necesita menos lineas de codigo y NO necesita el control rdInforme (Es un ReportDocument). Vease la siguiente imagen
La ventaja de usar el ReportDocument es que se obtiene una mayor flexibilidad a la hora de manipular el contenido del informe por codigo.
En cuanto al problema que se te presenta, parece ser que esta en el datatable (o lo que sea) con la que cargas el datasource del fichero RPT.
Es condicion necesaria que la fuente de datos tenga todos los campos que tiene el fichero RPTUn saludo desde Bilbo
Carlos- Propuesto como respuesta Tonatiuh AbregoModerator martes, 4 de junio de 2019 14:16
- Marcado como respuesta Tonatiuh AbregoModerator martes, 4 de junio de 2019 15:20
-
Hola:
Esta formaTry
' instanciar el objeto informe
Dim oRptPrueba As New CRLista()
oRptPrueba.SetDataSource(Lista)
' cargar el informe en el control visualizador
Me.crvInforme.ReportSource = oRptPrueba
Catch ex As Exception
MessageBox.Show(ex.Message)
End TryY esta otraTry
Dim lsFicheroRPT As String = ("..\..\CRLista.rpt") 'Path del fichero RPT
' Cargar el objeto informe en el ReportDocument
Me.rdInforme.Load(lsFicheroRPT)
Me.rdInforme.SetDataSource(Lista)
' cargar el ReportDocument en el CrystalReportViewer
Me.crvInforme.ReportSource = Me.rdInforme
Catch ex As Exception
MessageBox.Show("Alguna cosa ha errado, verifique... : " & ex.Message)
End Try
El resultado es exactamente el mismo.A primera vista la primera opcion necesita menos lineas de codigo y NO necesita el control rdInforme (Es un ReportDocument). Vease la siguiente imagen
La ventaja de usar el ReportDocument es que se obtiene una mayor flexibilidad a la hora de manipular el contenido del informe por codigo.
En cuanto al problema que se te presenta, parece ser que esta en el datatable (o lo que sea) con la que cargas el datasource del fichero RPT.
Es condicion necesaria que la fuente de datos tenga todos los campos que tiene el fichero RPTUn saludo desde Bilbo
Carlos
Buen día, creo que mi problema puede venir de lo ultimo que mencionas. En primer lugar yo estoy usando CrystalReportViewer y no CrystalReportDocument. En segundo lugar, el archivo.rpt esta creado "como informe en blanco" y los datos (variables) están creados desde la opción parámetros, donde creas el parámetro (nombre y tipo de variable) y luego desde el form donde esta el CrystalReportViewer le das valor al mismo a traves de la opcion Mireporte.SetParameterValue("FechaRecibo", FechaParaRecibo) luego de instanciar el objeto de tipo .rpt
Si bien la lista contiene los mismos datos como parametros hay en el archivo.rpt, no tengo en el archivo.rpt una tabla asociada con estos campos, como supe ver en algunos tutoriales.
Voy a hacer las modificaciones correspondientes, para ver si puedo lograr hacer funcionar esto y regreso.
Saludos.
-
Buen dia, bueno paso a comentar que mi problema ha sido resuelto, gracias Carlos por la ayuda. Debajo comento como quedo solucionado para que pueda servir a futuros novatos como yo:
Primero, el titulo queda mal, ya que ya no estoy recorriendo una list e imprimiendo en crystal Reports, lo hago desde una DataSet, cree un archivo DataSet.xsd, con la tabla de mi BD, en la cual selecciono solo los campos que voy a imprimir en el Reporte.
En un form, coloco el CrystalReportViewer, por otro lado, creo un archivo.rpt de forma estandar. Esto me dara la posibilidad de enlazar el archivo.rpt a la dataSet creada anteriormente, pudiendo colocar los campos de la dataSet dentro del reporte.
En un form normal, donde interactuo con el usuario tengo lo siguiente:
Public Shared DtRecibos As New DataTable 'necesito la variable de tipo shared para poder usar en otro form
If DtRecibos.Columns.Count = 0 Then 'creo las columnas con los mismos nombres de los campos
With DtRecibos 'de la dataSet. En caso de que ya tenga datos la misma, los borro
.Columns.Add("NombreSocio") 'para cargarla nuevamente.
.Columns.Add("DireccionSocio")
.Columns.Add("Descripcion")
.Columns.Add("Importe")
.Columns.Add("NumeroRecibo")
.Columns.Add("FechaRecibo")
End With
Else
DtRecibos.Clear()
End IfDim value As DataGridViewSelectedRowCollection = Me.DataGridView1.SelectedRows
For Each Fila As DataGridViewRow In value 'con este for each voy creando filas en la dataSet, los datos
DtRecibos.Rows.Add(AuxNombreSocio, 'introducidos son tomados desde un dataGrid, por eso el for each
AuxDomicilioSocio, 'recorre las filas seleccionadas del dataGridview, almacena en
AuxDescripcionRecibo, 'variables y luego utilizo esas variables para cargar el dataSet
AuxImporteCuota,
UltimoNumeroRecibo,
AuxFechaRecibo)
NextEn el otro form, donde tengo el crystalReportViewer tengo solo este codigo:
Private Sub FormRecibosMultiples_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ReporteDoc As CrystalDecisions.CrystalReports.Engine.ReportDocument
ReporteDoc = New RecibosMultiples
ReporteDoc.SetDataSource(FormSocios.DtRecibos)
CrystalReportViewer1.ReportSource = ReporteDoc
End SubY funciona a la perfeccion, lo demas es todo visual y como uno quiera ordenar los campos en el reporte.
Ahora bien, de yapa te hago otra consulta, hay manera desde aqui mismo, desde el codigo de generar un salto de pagina en el reporte? Para que por cada fila que recorrer del dataSet haga un salto de pagina?
Saludos.
-
-