Cómo abrir un reporte hecho en Crystal Reports (Visual Basic)

 

Autor: Daniel Maya Ortiz < danielmaya@hotmail.com >
Fecha: 22/Ago/2003
Actualizado: 22/Ago/2003


 

CÓMO ABRIR UN REPORTE HECHO EN CRYSTAL REPORTS

 

Para abrir un reporte hecho en Crystal Reports existen dos posibilidades:

 

1.      Hacer que el reporte esté dentro del proyecto, mediante el diseñador de Crystal Reports.

 

Ventajas:

 

·        El reporte forma parte del proyecto, de manera que no se tiene que agregar ningún archivo de reporte al empaquetado.

·        Al usar el diseñador se tiene la posibilidad de capturar algunos eventos que el reporte dispara, por ejemplo a la hora de leer los registros y a la hora de imprimir el reporte.

·        Existe una mayor flexibilidad para manejar la jerarquía de objetos y acceder a ella.

·        Se tiene mayor control sobre los objetos que forman parte del reporte.

 

Desventajas:

 

·        El uso de diseñadores hace que el proyecto crezca en tamaño.

·        Un paquete de instalación con diseñadores de Crystal Reports es más propenso a fallar (en mi experiencia) que si se lee un reporte desde un archivo externo.

 

 

 

2.      Abrir el reporte mediante código.

 

Ventajas:

 

·        El proyecto es mucho más ligero, puesto que no requiere más que el archivo RPT (que no es parte del proyecto).

·        El paquete de instalación falla menos (lástima, me hubiera gustado teclear que no falla).

 

Desventajas:

 

·        Se pierde el control que se obtiene con el diseñador.

·        Si alguien intencionadamente borra el archivo RPT causará un error a la hora de querer ver dicho reporte.

 

 

A final de cuentas, por experiencia propia yo he elegido la segunda opción. Y en el presente artículo voy a explicar lo más detalladamente posible cómo abro los reportes desde Visual Basic.

 

 

Los preparativos

 

Antes de comenzar, voy a considerar que al proyecto de Visual Basic sólo le faltan los reportes, y que éstos ya están hechos en Crystal, es decir, ya se tienen los archivos RPT. Para este artículo usaré un reporte que únicamente contiene dos parámetros, una fórmula y 3 objetos de texto. Otra consideración importante en la versión del producto. Utilizaré Visual Basic 6.0 Profesional y Crystal Reports 9 Developer Edition.

 

Lo primero que hay que hacer es agregar la librería Crystal Reports 9 ActiveX Designer Run Time Library. Además se debe agregar el componente Crystal Reports Viewer Control 9, como se muestra en las siguientes figuras:

 

 

 

A continuación necesitamos dos formularios, en uno de ellos vamos a insertar una instancia del CRViewer9, de manera que éste será el formulario donde finalmente de verá el reporte; yo acostumbro ponerle el estado inicial al formulario como maximizado, sin embargo, esto no es necesario. El tamaño del CRViewer9 no importa ya que mediante programación haremos que su tamaño se ajuste al tamaño del formulario; el nombre tampoco importa mucho, sin embargo, yo usaré como nombre crViewer, sólo por costumbre más que por otra cosa. A este formulario le llamaremos frmReporte.

 

El otro formulario servirá para que el usuario pueda introducir los parámetros que requiere el reporte. En el ejemplo de reporte que usaré para este artículo he definido dos parámetros, Parametro1 de tipo Cadena y Parametro2 de tipo Número. Por lo que un par de Labels y un par de TextBox, además de un par de botones será suficiente. Al formulario le llamaremos frmParametros.

 

 

Formulario frmReporte

 

A continuación voy presentando el código por partes, y voy a explicarlo lo más detallado que pueda. Comenzaremos con el formulario más importante: frmReporte.

 

Sección de declaraciones

 

Option Explicit

 

Private crApp As New CRAXDRT.Application

Private crReport As New CRAXDRT.Report

 

Private mflgContinuar As Boolean

Private mstrParametro1 As String

Private mlngParametro2 As Long

 

 

 

 

 

 

 

En la sección de declaraciones necesitamos las siguientes variables:

 

Variable

Descripción

crApp

Objeto que representa una instancia del programa Crystal Reports.

crReport

Objeto que representa el reporte que deseamos abrir.

mflgContinuar

Variable booleana que nos indica si hubo error al tratar de abrir el archivo RPT.

mstrParametro1

Variable de cadena que almacenará el valor que se le pasará al Parametro1 del reporte.

mlngParametro2

Variable numérica que almacenará el valor que se le pasará al Parametro2 del reporte.

 

Cabe mencionar que en el formulario se deben declarar tantas variables como parámetros tenga el reporte, además de las tres primeras variables, que no deberán faltar independientemente del número de parámetros.

 

 

Evento Resize

 

Private Sub Form_Resize()

    crViewer.Top = 0

    crViewer.Left = 0

    crViewer.Height = ScaleHeight

    crViewer.Width = ScaleWidth

End Sub

 

En este evento hacemos que el control crViewer ocupe toda el área del formulario en el que se encuentra, supongo que este código no requiere mayor explicación.

 

 

Procedimiento PasarParametros

 

Public Sub PasarParametros(sParam1 As String, lParam2 As Long)

    mstrParametro1 = sParam1

    mlngParametro2 = lParam2

   

End Sub

 

Este procedimiento sirve para mandar desde el formulario de parámetros los valores que tendrán los parámetros del reporte. Las variables a nivel de formulario sirven para guardar estos valores mientras se abre el  reporte.

 

 

Evento Load del formulario

 

Private Sub Form_Load()

    Dim crParamDefs As CRAXDRT.ParameterFieldDefinitions

    Dim crParamDef As CRAXDRT.ParameterFieldDefinition

 

    On Error GoTo ErrHandler

 

    'Abrir el reporte

    Screen.MousePointer = vbHourglass

   

    mflgContinuar = True

    Set crReport = crApp.OpenReport(App.Path & "\Ejemplo.rpt", 1)

 

    ' Parametros del reporte

    Set crParamDefs = crReport.ParameterFields

 

    For Each crParamDef In crParamDefs

        Select Case crParamDef.ParameterFieldName

            Case "Parametro1"

                crParamDef.AddCurrentValue (mstrParametro1)

       

            Case "Parametro2"

                crParamDef.AddCurrentValue (mlngParametro2)

               

        End Select

 

    Next

 

    crViewer.ReportSource = crReport

    crViewer.DisplayGroupTree = False

    crViewer.ViewReport

    Screen.MousePointer = vbDefault

 

    Set crParamDefs = Nothing

    Set crParamDef = Nothing

    Exit Sub

 

ErrHandler:

    If Err.Number = -2147206461 Then

        MsgBox "El archivo de reporte no se encuentra, restáurelo de los discos de instalación", _

            vbCritical + vbOKOnly

    Else

        MsgBox Err.Description, vbCritical + vbOKOnly

    End If

 

    mflgContinuar = False

    Screen.MousePointer = vbDefault

   

End Sub

 

La líneas:

 

Dim crParamDefs As CRAXDRT.ParameterFieldDefinitions

Dim crParamDef As CRAXDRT.ParameterFieldDefinition

 

se utilizarán para establecer los valores de los parámetros. A continuación se muestra su descripción.

 

Variable

Descripción

crParamDefs 

Objeto que representa a la colección de Parámetros de un reporte.

crParamDef

Objeto que representa a un parámetro en específico. Esta variable se utilizará para iterar por la colección crParamDefs

 

En otras palabras crParamDefs será la variable que utilizaremos para referirnos a la colección de parámetros del reporte y crParamDef se utilizará para referirnos a un parámetro en particular. Los nombres de las variables no tienen que ser los mismos, los puse así para que el nombre indique el uso que se le dará a cada variable.

 

A continuación establecemos un manejador de error para nuestro procedimiento. Esto es necesario porque puede darse el caso de que el reporte no se encuentre en la ubicación que le especifiquemos, y debemos manejar ese error.

 

    On Error GoTo ErrHandler

 

Luego debemos abrir el reporte, pero es conveniente establecer el puntero del cursor como reloj de arena por si acaso llegara a tardar mucho esta operación. Claro está que el tiempo que tarde variará de una computadora a otra.

 

    'Abrir el reporte

    Screen.MousePointer = vbHourglass

 

También debemos establecer nuestra variable mflgContinuar a TRUE, esto es así, por que por default, las variables booleanas se establecen a FALSE, y en este caso queremos indicar que podemos continuar, es decir, que no ha pasado nada que nos impida continuar en el proceso.

   

    mflgContinuar = True

 

A continuación viene la instrucción que propiamente abre el archivo RPT y establece la referencia a nuestra variable crReport.

 

Si se generara algún tipo de instrucción en esta instrucción, nuestro manejador de errores se haría cargo de informarle al usuario sobre lo ocurrido. Si no se genera ningún error, entonces ahora la variable crReport “apunta” a nuestro reporte.

 

Cabe aclarar un par de cosas sobre esta instrucción. El primer parámetro, como es de imaginarse, es el nombre del reporte con todo y su ruta. Podemos usar ubicaciones de nuestro disco duro o ubicaciones dentro de red, si es que usamos el programa en un ambiente de red. No debemos olvidar el “.rpt”, de lo contrario la instrucción fallará. Yo acostumbro crear una carpeta Reportes dentro de cada aplicación que hago y ahí guardo los archivos RPT de mi aplicación, de manera que si alguien borra uno o varios de los archivos RPT puedo crear un programita que los restaure a partir de una ubicación de red, por ejemplo. O yo mismo puedo respaldarlos a partir de los discos de instalación.

 

El segundo parámetro del método OpenReport es opcional, un 1 indica que queremos abrir el reporte de manera exclusiva, un 0 indica que queremos crear una copia temporal y trabajar con ella. Este parámetro se utiliza porque mediante programación podemos modificar el diseño del reporte, por lo que si abrimos una copia temporal, los cambios no afectarán al archivo original. Como ya mencioné el parámetro es opcional, y su valor por default es 1.

 

Otra nota importante, el método OpenReport regresa una instancia del reporte indicado o 0 si el archivo no existe o se genera algún error. Por lo tanto no es estrictamente necesario establecer un manejador de errores para esta rutina, basta con checar si crReport vale 0 para darnos cuenta de que se generó un error. Sin embargo, yo prefiero establecer un manejador de error para poder manejar otros errores de otras instrucciones, aunque por simplicidad no lo hago en este ejemplo.

 

    Set crReport = crApp.OpenReport(App.Path & "\Ejemplo.rpt", 1)

 

Una vez que tenemos abierto el reporte, debemos establecer los valores de los parámetros antes de visualizar el reporte. la instrucción Set que se muestra a continuación hace que la variable crParamDefs “apunte” a la colección de parámetros del reporte.

 

    ' Parametros del reporte

    Set crParamDefs = crReport.ParameterFields

 

Ya podemos hacer una iteración por la colección de parámetros para asignarle un valor a cada uno de ellos. Dentro del ciclo usamos la estructura Select Case para evaluar el nombre del parámetro, el cual está contenido en el miembro ParameterFieldValue del objeto crParamDef. Cabe aclarar que para la cláusula Case debemos usar exactamente el mismo nombre que le dimos a cada parámetro dentro de Crystal Reports.

 

El método AdCurrentValue es el que propiamente asigna el valor que le pasemos como parámetro al parámetro en sí.

 

    For Each crParamDef In crParamDefs

        Select Case crParamDef.ParameterFieldName

            Case "Parametro1"

                crParamDef.AddCurrentValue (mstrParametro1)

       

            Case "Parametro2"

                crParamDef.AddCurrentValue (mlngParametro2)

               

        End Select

 

    Next

 

Ahora sí el reporte está listo para ser desplegado en el crViewer. Al asignar la variable crReport al miembro ReportSource del control crViewer estamos propiamente asignando el reporte al control, pero no el reporte no será visible hasta que se mande llamar al método ViewReport del crViewer. Y por último restauramos el puntero del ratón al valor por default.

 

    crViewer.ReportSource = crReport

    crViewer.ViewReport

    Screen.MousePointer = vbDefault

 

El establecer a Nothing las variables crParamDefs y crParamDef no es obligatorio, debido a que no usamos el New, sin embargo es una práctica sana de programación. La instrucción Exit Sub es necesaria para no caer en el manejador de errores.

 

    Set crParamDefs = Nothing

    Set crParamDef = Nothing

    Exit Sub

 

Lo que nos falta para completar el evento Load del formulario es el manejador de errores. Lo primero que preguntamos en el manejador de errores es si el error que se generó es el número –2147206461, el cual se genera cuando la instrucción OpenReport no encuentra el archivo que se especificó como primer parámetro. El número del error lo encontré haciendo que se generara el error para anotar el número, no lo encontré en ninguna documentación de Crystal Reports.

 

Si se genera otro error, solamente mostramos el mensaje de acuerdo a la descripción que contenga dicho error. Lo importante aquí es establecer la variable mflgContinuar a FALSE, para indicar al programa que por un error no puede continuar la ejecución normal del código.

 

ErrHandler:

    If Err.Number = -2147206461 Then

        MsgBox "El archivo de reporte no se encuentra, restáurelo de los discos de _

                instalación", vbCritical + vbOKOnly

    Else

        MsgBox Err.Description, vbCritical + vbOKOnly

    End If

 

    mflgContinuar = False

    Screen.MousePointer = vbDefault

    

End Sub

 

 

 

 

Evento Activate del formulario

 

Private Sub Form_Activate()

    If Not mflgContinuar Then Unload Me

   

End Sub

 

He aquí la razón fundamental del uso de la variable mflgContinuar, recordemos que el evento Load se ejecuta antes del evento Activate, por lo tanto, si en el evento Load del formulario aparece un error, en el evento Activate haremos que el formulario se descargue de la memoria, en pocas palabras, si se genera algún tipo de error, el formulario ni siquiera se muestra en la pantalla.

 

 

Evento Unload del formulario

 

Private Sub Form_Unload(Cancel As Integer)

    Set crReport = Nothing

    Set crApp = Nothing

   

End Sub

 

Y por último hacemos limpieza de memoria.

 

 

Formulario frmParámetros

 

A continuación presento el código

 

Private Sub cmdSalir_Click()

    Unload Me

 

End Sub

 

El código que realmente vale la pena mencionar de este formulario es el que se presenta a continuación, en el cual declaramos una intancia del formulario en el que se verá el reporte, a continuación y muy importante es pasarle los parámetros al formulario para que éste a su vez los pase al reporte y mandamos mostrar dicho formulario.

 

Private Sub cmdVerReporte_Click()

    Dim frmRep As New frmReporte

   

    frmRep.PasarParametros txtParametro1, CLng(txtParametro2)

    frmRep.Show vbModal

   

    Set frmRep = Nothing

   

End Sub

 

 

Espero que este artículo haya sido de utilidad para ustedes. Cualquier duda o comentario pueden mandarme un mail a: danielmaya@hotmail.com

 

Saludos. Daniel Maya Ortiz.


El código de ejemplo (incluye ejecutable y ficheros fuente) crystalDanielMayaEjemplo.zip 13.5 KB


Otros artículos sobre Crystal Report

ir al índice