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: [email protected]
Saludos. Daniel Maya Ortiz.
El c�digo de ejemplo (incluye ejecutable y ficheros fuente) crystalDanielMayaEjemplo.zip 13.5 KB