Está en la página 1de 35

¡BIENVENIDO AL CURSO "DESARROLLO DE INFORMES DE DATOS CON

CRYSTAL REPORTS .NET"!


Este curso le ofrece todos los conocimientos que necesita para diseñar informes de datos Crystal Reports
e incorporarlos en sus aplicaciones .NET (tanto Windows como Web).
En este curso aprenderá:
󲐀 Cómo crear informes de datos utilizando el diseñador de informes integrado en Visual Studio 2005
󲐀 Cómo utilizar los componentes que ofrece Crystal Reports para incorporar esos informes en
aplicaciones .NET.
󲐀 Cómo crear instaladores para esas aplicaciones, para facilitar su despliegue.
REQUISITOS: Para una correcta asimilación de los contenidos del curso, el alumno deberá estar
familiarizado con los conceptos fundamentales de la programación en Visual Basic .NET y con el entorno
de desarrollo Visual Studio 2005. Igualmente, deberá conocer los principales conceptos relacionados con
el mundo de las bases de datos relacionales (base de datos, tablas, filas, columnas); una ligera
familiaridad con el lenguaje SQL (en particular, con la sentencia SELECT) no es imprescindible, pero sí muy
conveniente.
REQUISITOS DE SOFTWARE: Crystal Reports .NET viene incluido únicamente en la edición Profesional de
Visual Studio 2005; si se dispone de una edición inferior, la alternativa es adquirir de manera
independiente el producto Crystal Reports Developer, e instalarlo sobre cualquier versión de Visual Studio
2005. Como motor de bases de datos, el curso utiliza Microsoft SQL Server 2005; cualquiera de sus
ediciones es válida (en particular, la Express, disponible gratuitamente). Los ejemplos se basan en la base
de datos AdventureWorks, que viene incluida en las ediciones de pago de SQL Server 2005; si va a utilizar
la edición Express, puede descargarla desde aquí.

INTRODUCCIÓN A CRYSTAL REPORTS .NET


En esta primera lección aprenderá qué es Crystal Reports, las particularidades de su versión para .NET
Framework, su arquitectura y las posibilidades que ofrece para el diseño y ejecución de informes de
datos.
La lección consta de los siguientes temas:
󲐀 Cómo crear informes de datos utilizando el diseñador de informes integrado en Visual Studio 2005
󲐀 Cómo utilizar los componentes que ofrece Crystal Reports para incorporar esos informes en
aplicaciones .NET.
󲐀 Cómo crear instaladores para esas aplicaciones, para facilitar su despliegue.

QUÉ ES CRYSTAL REPORTS


Crystal Reports es una herramienta potente a la vez que fácil de usar para el diseño y generación de
informes a partir de datos almacenados en una base de datos u otra fuente de información. Es, con
diferencia, la herramienta más popular en su categoría, y no solo entre quienes podrían considerarse sus
“usuarios” puros (aquellos que necesitan obtener periódicamente información para la toma de decisiones
a partir de los datos de la empresa), sino también entre los programadores, que lo han convertido en su
herramienta favorita a la hora de embeber capacidades de generación de informes dentro de las
aplicaciones a medida. A este último hecho indudablemente ha contribuido mucho el que, desde hace
más de diez años, Crystal Reports venga siendo incorporado “de serie” a las herramientas de desarrollo
de Microsoft (Visual Basic y luego Visual Studio).
Con la aparición de .NET Framework, una transformación revolucionaria de las tecnologías de desarrollo
de Microsoft, los fabricantes de Crystal Reports se dieron a la tarea de adaptar el producto a los nuevos

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.

ARQUITECTURA. COMPONENTES PRINCIPALES


La arquitectura de Crystal Reports.NET gira alrededor del soporte para un tipo de ficheros de formato
propietario, que se distingue por la extensión .RPT (report) y en el que se almacena la definición de los
informes. El producto se puede ver como la combinación de tres componentes principales, que son:
󲐀 El Motor de Impresión (Crystal Reports Print Engine, CRPE). A pesar de lo que su nombre sugiere, este
componente, escrito en código no administrado, no sólo se encarga de lo relacionado con la impresión en
papel de los informes, sino además con todo lo que tiene que ver con la ejecución de los mismos,
empezando por el acceso a la base de datos para leer la información y continuando con la generación de
la imagen de las diferentes páginas para luego volcarlas en pantalla, papel o exportarlas a otros formatos
como Adobe PDF o Microsoft Word.
󲐀 Las Librerías de Código Manejado encapsulan la funcionalidad del Motor de Impresión a través de un
conjunto de clases fácilmente accesibles desde aplicaciones escritas en Visual Basic, C# o cualquier otro
lenguaje .NET. Estas son las librerías que utilizaremos desde nuestras aplicaciones o servicios (para
Windows o la Web) para cargar, ejecutar e imprimir los informes.
󲐀 Por último, el Diseñador de Informes es el software que presenta la interfaz de usuario a través de la
cual un usuario, programador o no, puede crear (“diseñar”) un informe y guardarlo en un fichero .RPT
para su posterior reutilización. Se trata de una aplicación sofisticada, repleta de potentes asistentes que
garantizan una alta productividad sin limitar las posibilidades a nuestra disposición. La versión del
Diseñador que incluye Crystal Reports.NET se integra perfectamente dentro de Visual Studio 2005,
permitiendo creando una experiencia aún más ágil y productiva.

Arquitectura de Crystal Reports

POSIBILIDADES DE ACCESO A DATOS Y EXPORTACIÓN


2
Indudablemente, otra de las características que han hecho tan popular a Crystal Reports es la amplia
gama de orígenes de datos que soporta, así como de formatos de salida a los que se pueden exportar los
resultados. El Motor de Impresión de Crystal Reports tiene una arquitectura modular, y se apoya en
controladores (drivers) independientes para acceder a los diversos orígenes de datos soportados y
generar los informes en los diferentes formatos de salida posibles.
Las posibilidades de acceso a diferentes orígenes de datos sobrepasan ampliamente la mera capacidad
para comunicarse con bases de datos (prácticamente todos los sistemas de bases de datos, tanto
relacionales como “planos” están soportados), y abarcan desde la lectura de todo tipo de bitácoras (logs),
por ejemplo las producidas por los servidores Web para el seguimiento de la navegación de los usuarios,
hasta el acceso a objetos en memoria generados por las aplicaciones que hospedan al Motor de
Impresión. Por ejemplo, en este curso veremos cómo ejecutar informes contra conjuntos de datos
(objetos de la clase DataSet) que tengamos en nuestras aplicaciones.
En cuanto a las posibilidades de salida, el Motor de Impresión de Crystal no solo nos permite obtener
nuestros resultados en papel o en pantalla (una ventana, en caso de aplicaciones Windows; o el
navegador Web, en el caso de aplicaciones Web), sino que también ofrece la posibilidad de exportar los
resultados a numerosos formatos externos, como Adobe PDF, Microsoft Word, Microsoft Excel, ficheros
de texto o XML, entre otros.
Tenga en cuenta que, aunque aún no podemos prescindir del papel ni mucho menos, la presentación de
informes se está convirtiendo cada vez más en una tarea interactiva. Las versiones más recientes de
Crystal Reports incluyen numerosas facilidades que veremos en este curso (Árbol de grupos, elementos
con hiperenlaces) y que están orientadas única y exclusivamente a la visualización de informes en una
ventana de Windows o en un navegador Web.

LIBRERÍAS DE CRYSTAL REPORTS


Las librerías de código manejado incluidas en Crystal Reports.NET conforman una potente API Application
Programming Interface - Interfaz para la Programación de Aplicaciones) que facilita a los desarrolladores
la tarea de integrar informes previamente desarrollados dentro de sus propias aplicaciones.
Debido a la diversidad de contextos en los que se puede hacer uso de Crystal Reports en aplicaciones
.NET (aplicaciones Windows, aplicaciones o servicios Web), el fabricante decidió crear diferentes
ensamblados físicos (DLLs) para simplificar las dependencias y el despliegue ulterior de las aplicaciones.
La siguiente tabla presenta los principales ensamblados (librerías de clases) que forman parte de Crystal
Reports.NET y se instalan en la Caché Global al instalar el producto. Generalmente no es necesario
agregar explícitamente las referencias a estos ensamblados en nuestros proyectos, ya que los asistentes
de Visual Studio se encargan automáticamente de ello cuando, por ejemplo, incorporamos a una
aplicación un informe de Crystal Reports.

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.

CrystalDecisions.Windows.Forms Clases para la presentación de informes Crystal en


aplicaciones Windows.
CrystalDecisions.Web Clases para la presentación de informes Crystal en
aplicaciones Web

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.

PRESENTACIÓN DE LA BASE DE DATOS DE EJEMPLO


Desarrollaremos los ejemplos de este curso utilizando como origen de datos para los informes a
AdventureWorks, la base de datos de ejemplo que acompaña a SQL Server 2005. Se trata de una base de
datos que almacena toda la información generada por una empresa ficticia dedicada a la fabricación y
venta de bicicletas. Dado que cubre todos los aspectos del funcionamiento de la empresa, es una base de
datos bastante extensa, y por eso Microsoft ha dividido las tablas que componen la base de datos en los
siguientes esquemas:

Esquema Contiene objetos relacionados con


Person Personas. Aquí se almacenan los nombres y direcciones de clientes
individuales, proveedores y empleados.
Purchasing Compras. Información sobre las piezas y productos que la empresa
compra y sus proveedores.
Production Producción. Información sobre los productos fabricados y vendidos por
la empresa.
Sales Ventas. Información sobre los clientes y los pedidos que realizan.
HumanResources Recursos Humanos. Información sobre los empleados de la empresa.

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.

TÉCNICAS BÁSICAS DE DISEÑO DE INFORMES


En este tema se presenta el Diseñador de Informes de Crystal Reports integrado en Visual Studio 2005 y
se presentan las técnicas básicas de diseño de informes en las que se apoyan los temas subsiguientes.

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.

CREACIÓN DE INFORMES ESTÁNDAR UTILIZANDO EL ASISTENTE


Dentro de Visual Studio 2005, seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de
diálogo ‘Nuevo proyecto’ elija Visual Basic | Aplicación para Windows (observe que hay otra plantilla
Aplicación de Crystal Reports, que evitaremos de momento). Llame al proyecto Ejemplo1 y póngalo en el
directorio adecuado. Como toda aplicación para Windows, incluye un formulario principal inicialmente
vacío.
Ahora sobre el nombre del proyecto en el Explorador de Soluciones, pulse botón derecho del ratón y
Agregar | Nuevo elemento. Del cuadro de diálogo con los distintos tipos de elemento posibles, elija
Crystal Reports. Llame al nuevo fichero ListadoProductos.rpt. Al agregar un informe al proyecto, se activa
el Diseñador de Crystal Reports. Lo que ve en pantalla ahora (“Galería de Crystal Reports”) es la ventana
introductoria del Diseñador, que nos pregunta:

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

Cuando haya elegido esos tres campos, pulse Siguiente.

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.

ESPECIFICACIÓN DE LAS TABLAS DEL INFORME. OPCIONES DE ENLACE


Como resultado del paso anterior, tenemos a nuestra disposición en el área de trabajo de Visual Studio
como “vista activa” del informe el “lienzo” generado por el Asistente, sobre el que podremos hacer todas

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:

󲐀 Las barras de herramientas de Crystal Reports


󲐀 La barra de herramientas ‘Principal’ ofrece múltiples botones para, por una parte, lanzar diferentes
asistentes que nos ayudarán con las tareas comunes (selección, ordenación), y por otra parte, facilitarnos
las tareas de formato (atributos de texto, justificación, cantidad de decimales en campos numéricos)
󲐀 La barra de herramientas ‘Insertar’ ofrece botones que despliegan asistentes que nos permitirán
insertar objetos más o menos complejos en el informe (grupos, totales, gráficos, imágenes)
󲐀 En el menú principal de Visual Studio, o si se pulsa el botón derecho del ratón sobre el lienzo de diseño
(teniendo cuidado de no estar situado sobre una sección, pues entonces aparecería el menú de la
sección), tendremos el menú principal del diseñador, que incluye todas las opciones de las barras de
herramientas más algunas otras no disponibles en ningún otro sitio. Las principales opciones de este
menú son las siguientes:

󲐀 Insertar: para insertar diferentes objetos sobre el lienzo de diseño.


󲐀 Base de datos: para realizar diferentes tareas relacionadas con la base de datos a la que accedemos,
por ejemplo agregar nuevas tablas al informe.
󲐀 Report: para lanzar diferentes asistentes o establecer la configuración del informe. Por ejemplo, vamos
a establecer el título del informe y el nombre de su autor. Para ello utilizamos la opción del menú Report
| Resumen de información, que nos lanzará un cuadro de diálogo en el que podremos indicar esos
valores. Utilice como título ‘Listado de productos para venta’; ponga su nombre en el campo ‘Autor’.
󲐀 Diseño: para actuar sobre las opciones de configuración general del diseñador, que dictan cómo éste se
comporta de manera predeterminada. Por ejemplo, una opción que puede resultar conveniente es la de
activar la opción Cuadrícula, que hará aparecer una rejilla de puntos sobre el diseñador, lo que nos
ayudará a establecer la alineación de los objetos.
󲐀 El Explorador de campos, que aparece por defecto a la izquierda del lienzo de diseño, nos presenta una
vista de árbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para
arrastrarlo sobre la sección adecuada en el área de diseño. Por ejemplo, si despliega el nodo ‘Campos de
base de datos’, encontrará la tabla Product con todos sus campos; por favor, seleccione el campo
SellEndDate (fecha en que el producto se dejó de vender) y arrástrelo sobre la sección de Detalles del
informe, justo a la derecha del campo Color. Si cambia a la Vista previa, verá que sólo algunos productos
tienen asociada una fecha de vencimiento. En caso de que un campo tenga asociado el valor nulo,
simplemente no se mostrará nada en la posición correspondiente.

TÉCNICAS PRINCIPALES DE UTILIZACIÓN DEL ENTORNO DE DISEÑO


Para insertar cualquier elemento en un informe, como hemos visto antes, se utilizan dos técnicas
fundamentales:
󲐀 Si se trata de un campo de base de datos, parámetro, grupo, etc. ya existente y visible en el Explorador
de campos, basta con arrastrarlo desde allí hacia la posición deseada dentro de la sección adecuada,
como acabamos de hacer. Como segundo ejemplo, vamos a poner el título del informe en la sección de
Encabezado del informe (para que aparezca una vez, en la parte superior de la primera página, cuando se
ejecute el informe). Para ello iremos al Explorador de campos, desplegaremos el nodo ‘Campos
especiales’, y elegiremos el elemento ‘Título del informe’ y lo arrastraremos hacia la sección de
Encabezado de informe, digamos que más hacia la esquina izquierda del informe. De nuevo, pasando a la

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.

PRINCIPALES TIPOS DE OBJETOS


Cada vez que arrastramos algo desde el Explorador de campos, o insertamos un objeto desde el menú o
la barra de herramientas, el Diseñador de Crystal Reports crea para nosotros un objeto del tipo
correspondiente. Los principales tipos de objetos que podemos arrastrar sobre el lienzo de diseño desde
el Explorador de campos son:
󲐀 Campos de bases de datos: objetos que mostrarán los valores de los campos de los diferentes registros
extraídos de la base de datos. En dependencia del tipo de datos del campo – Crystal Reports distingue los
tipos Alfanumérico (Cadena), Número, Moneda, Fecha, Hora, Fecha/Hora y Lógico (Booleano) -, el cuadro
de diálogo de configuración ofrecerá una pestaña específica para configurar los datos de ese tipo.
󲐀 Campos de fórmula: Como estudiaremos en el tema 4, Crystal Reports ofrece un lenguaje de fórmulas
que nos permitirá implementar, por ejemplo, campos calculados que no existan físicamente en la base de
datos. Se puede crear fórmulas de cualquiera de los tipos de datos antes mencionados, y Crystal ofrece
una amplísima biblioteca de funciones predefinidas para facilitarnos el desarrollo de fórmulas.
󲐀 Campos de parámetro: Otro de los elementos importantísimos de Crystal Reports desde el punto de
vista práctico son los parámetros. Los parámetros (que estudiaremos en el tema 5) hacen posible que un
mismo informe pueda ser utilizado en múltiples situaciones sin necesidad de hacer “retoques” al diseño
del informe. El informe se diseña con uno o más parámetros, y los valores de los parámetros se
suministran al motor de impresión “desde fuera”, inmediatamente antes de cada ejecución del informe.
󲐀 Campos de nombre de grupo: En un informe con datos agrupados, el nombre de grupo es el campo
por el que se agrupan los datos. Por ejemplo, en un listado de clientes agrupados por países, el nombre
de grupo será el nombre del país. Generalmente, el nombre de grupo se coloca en la sección de
Encabezado de grupo.
󲐀 Campos de totales acumulados: Los totales acumulados permiten implementar los típicos “suma y
sigue”, resúmenes que se van acumulando y pueden ser reiniciados cuando se desee (al final de cada
grupo, al cambiar el valor de cierto campo, o nunca). Estudiaremos los totales acumulados en el tema 3.
󲐀 Campos especiales: Bajo el nombre común de “campos especiales” se han agrupado toda una serie de
elementos de información que generalmente se desea mostrar en los informes: título y autor del informe
(que ya hemos presentado antes), fecha de impresión o modificación del informe, número de página
actual, cantidad total de páginas del informe, entre otros.
Por otra parte, desde el menú de Crystal Reports o la barra de herramientas correspondiente podremos
insertar en el informe objetos como:
󲐀 Secciones: Aunque ya el Asistente ha creado para nosotros cada una de las secciones típicas de un
informe, un programador podría estar interesado en dividir una sección en dos o más subsecciones.
Hablaremos más sobre las secciones algo más adelante en el curso.
󲐀 Grupos: Al insertar un grupo en el informe, en realidad (como veremos a continuación) se crean tres
elementos diferentes: la sección de Encabezado de grupo y Pie de grupo correspondiente, más un campo
de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar.
󲐀 Resúmenes: Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos)
de los valores de un campo de la base de datos.
󲐀 Tablas cruzadas: Una tabla cruzada permite mostrar 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. Generalmente las tablas cruzadas se insertan en la sección de Pie del informe.
󲐀 Gráficos: Crystal Reports permite incorporar a los informes diversos tipos de gráficos comerciales (de
líneas, barras, tarta, etc.) basados en los registros obtenidos de la base de datos. Generalmente los
gráficos se colocan en la sección de Pie del informe o algún Pie de grupo.

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.

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas:


󲐀 El botón de Exportar, que permite exportar el resultado del informe a diferentes formatos como
Microsoft Excel, Microsoft Word, texto enriquecido (.RTF) o Adobe PDF.
󲐀 El botón de Imprimir, que permite seleccionar una impresora y enviar a ella el informe para así obtener
una copia en papel.
󲐀 El botón de Árbol de grupos, que permite mostrar u ocultar el árbol de grupos, banda situada a la
izquierda del visor (ahora vacía, puesto que nuestro informe inicial no tiene grupos). En un informe con
grupos, en esta banda se situarán los nombres de los diferentes grupos existentes en el informe, en forma
de hiperenlaces a la página del informe en la que comienzan los datos correspondientes a cada uno de los
grupos. Por ejemplo, en un listado de clientes agrupados por países, en el Árbol de grupos aparecerá cada
uno de los nombres de los países en los que hay clientes, y podríamos saltar a ver los clientes de cada país
con un simple clic de ratón.
󲐀 Los botones de navegación, que permiten desplazarse hacia delante y hacia atrás por las páginas del
informe. Tenga en cuenta que la generación de las páginas de un informe se produce dinámicamente, a
medida que va siendo necesario; desplazarse a la última página del informe provocará que se generen
todas y cada una de las páginas (que el motor de Crystal almacena en memoria para su posterior
reutilización).
󲐀 Un cuadro de texto que nos muestra la página actual y también nos permite teclear un número para
saltar a cualquier otra página.
󲐀 El botón de Detener carga, que sólo está activo mientras se está cargando el informe, con el objetivo
de que podamos cancelar la carga de datos si ya hemos visto lo que queríamos ver o hemos detectado un
error en el informe.
󲐀 El botón de Actualizar (refrescar) informe, que nos permitirá regenerar el informe desde cero (por
ejemplo, para obtener una versión más actual del informe en caso de que los datos de la base de datos
hayan cambiado).
󲐀 El cuadro de combinación de Zoom, que nos permitirá establecer la escala de visualización de las
páginas del informe.
Este Visor de informes es casi el mismo que verán los usuarios de nuestras aplicaciones Windows que
incluyan informes Crystal Reports cuando ordenen la visualización de un informe; desde programa,

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).

EJEMPLO BÁSICO DE APLICACIÓN WINDOWS


Estamos utilizando el Diseñador de Crystal Reports embebido en Visual Studio, y no vamos a dejarle con
la miel en los labios, sino que mostraremos ahora un sencillo ejemplo de cómo alcanzar uno de los
objetivos finales de este curso, que es integrar los informes Crystal dentro de una aplicación Windows. El
proceso en relativamente muy simple, y muestra la potencia de la programación basada en componentes
que Visual Studio promueve.
Seleccione el formulario principal (y único) de la aplicación y configure sus tres o cuatro propiedades
principales (título, estilo, dimensiones, posición inicial). Luego coloque sobre el formulario un
componente de la clase CrystalReportsViewer (ficha Crystal Reports). Encaje el visor en el área cliente de
la ventana para que la llene completamente.
CrystalReportsViewer es un componente que encapsula el visor de Crystal Reports para aplicaciones
Windows. Configuremos sus propiedades principales:

󲐀 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.

TÉCNICAS FUNDAMENTALES DE DISEÑO DE INFORMES


En este tema se presentan las técnicas fundamentales que necesitará dominar perfectamente el
programador que diseñe informes de Crystal Reports, pues se presentan en la práctica con mucha
frecuencia.

INFORMES CON MÚLTIPLES TABLAS


Rara es la ocasión en que todos los datos necesarios para presentar en un informe se pueden obtener de
una misma tabla de la base de datos. Las metodologías modernas de diseño de bases de datos
relacionales favorecen la normalización, y esa técnica promueve la separación de la información en
diferentes tablas para evitar problemas de redundancia e inconsistencia. Generalmente, al diseñar un
informe necesitaremos combinar la información proveniente de la tabla principal con los contenidos de al
menos uno o más catálogos u otras tablas de propósito general.
Por ejemplo, la base de datos AdventureWorks agrupa los productos por subcategorías y categorías.
Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados, inicialmente,
por subcategorías. La tabla Products incluye un campo ProductSubcategory en la que se almacena el
código de subcategoría, una clave externa (foránea) a otra tabla de la base de datos,
Production.ProductSubcategory. Si queremos mostrar en el informe los nombres de las subcategorías
en lugar de sus códigos, tendremos que indicarle a Crystal Reports que obtenga la información
correspondiente, cruzando la tabla de productos con la de subcategorías.

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.

MÁS SOBRE LAS SECCIONES. PROFUNDIZACIÓN


Las secciones como un todo también tienen un conjunto de propiedades que podemos configurar para
mejorar la apariencia y funcionalidad de nuestros informes. Para ello, es necesario utilizar el Asistente de
sección, disponible en el menú de Crystal Reports en Report | Asistente de sección. El Asistente de
15
sección muestra todas y cada una de las secciones (y subsecciones, posiblemente) de nuestro informe y
nos permite establecer para cada una de ellas todo un conjunto de propiedades como:
󲐀 suprimir la sección completamente. Por ejemplo, en nuestro informe la sección de Pie de grupo del
grupo interno ha quedado vacía y lo mejor es suprimirla.
󲐀 provocar un salto de página antes o después de imprimir la sección.
󲐀 ajustar la sección a la parte inferior de la página (lo que implica que el contenido de la próxima sección
pasará a la página siguiente)
󲐀 reiniciar la numeración de las páginas después de imprimir la sección.
󲐀 mantener unido todo el contenido de la sección, aunque haya que cambiar de página para ello.
󲐀 suprimir la sección en caso de que no contenga nada.
󲐀 hacer que el contenido de la sección subyazca al de las siguientes secciones; más adelante utilizaremos
esta opción para provocar un efecto de “marca de agua” en todas las páginas del informe.
󲐀 Por último, queríamos hacer especial énfasis en la opción ‘Ocultar (se permite profundizar)’, que nos
parece especialmente importante. Tenga en cuenta que cada vez más los informes no se destinan a ser
presentados en papel, sino a ser consumidos de forma interactiva. Esta opción, al igual que ‘Suprimir’,
hace que una sección no se muestre cuando se presente el informe; pero a diferencia de la anterior,
permite que el usuario, haciendo clic con el ratón sobre un elemento de nivel superior (generalmente, un
nombre de grupo o resumen), despliegue el contenido de esa sección oculta en una vista independiente.
Por ejemplo, marquemos con la opción ‘Ocultar (se permite profundizar)’ a la sección de detalles de
nuestro informe y veamos el efecto que se obtiene: a primera vista, el informe sólo contiene los
resúmenes; pero si el usuario pulsa sobre cualquiera de los nombres de subcategorías, verá los productos
pertenecientes a esa subcategoría en una nueva pestaña del visor. Esto es a lo que se le llama
“profundización” (drill down).
Desde el Asistente de sección también tenemos la posibilidad de insertar y eliminar (sub)secciones. El
objetivo de la opción ‘Insertar’ de menú, como hemos mencionado antes, es realmente el de que
podamos dividir una sección en subsecciones con el objetivo de aplicarles distintos valores de
propiedades a cada subsección. Veamos un ejemplo típico. Supongamos que queremos poner el logotipo
de nuestra empresa como “marca de agua” en el centro de todas las páginas del informe. Para ello,
seguiremos los siguientes pasos:
a) Dividiremos la sección de Encabezado de página (que, como sabemos, se imprime en la parte superior
de cada página del informe) en dos subsecciones. Para ello, seleccionamos la sección de Encabezado de
página y pulsamos el botón ‘Insertar’. Verá que la sección se divide en dos subsecciones, denominadas ‘a’
y ‘b’, y todo lo que hubiera en la sección original es pasado a la subsección ‘a’.
b) Configuraremos la nueva subsección ‘b’ (y solo ella) para que subyazca al resto de las secciones (opción
‘Situar debajo de las secciones posteriores’).
c) Ya en el Diseñador, ampliaremos por la vertical la subsección ‘b’ del encabezado y pondremos cerca del
borde inferior el logotipo de nuestra empresa.
¡Listo! Si activa la Vista previa, verá que el logotipo subyace perfectamente a todas las páginas del
informe.

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.

SELECCIÓN Y ORDENACIÓN DE GRUPOS


A diferencia de la selección de registros, que incluye o excluye del informe registros individuales en base a
una condición, la selección de grupos permite establecer qué grupos enteros deben o no ser incluidos en
el informe. En términos de SQL, si la formula de selección de registros corresponde a la cláusula WHERE
de una sentencia SELECT, entonces la fórmula de selección de grupo corresponde a la cláusula HAVING.
El Asistente de selección determina que una fórmula de selección es de grupo si el campo de Crystal
Reports que utilizamos en la condición es un campo normal de la base de datos o un resumen. En este
último caso, está claro que se trata de una condición de selección de grupo. Por ejemplo, supongamos
que nos interesan únicamente las categorías con más de 50 productos. En el Asistente de selección,
pulsamos ‘Nuevo’ para agregar una nueva condición; en el diálogo de selección de campo que aparece,
elegimos el recuento de productos por nombre de categorías, y en los siguientes desplegables
introducimos ‘es mayor que’ y el valor 50. Al pulsar el botón ‘Mostrar fórmula’, veremos la fórmula
Crystal correspondiente a la condición especificada. Por otra parte, una ojeada a la Vista previa nos
convencerá de que la selección funciona.
Nota avanzada: Por lo general (al menos en informes de tipo “listado”), el motor de Crystal Reports
ejecuta la agrupación y la selección de grupos en la máquina cliente. Existe una opción de configuración,
‘Realizar agrupamiento en el servidor’ (Report | Opciones del informe del menú), mediante la cual se
indica al motor que utilice cláusulas GROUP BY y HAVING cuando sea posible. Pero cuando es necesario
traer también los registros individuales para utilizarlos en el informe, el motor no hace uso de esa
posibilidad.
En cuanto a la ordenación de grupos, por defecto los grupos aparecen en el informe en el orden
determinado por el tipo de datos al que pertenece el campo por el que se agrupa. En nuestro ejemplo, las
categorías y subcategorías se presentarán en orden alfabético, dado que hemos agrupado por los
nombres, que son campos de cadena de caracteres. Frecuentemente, lo que se desea no es eso, sino
presentar los grupos en orden ascendente o descendente del valor de un resumen incorporado al
informe.
Para eso, Crystal Reports ofrece un Asistente de ordenación de grupos (botón en la barra de herramientas
‘Principal’, u opción Report | Asistente de ordenación de grupos en el menú).
Supongamos por ejemplo que deseamos presentar las categorías no en orden alfabético, sino en orden
descendente de la cantidad de productos diferentes pertenecientes a cada categoría. Lanzamos el
Asistente de ordenación de grupos, y veremos que nos presenta dos pestañas, dado que el informe
17
incluye dos grupos. El grupo que nos interesa es el externo, que es el preseleccionado por defecto. En el
desplegable ‘Ordenar’ seleccionamos Todo, y entonces a su derecha aparecerá la lista de los resúmenes
definidos a ese nivel, para que indiquemos el criterio según el que queremos ordenar los grupos. En
nuestro caso, habrá solo un resumen, que seleccionaremos. Adicionalmente, se nos permite indicar si
deseamos que los grupos aparezcan en orden ascendente o descendente (este último, nuestro caso).
Después de pulsar Aceptar podremos ver el resultado en la vista preliminar.
Hay que decir que este Asistente, además de la ordenación, también nos permite realizar una selección
de grupos según criterios que se utilizan con relativa frecuencia en la práctica y cuya especificación
mediante el Asistente de selección que hemos visto anteriormente requeriría la programación de
fórmulas de cierta complejidad. Si en lugar de elegir la opción ‘Todo’ en el desplegable ‘Ordenar’
seleccionamos ‘N superiores’ (‘N inferiores’), estaríamos indicando que deseamos incluir en el informe
solo los N primeros (últimos) grupos según el resumen indicado, en orden descendente (ascendente) de
los valores. Por otra parte, las opciones ‘Porcentaje máximo’ y ‘Porcentaje mínimo’ nos permiten limitar
el informe a aquellos grupos cuyo porcentaje sobre el total general supera o no supera un cierto valor P.
Tanto N como P pueden ser especificados según nuestra conveniencia. Observe además que existe la
posibilidad de agrupar los elementos que los grupos que no superen la “criba” en un grupo común, cuyo
nombre por defecto es ‘Otros’.

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.

EXPORTACIÓN A OTROS FORMATOS. WORD, EXCEL, HTML, PDF


Crystal Reports nos permite exportar los resultados de la ejecución de un informe a diferentes formatos.
Ciertos formatos (Microsoft Word, Adobe Acrobat, HTML) se utilizan mayormente con vistas a poner el
informe como tal a disposición de terceros; en otros casos (Microsoft Excel, Microsoft ODBC), el objetivo
es capturar los resultados numéricos que el informe contiene para realizar ciertas transformaciones
posteriores sobre ellos utilizando otras aplicaciones.
Si pulsa el botón de Exportar informe de la barra de herramientas del visor, le aparecerá un diálogo en el
que podrá elegir el formato de exportación y el destino (en la versión integrada en Visual Studio,
únicamente un fichero en disco). Un segundo diálogo específico para el formato de exportación elegido
aparecerá a continuación para permitirnos configurar el resultado. Y esto dará paso a un tercer cuadro de
diálogo en el que podremos elegir la ruta y el nombre del fichero a crear.
En los temas del curso dedicados a la programación veremos cómo exportar informes desde nuestras
aplicaciones.

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.

SINTAXIS DEL LENGUAJE DE FÓRMULAS CRYSTAL Y VISUAL BASIC


Una fórmula se compone a partir de diferentes elementos básicos, como son:
󲐀 Constantes: 12 (entero), 0.07 (número decimal), “Total” (cadena de caracteres), True (lógica),
#12/5/2006# (de fecha/hora).
󲐀 Identificadores, que pueden representar:
󲐀 Nombres de campos, con la sintaxis {NombreTabla.NombreCampo}. Por ejemplo, para representar al
campo Sexo de una tabla llamada Clientes, utilizaríamos {Clientes.Sexo}.
󲐀 Otras fórmulas, con la sintaxis {@NombreFormula}. Por ejemplo, si al definir la fórmula B necesitamos
utilizar otra fórmula A, la escribiríamos así {@A}.
󲐀 Totales acumulados, con la sintaxis {#NombreTotal}.
󲐀 Parámetros del informe, con la sintaxis {?NombreParametro}. Los parámetros juegan un papel esencial
en el desarrollo de informes genéricos que puedan utilizarse en múltiples situaciones diferentes sin
necesidad de modificaciones. A ellos les dedicaremos el Tema 5.
󲐀 Operadores: +, - (aritméticos), <, > (de comparación), Not, And, Or (lógicos), y otros.
󲐀 Funciones predefinidas: Crystal ofrece un amplio espectro de funciones de uso general incorporadas de
antemano al producto, de modo que el programador no tenga que “reinventar la rueda” cada vez que
quiera ejecutar una tarea más o menos trivial. Por ejemplo, si el campo Nombre de la tabla Clientes

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.

APLICACIONES DE LAS FÓRMULAS


En esta sección estudiaremos los fundamentos de las fórmulas de Crystal Reports y presentaremos sus
principales aplicaciones, que son:
󲐀 Campos calculados
󲐀 Formato condicional
󲐀 Selección de registros y grupos
󲐀 Grupos a medida
󲐀 Totales acumulados condicionales

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:

formula = {SalesOrderHeader.ShipDate} - {SalesOrderHeader.OrderDate}

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:

if {@DíasHastaSalida} >= 5 then formula = crRed else formula = crBlack

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:

if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite

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:

{SalesOrderHeader.OrderDate} >= #1/7/2004# and {SalesOrderHeader.OnlineOrderFlag}

Nota avanzada: Como hemos comentado anteriormente, es conveniente limitarse a fórmulas de


selección sencillas siempre que sea posible, pues Crystal Reports determina automáticamente cuándo es
posible traducir una fórmula de selección en una cláusula WHERE de SQL para pasarla al motor de bases
de datos, lo que redunda en una mayor eficiencia.

SELECCIÓN DE REGISTROS Y GRUPOS


Otra aplicación sumamente útil de las fórmulas son los grupos personalizados o a medida. De manera
predeterminada, los grupos de Crystal Reports están compuestos por registros que tienen un mismo valor
en el campo seleccionado. Sin embargo, frecuentemente se quieren agrupar los registros de forma que la
pertenencia a un mismo grupo venga dictada por otra condición que no es la estricta igualdad de los
campos. Esto es lo que hacen posible los grupos a medida de Crystal Reports.
Suponga que deseamos agrupar los registros del listado de pedidos en tres categorías: los de menos de 25
Euros, los que están entre 25 y 100, y los de más de 100 Euros. Debemos utilizar el botón ‘Insertar grupo’
de la barra de herramientas ‘Insertar’ (o seleccionar la opción correspondiente del menú). Como campo
para agrupar, seleccionamos SalesOrderHeader.TotalDue y como criterio de agrupación ‘en orden
específico’.
Aparecerá una nueva pestaña, en la que podremos crear nuestros grupos personalizados, indicando para
cada uno un nombre, y la condición (fórmula) de pertenencia de los registros a los grupos. En nuestro
caso, llamemos a los grupos PEQUEÑOS, MEDIANOS y GRANDES, y asociemos a cada grupo las
condiciones correspondientes. Al pulsar ‘Aceptar’ podremos comprobar que el grupo ha sido creado, y la
vista previa nos convencerá de que la agrupación se realiza correctamente.

TOTALES ACUMULADOS CON CONDICIONES


En el tema anterior estudiamos los totales acumulados, pero no profundizamos en la posibilidad de
asociarles fórmulas para indicar cuándo se desea evaluarlas y cuándo reiniciarlas a cero. Esta es una
posibilidad que conviene tener en cuenta para cuando sea necesaria.
Por ejemplo, suponga que queremos hacer que el total acumulado del listado de pedidos se reinicie cada
vez que se produzca un cambio de fecha. Previamente ordenamos el listado por el campo OrderDate,
utilizando el Asistente de ordenación. En este veremos que ya hay un criterio establecido, el del grupo
(recuerde la máxima “para agrupar, hay que ordenar”), pero podremos establecer la fecha como criterio
de ordenación secundario dentro de cada grupo.
Ahora seleccionemos nuestro total acumulado, pulsemos el botón derecho del ratón sobre él y
seleccionemos ‘Editar total acumulado’. En la zona ‘Restablecer’ (inferior derecha) marquemos la opción
23
‘Use una fórmula’ y pulse el botón de fórmula correspondiente. Introduzca la fórmula:

formula = PreviousValue({SalesOrderHeader.OrderDate}) <> {SalesOrderHeader.OrderDate}

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.

DEFINICIÓN Y USO DE PARÁMETROS


Para definir un parámetro, se debe pulsar con el botón derecho del ratón sobre el nodo ‘Campos de
parámetro’ del Explorador de campos y seleccionar la opción ‘Nuevo’. En el diálogo que aparece,
debemos introducir los siguientes datos:
󲐀 Nombre del parámetro. Llamemos al parámetro FechaInicio. Para referirse luego al parámetro desde
fórmulas, etc. se utilizará la sintaxis {?FechaInicio}.
󲐀 Texto de la solicitud. Antes de ejecutar un informe con parámetros, Crystal Reports preguntará los
valores a asignar a los parámetros. Aquí se debe introducir el texto que aparecerá en el diálogo de
pregunta, en este caso ‘Fecha de inicio’.
󲐀 Tipo de datos. El tipo de datos del parámetro, en este caso Fecha.
󲐀 Valores predeterminados. Aquí podemos especificar para el parámetro uno o más valores por defecto,
que se mostrarán en el cuadro de diálogo de solicitud de parámetros para que el usuario no tenga que
teclearlos.
󲐀 Opciones. Opciones avanzadas relacionadas con la utilización de múltiples valores.
Esa es una de las dos facetas de la utilización de un parámetro. La segunda es su utilización, y para ello
podemos hacer con el parámetro todo lo que podemos hacer con cualquier otro campo: arrastrarlo sobre
el informe o utilizarlo en cualquier fórmula. En nuestro ejemplo, la fecha de inicio forma parte de la
fórmula de selección de registros. Para hacer uso del parámetro, lanzamos el Asistente de selección y
sustituimos la fecha actualmente en uso por la sintaxis de uso del parámetro {?FechaInicio}. Solo resta
entonces mostrar la vista previa para cerciorarnos de que la definición del parámetro ha sido aceptada:
Crystal nos solicitará que indiquemos un valor para la fecha de inicio antes de mostrar el informe.

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.

UTILIZACIÓN DE INFORMES EN APLICACIONES WINDOWS


En este primer tema relacionado con la programación de aplicaciones que utilicen informes se presentan
los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de
escritorio.

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.

INCORPORACIÓN DE UN INFORME A UNA APLICACIÓN


Para este nuevo tema relacionado con la programación .NET, comenzaremos una nueva aplicación
Windows Forms en la que incluiremos un informe Crystal sencillo, puesto que ya hemos cubierto los
temas relacionados con el diseño de informes. Eso sí, el informe incluirá parámetros, ya que como hemos
dicho los parámetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de
aplicaciones.
En Visual Studio 2005, cierre la solución que tenga abierta y seleccione Archivo | Nuevo | Proyecto.
Cuando aparezca el cuadro de diálogo ‘Nuevo proyecto’ elija Visual Basic | Aplicación de Crystal Reports,
lo que nos ahorrará ciertos pasos que ya hemos visto en el tema 1. Llame al proyecto Ejemplo2 y póngalo
en el directorio adecuado.
Inmediatamente se presentará el Asistente de informes de Crystal, para que diseñemos el (primer)
informe que el proyecto contendrá. Definiremos en este caso un listado de pedidos similar al que ya
hemos hecho anteriormente: la tabla es Sales.SalesOrderHeader, y los campos que mostraremos son
SalesOrderID, OrderDate y TotalDue. No incluiremos fórmula de selección ni parámetros de momento; lo
haremos más adelante. Por ahora trabajaremos con un listado totalmente “plano”.
Al finalizar el diseño del informe, se nos presenta el entorno integrado de Visual Studio con una aplicación
que en principio ya funciona, como podemos comprobar.
¿Qué ha creado el asistente de proyectos Crystal para nosotros? Si mostramos la vista Diseño del
formulario Form1, veremos que en éste contiene dos componentes:
󲐀 Un componente no visual (por lo tanto, situado en la banda inferior del diseñador) llamado
CrystalReport11. ¿A qué clase pertenece este objeto? Para responder a esta pregunta, conviene pulsar el
botón ‘Mostrar todos los archivos’ en el Explorador de soluciones. Veremos que nuestro informe
CrystalReport1.rpt tiene un archivo de VB dependiente, y si abrimos ese archivo, en la vista de Código
veremos que contiene la definición de una clase llamada CrystalReport1 igual que el informe; se trata de
una clase que representa al informe concreto (en el argot de Crystal, se dice que la clase implementa un
informe tipado). El componente CrystalReport11 es de esa clase, y por lo tanto es un objeto que
representa a un informe como ése. En la siguiente sección hablaremos con más detalle sobre este objeto.
󲐀 Un componente visual que ocupa toda el área de la ventana y tiene como función presentar un informe
Crystal, llamado CrystalReportViewer1. La clase a la que pertenece es CrystalReportViewer (cuyo espacio
de nombres es CrystalDecisions.Windows.Forms). Se trata ni más ni menos que del visor de informes
Crystal para Windows – utilizaremos siempre objetos de esta clase para mostrar los informes en nuestras
aplicaciones de escritorio. Observe en la Ventana de propiedades que la propiedad ReportSource del
visor la apunta al componente CrystalReport11 (recordemos que al inicio del curso ya hemos visto algo
similar).
En principio, la construcción de estos objetos al crearse el formulario es suficiente para que veamos el
informe al ejecutar la aplicación.

EL MODELO DE OBJETOS DE CRYSTAL REPORTS.NET


El ejemplo anterior ya nos da una idea bastante completa de las librerías de clases para .NET de Crystal
Reports.
󲐀 Por una parte, una librería ofrece clases que representan a un informe como un todo
(ReportDocument) y a todos los objetos que componen un informe Crystal o participan en él.
Estas clases de propósito general se concentran fundamentalmente en el ensamblado
CrystalDecisions.CrystalReports.Engine.
26
󲐀 En segundo lugar, otra librería ofrece clases para la presentación de informes en aplicaciones Windows
Forms. Estas clases se almacenan en el ensamblado CrystalDecisions.Windows.Forms.dll y entre ellas
destaca una en específico – CrystalReportViewer, que implementa el visor de informes Windows.
󲐀 En tercer lugar, otra librería ofrece clases para la presentación de informes en aplicaciones Web
ASP.NET. Estas clases se almacenan en el ensamblado CrystalDecisions.Web.dll y entre ellas destaca
también una en específico – una que también se llama CrystalReportViewer, aunque su espacio de
nombres es diferente, y que implementa el visor de informes para aplicaciones Web.
Hablaremos más sobre esta clase en el siguiente tema.
Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio,
verá que actualmente (estamos trabajando en una aplicación Windows) aparecen dos: ReportDocument y
CrystalReportViewer. Un panorama similar se podrá observar cuando trabajemos en una aplicación Web,
sólo que entonces se tratará del otro visor de informes, el adecuado para aplicaciones Web.
En general, cuando se habla del modelo de objetos de Crystal Reports, se hace referencia únicamente a
las clases de la primera librería, cuyo uso es común tanto a las aplicaciones Windows como a las
aplicaciones Web. El modelo de objetos de Crystal contiene cientos de clases para representar con todos
sus detalles a todos los diferentes elementos que componen un informe o participan de algún modo en
él.
Por ejemplo, incluye una clase ParameterField para representar las características de un parámetro, y la
clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array
ParameterFields() mediante la que podríamos acceder a todos los parámetros de un informe.
INFORMES TIPADOS Y NO TIPADOS
Como acabamos de ver, la clase que juega un papel predominante en el modelo de objetos de Crystal
Reports es ReportDocument, que permite representar un informe. Ahora bien, esta clase representa a un
informe genérico, sin ninguna característica conocida de antemano. En Crystal a esta clase se la conoce
bajo el nombre de informe no tipado. Podríamos trabajar con nuestro listado de pedidos a través de un
objeto ReportDocument, pero perderíamos cierta información específica de nuestro informe concreto, y
tendríamos que referirnos a cualquier característica del informe a través de las propiedades y métodos
generales de ReportDocument.
A diferencia de lo anterior, la clase CrystalReport1 generada por el asistente e incluida en nuestro
proyecto (que hereda de ReportClass, que a su vez hereda de ReportDocument), representa un informe
tipado – una clase especializada a partir de ReportDocument que solo vale para nuestro informe
concreto, pero que almacena información sobre él que nos facilitan la vida. En particular, los informes
tipados contienen código que se encarga automáticamente de cargar el informe concreto, que se
almacena dentro del ejecutable en forma de recurso. Observe en el código fuente de CrystalReport1 la
propiedad ResourceName.
Como otro ejemplo, vea la definición de la propiedad Section1 de CrystalReport1. Observe ahora cómo el
uso de la clase tipada facilita el acceso a la primera sección del informe:

Dim doc As ReportDocument = CType(CrystalReport11, ReportDocument)


' estas dos líneas hacen lo mismo
MessageBox.Show(CrystalReport11.Section1.Name)
MessageBox.Show(doc.ReportDefinition.Sections(0).Name)

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.

INFORMES INCRUSTADOS Y EXTERNOS


Si selecciona un informe de Crystal Reports en el Explorador de soluciones, verá sus propiedades en la
Ventana de propiedades. Debemos mencionar dos muy importantes, cuyo significado conviene conocer.
La primera de ellas es Acción de generación. Verá que su valor predeterminado es ‘Recurso incrustado’.
Eso significa que cuando la aplicación es compilada la definición del informe es almacenada como un
recurso dentro del ensamblado principal del proyecto (en nuestro caso, del ejecutable). Por lo tanto, no
necesitaremos desplegar físicamente el fichero .rpt junto con el ejecutable cuando instalemos la
aplicación a otros usuarios, lo cual es más cómodo y más seguro. Como inconveniente, si necesitamos
hacer modificaciones a un informe incrustado, tendremos que recompilar la aplicación y volver a
desplegar el ejecutable.
La otra opción de esta propiedad que se utiliza con cierta frecuencia es ‘Ninguna’, para no incrustar el
informe en el ensamblado. En ese caso, a la propiedad Copiar en el directorio de resultado se le asigna el
valor ‘Copiar siempre’ o ‘Copiar si es posterior’, con el objetivo de que el fichero .rpt sea copiado al
mismo directorio que el ejecutable o librería final. Para un correcto funcionamiento de la aplicación, el
fichero .rpt siempre deberá ir junto con el ejecutable. La ventaja de este enfoque es que se podría enviar
una nueva versión del informe al usuario sin necesidad de redesplegar toda la aplicación. Y el peligro está
en que el informe podría ser borrado o alterado con o sin mala intención.
Para cargar la definición de un informe externo a un objeto ReportDocument o una clase derivada
(informe tipado) se utiliza el método Load:

' carga cualquier informe externo en un ReportDocument no tipado


ReportDocument1.Load("CrystalReport1.rpt")
ReportDocument1.Refresh()
CrystalReportViewer1.ReportSource = reportDocument1

CONEXIÓN A LA BASE DE DATOS


La clase ReportDocument (y por herencia, todos los informes tipados, que heredan de ella), ofrecen un
método SetDatabaseLogon que permite suministrar al motor de Crystal Reports la información de
conexión necesaria para acceder a la base de datos donde están los datos que necesita el informe.
Este método ofrece dos variantes fundamentales, que permiten indicar:
󲐀 a) Usuario y contraseña. El informe se ejecutará contra el servidor y base de datos definidos dentro del
informe.
󲐀 b) Servidor, Base de datos, Usuario y contraseña. El informe se ejecutará contra el servidor y base de
datos especificados. Esta variante es más útil en situaciones donde tenemos una base de datos de
desarrollo y otra de producción.
Si en nuestro ejemplo necesitáramos suministrar información de conexión para ejecutar el informe,
deberíamos desconectar el visor de informes de CrystalReport11 en tiempo de diseño y programar lo
siguiente en el evento Load del formulario:

CrystalReport11.SetDatabaseLogon(".\SQLExpress", "AdventureWorks", "sa", "kk")


' conexión del visor en tiempo de ejecución
CrystalReportViewer1.ReportSource = CrystalReport11

PASO DE PARÁMETROS EN TIEMPO DE EJECUCIÓN

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:

{SalesOrderHeader.OrderDate} in {?FInicio} to {?FFin}

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.

EXPORTACIÓN DE INFORMES MEDIANTE CÓDIGO


Otra de las técnicas comúnmente requeridas por los desarrolladores es la posibilidad de exportar el
informe a un formato de presentación diferente, tradicionalmente Adobe PDF o Microsoft Word o Excel.
Aquí de nuevo viene en nuestra ayuda la clase ReportDocument, que ofrece varios métodos que nos
facilitan la tarea.
El método Export() es el más potente de la familia, y a la vez el mas complejo de utilizar. Permite
especificar, además del destino de la exportación, otras características de la exportación que son útiles
sobre todo cuando se exporta a Excel. Adicionalmente, tenemos los métodos ExportToDisk(),
ExportToStream() y ExportToHttpResponse(), que simplifican la exportación de informes a un fichero en
disco, un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicación o servicio Web.
Para exportar nuestro informe a un fichero en formato PDF, podremos escribir:

' exportar a PDF


CrystalReport11.ExportToDisk( CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, _
"C:\PEDIDOS.PDF")

El primer parámetro es de un tipo enumerado que determina el formato de exportación.

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.

CONFIGURACIÓN DEL VISOR DE INFORMES


El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquí. La primera,
ReportSource, tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar; las demás
tienen relación con la estética de presentación del informe.
󲐀 ReportSource: esta propiedad indica al visor de dónde debe obtener el informe a mostrar. Es una
propiedad de tipo Object, porque se le puede asignar diferentes valores:
󲐀 Una cadena de caracteres que representa el nombre del fichero que contiene el informe.
Esta variante es la más simple y primitiva de todas; existe desde la primera versión de la librería.
Utilizando esta opción es posible saltarse completamente el modelo de objetos de Crystal.
󲐀 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado). Esta
variante es la que estamos presentando aquí.
󲐀 A continuación, tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben
aparecer o no:
󲐀 DisplayGroupTree – si se debe mostrar o no el Árbol de grupos (en caso de que el informe tenga
grupos).
󲐀 DisplayStatusBar – si se debe mostrar o no la barra de estado.
󲐀 DisplayToolbar – si se debe mostrar o no la barra de herramientas.
󲐀 Por último, tenemos varias propiedades booleanas que determinan qué botones de la barra de
herramientas deben aparecer o no:
󲐀 ShowCloseButton – mostrar o no el botón de Cerrar.
󲐀 ShowExportButton – mostrar o no el botón de Exportar.
󲐀 ShowGotoPageButton – mostrar o no el botón de Ir a página.
󲐀 ShowGroupTreeButton – mostrar o no el botón de Mostrar Árbol de grupos.
󲐀 ShowPageNavigateButtons – mostrar o no los botones de navegación por las páginas.
󲐀 ShowPrintButton – mostrar o no el botón de Imprimir.
󲐀 ShowRefreshButton – mostrar o no el botón de Actualizar.
󲐀 ShowTextSearchButton – mostrar o no el botón de Buscar texto.
󲐀 ShowZoomButton – mostrar o no el botón de Acercar/Alejar.

INFORMES A PARTIR DE UN DATASET


Los informes Crystal que hemos presentado hasta ahora han obtenido sus datos directamente de la base
de datos en el momento necesario. Pero los informes de Crystal Reports pueden nutrirse de muchas otras
diversas fuentes de información. En particular, un informe Crystal puede obtener sus datos de un DataSet
(conjunto de datos) de ADO.NET, lo cual es muy conveniente porque las arquitecturas de múltiples capas
de uso común en la práctica actual favorecen la utilización de objetos de este tipo para la transmisión de
información entre capas, y generalmente se los puede encontrar en la capa de presentación de las
aplicaciones, que es donde se muestran los informes.
Si creamos un nuevo informe con el Asistente, veremos que en la lista de los posibles orígenes de datos a
utilizar para un informe hay un nodo ‘ADO.NET DataSets’ dentro del cual se muestran todos las clases
derivadas de DataSet (los llamados conjuntos de datos tipados) disponibles en el proyecto. Como los
conjuntos de datos tipados contienen metadatos que describen su estructura, el Diseñador de Crystal es
capaz de acceder a ella para permitirnos seleccionar las tablas, campos, etc. con los que queremos
trabajar.

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()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES


CRYSTAL
Una vez terminado el desarrollo de una aplicación, llega el momento del despliegue. Con ese objetivo,
Visual Studio ofrece diferentes tipos de proyectos de instalación que permiten empaquetar los ficheros
que se deben copiar al equipo de destino, así como la secuencia de comandos que se deben ejecutar en
éste para que la aplicación quede lista para funcionar en la máquina de destino.
En lo concerniente a Crystal Reports, para desplegar correctamente cualquier aplicación .NET que utilice
informes Crystal es necesario incluir en el programa de instalación:
󲐀 las librerías .NET de Crystal Reports.
󲐀 los ficheros .RPT que sean externos a la aplicación.
Creemos un nuevo proyecto de instalación para desplegar nuestra reciente aplicación Ejemplo3. Para
ello, lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalación
debajo del nodo Otros tipos de proyectos | Instalación e implementación. Llamemos al proyecto
Instalar3 y pulsamos Aceptar. Se presentará un editor especializado en el que debemos especificar qué
ficheros, accesos directos, etc. queremos colocar en qué directorios del equipo de destino.
Generalmente, el ejecutable y los ensamblados privados que componen la aplicación se colocan en la
carpeta de la aplicación, y opcionalmente se colocan accesos directos al ejecutable en el menú Programas
o el escritorio del usuario.
Ante todo, debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las
propiedades básicas del proyecto, sobre todo Manufacturer (fabricante) y Product Name (nombre del
producto), que determinarán la carpeta de aplicación por defecto (\[Archivos de programa]\[Fabricante]
\[NombreProducto]). Para agregar archivos a la carpeta de la aplicación, pulsamos el botón derecho sobre
ella y seleccionamos la opción Agregar. En este caso sencillo, utilizamos la opción Archivo para añadir el
único archivo necesario, el ejecutable Ejemplo3.exe (el informe Crystal utilizado está como recurso
incrustado).
Ahora debemos seleccionar la opción Proyecto | Propiedades del menú de Visual Studio. La mayor parte
de las opciones del diálogo que aparece son satisfactorias, pero sí debemos pulsar el botón Requisitos
previos, que nos permite indicar qué software debe incluirse en nuestro proyecto para instalarlo en la
máquina de destino si no estuviera ya instalado. Además de .NET Framework 2.0 (que ya deberá estar
marcado), debemos marcar la casilla correspondiente a Microsoft Data Access Components 2.8
(necesario para .NET) y la casilla de Crystal Reports para .NET Framework 2.0.
Pulsamos Aceptar dos veces para cerrar los cuadros de diálogo, y ¡ya casi está! Solo nos queda
seleccionar la opción Generar | Generar de Visual Studio para generar el proyecto de instalación.
El proyecto de instalación siempre consiste de una jerarquía de carpetas con todos los recursos
necesarios para la instalación, empaquetados o no, según las opciones que hayamos seleccionado. En
cualquier caso, en el directorio raíz siempre se incluye un fichero Setup.exe, que es el que debemos
ejecutar en la máquina de destino para proceder a la instalación de la aplicación.

UTILIZACIÓN DE INFORMES EN APLICACIONES WEB

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.

INCORPORACIÓN DE UN INFORME A UNA APLICACIÓN


Para mostrar cómo incorporar un informe Crystal Reports a una aplicación Web, comenzaremos un nuevo
sitio Web ASP.NET ubicado en el sistema de archivos. Al pulsar Archivo | Nuevo | Sitio Web verá que
existe una plantilla ‘Sitio Web ASP.NET de Crystal Reports’ que nos haría aún más fácil la vida; aquí vamos
a evitarlo para estudiar el mecanismo a utilizar en el caso general. Seleccione la plantilla genérica ‘Sitio
Web ASP.NET’, y llame al directorio EjemploWeb (puede ubicarlo en la zona del disco que desee, una de
las grandes ventajas de Visual Studio 2005 a la hora de crear aplicaciones Web).
A continuación, agregaremos al proyecto un nuevo informe Crystal, que llamaremos Paises.rpt y mostrará
un listado sencillo de los países/regiones almacenados en la tabla Person.CountryRegion de
AdventureWorks. En el caso de las aplicaciones Web, es conveniente colocar todos los informes del
proyecto dentro de una carpeta común, que llamaremos ‘informes’. Una vez diseñado el informe,
podemos arrastrarlo hacia esa carpeta.
Llega la hora de configurar la página Web actual, Default.aspx, para que muestre nuestro informe cuando
ejecutemos la aplicación. Para ello, veamos primero qué componentes debemos seleccionar del nodo
‘Crystal Reports’ del Cuadro de herramientas en el caso de una aplicación Web.
En primer lugar, para mostrar un informe en una página ASPX necesitaremos un componente
CrystalReportSource (‘origen de informe Crystal’). Se trata de un componente que encapsula un objeto
de la clase ReportDocument que hemos estudiado antes, dotándonos a la vez de propiedades adicionales
que son de gran utilidad en el mundo de las aplicaciones Web. Vamos a arrastrar un componente
CrystalReportSource sobre la vista de Diseño de la página ASPX. A continuación pulsamos sobre el enlace
a su utilidad de configuración, y veremos que sólo ofrece una opción: ‘Configurar el origen del informe’,
donde debemos indicar a qué informe del proyecto queremos asociarlo.
Entre las propiedades que ofrece la clase CrystalReportSource, debemos destacar:
󲐀 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos). Si
EnableCaching es verdadera, el motor de CrystalReports “cacheará” en la memoria del servidor el
resultado de la ejecución de un informe durante el intervalo indicado en CacheDuration, no teniendo que
ejecutar el informe nuevamente si se recibe otra petición del informe antes de que expire el intervalo.
Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web.
󲐀 Report. Es una propiedad que integra varias características del informe, como el nombre del fichero de
informe, los parámetros y orígenes de datos de los que se nutre. Se trata mayormente de información
descriptiva; para el tratamiento programático del informe recomendamos utilizar la propiedad
ReportDocument.

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).

CONFIGURACIÓN DEL VISOR DE INFORMES HTML


Una vez configurado el objeto CrystalReportSource, llega el momento de poner sobre la página ASPX el
componente que permitirá mostrar en el navegador el resultado de la ejecución del informe. Para ello
necesitaremos el componente CrystalReportViewer (nodo ‘Crystal Reports’ del Cuadro de herramientas).
Observe que aunque el nombre corto de esta clase es el mismo de la que se utiliza en las aplicaciones
Windows, no se trata ni mucho menos de la misma clase; su nombre completo es
CrystalDecisions.Web.CrystalReportViewer.
La tarea del componente CrystalReportViewer es generar código HTML + Javascript que pueda ser
mostrado por un navegador estándar. Le recomendamos ejecutar la aplicación Web y utilizar la opción
Ver | Código fuente del navegador para cerciorarse de que la interfaz de usuario está “hecha” con HTML.
La siguiente imagen muestra la barra de botones del visor Web; el significado de los botones es
intuitivamente claro.
Cuando arrastramos un componente CrystalReportViewer sobre una página ASPX, automáticamente se
lanza el asistente para su configuración; lo primero que debemos indicar es a qué origen de informe
queremos conectarlo (en nuestro caso, el origen recién creado). Esta conexión se establece a través de la
propiedad ReportSourceID del visor. El resto de las propiedades del visor tiene que ver con la
visualización en sí; a continuación detallamos las propiedades más importantes:
󲐀 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe
a mostrar.
󲐀 SeparatePages – indica si los registros del informe deben separarse en páginas, o si todos deben ir
contiguos, como en una sola gran página.
󲐀 ClientTarget – determina el código que emitirá el componente para enviar al navegador. Si sabemos
que algunos usuarios utilizan navegadores antiguos o limitados, podemos asignar a esta propiedad el
valor Downlevel; por el contrario, si sabemos que todos utilizan navegadores avanzados, el valor
adecuado puede ser Uplevel; en general, lo mejor es mantener el valor Auto, donde el propio
componente determina qué tipo de HTML generar en función del navegador que hace la llamada.
󲐀 PrintMode – el método que se utilizará para la impresión local de los informes: ActiveX o Pdf. Se
recomienda utilizar este último valor.
󲐀 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diálogo
emergentes para solicitar la información que pueda faltarle para la ejecución del informe. Teóricamente,
nunca deberíamos dejar que estos diálogos aparecieran, sino que deberíamos suministrar los datos por
programa (por ejemplo, en el evento Load de la página) utilizando los métodos ya estudiados de la clase
ReportDocument:
󲐀 EnableDatabaseLogonPrompt – si debe solicitarse el usuario y contraseña de conexión en caso
necesario.
󲐀 EnableParameterPrompt – si deben solicitarse valores para los parámetros que carezcan de ellos.
󲐀 A continuación, tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben
aparecer o no:
󲐀 DisplayGroupTree – si se debe mostrar o no el Árbol de grupos (en caso de que el informe tenga
grupos).
󲐀 DisplayPage – si se debe mostrar o no la página del informe.
󲐀 DisplayToolbar – si se debe mostrar o no la barra de herramientas.

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.

VISUALIZACIÓN DIRECTA EN FORMATO PDF


Si probamos las opciones de Exportar o Imprimir del visor de informes Web, veremos que presentan un
cuadro de diálogo para que el usuario final seleccione el formato de exportación o el rango de páginas,
entre otras características. Frecuentemente quisiéramos que la exportación a PDF (un formato de amplia
popularidad) se produjera de manera automática y que en el navegador apareciera directamente el
resultado. Esta técnica nos permitiría incluso obviar la utilización del visor. Aquí mostraremos cómo
hacerlo.
Sobre la página con la que estamos trabajando, colocaremos un botón y le asignaremos el título ‘PDF’.
Programe el evento Click del botón de la siguiente forma:

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click


' nombre de fichero único
Dim nombre As String = "C:\temp\" & Session.SessionID & ".pdf"
' exportamos a PDF
CrystalReportSource1.ReportDocument.ExportToDisk( _
CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, nombre)
' enviamos el fichero PDF al navegador
Response.ClearHeaders()
Response.ClearContent()
Response.ContentType = "application/pdf" ' tipo MIME
Response.WriteFile(nombre) ' contenido
Response.Flush()
Response.Close()
End Sub

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.

DESPLIEGUE DE APLICACIONES WEB QUE INCLUYAN INFORMES CRYSTAL


El despliegue de aplicaciones Web que utilizan informes Crystal es realmente muy similar al despliegue de
aplicaciones Windows, pero generalmente causan muchísimo menos dolores de cabeza, dado que las
aplicaciones Web se desplieguen de forma centralizada en un servidor.
En lugar de crear un nuevo Proyecto de instalación, se debe utilizar un nuevo Proyecto de programa de
instalación Web. En general, es un tipo de proyecto muy similar al anterior, con modus operandi y
resultados similares. En el caso de una aplicación Web, para su correcto despliegue es necesario incluir en
el proyecto todos los ficheros que forman parte de la carpeta de la aplicación y sus subcarpetas,

34
incluyendo en nuestro caso los ficheros .rpt (que en las aplicaciones Web siempre se almacenan como
ficheros externos).

35