Beruflich Dokumente
Kultur Dokumente
1
requerimientos de la plataforma y del entorno de desarrollo. Como resultado, todas las versiones .NET
aparecidas hasta la fecha de Visual Studio han incorporado las versiones correspondientes de lo que se ha
dado en llamar “Crystal Reports .NET”.
Este curso tiene dos objetivos fundamentales:
Enseñarle a utilizar el diseñador de Crystal Reports integrado en Visual Studio 2005 para crear informes
de datos potentes y flexibles.
Mostrarle cómo incorporar esos informes en sus aplicaciones .NET para Windows y la Web, utilizando
como lenguaje de programación a Visual Basic.
ENSAMBLADO USO
CrystalDecisions.Shared Contiene tipos compartidos por Crystal Reports.NET y otras
aplicaciones de la empresa.
CrystalDecisions.ReportSource Contiene la implementación de clases para conectarse a
diferentes orígenes de informes.
CrystalDecisions.CrystalReports.Engine Interfaz con el Motor de Impresión de Crystal Reports.
3
REQUISITOS PARA SEGUIR EL CURSO
Para seguir este curso, necesitará tener instalado el siguiente software:
Visual Studio 2005 edición Profesional o superior. Las ediciones Express y Estándar *NO* incluyen,
desgraciadamente, Crystal Reports.NET. La alternativa, en caso de disponer de alguna de esas ediciones
“de gama baja” de Visual Studio, consiste en adquirir Crystal Reports.NET de forma independiente
(diríjase al sitio web del fabricante).
SQL Server 2005, cualquier edición. Si no dispone de una edición comercial de SQL Server 2005, puede
descargar e instalar la edición Express (Service Pack 1) desde aquí. En este último caso, también le será de
utilidad el SQL Server Management Studio Express.
La base de datos de ejemplo AdventureWorks, que utilizaremos para los informes. Si dispone de una
edición comercial de SQL Server 2005, la base de datos forma parte de la instalación del producto; en
cualquier caso, puede descargarse desde aquí. En principio, de esta descarga únicamente es necesario el
fichero AdventureWorksDB.msi.
El curso asume una cierta familiaridad con la programación de aplicaciones .NET en Visual Basic y con el
trabajo con bases de datos relacionales.
Puede encontrar una amplia información sobre todas y cada una de las tablas y otros objetos de base de
datos que contiene AdventureWorks aquí. En general, el uso de las diferentes tablas a la hora de
componer los informes es bastante intuitivo, y siempre comenzaremos cada ejemplo concreto indicando
en qué tablas se almacena la información a partir de la que se desea diseñar el informe.
INTRODUCCIÓN
Antes que nada, es conveniente definir qué entendemos por informe. En este curso, consideraremos
como informe a cualquier documento que presente un subconjunto de los datos almacenados en un
origen de datos (generalmente, una base de datos relacional) de una manera más o menos elaborada. En
4
este sentido, un simple listado de los empleados de la empresa podría perfectamente considerarse un
informe.
Otro documento que muestre a esos empleados agrupados por categorías según su volumen de ventas
del año anterior sería otro informe, claro está bastante más elaborado que el anterior.
Definir o crear un informe consiste en indicar al Diseñador de Crystal Reports de dónde tiene que obtener
los datos necesarios, cómo tiene que transformarlos y por último, cómo debe presentar cada elemento
de datos sobre el documento final. Toda esa información se almacenará de la definición del informe, que
tradicionalmente se guarda en un fichero externo .RPT para su posterior ejecución. Pero antes de
enfrentarse al Diseñador de Crystal Reports (o de hecho, a cualquier generador de informes), es
altamente conveniente realizar un trabajo de análisis y diseño previos que nos den una idea clara de a)
qué necesita obtener exactamente el usuario que nos ha encargado el informe, b) en consecuencia,
cuáles son los datos que debemos utilizar y c) qué apariencia aproximada deberá tener nuestro informe
cuando sea ejecutado. Tener las ideas claras nos ayudará a cumplir con los objetivos requeridos en el
menor tiempo y con la mayor calidad posible.
5
a) En primer lugar, cómo queremos diseñar el informe. Las opciones posibles son:
1. Utilizando el Asistente del Diseñador. Como veremos a continuación, el Asistente nos guía a través de
diferentes pantallas para que definamos las características principales del informe. Una vez finalizado el
Asistente, podremos añadir al informe nuevas posibilidades o modificar las decisiones tomadas
anteriormente. Como se dará cuenta rápidamente, el Asistente de informes es una combinación de otros
asistentes más sencillos que podrá invocar por separado posteriormente. En general, es conveniente
dejarse guiar por el Asistente, para obtener rápidamente un diseño inicial que luego podemos modificar a
voluntad.
2. Partiendo desde cero sobre un lienzo en blanco. Generalmente no es productivo ir por esta “ruta
difícil”.
3. A partir de un informe existente. Esta opción es conveniente si queremos diseñar un informe muy
parecido a otro que ya hemos creado anteriormente.
b) Si decidimos utilizar el Asistente, éste es capaz de ayudarnos con tres tipos de informes diferentes:
1. Informe estándar. Esta opción se utiliza para crear un informe de tipo “listado”. Es la opción más
conveniente en la gran mayoría de los casos, a menos que se tenga claro que el informe únicamente
incluirá una tabla cruzada, en cuyo caso es más conveniente seleccionar la siguiente opción.
2. Tablas cruzadas. Un informe de tabla cruzada es un informe que presenta en una tabla resúmenes
agrupados por categorías, por ejemplo los volúmenes de ventas de cada tipo de productos por cada país
en el que la empresa opera. No es ningún problema añadir manualmente una tabla cruzada a un informe
estándar si se desea.
3. Etiqueta. Listado de múltiples filas y columnas, generalmente a partir de una tabla de clientes, para
producir las etiquetas a adherir a los sobres de correos cuando se hace un mailing.
Comenzaremos diseñando un informe estándar – por ejemplo, un informe que presente la lista de
productos que la empresa AdventureWorks ha vendido al público o vende actualmente. Mantenga las
opciones por defecto y pulse Aceptar.
PASO 1.
El primer paso a la hora de diseñar el informe es indicarle al Asistente dónde están y cuáles son los datos
que se van a utilizar en el informe. Aquí tenemos que indicar:
a) La tecnología a utilizar para conectarse al origen de datos. En este caso, tratándose de una base de
datos SQL Server, debemos indicar Crear nueva conexión | OLE DB (ADO) y luego elegir el proveedor
‘Microsoft OLE DB Provider for SQL Server’. Pulse Siguiente.
b) El nombre del servidor, la base de datos y el usuario y contraseña necesarios para establecer la
conexión. En nuestro caso, utilizaremos como nombre de servidor .\SQLExpress (‘.’ significa la máquina
local, y ‘SQLExpress’ es el nombre de la instancia en que se instala SQL Server Express de forma
predeterminada). De momento utilizaremos la autenticación integrada (marcando la casilla
correspondiente), aunque la autenticación de usuario/contraseña es más utilizada en la vida real, sobre
todo en aplicaciones Web. Por último, despliegue la lista de bases de datos disponibles y seleccione
AdventureWorks. Pulse Siguiente.
c) Por último, se nos permite indicar las propiedades avanzadas de la conexión. No necesitamos ninguna
en este caso, y por eso pulsamos directamente en Finalizar.
6
Una vez indicados el servidor y la base de datos, la verá en la lista de los orígenes de datos disponibles.
En este momento es conveniente pulsar el botón derecho del ratón sobre el nombre del servidor y
utilizar la opción ‘Agregar a Favoritos’ para recordar este origen de datos para futuros informes.
PASO 2.
Llega ahora el momento de indicar la(s) tabla(s), vista(s) o procedimiento almacenado de la base de datos
de donde se deberá obtener la información. En nuestro caso, necesitaremos la tabla Product del esquema
Production. Seleccione esa tabla en la vista de árbol (pasándola a la columna derecha del diálogo
mediante el botón ‘>’) y pulse Siguiente.
PASO 3.
El siguiente paso consiste en indicar cuáles de las columnas (campos) que componen la tabla elegida
queremos mostrar en las columnas del listado. En nuestro ejemplo, seleccionaremos los siguientes
campos:
ProductNumber – el código de identificación del producto
Name – el nombre del producto
Color – el color del producto
PASO 4.
Una vez elegidas las columnas a mostrar en el listado, toca el turno a indicar los criterios por los que se
quiere agrupar las filas del resultado. Por ejemplo, en nuestro caso podríamos agrupar los productos a
listar según su color. Para este ejemplo inicial, sin embargo, no especificaremos criterio de agrupación
alguno. Pulse Siguiente.
PASO 5.
La otra decisión importante que debemos tomar con respecto a los datos es qué filas de la tabla
seleccionada deseamos que aparezcan en el informe. Para ello es necesario especificar una condición de
selección – sólo aquellas filas que satisfagan la condición que indiquemos serán recuperadas del servidor
de base de datos. En nuestro ejemplo (necesitamos los productos que la empresa ha vendido o vende) el
producto debe ser un producto que se vende y no para consumo interno (en cuyo caso el campo
FinishedGoodsFlag será 1, que significa verdadero). Fíjese cómo al seleccionar un campo en la zona
inferior derecha de la ventana aparece un cuadro de combinación en el que se muestran algunas de las
condiciones comunes para campos de ese tipo. En nuestro caso, nos interesa la condición ‘es Verdadero’.
Observe también que no es necesario que el campo de la condición esté entre los campos a mostrar en el
informe para utilizarlo en la condición de filtro. Una vez indicada la condición, pulse Siguiente.
PASO 6.
Por último, el Asistente nos permite elegir entre un conjunto de plantillas de estilos disponibles. Las
plantillas de estilos permiten establecer de una sola vez todo el conjunto de características visuales
(“estilos”) que se aplicarán a los diferentes tipos de objetos que pueden aparecer en el informe.
Mantenga el estilo Estándar y pulse Finalizar. En este momento el Asistente generará el informe, que
veremos reflejado en el área de trabajo de Visual Studio 2005.
7
las modificaciones que queramos para adecuar más el informe a los requerimientos de nuestra aplicación
o usuarios.
Observe también en la parte inferior de la ventana la otra posible vista del informe que podemos
seleccionar, la Vista previa, que nos ofrecerá instantáneamente una presentación del resultado de la
ejecución del informe para que podamos ver cómo lucirá nuestro informe con los datos reales. Aunque
formalmente el diseño del informe debe hacerse desde la vista ‘Informe principal’, verá que el Diseñador
nos permite también realizar casi todas las tareas de diseño sobre esta vista previa.
Volviendo a la vista de diseño, verá que el diseño del informe consta de diferentes secciones que se
pueden expandir o contraer a voluntad y que juegan un papel conceptual muy importante en Crystal
Reports. Básicamente, la sección en la que esté situado un elemento determina cuándo y cuántas veces
se imprimirá ese elemento al ejecutar el informe. Las secciones disponibles en Crystal Reports son las
siguientes:
Encabezado del informe: los elementos que se coloquen en esta sección aparecerán en el informe una
sola vez, en la parte superior de la primera página del informe. En esta sección típicamente se colocan el
título del informe, la fecha de ejecución, etc. Por defecto, esta sección aparece inicialmente suprimida
(indicado por las rayas transversales).
Encabezado de página: los elementos que se sitúen en esta sección aparecerán en el informe una vez
por cada página del informe, en la parte superior de la misma. Tradicionalmente se colocan en esta
sección los números de página y las etiquetas de las columnas del informe (cosa que el Asistente de
informes ya ha hecho por nosotros).
Encabezado de grupo: habrá uno por cada uno de los grupos que tenga el informe (nuestro informe
básico no tiene grupos). Los elementos que se coloquen en esta sección (un ejemplo típico es el nombre
del grupo) aparecerán en el informe una vez al principio de cada uno de los diferentes grupos que el
motor de ejecución encuentre en los datos. Más adelante en este mismo tema trataremos con
profundidad el tema de los grupos.
Detalles: en la sección de Detalles se coloca todo aquello que se quiere que aparezca una vez por cada
uno de los registros del conjunto de datos de entrada. Típicamente, si el informe es del tradicional estilo
“listado”, en esta sección se colocan objetos que representan a los campos de la tabla o consulta de
origen. En un informe típico de tabla cruzada, por ejemplo, la sección de detalles se deja vacía (o se
suprime) porque no se desea que aparezca información sobre cada uno de los registros, sino solo los
resúmenes (que normalmente se ponen en la sección de Pie del Informe).
Pie de grupo: es la sección “opuesta” al Encabezado de grupo, y se imprime una vez al finalizar cada
uno de los grupos que el motor de ejecución encuentre en los datos que componen el informe. Habrá una
sección de Pie de grupo para cada Encabezado de grupo, y los grupos siempre están perfectamente
anidados (por ejemplo, en un informe con dos grupos, por Países y Provincias, los grupos
correspondientes a las provincias de un país siempre quedarán anidados dentro del grupo
correspondiente al país). En esta sección típicamente se colocan los totales de grupo (por ejemplo, la
cantidad de clientes por cada país, en un listado de clientes agrupado por países).
Pie de página: opuesta al Encabezado de página, los elementos que se sitúen en esta sección
aparecerán en el informe una vez por cada página del informe, en la parte inferior de la misma.
Tradicionalmente se colocan en esta sección los totales acumulados (tipo “suma y sigue”) o también los
números de página.
Pie del informe: los elementos que se coloquen en esta sección aparecerán en el informe una sola vez,
en la última página del informe. En esta sección típicamente se colocan los totales generales.
Si se pulsa con el botón derecho del ratón sobre cualquiera de las bandas que identifican a las secciones
(por ejemplo, sobre la sección de Encabezado del informe) aparecerá el menú de contexto de la sección,
8
que exploraremos con más profundidad un poco más adelante en el curso. Por el momento, ejecute la
opción No suprimir sobre la sección de Encabezado de informe, para indicar que queremos que esta
sección aparezca al ejecutar el informe.
Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de diseño para
ayudarnos con las tareas más habituales son:
9
Vista previa podrá comprobar que el título que hemos asignado al informe aparecerá en el lugar elegido
(puede que haya que guardar el informe previamente).
Si lo que queremos es añadir al informe otro tipo de elemento visual (resumen, gráfico, imagen, etc.),
tendremos que utilizar el correspondiente asistente desde el menú de Crystal Reports o la barra de
herramientas Insertar. En cualquier caso, también se nos permitirá indicar en qué sección y posición
concreta queremos colocar el elemento. Por ejemplo, vamos insertar un resumen general en la sección
de Pie de informe que indique cuántos productos contiene el listado. Para ello tendremos que dar los
siguientes pasos:
Pulsar con el botón derecho del ratón sobre la sección 4 (Pie del informe), y en el menú de contexto de
la sección seleccionar ‘No suprimir’, para hacer que visible a esa sección.
Pulsar el botón ‘Resumen’ de la barra de herramientas, que nos pedirá que elijamos:
El campo a resumir (puede ser cualquier campo, no necesariamente uno de los que se va a mostrar). En
nuestro caso, un candidato ideal es el campo ProductNumber.
El tipo de resumen deseado. En este caso nos interesa un Recuento (conteo), aunque también podría
ser un Recuento distintivo, que produciría exactamente el mismo resultado dado que el código de
producto es único para cada producto.
Verá que las opciones más típicas (Suma, Promedio, etc.) no están disponibles en este caso, por tratarse
de un campo alfanumérico.
La posición en la que se desea ubicar el resumen. Tratándose de un listado sencillo, sin grupos, la única
opción disponible es la de colocar el valor resultante al final de todo, al pie del informe. En presencia de
grupos, este asistente nos permitirá también crear resúmenes parciales por cada nivel de agrupación.
Al pulsar el botón Aceptar, el Diseñador colocará un objeto de resumen configurado según le hemos
indicado en la sección Pie del informe. Cambie a la Vista previa y vaya hasta la última página del informe,
y verá el total reflejado en el sitio adecuado.
Una vez que el objeto ha sido colocado sobre el lienzo de diseño, toca la labor de configurarlo para que
responda a los requisitos de diseño del informe:
En primer lugar, podemos seleccionar el objeto con el ratón y arrastrarlo hacia cualquier otro sitio, en
la misma sección o una sección diferente. Tenga especial cuidado al cambiar un objeto de una sección a
otra – su sentido común le orientará correctamente en la mayoría de los casos.
Cuando un objeto está seleccionado, en sus cuatro costados aparecen las típicas “grapas” que nos
permiten redimensionarlo como queramos.
La barra de herramientas ‘Principal’ ofrece diferentes botones que nos permiten establecer los
atributos del texto del objeto (fuente y tamaño de letra, negrita, itálicas, etc.), la alineación (izquierda,
derecha, centrada), o el formato de presentación para datos numéricos.
En el caso de los objetos de texto (por ejemplo, los que corresponden a las etiquetas en que se
muestran los encabezados de columnas), haciendo doble clic sobre el objeto se activará el modo de
edición para que podamos modificar el texto a mostrar.
Por último, pulsando con el botón derecho del ratón sobre el objeto seleccionado obtendremos un
menú de contexto que incluye la opción ‘Dar formato a objeto’. Esta opción de menú despliega un cuadro
de diálogo de múltiples pestañas que nos permitirá configurar todas y cada una de las propiedades del
objeto. La mayoría de las pestañas (Común, Bordes, Fuente, Hipervínculo) son comunes a casi todos los
objetos, y para ciertos tipos de objetos aparece una pestaña especial con sus características específicas.
Por ejemplo, si seleccionamos el objeto que corresponde al campo SellEndDate, veremos una pestaña
‘Fecha y hora’ donde podemos establecer el formato de visualización de los datos de esa columna, que es
de tipo DateTime.
Debido a que estamos utilizando la versión del Diseñador de Crystal Reports integrada en Visual Studio,
una alternativa al cuadro de diálogo anterior es utilizar la Ventana de Propiedades del entorno para
establecer los valores de las propiedades. Dado que las propiedades tienen nombres en inglés, mientras
10
que el cuadro de diálogo está traducido al castellano (además de mejor organizado), recomendamos
utilizar éste último.
11
Subinformes: Una técnica bastante potente para componer informes complejos es la de insertar un
informe ya creado dentro de otro. Veremos los subinformes en el tema 5.
Objetos de texto: Los objetos de texto permiten mostrar una etiqueta de texto en cualquier sección y
posición del informe, horizontal o verticalmente.
Imágenes: Podemos incorporar a nuestros informes imágenes BMP, JPG o PNG con el logotipo de la
empresa, fondos de “marca de agua”, etc.
Líneas y cuadros: Por último, también podemos utilizar objetos de líneas y cuadros para realzar los
informes.
EL VISOR DE INFORMES
Si ha activado la pestaña de Vista previa para ver el resultado en pantalla de la ejecución del informe,
habrá visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para
aplicaciones Windows (en realidad, una versión especializada del mismo). Crystal Reports ofrece
igualmente otro visor basado en HTML y Javascript para su utilización en aplicaciones Web.
12
tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por
ejemplo, el botón de Árbol de grupos en un listado sencillo que no tenga grupos).
La propiedad ReportSource es una propiedad polimórfica que puede apuntar a diferentes entidades
capaces de proveer un informe. Para este primer ejemplo, despliegue la lista de posibles opciones para la
propiedad y seleccione ‘Crear una nueva instancia de ReportDocument | Ejemplo1.ListadoProductos’.
Más adelante veremos con más detalles qué significa eso.
Si examina las propiedades disponibles en la Ventana de propiedades, verá toda una serie de
propiedades lógicas con nombres ‘Display…’ y ‘Show…’, cuyo objetivo es permitirnos configurar qué zonas
o botones queremos que el visor muestre o no. En nuestro caso, dado que el informe no tiene grupos,
vamos a asignar False a las propiedades DisplayGroupTree y ShowGroupTreeButton.
¡Y ya está! Ejecute la aplicación, y verá cómo hemos logrado mostrar en una ventana de Windows un
informe Crystal Reports sin escribir ni una sola línea de código.
13
Para lograr esto, haremos uso de otro de los asistentes de Crystal, el Asistente de base de datos (opción
Base de datos | Asistente de base de datos en el menú de Crystal Reports). Se dará cuenta que este
diálogo de propiedades ya lo ha visto antes: se trata del primer asistente integrado en el Asistente de
informes general. Pues bien, debemos seleccionar nuestra tabla Production.ProductSubcategory en la
vista de árbol de la izquierda (despliegue el nodo ‘Conexiones actuales’ y verá nuestro servidor de base de
datos y dentro de él, a la base de datos AdventureWorks) y añadirla a la vista de la derecha.
Inmediatamente después de que agregue la tabla de subcategorías al informe, aparecerá en el cuadro de
diálogo una segunda pestaña, Vínculos, que es donde debemos indicarle a Crystal cómo establecer la
relación entre las dos tablas. Siempre que un informe incluya más de una tabla, Crystal nos obligará a
establecer claramente cuál es la relación entre las mismas. Aunque el Diseñador es capaz de proponernos
vínculos en base a las relaciones entre las tablas, como podrá observar que ocurre en este caso.
En la pestaña Vínculos del asistente podemos establecer relaciones entre las tablas simplemente
arrastrando con el ratón desde el campo de origen hacia el de destino. Pruebe a borrar el vínculo creado
implícitamente (botón ‘Borrar vínculos’) y a volverlo a establecer. Una vez lo haya hecho, cierre el
asistente pulsando Aceptar.
Una vez que hayamos agregado la nueva tabla al informe, veremos que en el Explorador de campos
estarán disponibles todos los campos de la tabla de subcategorías, y podremos arrastrar los campos de
esa tabla sobre cualquier sección del informe. Por ejemplo, para ver el nombre de la subcategoría a la que
pertenece cada producto, arrastraremos el campo Name de la tabla Production.Subcategory sobre la
sección de Detalles. Posteriormente habrá que recolocar los objetos de esa sección para mejorar el
aspecto del informe. Si cambia a la Vista previa, verá que para cada producto se muestra su subcategoría.
ORDENACIÓN Y AGRUPACIÓN
Si al examinar la vista preliminar del informe tiene la impresión de que los registros ya llegan ordenados
por subcategorías, no se fíe – ello ha sido puramente coyuntural. En ningún momento hemos dicho que
queremos obtener el listado ordenado por subcategorías, nombres de producto u otro criterio. De hecho,
si examina la sentencia SQL que Crystal Reports enviará a la base de datos para recuperar la información
necesaria (en el menú de Crystal Reports, seleccione Base de datos | Mostrar consulta SQL) verá que
ésta tampoco incluye ninguna cláusula ORDER BY. Para indicar los criterios de ordenación, debemos
utilizar el Asistente de ordenación de registros, en la barra de herramientas ‘Principal’ o en el menú
Report | Asistente de ordenación de registros. Este asistente nos presenta un cuadro de diálogo en el
que podemos establecer el criterio de ordenación principal, así como otros secundarios, que sólo
entrarán en funcionamiento en caso de que el varios registros coincida en todos los campos anteriores.
Por ejemplo, si queremos que nuestros productos aparezcan ordenados por categoría, y dentro de cada
categoría, por nombre, debemos indicar ambos campos, en ese orden, al asistente. Observe que las
categorías aparecerán en orden alfabético, dado que se trata de un campo alfanumérico.
Hay que tener claro desde el primer momento que ordenar es un prerrequisito necesario para agrupar.
Para Crystal Reports, un grupo es un conjunto de registros consecutivos que tienen el mismo valor del
campo indicado. Si quitamos los criterios de ordenación de registros que acabamos de establecer, y vez
de ello insertamos un grupo por subcategorías, utilizando el botón correspondiente de la barra de
herramientas ‘Insertar’ (o la opción Insertar | Grupo del menú), y luego lanzamos de nuevo el Asistente
de ordenación de registros, veremos que el campo correspondiente habrá sido agregado a la lista de
criterios de ordenación.
Cuando se selecciona la opción de Insertar grupo, se presenta un cuadro de diálogo en el que podemos
indicar el campo por el que deseamos agrupar (en nuestro caso, ProductSubcategory.Name, si queremos
los grupos en orden alfabético) y si queremos un orden ascendente o descendente. La pestaña Opciones
nos ofrece varias posibilidades adicionales, como la de indicar que deseamos mantener los registros de
cada grupo juntos siempre que sea posible (cambiando de página para ello si fuera necesario) o repetir el
encabezado del grupo en cada página al ejecutar el informe.
14
Observará que se crean dos nuevas secciones, de Encabezado y Pie de grupo, numeradas con #1 por
tratarse del primer (y único) grupo del informe. En la sección de Encabezado de grupo, el Diseñador
coloca además un objeto de nombre de grupo asociado al campo que hemos indicado como campo para
agrupar. En la Vista previa podremos ver cómo luce ahora el informe; y cómo en principio podemos
eliminar el nombre de subcategoría (que se repite para cada producto del grupo) de la sección de
Detalles.
Vamos a complicar ahora un poco más el informe y crear un segundo grupo externo. Para ello,
necesitaremos agregar al informe otra nueva tabla, Production.ProductCategory, pues las subcategorías
pertenecen a su vez a categorías. El enlace esta vez se realiza a través de la clave foránea
ProductCategoryID de la tabla Subcategory. Una vez agregada la tabla al informe, crearemos un nuevo
grupo utilizando como campo por el que agrupar al campo Name de la tabla de categorías. Esta vez lo
más conveniente es hacerlo utilizando el Asistente de grupos (en el menú de Crystal Reports,
seleccionamos Report | Asistente de grupos), pues queremos que este grupo quede a nivel externo,
englobando al de subcategorías. Una vez creado el grupo, en la Vista previa podremos observar el
resultado.
TOTALIZACIÓN (RESÚMENES)
Mediante el botón de Insertar resumen o la opción correspondiente del menú podremos añadir
resúmenes estadísticos generales (basados en la totalidad de los datos obtenidos de la base de datos, y
normalmente mostrados en el Pie de informe) o parciales para cada uno de los grupos (que generalmente
se colocan en el Pie de grupo correspondiente). Ya anteriormente hemos hecho un recuento general de
los productos disponibles; vamos ahora a mostrar en el informe cuántos productos hay por cada
categoría y subcategoría.
Si pulsamos el botón de Insertar resumen, el Diseñador nos preguntará, como antes, qué campo es el que
queremos resumir (Product.ProductNumber), qué tipo de operación queremos realizar (Recuento) y la
ubicación del resumen; observe que ahora, dado que tenemos dos grupos, el asistente nos propone tres
posibles lugares donde colocar el resumen: en el Pie del informe (si quisiéramos un total general, que ya
tenemos), en el Pie del grupo externo (si quisiéramos contar cuántos productos hay de cada categoría) o
en el Pie del grupo interno (si quisiéramos contar cuántos productos hay en cada subcategoría). Primero
insertaremos un resumen a nivel de categorías (grupo externo); para mejorar la estética del informe,
pondremos a su izquierda un objeto de texto que diga ‘Total categoría’. Observe también que tendremos
que cambiar el formato del resultado, pues Crystal Reports por defecto muestra los campos numéricos
con dos cifras decimales (opción que puede cambiarse en la configuración general del Diseñador,
accesible desde la opción del menú Diseño | Especificaciones predeterminadas | Campos | Número).
A continuación, repetiremos la operación de insertar resumen, pero ahora contabilizando la cantidad de
productos por cada subcategoría; para variar, mostraremos el resumen no como una cantidad absoluta,
sino como un porcentaje relativo a la cantidad de productos en su categoría (opción ‘Mostrar como
porcentaje de’).
Tenga en cuenta que los resúmenes de grupos normalmente se colocan en el pie del grupo, pero pueden
también moverse a la sección de Cabecera del grupo correspondiente; esto provocará una cierta
sobrecarga al motor de impresión de Crystal Reports, que tendrá que generar en memoria todos los datos
del grupo antes comenzar a imprimirlo, pero este coste es generalmente asumible y poner los resúmenes
en la cabecera es muchas veces estéticamente conveniente. Esto es lo que haremos con este último
resumen por subcategorías.
SELECCIÓN DE REGISTROS
El Asistente de selección de Crystal Reports permite establecer las condiciones que deben satisfacer los
registros que han de ser utilizados para la confección del informe. Para nuestro informe actual, el
asistente mostrará una única pestaña asociada a la condición de que el campo
Product.FinishedGoodsFlag sea verdadero. A esa pestaña podremos agregar otras con nuevas
condiciones, y Crystal Reports hará que solo se utilicen los registros que satisfagan todas las condiciones
especificadas (o sea, se aplicará la operación lógica AND a todas las condiciones). A modo de ejemplo,
vamos a limitar el conjunto de registros a aquellos productos que continúan a la venta – esos registros
tendrán un valor nulo en el campo SellEndDate. Pulsemos el botón ‘Nuevo’ para indicar una nueva
16
condición de selección. Elijamos el campo Product.SellEndDate (de nuevo, observe que podríamos
seleccionar cualquier campo de cualquiera de las tablas implicadas en el informe). Para indicar que nos
interesan los registros con valores no nulos en el campo tendremos que utilizar la última opción de la lista
desplegable que aparece en la pestaña: ‘fórmula’. Y la fórmula que deberemos teclear es IsNull
({Product.SellEndDate}).
Si pulsamos el botón ‘Mostrar fórmula’ del asistente, veremos una fórmula con todas las de la ley escrita
en el lenguaje de fórmulas de Crystal Reports (que estudiaremos en el tema 4). Se trata de un lenguaje de
programación completo, complementado además con una enorme biblioteca de funciones para todas las
necesidades comunes. En este lenguaje es que se escriben en última instancia las condiciones de
selección de un informe.
Nota avanzada: El Diseñador de Crystal Reports determina, de manera inteligente, cuándo es posible
traducir una fórmula de selección escrita en el lenguaje de Crystal en una cláusula WHERE de SQL para
pasarla al motor de bases de datos. Si incluye fórmulas Crystal complejas en sus fórmulas de selección, no
será posible traducirlas a SQL y el filtrado de registros deberá hacerse en la máquina cliente, con el
consiguiente incremento del tráfico de red y pérdida de rendimiento. Mediante la opción Base de datos |
Mostrar sentencia SQL del menú de Crystal Reports podrá comprobar que las dos condiciones que hemos
puesto se traducen perfectamente a SQL.
GRÁFICOS.
Crystal Reports ofrece unas posibilidades muy amplias para la incorporación de gráficos comerciales en
nuestros informes; aquí simplemente mostraremos un ejemplo típico que le dará una idea de cómo
pueden incorporarse a un informe tales gráficos. Para poder incorporar un gráfico a un informe, es
necesario haber definido previamente los resúmenes que servirán como valores a partir de los cuales se
dibujará el gráfico.
Para incorporar un gráfico a un informe, se debe utilizar la opción Insertar | Gráfico del menú o el botón
correspondiente de la barra de herramientas ‘Insertar’, que despliegan el Asistente de gráficos. Este
asistente tiene dos modos de trabajo que se configuran mediante la casilla ‘Establecer opciones
automáticamente’ de su primera pestaña. Si la casilla está marcada, el asistente generará
automáticamente los títulos para el gráfico y los ejes, escalas, colores, etc. En caso contrario, tendremos
la posibilidad de indicar todas esas características. Una buena técnica puede ser mantener inicialmente la
configuración automática, y más adelante editar las opciones del gráfico y pasar al modo manual para
indicar esas opciones en detalle. Además de esta opción, en la primera pestaña se indica el tipo de gráfico
que deseamos incorporar al informe (de barras, líneas, áreas, circular o tarta, etc.). Para nuestro ejemplo
elegiremos un gráfico de barras.
En la segunda pestaña del asistente es donde se especifica lo fundamental: los datos a partir de los cuales
se dibujará el gráfico y la situación del mismo. En nuestro caso, debido a que tenemos dos niveles de
agrupación, podemos basar el gráfico en dos series de datos: la cantidad de productos por cada categoría,
en cuyo caso el gráfico aparecerá una sola vez en el pie o la cabecera del informe (recuerde que
generalmente los objetos situados en una sección de ‘pie’ pueden moverse a su ‘cabecera’ hermana); o la
cantidad de productos por cada subcategoría dentro de cada categoría, en cuyo caso tendremos un
gráfico para cada categoría, situado en la sección de pie (o la cabecera) del grupo correspondiente a las
categorías. Vamos a elegir aquí la opción más difícil, la segunda: indiquemos ‘Por cada
ProductCategory.Name’ en el desplegable ‘Ubicar’. Verá que en el grupo ‘Datos’ aparecen
automáticamente la información adecuada: los valores a utilizar para el gráfico se obtienen cuando
cambia la subcategoría (el grupo más interno), y el resumen a utilizar es el único disponible a ese nivel, el
que cuenta la cantidad de productos de cada categoría.
Por último, la tercera pestaña del asistente permite establecer los textos que aparecerán en el gráfico
como título, subtítulo, nombres de ejes, etc. y sus propiedades. De momento, mantenga los valores
18
predeterminados y pulse Aceptar para cerrar el asistente. Verá cómo aparece en el informe un gráfico de
subcategorías para cada una de las categorías.
TOTALES ACUMULADOS
Un tipo de resumen muy común y que tiene sus particularidades que lo distinguen de los demás
resúmenes son los totales acumulados. Los totales acumulados nos permiten implementar en nuestros
informes los conocidos “suma y sigue” frecuentes, por ejemplo, en listados de operaciones bancarias.
Suponga que deseamos listar los pedidos (código, fecha, importe) recibidos a partir del 1/7/2004 (no hay
datos muy recientes en AdvertureWorks :-) En una columna del listado queremos mostrar un “suma y
sigue” con el total acumulado hasta ese momento del importe de los pedidos. Los datos generales sobre
los pedidos se almacenan en la tabla Sales.SalesOrderHeader de la base de datos. Además, en la tabla
Sales.SalesOrderDetail se almacenan los detalles (líneas) de cada pedido, pero en este momento no
necesitaremos esa segunda tabla.
Ante todo, añadiremos a nuestro proyecto de Visual Studio un nuevo informe (botón derecho sobre el
nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports).
Llamemos al informe ListadoPedidos.rpt. Inmediatamente después de indicar el nombre, el Asistente de
informes aparecerá automáticamente para que especifiquemos las características del informe. Se trata de
un informe estándar, y seleccionamos la base de datos AdventureWorks, y de ella la tabla
Sales.SalesOrderHeader. Los campos que nos interesan son SalesOrderID, OrderDate y TotalDue. No
necesitamos agrupaciones, por lo que saltamos directamente sobre esa página del Asistente. En la página
de selección de registros, indicamos que nos interesan los pedidos en los que OrderDate es posterior al
1/7/2004. Pulsamos ‘Finalizar’ y podremos ver la presentación preliminar del informe.
Ahora crearemos el total acumulado. Para ello, en el nodo ‘Campos de totales acumulados’ del
Explorador de campos pulsamos el botón derecho del ratón y seleccionamos ‘Nuevo’. Aparecerá un
cuadro de diálogo en el que se pueden indicar las características que queremos que tenga el total
acumulado.
Ante todo, se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operación de
resumen (aquí suma). En la sección ‘Evaluar’ se indica en qué momento queremos que el acumulador se
evalúe. En este caso dejaremos la opción por defecto, evaluar para cada registro, pero observe que
también es posible evaluar el total acumulado solo cuando cambie el valor de un campo, cuando se
cambie de grupo, o cuando se cumpla una condición cualquiera (expresada mediante una fórmula). Por
su parte, en la sección ‘Restablecer’ indicamos cuándo queremos que el acumulador se reinicie a cero.
Aunque también lo dejaremos ahora en ‘Nunca’, observe que se puede reiniciar el acumulador cada vez
que se cambia de campo, de grupo o cuando se cumpla una fórmula. Estudiaremos el lenguaje de
fórmulas de Crystal Reports en el siguiente tema. Y en principio, ¡ya está! Basta con pulsar el botón
19
‘Finalizar’ y arrastrar el campo recién creado a la sección de Detalles del informe (preferiblemente a la
derecha del importe del pedido). Verá la suma parcial de los importes evaluada para cada registro.
TRUCO: Frecuentemente en listados con este tipo de totales nos piden que pongamos el valor del total
acumulado hasta el momento al pie de cada página. Para ello, seleccione el campo de total acumulado,
cópielo al Portapapeles (CTRL-C) y luego páguelo (CTRL-V) en la sección de Pie de página. ¡Listo! Este es
uno de los pocos casos en los que tiene sentido mover objetos de una sección a otra que no sea su
“hermana”.
FÓRMULAS
En este tema se presentan las fórmulas de Crystal Reports y sus principales aplicaciones. Rápidamente se
convencerá de que las fórmulas juegan un papel muy importe tanto en informes básicos como en
aplicaciones más avanzadas.
INTRODUCCIÓN
Las fórmulas son una característica muy importante de Crystal Reports, que le dan la potencia necesaria
para acometer numerosas tareas que de otras maneras serían imposibles y limitarían seriamente las
posibilidades del producto.
Básicamente, una fórmula es una expresión más o menos compleja escrita en uno de los dos lenguajes de
programación que soporta Crystal Reports: Crystal y Visual Basic, y cuyo objetivo es calcular un valor que
debe ser utilizado en alguna de las fases de confección de un informe. En este curso utilizaremos la
sintaxis Visual Basic, que será mucho más familiar a los programadores que utilicen VB.NET. Para
garantizar que las fórmulas utilicen ese lenguaje, por favor vaya a la opción Crystal Reports | Diseño |
Especificaciones predeterminadas | Elaborando informes del menú y selecciones ‘Sintaxis Basic’ en el
desplegable Lenguaje de fórmulas.
En general, los lenguajes de fórmulas de Crystal Reports son lenguajes de programación completos, que
incluyen declaraciones de variables, condicionales, estructuras de bucle, etc. No obstante, gracias a los
potentes asistentes incorporados al producto, rara vez es necesario hacer uso de tales facilidades y las
fórmulas se utilizan en el sentido literal del término – el de una expresión que produce un valor de un
determinado tipo.
20
contiene el nombre del cliente, y en un informe deseamos mostrar ese nombre en mayúsculas, podemos
escribir la siguiente fórmula: UCase({Clientes.Nombre}).
Aunque pueda parecer necesaria una gran cantidad de tecleo, en realidad el programador no tiene que
teclear casi nada para componer estas fórmulas: a continuación veremos cómo un potente editor nos
ayuda con esta tarea.
Hay que tener en cuenta siempre el tipo de datos del resultado que una fórmula produce. En ciertas
ocasiones una fórmula puede producir un resultado de cualquier tipo que queramos, pero en otros casos
Crystal Reports espera que le suministremos una fórmula que produce un resultado de un tipo
determinado y protestará si le suministramos una fórmula que produce otra cosa, aunque sea
sintácticamente correcta.
CAMPOS CALCULADOS
La aplicación más típica de las fórmulas son los campos calculados. Un campo calculado es un campo (de
cualquier tipo de datos soportado por Crystal) que físicamente no se almacena dentro de la base de
datos, pero que puede ser calculado por Crystal a partir de los valores de otros campos del informe.
Como ejemplo, supongamos que queremos determinar el tiempo que ha tardado cada pedido del año
2004 en salir del almacén de la empresa de camino a su destinatario. En la tabla Sales.SalesOrderHeader
no tenemos directamente ese dato, pero sí tenemos los campos OrderDate (la fecha en que se hizo el
pedido) y ShipDate (la fecha en que se hizo el envío). Podemos calcular el intervalo deseado restando
ambas fechas, y para ello hace falta una fórmula.
En nuestro proyecto, seleccione el informe ListadoPedidos.rpt. En el Explorador de campos, pulse el
botón derecho del ratón sobre el nodo ‘Campos de fórmula’ y seleccione ‘Nueva’. Ante todo, es necesario
dar un nombre a la fórmula: llamémosle ‘DíasHastaSalida’. Verá que para seguir adelante hay dos
opciones: ‘Usar Asistente’ o ‘Usar Editor’. Se trata de dos herramientas diferentes con un mismo
propósito: ayudarnos a escribir las fórmulas con un mínimo de tecleo y comprobación de que la fórmula
es correcta. En este curso utilizaremos el Editor, que nos parece más intuitivo, sin carecer de ninguna de
las posibilidades.
Al pulsar el botón ‘Usar Editor’, aparecerá ante nosotros el Editor de fórmulas. En el panel de la izquierda
está un árbol con todas las fórmulas del informe; podemos cerrarlo para hacer más espacio para nuestra
fórmula actual.
Ahora, la fórmula se compone en la zona inferior del editor (donde ya aparece automáticamente ‘formula
=’). La zona superior se divide en tres paneles: el panel de Identificadores, desde el que podemos elegir
los campos del informe o la base de datos, fórmulas, totales acumulados, etc.; el panel de Funciones, en
el que tenemos a nuestra disposición la lista de todas las funciones predefinidas de Crystal (algo
sumamente útil) y el panel de Operadores, en el que podremos encontrar a todos los operadores del
lenguaje.
Para introducir nuestra fórmula, buscamos en el panel de Identificadores el campo ShipDate de
SalesOrderHeader (como el campo no está incluido directamente en el informe, debemos bajar a buscarlo
en la lista general de todos los campos de la tabla) y hacemos doble clic sobre él – verá que es copiado a
la fórmula con la sintaxis correcta: {SalesOrderHeader.ShipDate}. El operador ‘-’ podríamos elegirlo de un
21
modo similar, seleccionándolo en el nodo de operadores aritméticos; pero en este caso la ventaja no está
tan clara, y probablemente sea mejor teclear el carácter. Por último, seleccionamos del panel de
Identificadores el segundo operando, OrderDate. La fórmula final es:
En cualquier momento podemos comprobar la validez de una fórmula pulsando el botón ‘Revisar’. Una
vez editada y validada la fórmula, podemos guardarla y cerrar el editor mediante ‘Guardar y cerrar’. Y ya
definida la formula, podemos arrastrarla al informe – en este caso, a la sección de Detalles. Por supuesto,
también podríamos definir resúmenes basados en esa fórmula, que se convierte en un campo más del
informe.
FORMATO CONDICIONAL
La aplicación de las fórmulas al formato condicional consiste en que, mediante una fórmula, es posible
programar las características visuales de cualquier campo o sección del informe, o incluso que aparezca o
no en él.
Continuando con el mismo ejemplo, suponga que queremos resaltar aquellos pedidos que tardaron más
de 7 días en salir del almacén. Para ello, vamos a resaltar en color rojo los valores correspondientes.
Seleccionamos la fórmula, pulsamos el botón derecho del ratón y elegimos la opción ‘Dar formato al
campo’. En el diálogo que aparece, activamos la pestaña ‘Fuente’. Lo que deseamos es cambiar el color
del texto, pero no incondicionalmente, sino sujeto a una condición. Por eso, pulsamos el botón de
fórmula situado a la derecha del desplegable correspondiente al color de la fuente. Aparece el editor de
fórmulas, y en él debemos introducir la fórmula que determinará el color del texto. En este caso, la
fórmula es:
Las constantes crRed y crBlack , aparecen en el panel de Funciones cuando se esté editando una fórmula
que deba producir un color, como es el caso.
De un modo similar, podemos programar cualquiera de las características visuales de los campos del
informe. En estos casos, la fórmula que debemos utilizar tiene que producir un resultado del tipo
adecuado. Como otro ejemplo, suponga que deseamos que cierto campo no aparezca en el informe (o
sea, suprimirlo) en caso de que se cumpla una condición. En tal caso, debemos utilizar la propiedad
Suprimir (pestaña ‘Común’) del Editor de formato. La fórmula debe producir un resultado booleano, y
cuando su valor sea True el campo se suprimirá del informe.
Por último, el formato condicional se puede aplicar no solo a campos individuales, sino a secciones
enteras. Por ejemplo, vamos a dar al listado de pedidos formato de “pijama”, haciendo que la sección de
Detalles tenga alternativamente fondo gris o blanco para cada fila del informe. Para ello, lance el
Asistente de sección y seleccione la sección de Detalles. Active luego la pestaña ‘Color’ y pulse sobre el
botón de fórmula asociado al desplegable de color de fondo. Introduzca la siguiente fórmula:
RecordNumber es otra función predeterminada de Crystal, que produce un número secuencial para cada
registro del conjunto de datos (puede encontrarse bajo el nodo “Estado de impresión”).
GRUPOS PERSONALIZADOS
La siguiente aplicación de las fórmulas es la que tiene que ver con la selección de registros y grupos.
22
Como ya hemos presentado anteriormente, Crystal permite hacer una selección tanto de los registros
individuales como de los grupos que se utilizarán al ejecutar el informe. El Asistente de selección nos
permite especificar las condiciones que deberán cumplir los registros o grupos en los casos de
condiciones sencillas, y se encarga de generar automáticamente las fórmulas correspondientes. Pero
cuando lo que queremos expresar va más allá de las posibilidades cubiertas por el asistente, es necesario
pasar a la acción y escribir la fórmula nosotros mismos.
Para un ejemplo sencillo, suponga que deseamos que el listado de pedidos (además de los pedidos a
partir de julio del año 2004) incluya solamente los pedidos recibidos a través de Internet (aquellos para
los que el campo SalesOrderHeader.OnlineOrderFlag es True). Simplemente lanzamos el Asistente de
selección (Crystal Reports | Report | Asistente de selección o el botón correspondiente en la barra de
herramientas ‘Principal’). Pulsamos el botón ‘Nuevo…’ para añadir una nueva condición de selección. Y en
el desplegable que aparece seleccionamos ‘es Verdadero’. Si ahora pulsamos el botón ‘Mostrar fórmula’
podremos ver la fórmula correspondiente:
La función predefinida PreviousValue nos da el valor del campo indicado en el registro anterior. Es muy
útil para detectar situaciones de cambios de grupo y otras situaciones similares, frecuentemente en
combinación con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el
primer registro).
PARÁMETROS
En este tema presentaremos los parámetros, que juegan un papel muy importante de cara a la
programabilidad de los informes.
INTRODUCCIÓN
La inmensa mayoría de los informes se diseñan para luego utilizarlos frecuentemente de manera
periódica. Sin embargo, cada nueva ejecución del informe necesitará pequeños ajustes derivado del
cambio de los datos de entrada del informe. Si los parámetros no existieran, cada nueva ejecución
requeriría una modificación previa del informe en el Diseñador – un verdadero problema para la
productividad. Los parámetros nos permiten precisamente definir informes adaptables, en los que los
datos de entrada cambiantes se solicitan inmediatamente antes de la ejecución.
Continuando con nuestro listado de productos de ejemplo, supongamos que nos interesara poder
ejecutar el informe para distintos valores de la fecha de inicio – ahora mismo, el informe tiene “clavado”
el valor #1/7/2004#. Pues bien, lo ideal hubiera sido haber definido un parámetro para esa fecha de
inicio, cosa que mostraremos a continuación.
24
Hay que señalar que (como veremos en el próximo tema) las librerías .NET de Crystal ofrecen la
posibilidad de asignar desde programa valores a los parámetros, de modo que el cuadro de diálogo no
aparezca en pantalla.
SUBINFORMES
Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro,
una característica que comúnmente se conoce como subinformes. Para incorporar un informe como
subinforme dentro de otro, se utiliza el botón ‘Insertar subinforme’ de la barra de herramientas ‘Insertar’
(o la opción correspondiente del menú). Esta posibilidad puede utilizarse, por ejemplo, para “concatenar”
un informe a continuación de otro, insertándolo en una subsección del pie de informe. Tal aplicación es,
en general, sumamente directa, y la única opción interesante es la de integrar el subinforme completo
cuando se ejecuta el informe externo, o simplemente poner un hipervínculo para que el subinforme se
ejecute bajo demanda (‘a petición’ es el término que utiliza Crystal).
SUBINFORMES PARAMETRIZADOS
La aplicación más importante de los subinformes son los subinformes parametrizados. En ellos, un
informe se integra como subinforme dentro de otro (normalmente en la sección de Detalles de éste), y el
informe externo (contenedor) comunica al interno a través de un parámetro un valor que le indica a éste
último qué datos debe mostrar.
Como ejemplo, supongamos que queremos mostrar los detalles de cada uno de los pedidos de nuestro
listado de pedidos. Un posible enfoque podrá ser el de integrar dentro de la sección de Detalles del
informe actual un subinforme que presente los detalles del pedido actual. Esta técnica tiene la ventaja de
que podríamos indicar que el subinforme se ejecute bajo demanda, lo que reduciría la carga sobre el
motor de base de datos.
Para empezar, inserte un subinforme en la sección de detalles del listado de pedidos. Marque la casilla
‘Subinforme a petición’. Indique que desea crear un nuevo subinforme con el Asistente; llame al nuevo
subinforme DetallesPedido.rpt y pulse el botón ‘Asistente de informes’.
Al diseñar el nuevo informe, indicaremos que la tabla deseada es Sales.SalesOrderDetail. Elegiremos
varios campos, como ProductID (código de producto – en la vida real necesitaríamos conectar con la tabla
de productos para obtener el nombre), OrderQuantity (cantidad), UnitPrice (precio unitario),
UnitPriceDiscount (descuento sobre precio unitario) y LineTotal (importe total de línea). Pulse ‘Finalizar’
para terminar el diseño del informe. Será llevado nuevamente al diálogo de inserción de subinforme; es
hora de pasar a la pestaña ‘Vínculo’ para establecer la conexión entre el informe y el subinforme.
En la pestaña ‘Vínculo’, debemos primero indicar el campo del informe contenedor cuyo valor se debe
pasar al subinforme; es SalesOrderHeader.SalesOrderID, el código del pedido. A continuación, debemos
indicar el campo del subinforme que recibirá (a través de un parámetro cuyo nombre propone el
asistente) el código del pedido cuyos detalles debe mostrar. En nuestro ejemplo, es SalesOrderID. Y solo
nos queda pulsar el botón ‘Aceptar’. De la creación del parámetro y el establecimiento de la fórmula de
selección adecuada en el informe recién creado se encarga el automáticamente el asistente.
La presentación de la vista previa nos mostrará cómo funcionan los informes con subinformes bajo
demanda: al pulsar sobre el “hipervínculo” asociado a un pedido, el subinforme con los detalles de dicho
pedido se desplegará en una nueva pestaña del visor de informes.
25
TÉCNICAS FUNDAMENTALES
Las diferentes subsecciones de esta sección presentan los fundamentos teóricos y las técnicas comunes
que se utilizan en la incorporación de informes Crystal a aplicaciones Windows Forms.
Como habrá comprendido, la primera línea de código declara una variable genérica de tipo
ReportDocument y la inicializa para que apunte a nuestro informe tipado.
En general, es recomendable trabajar con los informes tipados siempre que sea posible, y utilizar
directamente la clase ReportDocument sólo para trabajos de índole genérica, por ejemplo cuando
queremos que el mismo componente apunte a diferentes informes durante la ejecución. De hecho,
cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario, Visual Studio nos
27
pregunta si realmente deseamos un objeto no tipado o si preferimos crear una clase tipada asociada a
alguno de los informes del proyecto.
28
Una de las características favoritas de los desarrolladores es la posibilidad de pasar directamente valores
de parámetros a los informes de manera transparente.
Ante todo, añadiremos dos parámetros a nuestro informe, correspondientes a la fecha de inicio y fecha
de fin de los pedidos. O sea, no deseamos obtener todos los pedidos de la base de datos, sino solo los que
estén entre las fechas de inicio y fin indicadas por los parámetros. Llamaremos a los parámetros FInicio y
FFin, y haremos que la fórmula de selección del informe sea:
Observe la utilización de los operadores in..to (desde..hasta) por parte del Asistente.
A continuación, añadiremos las siguientes líneas de código al evento Load del formulario: ' asignar valores
a parámetros CrystalReport11.SetParameterValue("FInicio", New DateTime(2003, 9, 1))
CrystalReport11.SetParameterValue("FFin", New DateTime(2003, 9, 5))
Esto es suficiente para hacer que se muestren solamente los pedidos efectuados entre el 1 y el 5 de
septiembre de 2003. El método SetParameterValue de ReportDocument espera dos valores, el nombre
del parámetro y el valor a asignar, respectivamente. El segundo parámetro es de tipo Object, dado que
los parámetros pueden ser de distintos tipos. Hay que comprobar siempre que enviamos datos de los
tipos correctos al informe.
IMPRESIÓN DE INFORMES
Para la impresión de un informe desde código, de nuevo podemos utilizar un potente método de la clase
ReportDocument: PrintToPrinter(). Previamente, se debe utilizar la propiedad PrintOptions (una
propiedad con poca “ciencia” y bastante “miga”, sobre la que no daremos muchos detalles aquí) para
seleccionar la impresora activa y establecer múltiples opciones de impresión.
Por ejemplo, para enviar a mi impresora predeterminada una copia de todas las páginas del informe,
debo escribir:
' imprimir
CrystalReport11.PrintOptions.PrinterName = "Dell Laser Printer 5210n"
CrystalReport11.PrintToPrinter(1, False, 0, 0)
29
Los parámetros de PrintToPrinter significan: a) la cantidad de copias, b) si se deben combinar o no las
copias en caso de ser más de una, c) página de inicio, d) página de fin. Las páginas de inicio y fin se deben
poner a cero si se desea obtener copias completas.
30
A la hora de presentar el informe en tiempo de ejecución, es necesario utilizar el método SetDataSource
() de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto
de datos. Por ejemplo,
CrystalReport21.SetDataSource(AdventureWorksDataSet)
CrystalReport21.Refresh() ' elimina datos guardados por el informe
CrystalReport21.Show()
31
En este tema estudiaremos las particularidades relacionadas con la programación de aplicaciones Web
que utilicen Crystal Reports.
Los mecanismos para la incorporación de informes Crystal Reports en aplicaciones Web son muy similares
a los que ya hemos visto para las aplicaciones de escritorio. Casi todos los recursos de programación que
hemos visto anteriormente (conexión a la base de datos, aplicación de parámetros, utilización de un
DataSet como origen del informe) son igualmente aplicables para el desarrollo de aplicaciones Web. Las
principales diferencias tienen que ver no con el modelo de programación (como veremos, en el fondo se
utiliza la misma clase ReportDocument), sino con las características relacionadas con la visualización,
dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer.
El despliegue también es muy similar – básicamente se trata de hacer que las librerías .NET de Crystal
caigan “en su sitio” cuando se ejecute el programa de instalación.
TÉCNICAS FUNDAMENTALES
Las diferentes subsecciones de esta sección presentan las técnicas específicas que se utilizan al incorporar
informes Crystal en aplicaciones Web ASP.NET.
32
ReportDocument. No se ve en la ventana de propiedades, porque es una propiedad de tiempo de
ejecución. Como su nombre indica, almacena una referencia al objeto ReportDocument que representa al
informe tipado que ya hemos estudiado en las aplicaciones Windows. A este objeto podremos aplicarle
todas las técnicas que hemos estudiado anteriormente (conexión a la base de datos, aplicación de
parámetros, utilización de un DataSet como origen del informe).
33
Por último, tenemos varias propiedades booleanas que determinan qué botones de la barra de
herramientas deben aparecer o no:
HasDrillUpButton – mostrar o no el botón de Volver al informe anterior.
HasExportButton – mostrar o no el botón de Exportar.
HasGotoPageButton – mostrar o no el botón de Ir a página.
HasPageNavigationButtons – mostrar o no los botones de navegación por las páginas.
HasPrintButton – mostrar o no el botón de Imprimir.
HasRefreshButton – mostrar o no el botón de Actualizar.
HasSearchButton – mostrar o no el botón de Buscar texto.
HasToggleGroupTreeButton – mostrar o no el botón de Mostrar Árbol de grupos.
HasZoomFactorList – mostrar o no la lista de opciones de zoom.
Es esencial un nombre de fichero que sea único para cada sesión, de modo que no existan
“interferencias” entre varios posibles visitantes de la página.
34
incluyendo en nuestro caso los ficheros .rpt (que en las aplicaciones Web siempre se almacenan como
ficheros externos).
35