viernes, 10 de diciembre de 2010

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

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

1 comentario:

  1. Tengo una duda. Cuando uso el Visual Basic 2005 ¿necesito tener instalado el Crystal Reports? y ¿cómo hago para empaquetar todo un proyecto en VB6.0 y VB2005 con Crystal Reports sin necesidad de que instale el programa Crystal en otras PC?

    ResponderEliminar