jueves, abril 19, 2012

Desplegar una imagen en Crystal Reports desde VB 2010


El problema era que tenia que imprimir un gafete con la imagen de la persona.

El punto era como podria indicarle al campo de imagen cual archivo tomar? Ya que no se puede acceder a las propiedades de un objeto insertado tan facilmente.

Aunque esto ya lo habia hecho con Crystal Reports allá como a mediados de los 90's, la verdad es que no me acordaba, pero despues de jugar un rato con CrystalReports y su editor de formulas, me acordé:

La solución que implementé es la siguiente:

1. Crear un campo de formula en el reporte, en mi caso lo nombré "PicFileName".
2. Insertar un "OLE Object" del tipo Paintbrush Picture.
3. Darle formato al objeto OLE, en el tab de Picture, en "Graphic Location:" puse algo como
    "My-directorio-donde-almaceno-las-fotos\" + {@PicFileName}

En la sección del código, el que se ejecuta para desplegar el reporte, (en mi caso el evento Click) puse algo como:
...
frmCRBadge.CrystalReport.DataDefinition.FormulaFields("PicFileName").Text = "'" & Nombre-del-Archivo-de-Imagen & ".jpg'"
...

Y listo, cada vez que selecciono un registro diferente se muestra el reporte con su correspondiente imagen.

NOTA: Nombre-del-Archivo-de-Imagen  yo uso el ID del registro que le corresponde, así cada vez que se selecciona un registro diferente, el Nombre-del-Archivo-de-Imagen se actualiza solito.




21 comentarios:

  1. hola buenas tardes he programado todo lo que dices en tu post pero tengo problema no me carga la imagen, sera que por favor me puedes contactar, luisrafa30@hotmail.com

    ResponderBorrar
  2. Yo estoy usando SAP Crystal Reports for Visual Studio 2010.

    ResponderBorrar
  3. YO traigo la ruta completa de la foto en un campo del reporte, cuando lo veo en vista previa aparece el la foto con los datos, cuando ejecuto el programa solo aparecen los datos no la foto...
    Puse en Hipervinvulo y cuando le doy click al cuadro de foto, la me manda ala foto, pero no se por q no aparece la foto en el reporte, si me presenta todos los datos y hasta la ruta me da la Ubicaion.
    Agradeceria su aporte

    ResponderBorrar
  4. Anonimo,

    Si no te presenta ningun error, y te despliega los datos pero no la foto, donde buscaria seria mas bien en el formato del reporte primero.
    Es decir que los margenes, el tamaño de papel, o el tipo de impresora no se 'coman' a la foto y te lo despliege en otra hoja, o -como en tu caso- no se muestre la foto.

    Si todo esto esta bien, entonces verifica tu "OLE Object".
    El procedimiento descrito en el post, consiste de dos partes, darle formato al objeto OLE, y mandarle por codigo el directorio al objeto de la foto.


    Espero no este de mas, pero dejame decir que la variable "My-directorio-donde-almaceno-las-fotos" no es un hipervinculo, mas bien es un path, algo asi como "C:\Proyecto1\fotos\"
    Y la variable "Nombre-del-Archivo-de-Imagen", es solo un numero consecutivo el cual use como nombre para la foto.

    El reporte para desplegar la foto debe de desplegarla de donde la pueda leer, en este caso es de un directorio local que puede acceder el reporte.

    Saludos!

    ResponderBorrar
  5. Hola Miguel,
    Mande a llamar los mismos reportes pero desde otro formulario,
    En el load de el reporte yo tengo esto....

    Case "Carnet"
    Try

    sSql = "SELECT dbo.plndepartamentos.nombre_depto, dbo.plnubicaciones.nombre_ubicacion, dbo.plncargos.nombre_cargo, dbo.plnempleados.*" & _
    "FROM dbo.plndepartamentos INNER JOIN" & _
    " dbo.plnempleados ON dbo.plndepartamentos.codigo_depto = dbo.plnempleados.codigo_depto INNER JOIN" & _
    " dbo.plncargos ON dbo.plnempleados.codigo_cargo = dbo.plncargos.codigo_cargo INNER JOIN " & _
    " dbo.plnubicaciones ON dbo.plnempleados.codigo_ubicacion = dbo.plnubicaciones.codigo_ubicacion" & _
    " where dbo.plnempleados.codigo_empleado= '" + frm_Impresiondecarnet.TextBox1.Text + "'"

    da = New SqlDataAdapter(sSql, sCnn)
    Dim dt As New DataTable
    da.Fill(dt)
    Dim preport As New rptCarnet
    preport.DataSourceConnections(0).SetConnection(VgServer, vgDb, VgNombreUsuario, VgpassUser)
    preport.SetDataSource(dt)
    Me.Crpreporte.ReportSource = preport
    Me.Crpreporte.Refresh()
    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try

    y desde ese formulario los cargo bien, pero como son reportes de empleados, pues tiene que ir exigidamente en la formulario de empleados
    pero es formulario no me presenta la foto solo los demas datos...

    ResponderBorrar
  6. Anonimo,

    Lo que te sugeriria es que eso lo pongas en el formulario (en el evento click del boton) donde mandas a llamar el reporte, no en el reporte.

    Estas guardando las fotos en el disco o directorio local verdad?
    O las guardas com BLOB en la base de datos?

    Si es en el directorio local:

    'El reportsource lo puedes definir en las propiedades del reporte en tiempo de diseño.
    Me.Crpreporte.ReportSource = preport

    ' EN ESTA PARTE DEBES DE TENER ALGO COMO:
    ' Me.Crpreporte.DataDefinition.FormulaFields("NombreDeLaFormulaEnElReporte").Text = "'" & NombreDeLaFoto & "'"
    Me.Crpreporte.Refresh()
    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try



    ResponderBorrar
  7. Anonimo,
    Aunque no me lo preguntas, permiteme darte una sugerencia respecto al SQL que tienes:

    CAMBIAR ESTO:

    sSql = "SELECT dbo.plndepartamentos.nombre_depto, dbo.plnubicaciones.nombre_ubicacion, dbo.plncargos.nombre_cargo, dbo.plnempleados.*" & _
    "FROM dbo.plndepartamentos
    INNER JOIN dbo.plnempleados ON dbo.plndepartamentos.codigo_depto = dbo.plnempleados.codigo_depto
    INNER JOIN dbo.plncargos ON dbo.plnempleados.codigo_cargo = dbo.plncargos.codigo_cargo
    INNER JOIN dbo.plnubicaciones ON dbo.plnempleados.codigo_ubicacion = dbo.plnubicaciones.codigo_ubicacion
    " WHERE dbo.plnempleados.codigo_empleado= '" + frm_Impresiondecarnet.TextBox1.Text + "'"


    A ESTO SQL :

    sSql = "SELECT dbo.plndepartamentos.nombre_depto, dbo.plnubicaciones.nombre_ubicacion, dbo.plncargos.nombre_cargo, dbo.plnempleados.* FROM dbo.plndepartamentos, dbo.plnempleados, dbo.plncargos ,dbo.plnubicaciones
    WHERE dbo.plnempleados.codigo_empleado= '" + frm_Impresiondecarnet.TextBox1.Text + "'"
    AND dbo.plndepartamentos.codigo_depto = dbo.plnempleados.codigo_depto
    AND dbo.plnempleados.codigo_cargo = dbo.plncargos.codigo_cargo
    AND dbo.plnempleados.codigo_ubicacion = dbo.plnubicaciones.codigo_ubicacion

    Tambien te recomiendo que quites dbo.plnempleados.*, y solo indiques los campos que necesitas.

    Tendras un SQL mas rapido y eficiente.

    Saludos

    ResponderBorrar
  8. Amigo y si mejor sube un proyecto con tu ejemplo funcional para asi poder descargarlo y estudiarlo sin tener que esperar a que usted se pase por aqui 1 vez cada año?

    ResponderBorrar
  9. Hola Dydimos, por lo regular contesto en pocos dias depende de que tan ocupado ande; respecto a tu peticion, este caso es sencillo pero tiene su "truco", si eres un programador mas o menos con experiencia lo entiendes sin necesidad de ejemplos.
    Si estas empezando a programar, igual te puedo hacer el ejemplo. Despues te comparto el enlace en este mismo mensaje dentro de algunos dias.

    Saludos

    ResponderBorrar
  10. hola amigo disculpa pero cual es la formula para el campo de formula @PicFileName me supongo k tiene una formula o no;xk ya lo ise como tu dices en el post y nome sale error pero no me muestra la imagen porque Porfavor respondeme si te dejo mi correo Loco88_zc@hotmail.com mandame tu ejemplo por favor o explicame porue no me muestra la imagen

    ResponderBorrar
  11. Hola nuevamente buen es raro porque ago lo k tu dices bueno al correr mi aplicanion la primera salida sale la imagen y cuando vuelvo nuevamente a generar mi reporte ya no aparese esa imagen bueno despues de un ora igual sale y despues ya no sale nuevamente porque explicame k estoy asiendo mal si porfavor pero responde ps amigo o tengo que hacer una formula dentro para el campo de formula @PicFileName

    ResponderBorrar
  12. Dancer,
    Tal vez lo que necesites poner en el campo de formula es unos 50 espacios entre comillas. Algo asi como: " "
    Esa seria la unica 'formula' que lleva.
    Cuando tu mandas a llamar a tu reporte, le tienes que pasar a ese campo de formula el directorio y el nombre del archivo de la foto. (como esta indicado en el mensaje de arriba).
    Permiteme terminar el ejemplo y lo anexo.
    Saludos!

    ResponderBorrar
  13. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  14. mira bueno ya lo intente y no sale porfavor enviamelo si porfa.
    te digo mas o menos komo lo ago ps:
    lo k pasa k uso dataset tipado siempre es mas facil pero se me antojo aserlo sin dataset
    el punto va asi
    capturo valores por medio de parametros de crytsal report y tengo mandar una imagen,bueno los parametros si entran normal al reporte lo complicado k la imagen no buen aqui va el code:

    mi k formula que use fue asi: "C:\IMAGENES-CALZADOS\" + {@Foto}

    si lo mando asi si me muestra la imagen :
    Dim info As New CrystalReportDans
    Dim Nombre As String = "dancer"
    info.DataDefinition.FormulaFields("Foto").Text = "'" & Nombre & ".jpg'"

    'pero el nombre me trae statico definido ahora yo kier dinamicamente porque selecciono una grilla obvio k el valor tiene k ser string en este caso lo ise asi:

    'variable imagen me trae el dato de la cadena con su nombre de la imagen en string
    Dim Solo_Archivo As String = imagen.Substring(imagen.LastIndexOf("\") + 1)
    'extraigo solo el nombre y su extencion

    Dim Solo_Nombre As String = Separador_Imagen(Solo_Archivo, ".", 1)
    'Separador_Imagen es mi funcion donde extraigo solo el nombre

    Dim Solo_Extension As String = Separador_Imagen(Solo_Archivo, ".", 2)
    'Separador_Imagen es mi funcion donde extraigo solo la extension

    'y por ultimo concateno y el resultado no muestra nada apesar k son string

    info.DataDefinition.FormulaFields("Foto").Text = "'" & Solo_Nombre & "." & Solo_Extension & "'"

    CRForm6.CrystalReportViewer1.ReportSource = info
    CRForm6.CrystalReportViewer1.Refresh()
    'd esta manera bueno los parametros datos de un cliente envio si las envia pero la foto nada

    'trate de ponder solo la variable Solo_Archivo k me trae el nombre y su extencion de 'la imagen pero igual no muestra nada !porque? ;trate poner entre comillas dicha variables y no muestra nada; explicame porfavor le falta alguna propiedad en objeto ole ,una ayudita porfis;porfis mandame tu archivo tlo agradecera

    ResponderBorrar
  15. El ejemplo lo puedes descargar del siguiente link:

    https://drive.google.com/file/d/0BxqV9qeSNt6XdVMxd2RFcV9fa0k/edit?usp=sharing

    ResponderBorrar
  16. muy buenas tarde amigo, esta muy bieno tu blic y me funciono perfectamente... epro tengo un problemita como hago para isertar la imagen pero no desde la ubicacion de un disco de mi pc, si no desde la carpeta resource de mi aplicacion, como variaria este aspecto:
    "My-directorio-donde-almaceno-las-fotos\" + {@PicFileName}

    ResponderBorrar
  17. Hola Jesus David, de hecho ese es el problema original que intente resolver.
    Ya que como dije en el post, no puedes acceder un objeto embebido en el reporte.
    Por ejemplo en el caso que digas que tu tienes tu logo en el archivo de recursos y lo quieres mandar en el reporte; entonces lo que esta en el archivo de recursos es estático, si es asi, te convendria poner la imagen estatica en el reporte tambien.
    Si es dinamico, entonces seria recomendable la solución descrita.
    Saludos

    ResponderBorrar
  18. me funciona pero tengo un pequeño problema.
    cuando cargo la imagen desde el formulario lo hago de la siguiente forma
    PictureBox1.Load("..\Alumnos\" & readr(31))
    Las imágenes las tengo guardadas dentro de la carpeta de la aplicación
    pero en el OLE Object no me funciona de esta forma
    "..\Alumnos\" + {@PicFileName}

    pero si coloco la cadena completa "C:\users\etc etc\"
    si funciona

    por favor ayudenme

    ResponderBorrar
  19. Anonimo, asi es, tienes que pasarle el path completo, no acepta paths relativos.

    ResponderBorrar
  20. De esta forma si puedes indicar la ruta de la imagen dentro del proyecto

    reporte.DataDefinition.FormulaFields("Picture_1").Text = "'" & Server.MapPath("~/images/circle_Green.png" & "'")

    ResponderBorrar

Y USTED QUE OPINA?