Top Banner
1 ¡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
35

Crystal Report - Curso Practico

Dec 27, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Crystal Report - Curso Practico

1

iexclBIENVENIDO AL CURSO DESARROLLO DE INFORMES DE DATOS CON CRYSTAL REPORTS NET Este curso le ofrece todos los conocimientos que necesita para disentildear informes de datos Crystal Reports e incorporarlos en sus aplicaciones NET (tanto Windows como Web) En este curso aprenderaacute 992256 Coacutemo crear informes de datos utilizando el disentildeador de informes integrado en Visual Studio 2005 992256 Coacutemo utilizar los componentes que ofrece Crystal Reports para incorporar esos informes en aplicaciones NET 992256 Coacutemo crear instaladores para esas aplicaciones para facilitar su despliegue REQUISITOS Para una correcta asimilacioacuten de los contenidos del curso el alumno deberaacute estar familiarizado con los conceptos fundamentales de la programacioacuten en Visual Basic NET y con el entorno de desarrollo Visual Studio 2005 Igualmente deberaacute 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 siacute muy conveniente REQUISITOS DE SOFTWARE Crystal Reports NET viene incluido uacutenicamente en la edicioacuten Profesional de Visual Studio 2005 si se dispone de una edicioacuten inferior la alternativa es adquirir de manera independiente el producto Crystal Reports Developer e instalarlo sobre cualquier versioacuten de Visual Studio 2005 Como motor de bases de datos el curso utiliza Microsoft SQL Server 2005 cualquiera de sus ediciones es vaacutelida (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 edicioacuten Express puede descargarla desde aquiacute

INTRODUCCIOacuteN A CRYSTAL REPORTS NET En esta primera leccioacuten aprenderaacute queacute es Crystal Reports las particularidades de su versioacuten para NET Framework su arquitectura y las posibilidades que ofrece para el disentildeo y ejecucioacuten de informes de datos La leccioacuten consta de los siguientes temas 992256 Coacutemo crear informes de datos utilizando el disentildeador de informes integrado en Visual Studio 2005 992256 Coacutemo utilizar los componentes que ofrece Crystal Reports para incorporar esos informes en aplicaciones NET 992256 Coacutemo crear instaladores para esas aplicaciones para facilitar su despliegue

QUEacute ES CRYSTAL REPORTS Crystal Reports es una herramienta potente a la vez que faacutecil de usar para el disentildeo y generacioacuten de informes a partir de datos almacenados en una base de datos u otra fuente de informacioacuten Es con diferencia la herramienta maacutes popular en su categoriacutea y no solo entre quienes podriacutean considerarse sus ldquousuariosrdquo puros (aquellos que necesitan obtener perioacutedicamente informacioacuten para la toma de decisiones a partir de los datos de la empresa) sino tambieacuten entre los programadores que lo han convertido en su herramienta favorita a la hora de embeber capacidades de generacioacuten de informes dentro de las aplicaciones a medida A este uacuteltimo hecho indudablemente ha contribuido mucho el que desde hace maacutes de diez antildeos Crystal Reports venga siendo incorporado ldquode serierdquo a las herramientas de desarrollo de Microsoft (Visual Basic y luego Visual Studio) Con la aparicioacuten de NET Framework una transformacioacuten revolucionaria de las tecnologiacuteas de desarrollo de Microsoft los fabricantes de Crystal Reports se dieron a la tarea de adaptar el producto a los nuevos

2

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 ldquoCrystal Reports NETrdquo Este curso tiene dos objetivos fundamentales 992256 Ensentildearle a utilizar el disentildeador de Crystal Reports integrado en Visual Studio 2005 para crear informes de datos potentes y flexibles 992256 Mostrarle coacutemo incorporar esos informes en sus aplicaciones NET para Windows y la Web utilizando como lenguaje de programacioacuten a Visual Basic

ARQUITECTURA COMPONENTES PRINCIPALES La arquitectura de Crystal ReportsNET gira alrededor del soporte para un tipo de ficheros de formato propietario que se distingue por la extensioacuten RPT (report) y en el que se almacena la definicioacuten de los informes El producto se puede ver como la combinacioacuten de tres componentes principales que son 992256 El Motor de Impresioacuten (Crystal Reports Print Engine CRPE) A pesar de lo que su nombre sugiere este componente escrito en coacutedigo no administrado no soacutelo se encarga de lo relacionado con la impresioacuten en papel de los informes sino ademaacutes con todo lo que tiene que ver con la ejecucioacuten de los mismos empezando por el acceso a la base de datos para leer la informacioacuten y continuando con la generacioacuten de la imagen de las diferentes paacuteginas para luego volcarlas en pantalla papel o exportarlas a otros formatos como Adobe PDF o Microsoft Word 992256 Las Libreriacuteas de Coacutedigo Manejado encapsulan la funcionalidad del Motor de Impresioacuten a traveacutes de un conjunto de clases faacutecilmente accesibles desde aplicaciones escritas en Visual Basic C o cualquier otro lenguaje NET Estas son las libreriacuteas que utilizaremos desde nuestras aplicaciones o servicios (para Windows o la Web) para cargar ejecutar e imprimir los informes 992256 Por uacuteltimo el Disentildeador de Informes es el software que presenta la interfaz de usuario a traveacutes de la cual un usuario programador o no puede crear (ldquodisentildearrdquo) un informe y guardarlo en un fichero RPT para su posterior reutilizacioacuten Se trata de una aplicacioacuten sofisticada repleta de potentes asistentes que garantizan una alta productividad sin limitar las posibilidades a nuestra disposicioacuten La versioacuten del Disentildeador que incluye Crystal ReportsNET se integra perfectamente dentro de Visual Studio 2005 permitiendo creando una experiencia auacuten maacutes aacutegil y productiva

Arquitectura de Crystal Reports

POSIBILIDADES DE ACCESO A DATOS Y EXPORTACIOacuteN

3

Indudablemente otra de las caracteriacutesticas que han hecho tan popular a Crystal Reports es la amplia gama de oriacutegenes de datos que soporta asiacute como de formatos de salida a los que se pueden exportar los resultados El Motor de Impresioacuten de Crystal Reports tiene una arquitectura modular y se apoya en controladores (drivers) independientes para acceder a los diversos oriacutegenes de datos soportados y generar los informes en los diferentes formatos de salida posibles Las posibilidades de acceso a diferentes oriacutegenes de datos sobrepasan ampliamente la mera capacidad para comunicarse con bases de datos (praacutecticamente todos los sistemas de bases de datos tanto relacionales como ldquoplanosrdquo estaacuten soportados) y abarcan desde la lectura de todo tipo de bitaacutecoras (logs) por ejemplo las producidas por los servidores Web para el seguimiento de la navegacioacuten de los usuarios hasta el acceso a objetos en memoria generados por las aplicaciones que hospedan al Motor de Impresioacuten Por ejemplo en este curso veremos coacutemo 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 Impresioacuten 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 tambieacuten 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 auacuten no podemos prescindir del papel ni mucho menos la presentacioacuten de informes se estaacute convirtiendo cada vez maacutes en una tarea interactiva Las versiones maacutes recientes de Crystal Reports incluyen numerosas facilidades que veremos en este curso (Aacuterbol de grupos elementos con hiperenlaces) y que estaacuten orientadas uacutenica y exclusivamente a la visualizacioacuten de informes en una ventana de Windows o en un navegador Web

LIBRERIacuteAS DE CRYSTAL REPORTS Las libreriacuteas de coacutedigo manejado incluidas en Crystal ReportsNET conforman una potente API Application Programming Interface - Interfaz para la Programacioacuten 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 decidioacute crear diferentes ensamblados fiacutesicos (DLLs) para simplificar las dependencias y el despliegue ulterior de las aplicaciones La siguiente tabla presenta los principales ensamblados (libreriacuteas de clases) que forman parte de Crystal ReportsNET y se instalan en la Cacheacute Global al instalar el producto Generalmente no es necesario agregar expliacutecitamente las referencias a estos ensamblados en nuestros proyectos ya que los asistentes de Visual Studio se encargan automaacuteticamente de ello cuando por ejemplo incorporamos a una aplicacioacuten un informe de Crystal Reports ENSAMBLADO USO CrystalDecisionsShared

Contiene tipos compartidos por Crystal ReportsNET y otras aplicaciones de la empresa

CrystalDecisionsReportSource Contiene la implementacioacuten de clases para conectarse a diferentes oriacutegenes de informes

CrystalDecisionsCrystalReportsEngine

Interfaz con el Motor de Impresioacuten de Crystal Reports

CrystalDecisionsWindowsForms

Clases para la presentacioacuten de informes Crystal en aplicaciones Windows

CrystalDecisionsWeb

Clases para la presentacioacuten de informes Crystal en aplicaciones Web

4

REQUISITOS PARA SEGUIR EL CURSO Para seguir este curso necesitaraacute tener instalado el siguiente software 992256 Visual Studio 2005 edicioacuten Profesional o superior Las ediciones Express y Estaacutendar NO incluyen desgraciadamente Crystal ReportsNET La alternativa en caso de disponer de alguna de esas ediciones ldquode gama bajardquo de Visual Studio consiste en adquirir Crystal ReportsNET de forma independiente (diriacutejase al sitio web del fabricante) 992256 SQL Server 2005 cualquier edicioacuten Si no dispone de una edicioacuten comercial de SQL Server 2005 puede descargar e instalar la edicioacuten Express (Service Pack 1) desde aquiacute En este uacuteltimo caso tambieacuten le seraacute de utilidad el SQL Server Management Studio Express 992256 La base de datos de ejemplo AdventureWorks que utilizaremos para los informes Si dispone de una edicioacuten comercial de SQL Server 2005 la base de datos forma parte de la instalacioacuten del producto en cualquier caso puede descargarse desde aquiacute En principio de esta descarga uacutenicamente es necesario el fichero AdventureWorksDBmsi El curso asume una cierta familiaridad con la programacioacuten de aplicaciones NET en Visual Basic y con el trabajo con bases de datos relacionales

PRESENTACIOacuteN 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 acompantildea a SQL Server 2005 Se trata de una base de datos que almacena toda la informacioacuten generada por una empresa ficticia dedicada a la fabricacioacuten 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 Aquiacute se almacenan los nombres y direcciones de clientes

individuales proveedores y empleados Purchasing Compras Informacioacuten sobre las piezas y productos que la empresa

compra y sus proveedores Production Produccioacuten Informacioacuten sobre los productos fabricados y vendidos por

la empresa Sales Ventas Informacioacuten sobre los clientes y los pedidos que realizan HumanResources Recursos Humanos Informacioacuten sobre los empleados de la empresa Puede encontrar una amplia informacioacuten sobre todas y cada una de las tablas y otros objetos de base de datos que contiene AdventureWorks aquiacute 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 queacute tablas se almacena la informacioacuten a partir de la que se desea disentildear el informe

TEacuteCNICAS BAacuteSICAS DE DISENtildeO DE INFORMES En este tema se presenta el Disentildeador de Informes de Crystal Reports integrado en Visual Studio 2005 y se presentan las teacutecnicas baacutesicas de disentildeo de informes en las que se apoyan los temas subsiguientes

INTRODUCCIOacuteN Antes que nada es conveniente definir queacute 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 maacutes o menos elaborada En

5

este sentido un simple listado de los empleados de la empresa podriacutea perfectamente considerarse un informe Otro documento que muestre a esos empleados agrupados por categoriacuteas seguacuten su volumen de ventas del antildeo anterior seriacutea otro informe claro estaacute bastante maacutes elaborado que el anterior Definir o crear un informe consiste en indicar al Disentildeador de Crystal Reports de doacutende tiene que obtener los datos necesarios coacutemo tiene que transformarlos y por uacuteltimo coacutemo debe presentar cada elemento de datos sobre el documento final Toda esa informacioacuten se almacenaraacute de la definicioacuten del informe que tradicionalmente se guarda en un fichero externo RPT para su posterior ejecucioacuten Pero antes de enfrentarse al Disentildeador de Crystal Reports (o de hecho a cualquier generador de informes) es altamente conveniente realizar un trabajo de anaacutelisis y disentildeo previos que nos den una idea clara de a) queacute necesita obtener exactamente el usuario que nos ha encargado el informe b) en consecuencia cuaacuteles son los datos que debemos utilizar y c) queacute apariencia aproximada deberaacute tener nuestro informe cuando sea ejecutado Tener las ideas claras nos ayudaraacute a cumplir con los objetivos requeridos en el menor tiempo y con la mayor calidad posible

CREACIOacuteN DE INFORMES ESTAacuteNDAR UTILIZANDO EL ASISTENTE Dentro de Visual Studio 2005 seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten para Windows (observe que hay otra plantilla Aplicacioacuten de Crystal Reports que evitaremos de momento) Llame al proyecto Ejemplo1 y poacutengalo en el directorio adecuado Como toda aplicacioacuten para Windows incluye un formulario principal inicialmente vaciacuteo Ahora sobre el nombre del proyecto en el Explorador de Soluciones pulse botoacuten derecho del ratoacuten y Agregar | Nuevo elemento Del cuadro de diaacutelogo con los distintos tipos de elemento posibles elija Crystal Reports Llame al nuevo fichero ListadoProductosrpt Al agregar un informe al proyecto se activa el Disentildeador de Crystal Reports Lo que ve en pantalla ahora (ldquoGaleriacutea de Crystal Reportsrdquo) es la ventana introductoria del Disentildeador que nos pregunta

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 2: Crystal Report - Curso Practico

2

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 ldquoCrystal Reports NETrdquo Este curso tiene dos objetivos fundamentales 992256 Ensentildearle a utilizar el disentildeador de Crystal Reports integrado en Visual Studio 2005 para crear informes de datos potentes y flexibles 992256 Mostrarle coacutemo incorporar esos informes en sus aplicaciones NET para Windows y la Web utilizando como lenguaje de programacioacuten a Visual Basic

ARQUITECTURA COMPONENTES PRINCIPALES La arquitectura de Crystal ReportsNET gira alrededor del soporte para un tipo de ficheros de formato propietario que se distingue por la extensioacuten RPT (report) y en el que se almacena la definicioacuten de los informes El producto se puede ver como la combinacioacuten de tres componentes principales que son 992256 El Motor de Impresioacuten (Crystal Reports Print Engine CRPE) A pesar de lo que su nombre sugiere este componente escrito en coacutedigo no administrado no soacutelo se encarga de lo relacionado con la impresioacuten en papel de los informes sino ademaacutes con todo lo que tiene que ver con la ejecucioacuten de los mismos empezando por el acceso a la base de datos para leer la informacioacuten y continuando con la generacioacuten de la imagen de las diferentes paacuteginas para luego volcarlas en pantalla papel o exportarlas a otros formatos como Adobe PDF o Microsoft Word 992256 Las Libreriacuteas de Coacutedigo Manejado encapsulan la funcionalidad del Motor de Impresioacuten a traveacutes de un conjunto de clases faacutecilmente accesibles desde aplicaciones escritas en Visual Basic C o cualquier otro lenguaje NET Estas son las libreriacuteas que utilizaremos desde nuestras aplicaciones o servicios (para Windows o la Web) para cargar ejecutar e imprimir los informes 992256 Por uacuteltimo el Disentildeador de Informes es el software que presenta la interfaz de usuario a traveacutes de la cual un usuario programador o no puede crear (ldquodisentildearrdquo) un informe y guardarlo en un fichero RPT para su posterior reutilizacioacuten Se trata de una aplicacioacuten sofisticada repleta de potentes asistentes que garantizan una alta productividad sin limitar las posibilidades a nuestra disposicioacuten La versioacuten del Disentildeador que incluye Crystal ReportsNET se integra perfectamente dentro de Visual Studio 2005 permitiendo creando una experiencia auacuten maacutes aacutegil y productiva

Arquitectura de Crystal Reports

POSIBILIDADES DE ACCESO A DATOS Y EXPORTACIOacuteN

3

Indudablemente otra de las caracteriacutesticas que han hecho tan popular a Crystal Reports es la amplia gama de oriacutegenes de datos que soporta asiacute como de formatos de salida a los que se pueden exportar los resultados El Motor de Impresioacuten de Crystal Reports tiene una arquitectura modular y se apoya en controladores (drivers) independientes para acceder a los diversos oriacutegenes de datos soportados y generar los informes en los diferentes formatos de salida posibles Las posibilidades de acceso a diferentes oriacutegenes de datos sobrepasan ampliamente la mera capacidad para comunicarse con bases de datos (praacutecticamente todos los sistemas de bases de datos tanto relacionales como ldquoplanosrdquo estaacuten soportados) y abarcan desde la lectura de todo tipo de bitaacutecoras (logs) por ejemplo las producidas por los servidores Web para el seguimiento de la navegacioacuten de los usuarios hasta el acceso a objetos en memoria generados por las aplicaciones que hospedan al Motor de Impresioacuten Por ejemplo en este curso veremos coacutemo 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 Impresioacuten 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 tambieacuten 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 auacuten no podemos prescindir del papel ni mucho menos la presentacioacuten de informes se estaacute convirtiendo cada vez maacutes en una tarea interactiva Las versiones maacutes recientes de Crystal Reports incluyen numerosas facilidades que veremos en este curso (Aacuterbol de grupos elementos con hiperenlaces) y que estaacuten orientadas uacutenica y exclusivamente a la visualizacioacuten de informes en una ventana de Windows o en un navegador Web

LIBRERIacuteAS DE CRYSTAL REPORTS Las libreriacuteas de coacutedigo manejado incluidas en Crystal ReportsNET conforman una potente API Application Programming Interface - Interfaz para la Programacioacuten 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 decidioacute crear diferentes ensamblados fiacutesicos (DLLs) para simplificar las dependencias y el despliegue ulterior de las aplicaciones La siguiente tabla presenta los principales ensamblados (libreriacuteas de clases) que forman parte de Crystal ReportsNET y se instalan en la Cacheacute Global al instalar el producto Generalmente no es necesario agregar expliacutecitamente las referencias a estos ensamblados en nuestros proyectos ya que los asistentes de Visual Studio se encargan automaacuteticamente de ello cuando por ejemplo incorporamos a una aplicacioacuten un informe de Crystal Reports ENSAMBLADO USO CrystalDecisionsShared

Contiene tipos compartidos por Crystal ReportsNET y otras aplicaciones de la empresa

CrystalDecisionsReportSource Contiene la implementacioacuten de clases para conectarse a diferentes oriacutegenes de informes

CrystalDecisionsCrystalReportsEngine

Interfaz con el Motor de Impresioacuten de Crystal Reports

CrystalDecisionsWindowsForms

Clases para la presentacioacuten de informes Crystal en aplicaciones Windows

CrystalDecisionsWeb

Clases para la presentacioacuten de informes Crystal en aplicaciones Web

4

REQUISITOS PARA SEGUIR EL CURSO Para seguir este curso necesitaraacute tener instalado el siguiente software 992256 Visual Studio 2005 edicioacuten Profesional o superior Las ediciones Express y Estaacutendar NO incluyen desgraciadamente Crystal ReportsNET La alternativa en caso de disponer de alguna de esas ediciones ldquode gama bajardquo de Visual Studio consiste en adquirir Crystal ReportsNET de forma independiente (diriacutejase al sitio web del fabricante) 992256 SQL Server 2005 cualquier edicioacuten Si no dispone de una edicioacuten comercial de SQL Server 2005 puede descargar e instalar la edicioacuten Express (Service Pack 1) desde aquiacute En este uacuteltimo caso tambieacuten le seraacute de utilidad el SQL Server Management Studio Express 992256 La base de datos de ejemplo AdventureWorks que utilizaremos para los informes Si dispone de una edicioacuten comercial de SQL Server 2005 la base de datos forma parte de la instalacioacuten del producto en cualquier caso puede descargarse desde aquiacute En principio de esta descarga uacutenicamente es necesario el fichero AdventureWorksDBmsi El curso asume una cierta familiaridad con la programacioacuten de aplicaciones NET en Visual Basic y con el trabajo con bases de datos relacionales

PRESENTACIOacuteN 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 acompantildea a SQL Server 2005 Se trata de una base de datos que almacena toda la informacioacuten generada por una empresa ficticia dedicada a la fabricacioacuten 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 Aquiacute se almacenan los nombres y direcciones de clientes

individuales proveedores y empleados Purchasing Compras Informacioacuten sobre las piezas y productos que la empresa

compra y sus proveedores Production Produccioacuten Informacioacuten sobre los productos fabricados y vendidos por

la empresa Sales Ventas Informacioacuten sobre los clientes y los pedidos que realizan HumanResources Recursos Humanos Informacioacuten sobre los empleados de la empresa Puede encontrar una amplia informacioacuten sobre todas y cada una de las tablas y otros objetos de base de datos que contiene AdventureWorks aquiacute 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 queacute tablas se almacena la informacioacuten a partir de la que se desea disentildear el informe

TEacuteCNICAS BAacuteSICAS DE DISENtildeO DE INFORMES En este tema se presenta el Disentildeador de Informes de Crystal Reports integrado en Visual Studio 2005 y se presentan las teacutecnicas baacutesicas de disentildeo de informes en las que se apoyan los temas subsiguientes

INTRODUCCIOacuteN Antes que nada es conveniente definir queacute 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 maacutes o menos elaborada En

5

este sentido un simple listado de los empleados de la empresa podriacutea perfectamente considerarse un informe Otro documento que muestre a esos empleados agrupados por categoriacuteas seguacuten su volumen de ventas del antildeo anterior seriacutea otro informe claro estaacute bastante maacutes elaborado que el anterior Definir o crear un informe consiste en indicar al Disentildeador de Crystal Reports de doacutende tiene que obtener los datos necesarios coacutemo tiene que transformarlos y por uacuteltimo coacutemo debe presentar cada elemento de datos sobre el documento final Toda esa informacioacuten se almacenaraacute de la definicioacuten del informe que tradicionalmente se guarda en un fichero externo RPT para su posterior ejecucioacuten Pero antes de enfrentarse al Disentildeador de Crystal Reports (o de hecho a cualquier generador de informes) es altamente conveniente realizar un trabajo de anaacutelisis y disentildeo previos que nos den una idea clara de a) queacute necesita obtener exactamente el usuario que nos ha encargado el informe b) en consecuencia cuaacuteles son los datos que debemos utilizar y c) queacute apariencia aproximada deberaacute tener nuestro informe cuando sea ejecutado Tener las ideas claras nos ayudaraacute a cumplir con los objetivos requeridos en el menor tiempo y con la mayor calidad posible

CREACIOacuteN DE INFORMES ESTAacuteNDAR UTILIZANDO EL ASISTENTE Dentro de Visual Studio 2005 seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten para Windows (observe que hay otra plantilla Aplicacioacuten de Crystal Reports que evitaremos de momento) Llame al proyecto Ejemplo1 y poacutengalo en el directorio adecuado Como toda aplicacioacuten para Windows incluye un formulario principal inicialmente vaciacuteo Ahora sobre el nombre del proyecto en el Explorador de Soluciones pulse botoacuten derecho del ratoacuten y Agregar | Nuevo elemento Del cuadro de diaacutelogo con los distintos tipos de elemento posibles elija Crystal Reports Llame al nuevo fichero ListadoProductosrpt Al agregar un informe al proyecto se activa el Disentildeador de Crystal Reports Lo que ve en pantalla ahora (ldquoGaleriacutea de Crystal Reportsrdquo) es la ventana introductoria del Disentildeador que nos pregunta

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 3: Crystal Report - Curso Practico

3

Indudablemente otra de las caracteriacutesticas que han hecho tan popular a Crystal Reports es la amplia gama de oriacutegenes de datos que soporta asiacute como de formatos de salida a los que se pueden exportar los resultados El Motor de Impresioacuten de Crystal Reports tiene una arquitectura modular y se apoya en controladores (drivers) independientes para acceder a los diversos oriacutegenes de datos soportados y generar los informes en los diferentes formatos de salida posibles Las posibilidades de acceso a diferentes oriacutegenes de datos sobrepasan ampliamente la mera capacidad para comunicarse con bases de datos (praacutecticamente todos los sistemas de bases de datos tanto relacionales como ldquoplanosrdquo estaacuten soportados) y abarcan desde la lectura de todo tipo de bitaacutecoras (logs) por ejemplo las producidas por los servidores Web para el seguimiento de la navegacioacuten de los usuarios hasta el acceso a objetos en memoria generados por las aplicaciones que hospedan al Motor de Impresioacuten Por ejemplo en este curso veremos coacutemo 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 Impresioacuten 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 tambieacuten 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 auacuten no podemos prescindir del papel ni mucho menos la presentacioacuten de informes se estaacute convirtiendo cada vez maacutes en una tarea interactiva Las versiones maacutes recientes de Crystal Reports incluyen numerosas facilidades que veremos en este curso (Aacuterbol de grupos elementos con hiperenlaces) y que estaacuten orientadas uacutenica y exclusivamente a la visualizacioacuten de informes en una ventana de Windows o en un navegador Web

LIBRERIacuteAS DE CRYSTAL REPORTS Las libreriacuteas de coacutedigo manejado incluidas en Crystal ReportsNET conforman una potente API Application Programming Interface - Interfaz para la Programacioacuten 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 decidioacute crear diferentes ensamblados fiacutesicos (DLLs) para simplificar las dependencias y el despliegue ulterior de las aplicaciones La siguiente tabla presenta los principales ensamblados (libreriacuteas de clases) que forman parte de Crystal ReportsNET y se instalan en la Cacheacute Global al instalar el producto Generalmente no es necesario agregar expliacutecitamente las referencias a estos ensamblados en nuestros proyectos ya que los asistentes de Visual Studio se encargan automaacuteticamente de ello cuando por ejemplo incorporamos a una aplicacioacuten un informe de Crystal Reports ENSAMBLADO USO CrystalDecisionsShared

Contiene tipos compartidos por Crystal ReportsNET y otras aplicaciones de la empresa

CrystalDecisionsReportSource Contiene la implementacioacuten de clases para conectarse a diferentes oriacutegenes de informes

CrystalDecisionsCrystalReportsEngine

Interfaz con el Motor de Impresioacuten de Crystal Reports

CrystalDecisionsWindowsForms

Clases para la presentacioacuten de informes Crystal en aplicaciones Windows

CrystalDecisionsWeb

Clases para la presentacioacuten de informes Crystal en aplicaciones Web

4

REQUISITOS PARA SEGUIR EL CURSO Para seguir este curso necesitaraacute tener instalado el siguiente software 992256 Visual Studio 2005 edicioacuten Profesional o superior Las ediciones Express y Estaacutendar NO incluyen desgraciadamente Crystal ReportsNET La alternativa en caso de disponer de alguna de esas ediciones ldquode gama bajardquo de Visual Studio consiste en adquirir Crystal ReportsNET de forma independiente (diriacutejase al sitio web del fabricante) 992256 SQL Server 2005 cualquier edicioacuten Si no dispone de una edicioacuten comercial de SQL Server 2005 puede descargar e instalar la edicioacuten Express (Service Pack 1) desde aquiacute En este uacuteltimo caso tambieacuten le seraacute de utilidad el SQL Server Management Studio Express 992256 La base de datos de ejemplo AdventureWorks que utilizaremos para los informes Si dispone de una edicioacuten comercial de SQL Server 2005 la base de datos forma parte de la instalacioacuten del producto en cualquier caso puede descargarse desde aquiacute En principio de esta descarga uacutenicamente es necesario el fichero AdventureWorksDBmsi El curso asume una cierta familiaridad con la programacioacuten de aplicaciones NET en Visual Basic y con el trabajo con bases de datos relacionales

PRESENTACIOacuteN 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 acompantildea a SQL Server 2005 Se trata de una base de datos que almacena toda la informacioacuten generada por una empresa ficticia dedicada a la fabricacioacuten 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 Aquiacute se almacenan los nombres y direcciones de clientes

individuales proveedores y empleados Purchasing Compras Informacioacuten sobre las piezas y productos que la empresa

compra y sus proveedores Production Produccioacuten Informacioacuten sobre los productos fabricados y vendidos por

la empresa Sales Ventas Informacioacuten sobre los clientes y los pedidos que realizan HumanResources Recursos Humanos Informacioacuten sobre los empleados de la empresa Puede encontrar una amplia informacioacuten sobre todas y cada una de las tablas y otros objetos de base de datos que contiene AdventureWorks aquiacute 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 queacute tablas se almacena la informacioacuten a partir de la que se desea disentildear el informe

TEacuteCNICAS BAacuteSICAS DE DISENtildeO DE INFORMES En este tema se presenta el Disentildeador de Informes de Crystal Reports integrado en Visual Studio 2005 y se presentan las teacutecnicas baacutesicas de disentildeo de informes en las que se apoyan los temas subsiguientes

INTRODUCCIOacuteN Antes que nada es conveniente definir queacute 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 maacutes o menos elaborada En

5

este sentido un simple listado de los empleados de la empresa podriacutea perfectamente considerarse un informe Otro documento que muestre a esos empleados agrupados por categoriacuteas seguacuten su volumen de ventas del antildeo anterior seriacutea otro informe claro estaacute bastante maacutes elaborado que el anterior Definir o crear un informe consiste en indicar al Disentildeador de Crystal Reports de doacutende tiene que obtener los datos necesarios coacutemo tiene que transformarlos y por uacuteltimo coacutemo debe presentar cada elemento de datos sobre el documento final Toda esa informacioacuten se almacenaraacute de la definicioacuten del informe que tradicionalmente se guarda en un fichero externo RPT para su posterior ejecucioacuten Pero antes de enfrentarse al Disentildeador de Crystal Reports (o de hecho a cualquier generador de informes) es altamente conveniente realizar un trabajo de anaacutelisis y disentildeo previos que nos den una idea clara de a) queacute necesita obtener exactamente el usuario que nos ha encargado el informe b) en consecuencia cuaacuteles son los datos que debemos utilizar y c) queacute apariencia aproximada deberaacute tener nuestro informe cuando sea ejecutado Tener las ideas claras nos ayudaraacute a cumplir con los objetivos requeridos en el menor tiempo y con la mayor calidad posible

CREACIOacuteN DE INFORMES ESTAacuteNDAR UTILIZANDO EL ASISTENTE Dentro de Visual Studio 2005 seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten para Windows (observe que hay otra plantilla Aplicacioacuten de Crystal Reports que evitaremos de momento) Llame al proyecto Ejemplo1 y poacutengalo en el directorio adecuado Como toda aplicacioacuten para Windows incluye un formulario principal inicialmente vaciacuteo Ahora sobre el nombre del proyecto en el Explorador de Soluciones pulse botoacuten derecho del ratoacuten y Agregar | Nuevo elemento Del cuadro de diaacutelogo con los distintos tipos de elemento posibles elija Crystal Reports Llame al nuevo fichero ListadoProductosrpt Al agregar un informe al proyecto se activa el Disentildeador de Crystal Reports Lo que ve en pantalla ahora (ldquoGaleriacutea de Crystal Reportsrdquo) es la ventana introductoria del Disentildeador que nos pregunta

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 4: Crystal Report - Curso Practico

4

REQUISITOS PARA SEGUIR EL CURSO Para seguir este curso necesitaraacute tener instalado el siguiente software 992256 Visual Studio 2005 edicioacuten Profesional o superior Las ediciones Express y Estaacutendar NO incluyen desgraciadamente Crystal ReportsNET La alternativa en caso de disponer de alguna de esas ediciones ldquode gama bajardquo de Visual Studio consiste en adquirir Crystal ReportsNET de forma independiente (diriacutejase al sitio web del fabricante) 992256 SQL Server 2005 cualquier edicioacuten Si no dispone de una edicioacuten comercial de SQL Server 2005 puede descargar e instalar la edicioacuten Express (Service Pack 1) desde aquiacute En este uacuteltimo caso tambieacuten le seraacute de utilidad el SQL Server Management Studio Express 992256 La base de datos de ejemplo AdventureWorks que utilizaremos para los informes Si dispone de una edicioacuten comercial de SQL Server 2005 la base de datos forma parte de la instalacioacuten del producto en cualquier caso puede descargarse desde aquiacute En principio de esta descarga uacutenicamente es necesario el fichero AdventureWorksDBmsi El curso asume una cierta familiaridad con la programacioacuten de aplicaciones NET en Visual Basic y con el trabajo con bases de datos relacionales

PRESENTACIOacuteN 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 acompantildea a SQL Server 2005 Se trata de una base de datos que almacena toda la informacioacuten generada por una empresa ficticia dedicada a la fabricacioacuten 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 Aquiacute se almacenan los nombres y direcciones de clientes

individuales proveedores y empleados Purchasing Compras Informacioacuten sobre las piezas y productos que la empresa

compra y sus proveedores Production Produccioacuten Informacioacuten sobre los productos fabricados y vendidos por

la empresa Sales Ventas Informacioacuten sobre los clientes y los pedidos que realizan HumanResources Recursos Humanos Informacioacuten sobre los empleados de la empresa Puede encontrar una amplia informacioacuten sobre todas y cada una de las tablas y otros objetos de base de datos que contiene AdventureWorks aquiacute 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 queacute tablas se almacena la informacioacuten a partir de la que se desea disentildear el informe

TEacuteCNICAS BAacuteSICAS DE DISENtildeO DE INFORMES En este tema se presenta el Disentildeador de Informes de Crystal Reports integrado en Visual Studio 2005 y se presentan las teacutecnicas baacutesicas de disentildeo de informes en las que se apoyan los temas subsiguientes

INTRODUCCIOacuteN Antes que nada es conveniente definir queacute 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 maacutes o menos elaborada En

5

este sentido un simple listado de los empleados de la empresa podriacutea perfectamente considerarse un informe Otro documento que muestre a esos empleados agrupados por categoriacuteas seguacuten su volumen de ventas del antildeo anterior seriacutea otro informe claro estaacute bastante maacutes elaborado que el anterior Definir o crear un informe consiste en indicar al Disentildeador de Crystal Reports de doacutende tiene que obtener los datos necesarios coacutemo tiene que transformarlos y por uacuteltimo coacutemo debe presentar cada elemento de datos sobre el documento final Toda esa informacioacuten se almacenaraacute de la definicioacuten del informe que tradicionalmente se guarda en un fichero externo RPT para su posterior ejecucioacuten Pero antes de enfrentarse al Disentildeador de Crystal Reports (o de hecho a cualquier generador de informes) es altamente conveniente realizar un trabajo de anaacutelisis y disentildeo previos que nos den una idea clara de a) queacute necesita obtener exactamente el usuario que nos ha encargado el informe b) en consecuencia cuaacuteles son los datos que debemos utilizar y c) queacute apariencia aproximada deberaacute tener nuestro informe cuando sea ejecutado Tener las ideas claras nos ayudaraacute a cumplir con los objetivos requeridos en el menor tiempo y con la mayor calidad posible

CREACIOacuteN DE INFORMES ESTAacuteNDAR UTILIZANDO EL ASISTENTE Dentro de Visual Studio 2005 seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten para Windows (observe que hay otra plantilla Aplicacioacuten de Crystal Reports que evitaremos de momento) Llame al proyecto Ejemplo1 y poacutengalo en el directorio adecuado Como toda aplicacioacuten para Windows incluye un formulario principal inicialmente vaciacuteo Ahora sobre el nombre del proyecto en el Explorador de Soluciones pulse botoacuten derecho del ratoacuten y Agregar | Nuevo elemento Del cuadro de diaacutelogo con los distintos tipos de elemento posibles elija Crystal Reports Llame al nuevo fichero ListadoProductosrpt Al agregar un informe al proyecto se activa el Disentildeador de Crystal Reports Lo que ve en pantalla ahora (ldquoGaleriacutea de Crystal Reportsrdquo) es la ventana introductoria del Disentildeador que nos pregunta

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 5: Crystal Report - Curso Practico

5

este sentido un simple listado de los empleados de la empresa podriacutea perfectamente considerarse un informe Otro documento que muestre a esos empleados agrupados por categoriacuteas seguacuten su volumen de ventas del antildeo anterior seriacutea otro informe claro estaacute bastante maacutes elaborado que el anterior Definir o crear un informe consiste en indicar al Disentildeador de Crystal Reports de doacutende tiene que obtener los datos necesarios coacutemo tiene que transformarlos y por uacuteltimo coacutemo debe presentar cada elemento de datos sobre el documento final Toda esa informacioacuten se almacenaraacute de la definicioacuten del informe que tradicionalmente se guarda en un fichero externo RPT para su posterior ejecucioacuten Pero antes de enfrentarse al Disentildeador de Crystal Reports (o de hecho a cualquier generador de informes) es altamente conveniente realizar un trabajo de anaacutelisis y disentildeo previos que nos den una idea clara de a) queacute necesita obtener exactamente el usuario que nos ha encargado el informe b) en consecuencia cuaacuteles son los datos que debemos utilizar y c) queacute apariencia aproximada deberaacute tener nuestro informe cuando sea ejecutado Tener las ideas claras nos ayudaraacute a cumplir con los objetivos requeridos en el menor tiempo y con la mayor calidad posible

CREACIOacuteN DE INFORMES ESTAacuteNDAR UTILIZANDO EL ASISTENTE Dentro de Visual Studio 2005 seleccione Archivo | Nuevo | Proyecto y cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten para Windows (observe que hay otra plantilla Aplicacioacuten de Crystal Reports que evitaremos de momento) Llame al proyecto Ejemplo1 y poacutengalo en el directorio adecuado Como toda aplicacioacuten para Windows incluye un formulario principal inicialmente vaciacuteo Ahora sobre el nombre del proyecto en el Explorador de Soluciones pulse botoacuten derecho del ratoacuten y Agregar | Nuevo elemento Del cuadro de diaacutelogo con los distintos tipos de elemento posibles elija Crystal Reports Llame al nuevo fichero ListadoProductosrpt Al agregar un informe al proyecto se activa el Disentildeador de Crystal Reports Lo que ve en pantalla ahora (ldquoGaleriacutea de Crystal Reportsrdquo) es la ventana introductoria del Disentildeador que nos pregunta

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 6: Crystal Report - Curso Practico

6

a) En primer lugar coacutemo queremos disentildear el informe Las opciones posibles son

1 Utilizando el Asistente del Disentildeador Como veremos a continuacioacuten el Asistente nos guiacutea a traveacutes de diferentes pantallas para que definamos las caracteriacutesticas principales del informe Una vez finalizado el Asistente podremos antildeadir al informe nuevas posibilidades o modificar las decisiones tomadas anteriormente Como se daraacute cuenta raacutepidamente el Asistente de informes es una combinacioacuten de otros asistentes maacutes sencillos que podraacute invocar por separado posteriormente En general es conveniente dejarse guiar por el Asistente para obtener raacutepidamente un disentildeo inicial que luego podemos modificar a voluntad 2 Partiendo desde cero sobre un lienzo en blanco Generalmente no es productivo ir por esta ldquoruta difiacutecilrdquo 3 A partir de un informe existente Esta opcioacuten es conveniente si queremos disentildear un informe muy parecido a otro que ya hemos creado anteriormente

b) Si decidimos utilizar el Asistente eacuteste es capaz de ayudarnos con tres tipos de informes diferentes

1 Informe estaacutendar Esta opcioacuten se utiliza para crear un informe de tipo ldquolistadordquo Es la opcioacuten maacutes conveniente en la gran mayoriacutea de los casos a menos que se tenga claro que el informe uacutenicamente incluiraacute una tabla cruzada en cuyo caso es maacutes conveniente seleccionar la siguiente opcioacuten 2 Tablas cruzadas Un informe de tabla cruzada es un informe que presenta en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera No es ninguacuten problema antildeadir manualmente una tabla cruzada a un informe estaacutendar si se desea 3 Etiqueta Listado de muacuteltiples 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 disentildeando un informe estaacutendar ndash por ejemplo un informe que presente la lista de productos que la empresa AdventureWorks ha vendido al puacuteblico o vende actualmente Mantenga las opciones por defecto y pulse Aceptar PASO 1 El primer paso a la hora de disentildear el informe es indicarle al Asistente doacutende estaacuten y cuaacuteles son los datos que se van a utilizar en el informe Aquiacute tenemos que indicar a) La tecnologiacutea a utilizar para conectarse al origen de datos En este caso trataacutendose de una base de datos SQL Server debemos indicar Crear nueva conexioacuten | OLE DB (ADO) y luego elegir el proveedor lsquoMicrosoft OLE DB Provider for SQL Serverrsquo Pulse Siguiente b) El nombre del servidor la base de datos y el usuario y contrasentildea necesarios para establecer la conexioacuten En nuestro caso utilizaremos como nombre de servidor SQLExpress (lsquorsquo significa la maacutequina local y lsquoSQLExpressrsquo es el nombre de la instancia en que se instala SQL Server Express de forma predeterminada) De momento utilizaremos la autenticacioacuten integrada (marcando la casilla correspondiente) aunque la autenticacioacuten de usuariocontrasentildea es maacutes utilizada en la vida real sobre todo en aplicaciones Web Por uacuteltimo despliegue la lista de bases de datos disponibles y seleccione AdventureWorks Pulse Siguiente c) Por uacuteltimo se nos permite indicar las propiedades avanzadas de la conexioacuten No necesitamos ninguna en este caso y por eso pulsamos directamente en Finalizar

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 7: Crystal Report - Curso Practico

7

Una vez indicados el servidor y la base de datos la veraacute en la lista de los oriacutegenes de datos disponibles En este momento es conveniente pulsar el botoacuten derecho del ratoacuten sobre el nombre del servidor y utilizar la opcioacuten lsquoAgregar a Favoritosrsquo 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 deberaacute obtener la informacioacuten En nuestro caso necesitaremos la tabla Product del esquema Production Seleccione esa tabla en la vista de aacuterbol (pasaacutendola a la columna derecha del diaacutelogo mediante el botoacuten lsquogtrsquo) y pulse Siguiente PASO 3 El siguiente paso consiste en indicar cuaacuteles de las columnas (campos) que componen la tabla elegida queremos mostrar en las columnas del listado En nuestro ejemplo seleccionaremos los siguientes campos 992256 ProductNumber ndash el coacutedigo de identificacioacuten del producto 992256 Name ndash el nombre del producto 992256 Color ndash 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 podriacuteamos agrupar los productos a listar seguacuten su color Para este ejemplo inicial sin embargo no especificaremos criterio de agrupacioacuten alguno Pulse Siguiente PASO 5 La otra decisioacuten importante que debemos tomar con respecto a los datos es queacute filas de la tabla seleccionada deseamos que aparezcan en el informe Para ello es necesario especificar una condicioacuten de seleccioacuten ndash soacutelo aquellas filas que satisfagan la condicioacuten que indiquemos seraacuten 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 seraacute 1 que significa verdadero) Fiacutejese coacutemo al seleccionar un campo en la zona inferior derecha de la ventana aparece un cuadro de combinacioacuten en el que se muestran algunas de las condiciones comunes para campos de ese tipo En nuestro caso nos interesa la condicioacuten lsquoes Verdaderorsquo Observe tambieacuten que no es necesario que el campo de la condicioacuten esteacute entre los campos a mostrar en el informe para utilizarlo en la condicioacuten de filtro Una vez indicada la condicioacuten pulse Siguiente PASO 6 Por uacuteltimo 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 caracteriacutesticas visuales (ldquoestilosrdquo) que se aplicaraacuten a los diferentes tipos de objetos que pueden aparecer en el informe Mantenga el estilo Estaacutendar y pulse Finalizar En este momento el Asistente generaraacute el informe que veremos reflejado en el aacuterea de trabajo de Visual Studio 2005

ESPECIFICACIOacuteN DE LAS TABLAS DEL INFORME OPCIONES DE ENLACE Como resultado del paso anterior tenemos a nuestra disposicioacuten en el aacuterea de trabajo de Visual Studio como ldquovista activardquo del informe el ldquolienzordquo generado por el Asistente sobre el que podremos hacer todas

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 8: Crystal Report - Curso Practico

8

las modificaciones que queramos para adecuar maacutes el informe a los requerimientos de nuestra aplicacioacuten o usuarios Observe tambieacuten en la parte inferior de la ventana la otra posible vista del informe que podemos seleccionar la Vista previa que nos ofreceraacute instantaacuteneamente una presentacioacuten del resultado de la ejecucioacuten del informe para que podamos ver coacutemo luciraacute nuestro informe con los datos reales Aunque formalmente el disentildeo del informe debe hacerse desde la vista lsquoInforme principalrsquo veraacute que el Disentildeador nos permite tambieacuten realizar casi todas las tareas de disentildeo sobre esta vista previa Volviendo a la vista de disentildeo veraacute que el disentildeo 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 Baacutesicamente la seccioacuten en la que esteacute situado un elemento determina cuaacutendo y cuaacutentas veces se imprimiraacute ese elemento al ejecutar el informe Las secciones disponibles en Crystal Reports son las siguientes 992256 Encabezado del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la parte superior de la primera paacutegina del informe En esta seccioacuten tiacutepicamente se colocan el tiacutetulo del informe la fecha de ejecucioacuten etc Por defecto esta seccioacuten aparece inicialmente suprimida (indicado por las rayas transversales) 992256 Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte superior de la misma Tradicionalmente se colocan en esta seccioacuten los nuacutemeros de paacutegina y las etiquetas de las columnas del informe (cosa que el Asistente de informes ya ha hecho por nosotros) 992256 Encabezado de grupo habraacute uno por cada uno de los grupos que tenga el informe (nuestro informe baacutesico no tiene grupos) Los elementos que se coloquen en esta seccioacuten (un ejemplo tiacutepico es el nombre del grupo) apareceraacuten en el informe una vez al principio de cada uno de los diferentes grupos que el motor de ejecucioacuten encuentre en los datos Maacutes adelante en este mismo tema trataremos con profundidad el tema de los grupos 992256 Detalles en la seccioacuten 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 Tiacutepicamente si el informe es del tradicional estilo ldquolistadordquo en esta seccioacuten se colocan objetos que representan a los campos de la tabla o consulta de origen En un informe tiacutepico de tabla cruzada por ejemplo la seccioacuten de detalles se deja vaciacutea (o se suprime) porque no se desea que aparezca informacioacuten sobre cada uno de los registros sino solo los resuacutemenes (que normalmente se ponen en la seccioacuten de Pie del Informe) 992256 Pie de grupo es la seccioacuten ldquoopuestardquo al Encabezado de grupo y se imprime una vez al finalizar cada uno de los grupos que el motor de ejecucioacuten encuentre en los datos que componen el informe Habraacute una seccioacuten de Pie de grupo para cada Encabezado de grupo y los grupos siempre estaacuten perfectamente anidados (por ejemplo en un informe con dos grupos por Paiacuteses y Provincias los grupos correspondientes a las provincias de un paiacutes siempre quedaraacuten anidados dentro del grupo correspondiente al paiacutes) En esta seccioacuten tiacutepicamente se colocan los totales de grupo (por ejemplo la cantidad de clientes por cada paiacutes en un listado de clientes agrupado por paiacuteses) 992256 Pie de paacutegina opuesta al Encabezado de paacutegina los elementos que se situacuteen en esta seccioacuten apareceraacuten en el informe una vez por cada paacutegina del informe en la parte inferior de la misma Tradicionalmente se colocan en esta seccioacuten los totales acumulados (tipo ldquosuma y siguerdquo) o tambieacuten los nuacutemeros de paacutegina 992256 Pie del informe los elementos que se coloquen en esta seccioacuten apareceraacuten en el informe una sola vez en la uacuteltima paacutegina del informe En esta seccioacuten tiacutepicamente se colocan los totales generales Si se pulsa con el botoacuten derecho del ratoacuten sobre cualquiera de las bandas que identifican a las secciones (por ejemplo sobre la seccioacuten de Encabezado del informe) apareceraacute el menuacute de contexto de la seccioacuten

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 9: Crystal Report - Curso Practico

9

que exploraremos con maacutes profundidad un poco maacutes adelante en el curso Por el momento ejecute la opcioacuten No suprimir sobre la seccioacuten de Encabezado de informe para indicar que queremos que esta seccioacuten aparezca al ejecutar el informe Otros tres elementos muy importantes de la interfaz de usuario que aparecen en modo de disentildeo para ayudarnos con las tareas maacutes habituales son 992256 Las barras de herramientas de Crystal Reports 992256 La barra de herramientas lsquoPrincipalrsquo ofrece muacuteltiples botones para por una parte lanzar diferentes asistentes que nos ayudaraacuten con las tareas comunes (seleccioacuten ordenacioacuten) y por otra parte facilitarnos las tareas de formato (atributos de texto justificacioacuten cantidad de decimales en campos numeacutericos) 992256 La barra de herramientas lsquoInsertarrsquo ofrece botones que despliegan asistentes que nos permitiraacuten insertar objetos maacutes o menos complejos en el informe (grupos totales graacuteficos imaacutegenes) 992256 En el menuacute principal de Visual Studio o si se pulsa el botoacuten derecho del ratoacuten sobre el lienzo de disentildeo (teniendo cuidado de no estar situado sobre una seccioacuten pues entonces apareceriacutea el menuacute de la seccioacuten) tendremos el menuacute principal del disentildeador que incluye todas las opciones de las barras de herramientas maacutes algunas otras no disponibles en ninguacuten otro sitio Las principales opciones de este menuacute son las siguientes 992256 Insertar para insertar diferentes objetos sobre el lienzo de disentildeo 992256 Base de datos para realizar diferentes tareas relacionadas con la base de datos a la que accedemos por ejemplo agregar nuevas tablas al informe 992256 Report para lanzar diferentes asistentes o establecer la configuracioacuten del informe Por ejemplo vamos a establecer el tiacutetulo del informe y el nombre de su autor Para ello utilizamos la opcioacuten del menuacute Report | Resumen de informacioacuten que nos lanzaraacute un cuadro de diaacutelogo en el que podremos indicar esos valores Utilice como tiacutetulo lsquoListado de productos para ventarsquo ponga su nombre en el campo lsquoAutorrsquo 992256 Disentildeo para actuar sobre las opciones de configuracioacuten general del disentildeador que dictan coacutemo eacuteste se comporta de manera predeterminada Por ejemplo una opcioacuten que puede resultar conveniente es la de activar la opcioacuten Cuadriacutecula que haraacute aparecer una rejilla de puntos sobre el disentildeador lo que nos ayudaraacute a establecer la alineacioacuten de los objetos 992256 El Explorador de campos que aparece por defecto a la izquierda del lienzo de disentildeo nos presenta una vista de aacuterbol desde la que podremos elegir cualquier elemento accesible a nuestro informe para arrastrarlo sobre la seccioacuten adecuada en el aacuterea de disentildeo Por ejemplo si despliega el nodo lsquoCampos de base de datosrsquo encontraraacute la tabla Product con todos sus campos por favor seleccione el campo SellEndDate (fecha en que el producto se dejoacute de vender) y arraacutestrelo sobre la seccioacuten de Detalles del informe justo a la derecha del campo Color Si cambia a la Vista previa veraacute que soacutelo algunos productos tienen asociada una fecha de vencimiento En caso de que un campo tenga asociado el valor nulo simplemente no se mostraraacute nada en la posicioacuten correspondiente

TEacuteCNICAS PRINCIPALES DE UTILIZACIOacuteN DEL ENTORNO DE DISENtildeO Para insertar cualquier elemento en un informe como hemos visto antes se utilizan dos teacutecnicas fundamentales 992256 Si se trata de un campo de base de datos paraacutemetro grupo etc ya existente y visible en el Explorador de campos basta con arrastrarlo desde alliacute hacia la posicioacuten deseada dentro de la seccioacuten adecuada como acabamos de hacer Como segundo ejemplo vamos a poner el tiacutetulo del informe en la seccioacuten de Encabezado del informe (para que aparezca una vez en la parte superior de la primera paacutegina cuando se ejecute el informe) Para ello iremos al Explorador de campos desplegaremos el nodo lsquoCampos especialesrsquo y elegiremos el elemento lsquoTiacutetulo del informersquo y lo arrastraremos hacia la seccioacuten de Encabezado de informe digamos que maacutes hacia la esquina izquierda del informe De nuevo pasando a la

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 10: Crystal Report - Curso Practico

10

Vista previa podraacute comprobar que el tiacutetulo que hemos asignado al informe apareceraacute en el lugar elegido (puede que haya que guardar el informe previamente) 992256 Si lo que queremos es antildeadir al informe otro tipo de elemento visual (resumen graacutefico imagen etc) tendremos que utilizar el correspondiente asistente desde el menuacute de Crystal Reports o la barra de herramientas Insertar En cualquier caso tambieacuten se nos permitiraacute indicar en queacute seccioacuten y posicioacuten concreta queremos colocar el elemento Por ejemplo vamos insertar un resumen general en la seccioacuten de Pie de informe que indique cuaacutentos productos contiene el listado Para ello tendremos que dar los siguientes pasos 992256 Pulsar con el botoacuten derecho del ratoacuten sobre la seccioacuten 4 (Pie del informe) y en el menuacute de contexto de la seccioacuten seleccionar lsquoNo suprimirrsquo para hacer que visible a esa seccioacuten 992256 Pulsar el botoacuten lsquoResumenrsquo de la barra de herramientas que nos pediraacute que elijamos 992256 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 992256 El tipo de resumen deseado En este caso nos interesa un Recuento (conteo) aunque tambieacuten podriacutea ser un Recuento distintivo que produciriacutea exactamente el mismo resultado dado que el coacutedigo de producto es uacutenico para cada producto Veraacute que las opciones maacutes tiacutepicas (Suma Promedio etc) no estaacuten disponibles en este caso por tratarse de un campo alfanumeacuterico 992256 La posicioacuten en la que se desea ubicar el resumen Trataacutendose de un listado sencillo sin grupos la uacutenica opcioacuten disponible es la de colocar el valor resultante al final de todo al pie del informe En presencia de grupos este asistente nos permitiraacute tambieacuten crear resuacutemenes parciales por cada nivel de agrupacioacuten 992256 Al pulsar el botoacuten Aceptar el Disentildeador colocaraacute un objeto de resumen configurado seguacuten le hemos indicado en la seccioacuten Pie del informe Cambie a la Vista previa y vaya hasta la uacuteltima paacutegina del informe y veraacute el total reflejado en el sitio adecuado Una vez que el objeto ha sido colocado sobre el lienzo de disentildeo toca la labor de configurarlo para que responda a los requisitos de disentildeo del informe 992256 En primer lugar podemos seleccionar el objeto con el ratoacuten y arrastrarlo hacia cualquier otro sitio en la misma seccioacuten o una seccioacuten diferente Tenga especial cuidado al cambiar un objeto de una seccioacuten a otra ndash su sentido comuacuten le orientaraacute correctamente en la mayoriacutea de los casos 992256 Cuando un objeto estaacute seleccionado en sus cuatro costados aparecen las tiacutepicas ldquograpasrdquo que nos permiten redimensionarlo como queramos 992256 La barra de herramientas lsquoPrincipalrsquo ofrece diferentes botones que nos permiten establecer los atributos del texto del objeto (fuente y tamantildeo de letra negrita itaacutelicas etc) la alineacioacuten (izquierda derecha centrada) o el formato de presentacioacuten para datos numeacutericos 992256 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 activaraacute el modo de edicioacuten para que podamos modificar el texto a mostrar 992256 Por uacuteltimo pulsando con el botoacuten derecho del ratoacuten sobre el objeto seleccionado obtendremos un menuacute de contexto que incluye la opcioacuten lsquoDar formato a objetorsquo Esta opcioacuten de menuacute despliega un cuadro de diaacutelogo de muacuteltiples pestantildeas que nos permitiraacute configurar todas y cada una de las propiedades del objeto La mayoriacutea de las pestantildeas (Comuacuten Bordes Fuente Hiperviacutenculo) son comunes a casi todos los objetos y para ciertos tipos de objetos aparece una pestantildea especial con sus caracteriacutesticas especiacuteficas Por ejemplo si seleccionamos el objeto que corresponde al campo SellEndDate veremos una pestantildea lsquoFecha y horarsquo donde podemos establecer el formato de visualizacioacuten de los datos de esa columna que es de tipo DateTime 992256 Debido a que estamos utilizando la versioacuten del Disentildeador de Crystal Reports integrada en Visual Studio una alternativa al cuadro de diaacutelogo anterior es utilizar la Ventana de Propiedades del entorno para establecer los valores de las propiedades Dado que las propiedades tienen nombres en ingleacutes mientras

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 11: Crystal Report - Curso Practico

11

que el cuadro de diaacutelogo estaacute traducido al castellano (ademaacutes de mejor organizado) recomendamos utilizar eacuteste uacuteltimo

PRINCIPALES TIPOS DE OBJETOS Cada vez que arrastramos algo desde el Explorador de campos o insertamos un objeto desde el menuacute o la barra de herramientas el Disentildeador de Crystal Reports crea para nosotros un objeto del tipo correspondiente Los principales tipos de objetos que podemos arrastrar sobre el lienzo de disentildeo desde el Explorador de campos son 992256 Campos de bases de datos objetos que mostraraacuten los valores de los campos de los diferentes registros extraiacutedos de la base de datos En dependencia del tipo de datos del campo ndash Crystal Reports distingue los tipos Alfanumeacuterico (Cadena) Nuacutemero Moneda Fecha Hora FechaHora y Loacutegico (Booleano) - el cuadro de diaacutelogo de configuracioacuten ofreceraacute una pestantildea especiacutefica para configurar los datos de ese tipo 992256 Campos de foacutermula Como estudiaremos en el tema 4 Crystal Reports ofrece un lenguaje de foacutermulas que nos permitiraacute implementar por ejemplo campos calculados que no existan fiacutesicamente en la base de datos Se puede crear foacutermulas de cualquiera de los tipos de datos antes mencionados y Crystal ofrece una ampliacutesima biblioteca de funciones predefinidas para facilitarnos el desarrollo de foacutermulas 992256 Campos de paraacutemetro Otro de los elementos importantiacutesimos de Crystal Reports desde el punto de vista praacutectico son los paraacutemetros Los paraacutemetros (que estudiaremos en el tema 5) hacen posible que un mismo informe pueda ser utilizado en muacuteltiples situaciones sin necesidad de hacer ldquoretoquesrdquo al disentildeo del informe El informe se disentildea con uno o maacutes paraacutemetros y los valores de los paraacutemetros se suministran al motor de impresioacuten ldquodesde fuerardquo inmediatamente antes de cada ejecucioacuten del informe 992256 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 paiacuteses el nombre de grupo seraacute el nombre del paiacutes Generalmente el nombre de grupo se coloca en la seccioacuten de Encabezado de grupo 992256 Campos de totales acumulados Los totales acumulados permiten implementar los tiacutepicos ldquosuma y siguerdquo resuacutemenes 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 992256 Campos especiales Bajo el nombre comuacuten de ldquocampos especialesrdquo se han agrupado toda una serie de elementos de informacioacuten que generalmente se desea mostrar en los informes tiacutetulo y autor del informe (que ya hemos presentado antes) fecha de impresioacuten o modificacioacuten del informe nuacutemero de paacutegina actual cantidad total de paacuteginas del informe entre otros Por otra parte desde el menuacute de Crystal Reports o la barra de herramientas correspondiente podremos insertar en el informe objetos como 992256 Secciones Aunque ya el Asistente ha creado para nosotros cada una de las secciones tiacutepicas de un informe un programador podriacutea estar interesado en dividir una seccioacuten en dos o maacutes subsecciones Hablaremos maacutes sobre las secciones algo maacutes adelante en el curso 992256 Grupos Al insertar un grupo en el informe en realidad (como veremos a continuacioacuten) se crean tres elementos diferentes la seccioacuten de Encabezado de grupo y Pie de grupo correspondiente maacutes un campo de nombre de grupo asociado al campo por el que hemos indicado que queremos agrupar 992256 Resuacutemenes Los objetos de resumen sirven para hacer totalizaciones generales o parciales (por grupos) de los valores de un campo de la base de datos 992256 Tablas cruzadas Una tabla cruzada permite mostrar en una tabla resuacutemenes agrupados por categoriacuteas por ejemplo los voluacutemenes de ventas de cada tipo de productos por cada paiacutes en el que la empresa opera Generalmente las tablas cruzadas se insertan en la seccioacuten de Pie del informe 992256 Graacuteficos Crystal Reports permite incorporar a los informes diversos tipos de graacuteficos comerciales (de liacuteneas barras tarta etc) basados en los registros obtenidos de la base de datos Generalmente los graacuteficos se colocan en la seccioacuten de Pie del informe o alguacuten Pie de grupo

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 12: Crystal Report - Curso Practico

12

992256 Subinformes Una teacutecnica bastante potente para componer informes complejos es la de insertar un informe ya creado dentro de otro Veremos los subinformes en el tema 5 992256 Objetos de texto Los objetos de texto permiten mostrar una etiqueta de texto en cualquier seccioacuten y posicioacuten del informe horizontal o verticalmente 992256 Imaacutegenes Podemos incorporar a nuestros informes imaacutegenes BMP JPG o PNG con el logotipo de la empresa fondos de ldquomarca de aguardquo etc 992256 Liacuteneas y cuadros Por uacuteltimo tambieacuten podemos utilizar objetos de liacuteneas y cuadros para realzar los informes

EL VISOR DE INFORMES Si ha activado la pestantildea de Vista previa para ver el resultado en pantalla de la ejecucioacuten del informe habraacute visto el informe presentado en un contenedor visual que se conoce como el Visor de informes para aplicaciones Windows (en realidad una versioacuten especializada del mismo) Crystal Reports ofrece igualmente otro visor basado en HTML y Javascript para su utilizacioacuten en aplicaciones Web

Visor de aplicaciones Windows de Crystal Reports

El Visor de informes ofrece los siguientes controles en su barra de herramientas 992256 El botoacuten de Exportar que permite exportar el resultado del informe a diferentes formatos como Microsoft Excel Microsoft Word texto enriquecido (RTF) o Adobe PDF 992256 El botoacuten de Imprimir que permite seleccionar una impresora y enviar a ella el informe para asiacute obtener una copia en papel 992256 El botoacuten de Aacuterbol de grupos que permite mostrar u ocultar el aacuterbol de grupos banda situada a la izquierda del visor (ahora vaciacutea puesto que nuestro informe inicial no tiene grupos) En un informe con grupos en esta banda se situaraacuten los nombres de los diferentes grupos existentes en el informe en forma de hiperenlaces a la paacutegina del informe en la que comienzan los datos correspondientes a cada uno de los grupos Por ejemplo en un listado de clientes agrupados por paiacuteses en el Aacuterbol de grupos apareceraacute cada uno de los nombres de los paiacuteses en los que hay clientes y podriacuteamos saltar a ver los clientes de cada paiacutes con un simple clic de ratoacuten 992256 Los botones de navegacioacuten que permiten desplazarse hacia delante y hacia atraacutes por las paacuteginas del informe Tenga en cuenta que la generacioacuten de las paacuteginas de un informe se produce dinaacutemicamente a medida que va siendo necesario desplazarse a la uacuteltima paacutegina del informe provocaraacute que se generen todas y cada una de las paacuteginas (que el motor de Crystal almacena en memoria para su posterior reutilizacioacuten) 992256 Un cuadro de texto que nos muestra la paacutegina actual y tambieacuten nos permite teclear un nuacutemero para saltar a cualquier otra paacutegina 992256 El botoacuten de Detener carga que soacutelo estaacute activo mientras se estaacute cargando el informe con el objetivo de que podamos cancelar la carga de datos si ya hemos visto lo que queriacuteamos ver o hemos detectado un error en el informe 992256 El botoacuten de Actualizar (refrescar) informe que nos permitiraacute regenerar el informe desde cero (por ejemplo para obtener una versioacuten maacutes actual del informe en caso de que los datos de la base de datos hayan cambiado) 992256 El cuadro de combinacioacuten de Zoom que nos permitiraacute establecer la escala de visualizacioacuten de las paacuteginas del informe Este Visor de informes es casi el mismo que veraacuten los usuarios de nuestras aplicaciones Windows que incluyan informes Crystal Reports cuando ordenen la visualizacioacuten de un informe desde programa

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 13: Crystal Report - Curso Practico

13

tendremos la posibilidad de ocultar aquellos botones que no tengan sentido o no queramos mostrar (por ejemplo el botoacuten de Aacuterbol de grupos en un listado sencillo que no tenga grupos)

EJEMPLO BAacuteSICO DE APLICACIOacuteN WINDOWS Estamos utilizando el Disentildeador 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 coacutemo alcanzar uno de los objetivos finales de este curso que es integrar los informes Crystal dentro de una aplicacioacuten Windows El proceso en relativamente muy simple y muestra la potencia de la programacioacuten basada en componentes que Visual Studio promueve Seleccione el formulario principal (y uacutenico) de la aplicacioacuten y configure sus tres o cuatro propiedades principales (tiacutetulo estilo dimensiones posicioacuten inicial) Luego coloque sobre el formulario un componente de la clase CrystalReportsViewer (ficha Crystal Reports) Encaje el visor en el aacuterea 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 992256 La propiedad ReportSource es una propiedad polimoacuterfica 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 lsquoCrear una nueva instancia de ReportDocument | Ejemplo1ListadoProductosrsquo Maacutes adelante veremos con maacutes detalles queacute significa eso 992256 Si examina las propiedades disponibles en la Ventana de propiedades veraacute toda una serie de propiedades loacutegicas con nombres lsquoDisplayhelliprsquo y lsquoShowhelliprsquo cuyo objetivo es permitirnos configurar queacute 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 iexclY ya estaacute Ejecute la aplicacioacuten y veraacute coacutemo hemos logrado mostrar en una ventana de Windows un informe Crystal Reports sin escribir ni una sola liacutenea de coacutedigo

TEacuteCNICAS FUNDAMENTALES DE DISENtildeO DE INFORMES En este tema se presentan las teacutecnicas fundamentales que necesitaraacute dominar perfectamente el programador que disentildee informes de Crystal Reports pues se presentan en la praacutectica con mucha frecuencia

INFORMES CON MUacuteLTIPLES TABLAS Rara es la ocasioacuten en que todos los datos necesarios para presentar en un informe se pueden obtener de una misma tabla de la base de datos Las metodologiacuteas modernas de disentildeo de bases de datos relacionales favorecen la normalizacioacuten y esa teacutecnica promueve la separacioacuten de la informacioacuten en diferentes tablas para evitar problemas de redundancia e inconsistencia Generalmente al disentildear un informe necesitaremos combinar la informacioacuten proveniente de la tabla principal con los contenidos de al menos uno o maacutes cataacutelogos u otras tablas de propoacutesito general Por ejemplo la base de datos AdventureWorks agrupa los productos por subcategoriacuteas y categoriacuteas Suponga que necesitamos mostrar en nuestro informe anterior los productos organizados inicialmente por subcategoriacuteas La tabla Products incluye un campo ProductSubcategory en la que se almacena el coacutedigo de subcategoriacutea una clave externa (foraacutenea) a otra tabla de la base de datos ProductionProductSubcategory Si queremos mostrar en el informe los nombres de las subcategoriacuteas en lugar de sus coacutedigos tendremos que indicarle a Crystal Reports que obtenga la informacioacuten correspondiente cruzando la tabla de productos con la de subcategoriacuteas

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 14: Crystal Report - Curso Practico

14

Para lograr esto haremos uso de otro de los asistentes de Crystal el Asistente de base de datos (opcioacuten Base de datos | Asistente de base de datos en el menuacute de Crystal Reports) Se daraacute cuenta que este diaacutelogo 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 ProductionProductSubcategory en la vista de aacuterbol de la izquierda (despliegue el nodo lsquoConexiones actualesrsquo y veraacute nuestro servidor de base de datos y dentro de eacutel a la base de datos AdventureWorks) y antildeadirla a la vista de la derecha Inmediatamente despueacutes de que agregue la tabla de subcategoriacuteas al informe apareceraacute en el cuadro de diaacutelogo una segunda pestantildea Viacutenculos que es donde debemos indicarle a Crystal coacutemo establecer la relacioacuten entre las dos tablas Siempre que un informe incluya maacutes de una tabla Crystal nos obligaraacute a establecer claramente cuaacutel es la relacioacuten entre las mismas Aunque el Disentildeador es capaz de proponernos viacutenculos en base a las relaciones entre las tablas como podraacute observar que ocurre en este caso En la pestantildea Viacutenculos del asistente podemos establecer relaciones entre las tablas simplemente arrastrando con el ratoacuten desde el campo de origen hacia el de destino Pruebe a borrar el viacutenculo creado impliacutecitamente (botoacuten lsquoBorrar viacutenculosrsquo) 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 estaraacuten disponibles todos los campos de la tabla de subcategoriacuteas y podremos arrastrar los campos de esa tabla sobre cualquier seccioacuten del informe Por ejemplo para ver el nombre de la subcategoriacutea a la que pertenece cada producto arrastraremos el campo Name de la tabla ProductionSubcategory sobre la seccioacuten de Detalles Posteriormente habraacute que recolocar los objetos de esa seccioacuten para mejorar el aspecto del informe Si cambia a la Vista previa veraacute que para cada producto se muestra su subcategoriacutea

ORDENACIOacuteN Y AGRUPACIOacuteN Si al examinar la vista preliminar del informe tiene la impresioacuten de que los registros ya llegan ordenados por subcategoriacuteas no se fiacutee ndash ello ha sido puramente coyuntural En ninguacuten momento hemos dicho que queremos obtener el listado ordenado por subcategoriacuteas nombres de producto u otro criterio De hecho si examina la sentencia SQL que Crystal Reports enviaraacute a la base de datos para recuperar la informacioacuten necesaria (en el menuacute de Crystal Reports seleccione Base de datos | Mostrar consulta SQL) veraacute que eacutesta tampoco incluye ninguna claacuteusula ORDER BY Para indicar los criterios de ordenacioacuten debemos utilizar el Asistente de ordenacioacuten de registros en la barra de herramientas lsquoPrincipalrsquo o en el menuacute Report | Asistente de ordenacioacuten de registros Este asistente nos presenta un cuadro de diaacutelogo en el que podemos establecer el criterio de ordenacioacuten principal asiacute como otros secundarios que soacutelo entraraacuten 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 categoriacutea y dentro de cada categoriacutea por nombre debemos indicar ambos campos en ese orden al asistente Observe que las categoriacuteas apareceraacuten en orden alfabeacutetico dado que se trata de un campo alfanumeacuterico 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 ordenacioacuten de registros que acabamos de establecer y vez de ello insertamos un grupo por subcategoriacuteas utilizando el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten Insertar | Grupo del menuacute) y luego lanzamos de nuevo el Asistente de ordenacioacuten de registros veremos que el campo correspondiente habraacute sido agregado a la lista de criterios de ordenacioacuten Cuando se selecciona la opcioacuten de Insertar grupo se presenta un cuadro de diaacutelogo en el que podemos indicar el campo por el que deseamos agrupar (en nuestro caso ProductSubcategoryName si queremos los grupos en orden alfabeacutetico) y si queremos un orden ascendente o descendente La pestantildea 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 paacutegina para ello si fuera necesario) o repetir el encabezado del grupo en cada paacutegina al ejecutar el informe

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 15: Crystal Report - Curso Practico

15

Observaraacute que se crean dos nuevas secciones de Encabezado y Pie de grupo numeradas con 1 por tratarse del primer (y uacutenico) grupo del informe En la seccioacuten de Encabezado de grupo el Disentildeador coloca ademaacutes un objeto de nombre de grupo asociado al campo que hemos indicado como campo para agrupar En la Vista previa podremos ver coacutemo luce ahora el informe y coacutemo en principio podemos eliminar el nombre de subcategoriacutea (que se repite para cada producto del grupo) de la seccioacuten de Detalles Vamos a complicar ahora un poco maacutes el informe y crear un segundo grupo externo Para ello necesitaremos agregar al informe otra nueva tabla ProductionProductCategory pues las subcategoriacuteas pertenecen a su vez a categoriacuteas El enlace esta vez se realiza a traveacutes de la clave foraacutenea 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 categoriacuteas Esta vez lo maacutes conveniente es hacerlo utilizando el Asistente de grupos (en el menuacute de Crystal Reports seleccionamos Report | Asistente de grupos) pues queremos que este grupo quede a nivel externo englobando al de subcategoriacuteas Una vez creado el grupo en la Vista previa podremos observar el resultado

TOTALIZACIOacuteN (RESUacuteMENES) Mediante el botoacuten de Insertar resumen o la opcioacuten correspondiente del menuacute podremos antildeadir resuacutemenes estadiacutesticos 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 cuaacutentos productos hay por cada categoriacutea y subcategoriacutea Si pulsamos el botoacuten de Insertar resumen el Disentildeador nos preguntaraacute como antes queacute campo es el que queremos resumir (ProductProductNumber) queacute tipo de operacioacuten queremos realizar (Recuento) y la ubicacioacuten 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 quisieacuteramos un total general que ya tenemos) en el Pie del grupo externo (si quisieacuteramos contar cuaacutentos productos hay de cada categoriacutea) o en el Pie del grupo interno (si quisieacuteramos contar cuaacutentos productos hay en cada subcategoriacutea) Primero insertaremos un resumen a nivel de categoriacuteas (grupo externo) para mejorar la esteacutetica del informe pondremos a su izquierda un objeto de texto que diga lsquoTotal categoriacutearsquo Observe tambieacuten que tendremos que cambiar el formato del resultado pues Crystal Reports por defecto muestra los campos numeacutericos con dos cifras decimales (opcioacuten que puede cambiarse en la configuracioacuten general del Disentildeador accesible desde la opcioacuten del menuacute Disentildeo | Especificaciones predeterminadas | Campos | Nuacutemero) A continuacioacuten repetiremos la operacioacuten de insertar resumen pero ahora contabilizando la cantidad de productos por cada subcategoriacutea para variar mostraremos el resumen no como una cantidad absoluta sino como un porcentaje relativo a la cantidad de productos en su categoriacutea (opcioacuten lsquoMostrar como porcentaje dersquo) Tenga en cuenta que los resuacutemenes de grupos normalmente se colocan en el pie del grupo pero pueden tambieacuten moverse a la seccioacuten de Cabecera del grupo correspondiente esto provocaraacute una cierta sobrecarga al motor de impresioacuten de Crystal Reports que tendraacute que generar en memoria todos los datos del grupo antes comenzar a imprimirlo pero este coste es generalmente asumible y poner los resuacutemenes en la cabecera es muchas veces esteacuteticamente conveniente Esto es lo que haremos con este uacuteltimo resumen por subcategoriacuteas

MAacuteS SOBRE LAS SECCIONES PROFUNDIZACIOacuteN Las secciones como un todo tambieacuten 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 seccioacuten disponible en el menuacute de Crystal Reports en Report | Asistente de seccioacuten El Asistente de

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 16: Crystal Report - Curso Practico

16

seccioacuten 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 992256 suprimir la seccioacuten completamente Por ejemplo en nuestro informe la seccioacuten de Pie de grupo del grupo interno ha quedado vaciacutea y lo mejor es suprimirla 992256 provocar un salto de paacutegina antes o despueacutes de imprimir la seccioacuten 992256 ajustar la seccioacuten a la parte inferior de la paacutegina (lo que implica que el contenido de la proacutexima seccioacuten pasaraacute a la paacutegina siguiente) 992256 reiniciar la numeracioacuten de las paacuteginas despueacutes de imprimir la seccioacuten 992256 mantener unido todo el contenido de la seccioacuten aunque haya que cambiar de paacutegina para ello 992256 suprimir la seccioacuten en caso de que no contenga nada 992256 hacer que el contenido de la seccioacuten subyazca al de las siguientes secciones maacutes adelante utilizaremos esta opcioacuten para provocar un efecto de ldquomarca de aguardquo en todas las paacuteginas del informe 992256 Por uacuteltimo queriacuteamos hacer especial eacutenfasis en la opcioacuten lsquoOcultar (se permite profundizar)rsquo que nos parece especialmente importante Tenga en cuenta que cada vez maacutes los informes no se destinan a ser presentados en papel sino a ser consumidos de forma interactiva Esta opcioacuten al igual que lsquoSuprimirrsquo hace que una seccioacuten no se muestre cuando se presente el informe pero a diferencia de la anterior permite que el usuario haciendo clic con el ratoacuten sobre un elemento de nivel superior (generalmente un nombre de grupo o resumen) despliegue el contenido de esa seccioacuten oculta en una vista independiente Por ejemplo marquemos con la opcioacuten lsquoOcultar (se permite profundizar)rsquo a la seccioacuten de detalles de nuestro informe y veamos el efecto que se obtiene a primera vista el informe soacutelo contiene los resuacutemenes pero si el usuario pulsa sobre cualquiera de los nombres de subcategoriacuteas veraacute los productos pertenecientes a esa subcategoriacutea en una nueva pestantildea del visor Esto es a lo que se le llama ldquoprofundizacioacutenrdquo (drill down) Desde el Asistente de seccioacuten tambieacuten tenemos la posibilidad de insertar y eliminar (sub)secciones El objetivo de la opcioacuten lsquoInsertarrsquo de menuacute como hemos mencionado antes es realmente el de que podamos dividir una seccioacuten en subsecciones con el objetivo de aplicarles distintos valores de propiedades a cada subseccioacuten Veamos un ejemplo tiacutepico Supongamos que queremos poner el logotipo de nuestra empresa como ldquomarca de aguardquo en el centro de todas las paacuteginas del informe Para ello seguiremos los siguientes pasos a) Dividiremos la seccioacuten de Encabezado de paacutegina (que como sabemos se imprime en la parte superior de cada paacutegina del informe) en dos subsecciones Para ello seleccionamos la seccioacuten de Encabezado de paacutegina y pulsamos el botoacuten lsquoInsertarrsquo Veraacute que la seccioacuten se divide en dos subsecciones denominadas lsquoarsquo y lsquobrsquo y todo lo que hubiera en la seccioacuten original es pasado a la subseccioacuten lsquoarsquo b) Configuraremos la nueva subseccioacuten lsquobrsquo (y solo ella) para que subyazca al resto de las secciones (opcioacuten lsquoSituar debajo de las secciones posterioresrsquo) c) Ya en el Disentildeador ampliaremos por la vertical la subseccioacuten lsquobrsquo del encabezado y pondremos cerca del borde inferior el logotipo de nuestra empresa iexclListo Si activa la Vista previa veraacute que el logotipo subyace perfectamente a todas las paacuteginas del informe

SELECCIOacuteN DE REGISTROS El Asistente de seleccioacuten de Crystal Reports permite establecer las condiciones que deben satisfacer los registros que han de ser utilizados para la confeccioacuten del informe Para nuestro informe actual el asistente mostraraacute una uacutenica pestantildea asociada a la condicioacuten de que el campo ProductFinishedGoodsFlag sea verdadero A esa pestantildea podremos agregar otras con nuevas condiciones y Crystal Reports haraacute que solo se utilicen los registros que satisfagan todas las condiciones especificadas (o sea se aplicaraacute la operacioacuten loacutegica AND a todas las condiciones) A modo de ejemplo vamos a limitar el conjunto de registros a aquellos productos que continuacutean a la venta ndash esos registros tendraacuten un valor nulo en el campo SellEndDate Pulsemos el botoacuten lsquoNuevorsquo para indicar una nueva

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 17: Crystal Report - Curso Practico

17

condicioacuten de seleccioacuten Elijamos el campo ProductSellEndDate (de nuevo observe que podriacuteamos 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 uacuteltima opcioacuten de la lista desplegable que aparece en la pestantildea lsquofoacutermularsquo Y la foacutermula que deberemos teclear es IsNull (ProductSellEndDate) Si pulsamos el botoacuten lsquoMostrar foacutermularsquo del asistente veremos una foacutermula con todas las de la ley escrita en el lenguaje de foacutermulas de Crystal Reports (que estudiaremos en el tema 4) Se trata de un lenguaje de programacioacuten completo complementado ademaacutes con una enorme biblioteca de funciones para todas las necesidades comunes En este lenguaje es que se escriben en uacuteltima instancia las condiciones de seleccioacuten de un informe Nota avanzada El Disentildeador de Crystal Reports determina de manera inteligente cuaacutendo es posible traducir una foacutermula de seleccioacuten escrita en el lenguaje de Crystal en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos Si incluye foacutermulas Crystal complejas en sus foacutermulas de seleccioacuten no seraacute posible traducirlas a SQL y el filtrado de registros deberaacute hacerse en la maacutequina cliente con el consiguiente incremento del traacutefico de red y peacuterdida de rendimiento Mediante la opcioacuten Base de datos | Mostrar sentencia SQL del menuacute de Crystal Reports podraacute comprobar que las dos condiciones que hemos puesto se traducen perfectamente a SQL

SELECCIOacuteN Y ORDENACIOacuteN DE GRUPOS A diferencia de la seleccioacuten de registros que incluye o excluye del informe registros individuales en base a una condicioacuten la seleccioacuten de grupos permite establecer queacute grupos enteros deben o no ser incluidos en el informe En teacuterminos de SQL si la formula de seleccioacuten de registros corresponde a la claacuteusula WHERE de una sentencia SELECT entonces la foacutermula de seleccioacuten de grupo corresponde a la claacuteusula HAVING El Asistente de seleccioacuten determina que una foacutermula de seleccioacuten es de grupo si el campo de Crystal Reports que utilizamos en la condicioacuten es un campo normal de la base de datos o un resumen En este uacuteltimo caso estaacute claro que se trata de una condicioacuten de seleccioacuten de grupo Por ejemplo supongamos que nos interesan uacutenicamente las categoriacuteas con maacutes de 50 productos En el Asistente de seleccioacuten pulsamos lsquoNuevorsquo para agregar una nueva condicioacuten en el diaacutelogo de seleccioacuten de campo que aparece elegimos el recuento de productos por nombre de categoriacuteas y en los siguientes desplegables introducimos lsquoes mayor quersquo y el valor 50 Al pulsar el botoacuten lsquoMostrar foacutermularsquo veremos la foacutermula Crystal correspondiente a la condicioacuten especificada Por otra parte una ojeada a la Vista previa nos convenceraacute de que la seleccioacuten funciona Nota avanzada Por lo general (al menos en informes de tipo ldquolistadordquo) el motor de Crystal Reports ejecuta la agrupacioacuten y la seleccioacuten de grupos en la maacutequina cliente Existe una opcioacuten de configuracioacuten lsquoRealizar agrupamiento en el servidorrsquo (Report | Opciones del informe del menuacute) mediante la cual se indica al motor que utilice claacuteusulas GROUP BY y HAVING cuando sea posible Pero cuando es necesario traer tambieacuten los registros individuales para utilizarlos en el informe el motor no hace uso de esa posibilidad En cuanto a la ordenacioacuten 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 categoriacuteas y subcategoriacuteas se presentaraacuten en orden alfabeacutetico 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 ordenacioacuten de grupos (botoacuten en la barra de herramientas lsquoPrincipalrsquo u opcioacuten Report | Asistente de ordenacioacuten de grupos en el menuacute) Supongamos por ejemplo que deseamos presentar las categoriacuteas no en orden alfabeacutetico sino en orden descendente de la cantidad de productos diferentes pertenecientes a cada categoriacutea Lanzamos el Asistente de ordenacioacuten de grupos y veremos que nos presenta dos pestantildeas dado que el informe

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 18: Crystal Report - Curso Practico

18

incluye dos grupos El grupo que nos interesa es el externo que es el preseleccionado por defecto En el desplegable lsquoOrdenarrsquo seleccionamos Todo y entonces a su derecha apareceraacute la lista de los resuacutemenes definidos a ese nivel para que indiquemos el criterio seguacuten el que queremos ordenar los grupos En nuestro caso habraacute solo un resumen que seleccionaremos Adicionalmente se nos permite indicar si deseamos que los grupos aparezcan en orden ascendente o descendente (este uacuteltimo nuestro caso) Despueacutes de pulsar Aceptar podremos ver el resultado en la vista preliminar Hay que decir que este Asistente ademaacutes de la ordenacioacuten tambieacuten nos permite realizar una seleccioacuten de grupos seguacuten criterios que se utilizan con relativa frecuencia en la praacutectica y cuya especificacioacuten mediante el Asistente de seleccioacuten que hemos visto anteriormente requeririacutea la programacioacuten de foacutermulas de cierta complejidad Si en lugar de elegir la opcioacuten lsquoTodorsquo en el desplegable lsquoOrdenarrsquo seleccionamos lsquoN superioresrsquo (lsquoN inferioresrsquo) estariacuteamos indicando que deseamos incluir en el informe solo los N primeros (uacuteltimos) grupos seguacuten el resumen indicado en orden descendente (ascendente) de los valores Por otra parte las opciones lsquoPorcentaje maacuteximorsquo y lsquoPorcentaje miacutenimorsquo 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 seguacuten nuestra conveniencia Observe ademaacutes que existe la posibilidad de agrupar los elementos que los grupos que no superen la ldquocribardquo en un grupo comuacuten cuyo nombre por defecto es lsquoOtrosrsquo

GRAacuteFICOS Crystal Reports ofrece unas posibilidades muy amplias para la incorporacioacuten de graacuteficos comerciales en nuestros informes aquiacute simplemente mostraremos un ejemplo tiacutepico que le daraacute una idea de coacutemo pueden incorporarse a un informe tales graacuteficos Para poder incorporar un graacutefico a un informe es necesario haber definido previamente los resuacutemenes que serviraacuten como valores a partir de los cuales se dibujaraacute el graacutefico Para incorporar un graacutefico a un informe se debe utilizar la opcioacuten Insertar | Graacutefico del menuacute o el botoacuten correspondiente de la barra de herramientas lsquoInsertarrsquo que despliegan el Asistente de graacuteficos Este asistente tiene dos modos de trabajo que se configuran mediante la casilla lsquoEstablecer opciones automaacuteticamentersquo de su primera pestantildea Si la casilla estaacute marcada el asistente generaraacute automaacuteticamente los tiacutetulos para el graacutefico y los ejes escalas colores etc En caso contrario tendremos la posibilidad de indicar todas esas caracteriacutesticas Una buena teacutecnica puede ser mantener inicialmente la configuracioacuten automaacutetica y maacutes adelante editar las opciones del graacutefico y pasar al modo manual para indicar esas opciones en detalle Ademaacutes de esta opcioacuten en la primera pestantildea se indica el tipo de graacutefico que deseamos incorporar al informe (de barras liacuteneas aacutereas circular o tarta etc) Para nuestro ejemplo elegiremos un graacutefico de barras En la segunda pestantildea del asistente es donde se especifica lo fundamental los datos a partir de los cuales se dibujaraacute el graacutefico y la situacioacuten del mismo En nuestro caso debido a que tenemos dos niveles de agrupacioacuten podemos basar el graacutefico en dos series de datos la cantidad de productos por cada categoriacutea en cuyo caso el graacutefico apareceraacute una sola vez en el pie o la cabecera del informe (recuerde que generalmente los objetos situados en una seccioacuten de lsquopiersquo pueden moverse a su lsquocabecerarsquo hermana) o la cantidad de productos por cada subcategoriacutea dentro de cada categoriacutea en cuyo caso tendremos un graacutefico para cada categoriacutea situado en la seccioacuten de pie (o la cabecera) del grupo correspondiente a las categoriacuteas Vamos a elegir aquiacute la opcioacuten maacutes difiacutecil la segunda indiquemos lsquoPor cada ProductCategoryNamersquo en el desplegable lsquoUbicarrsquo Veraacute que en el grupo lsquoDatosrsquo aparecen automaacuteticamente la informacioacuten adecuada los valores a utilizar para el graacutefico se obtienen cuando cambia la subcategoriacutea (el grupo maacutes interno) y el resumen a utilizar es el uacutenico disponible a ese nivel el que cuenta la cantidad de productos de cada categoriacutea Por uacuteltimo la tercera pestantildea del asistente permite establecer los textos que apareceraacuten en el graacutefico como tiacutetulo subtiacutetulo nombres de ejes etc y sus propiedades De momento mantenga los valores

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 19: Crystal Report - Curso Practico

19

predeterminados y pulse Aceptar para cerrar el asistente Veraacute coacutemo aparece en el informe un graacutefico de subcategoriacuteas para cada una de las categoriacuteas

EXPORTACIOacuteN A OTROS FORMATOS WORD EXCEL HTML PDF Crystal Reports nos permite exportar los resultados de la ejecucioacuten 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 disposicioacuten de terceros en otros casos (Microsoft Excel Microsoft ODBC) el objetivo es capturar los resultados numeacutericos que el informe contiene para realizar ciertas transformaciones posteriores sobre ellos utilizando otras aplicaciones Si pulsa el botoacuten de Exportar informe de la barra de herramientas del visor le apareceraacute un diaacutelogo en el que podraacute elegir el formato de exportacioacuten y el destino (en la versioacuten integrada en Visual Studio uacutenicamente un fichero en disco) Un segundo diaacutelogo especiacutefico para el formato de exportacioacuten elegido apareceraacute a continuacioacuten para permitirnos configurar el resultado Y esto daraacute paso a un tercer cuadro de diaacutelogo en el que podremos elegir la ruta y el nombre del fichero a crear En los temas del curso dedicados a la programacioacuten veremos coacutemo exportar informes desde nuestras aplicaciones

TOTALES ACUMULADOS Un tipo de resumen muy comuacuten y que tiene sus particularidades que lo distinguen de los demaacutes resuacutemenes son los totales acumulados Los totales acumulados nos permiten implementar en nuestros informes los conocidos ldquosuma y siguerdquo frecuentes por ejemplo en listados de operaciones bancarias Suponga que deseamos listar los pedidos (coacutedigo fecha importe) recibidos a partir del 172004 (no hay datos muy recientes en AdvertureWorks -) En una columna del listado queremos mostrar un ldquosuma y siguerdquo con el total acumulado hasta ese momento del importe de los pedidos Los datos generales sobre los pedidos se almacenan en la tabla SalesSalesOrderHeader de la base de datos Ademaacutes en la tabla SalesSalesOrderDetail se almacenan los detalles (liacuteneas) de cada pedido pero en este momento no necesitaremos esa segunda tabla Ante todo antildeadiremos a nuestro proyecto de Visual Studio un nuevo informe (botoacuten derecho sobre el nodo del proyecto en el Explorador de soluciones | Agregar | Nuevo elemento | Crystal Reports) Llamemos al informe ListadoPedidosrpt Inmediatamente despueacutes de indicar el nombre el Asistente de informes apareceraacute automaacuteticamente para que especifiquemos las caracteriacutesticas del informe Se trata de un informe estaacutendar y seleccionamos la base de datos AdventureWorks y de ella la tabla SalesSalesOrderHeader Los campos que nos interesan son SalesOrderID OrderDate y TotalDue No necesitamos agrupaciones por lo que saltamos directamente sobre esa paacutegina del Asistente En la paacutegina de seleccioacuten de registros indicamos que nos interesan los pedidos en los que OrderDate es posterior al 172004 Pulsamos lsquoFinalizarrsquo y podremos ver la presentacioacuten preliminar del informe Ahora crearemos el total acumulado Para ello en el nodo lsquoCampos de totales acumuladosrsquo del Explorador de campos pulsamos el botoacuten derecho del ratoacuten y seleccionamos lsquoNuevorsquo Apareceraacute un cuadro de diaacutelogo en el que se pueden indicar las caracteriacutesticas que queremos que tenga el total acumulado Ante todo se debe indicar el campo que se quiere acumular (en nuestro caso TotalDue) y la operacioacuten de resumen (aquiacute suma) En la seccioacuten lsquoEvaluarrsquo se indica en queacute momento queremos que el acumulador se evaluacutee En este caso dejaremos la opcioacuten por defecto evaluar para cada registro pero observe que tambieacuten es posible evaluar el total acumulado solo cuando cambie el valor de un campo cuando se cambie de grupo o cuando se cumpla una condicioacuten cualquiera (expresada mediante una foacutermula) Por su parte en la seccioacuten lsquoRestablecerrsquo indicamos cuaacutendo queremos que el acumulador se reinicie a cero Aunque tambieacuten lo dejaremos ahora en lsquoNuncarsquo observe que se puede reiniciar el acumulador cada vez que se cambia de campo de grupo o cuando se cumpla una foacutermula Estudiaremos el lenguaje de foacutermulas de Crystal Reports en el siguiente tema Y en principio iexclya estaacute Basta con pulsar el botoacuten

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 20: Crystal Report - Curso Practico

20

lsquoFinalizarrsquo y arrastrar el campo recieacuten creado a la seccioacuten de Detalles del informe (preferiblemente a la derecha del importe del pedido) Veraacute 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 paacutegina Para ello seleccione el campo de total acumulado coacutepielo al Portapapeles (CTRL-C) y luego paacuteguelo (CTRL-V) en la seccioacuten de Pie de paacutegina iexclListo Este es uno de los pocos casos en los que tiene sentido mover objetos de una seccioacuten a otra que no sea su ldquohermanardquo

FOacuteRMULAS En este tema se presentan las foacutermulas de Crystal Reports y sus principales aplicaciones Raacutepidamente se convenceraacute de que las foacutermulas juegan un papel muy importe tanto en informes baacutesicos como en aplicaciones maacutes avanzadas

INTRODUCCIOacuteN Las foacutermulas son una caracteriacutestica muy importante de Crystal Reports que le dan la potencia necesaria para acometer numerosas tareas que de otras maneras seriacutean imposibles y limitariacutean seriamente las posibilidades del producto Baacutesicamente una foacutermula es una expresioacuten maacutes o menos compleja escrita en uno de los dos lenguajes de programacioacuten 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 confeccioacuten de un informe En este curso utilizaremos la sintaxis Visual Basic que seraacute mucho maacutes familiar a los programadores que utilicen VBNET Para garantizar que las foacutermulas utilicen ese lenguaje por favor vaya a la opcioacuten Crystal Reports | Disentildeo | Especificaciones predeterminadas | Elaborando informes del menuacute y selecciones lsquoSintaxis Basicrsquo en el desplegable Lenguaje de foacutermulas En general los lenguajes de foacutermulas de Crystal Reports son lenguajes de programacioacuten 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 foacutermulas se utilizan en el sentido literal del teacutermino ndash el de una expresioacuten que produce un valor de un determinado tipo

SINTAXIS DEL LENGUAJE DE FOacuteRMULAS CRYSTAL Y VISUAL BASIC Una foacutermula se compone a partir de diferentes elementos baacutesicos como son 992256 Constantes 12 (entero) 007 (nuacutemero decimal) ldquoTotalrdquo (cadena de caracteres) True (loacutegica) 1252006 (de fechahora) 992256 Identificadores que pueden representar 992256 Nombres de campos con la sintaxis NombreTablaNombreCampo Por ejemplo para representar al campo Sexo de una tabla llamada Clientes utilizariacuteamos ClientesSexo 992256 Otras foacutermulas con la sintaxis NombreFormula Por ejemplo si al definir la foacutermula B necesitamos utilizar otra foacutermula A la escribiriacuteamos asiacute A 992256 Totales acumulados con la sintaxis NombreTotal 992256 Paraacutemetros del informe con la sintaxis NombreParametro Los paraacutemetros juegan un papel esencial en el desarrollo de informes geneacutericos que puedan utilizarse en muacuteltiples situaciones diferentes sin necesidad de modificaciones A ellos les dedicaremos el Tema 5 992256 Operadores + - (aritmeacuteticos) lt gt (de comparacioacuten) Not And Or (loacutegicos) y otros 992256 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 ldquoreinventar la ruedardquo cada vez que quiera ejecutar una tarea maacutes o menos trivial Por ejemplo si el campo Nombre de la tabla Clientes

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 21: Crystal Report - Curso Practico

21

contiene el nombre del cliente y en un informe deseamos mostrar ese nombre en mayuacutesculas podemos escribir la siguiente foacutermula UCase(ClientesNombre) Aunque pueda parecer necesaria una gran cantidad de tecleo en realidad el programador no tiene que teclear casi nada para componer estas foacutermulas a continuacioacuten veremos coacutemo un potente editor nos ayuda con esta tarea Hay que tener en cuenta siempre el tipo de datos del resultado que una foacutermula produce En ciertas ocasiones una foacutermula puede producir un resultado de cualquier tipo que queramos pero en otros casos Crystal Reports espera que le suministremos una foacutermula que produce un resultado de un tipo determinado y protestaraacute si le suministramos una foacutermula que produce otra cosa aunque sea sintaacutecticamente correcta

APLICACIONES DE LAS FOacuteRMULAS En esta seccioacuten estudiaremos los fundamentos de las foacutermulas de Crystal Reports y presentaremos sus principales aplicaciones que son 992256 Campos calculados 992256 Formato condicional 992256 Seleccioacuten de registros y grupos 992256 Grupos a medida 992256 Totales acumulados condicionales

CAMPOS CALCULADOS La aplicacioacuten maacutes tiacutepica de las foacutermulas son los campos calculados Un campo calculado es un campo (de cualquier tipo de datos soportado por Crystal) que fiacutesicamente 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 antildeo 2004 en salir del almaceacuten de la empresa de camino a su destinatario En la tabla SalesSalesOrderHeader no tenemos directamente ese dato pero siacute tenemos los campos OrderDate (la fecha en que se hizo el pedido) y ShipDate (la fecha en que se hizo el enviacuteo) Podemos calcular el intervalo deseado restando ambas fechas y para ello hace falta una foacutermula En nuestro proyecto seleccione el informe ListadoPedidosrpt En el Explorador de campos pulse el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de foacutermularsquo y seleccione lsquoNuevarsquo Ante todo es necesario dar un nombre a la foacutermula llameacutemosle lsquoDiacuteasHastaSalidarsquo Veraacute que para seguir adelante hay dos opciones lsquoUsar Asistentersquo o lsquoUsar Editorrsquo Se trata de dos herramientas diferentes con un mismo propoacutesito ayudarnos a escribir las foacutermulas con un miacutenimo de tecleo y comprobacioacuten de que la foacutermula es correcta En este curso utilizaremos el Editor que nos parece maacutes intuitivo sin carecer de ninguna de las posibilidades Al pulsar el botoacuten lsquoUsar Editorrsquo apareceraacute ante nosotros el Editor de foacutermulas En el panel de la izquierda estaacute un aacuterbol con todas las foacutermulas del informe podemos cerrarlo para hacer maacutes espacio para nuestra foacutermula actual Ahora la foacutermula se compone en la zona inferior del editor (donde ya aparece automaacuteticamente lsquoformula =rsquo) 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 foacutermulas totales acumulados etc el panel de Funciones en el que tenemos a nuestra disposicioacuten la lista de todas las funciones predefinidas de Crystal (algo sumamente uacutetil) y el panel de Operadores en el que podremos encontrar a todos los operadores del lenguaje Para introducir nuestra foacutermula buscamos en el panel de Identificadores el campo ShipDate de SalesOrderHeader (como el campo no estaacute 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 eacutel ndash veraacute que es copiado a la foacutermula con la sintaxis correcta SalesOrderHeaderShipDate El operador lsquo-rsquo podriacuteamos elegirlo de un

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 22: Crystal Report - Curso Practico

22

modo similar seleccionaacutendolo en el nodo de operadores aritmeacuteticos pero en este caso la ventaja no estaacute tan clara y probablemente sea mejor teclear el caraacutecter Por uacuteltimo seleccionamos del panel de Identificadores el segundo operando OrderDate La foacutermula final es formula = SalesOrderHeaderShipDate - SalesOrderHeaderOrderDate En cualquier momento podemos comprobar la validez de una foacutermula pulsando el botoacuten lsquoRevisarrsquo Una vez editada y validada la foacutermula podemos guardarla y cerrar el editor mediante lsquoGuardar y cerrarrsquo Y ya definida la formula podemos arrastrarla al informe ndash en este caso a la seccioacuten de Detalles Por supuesto tambieacuten podriacuteamos definir resuacutemenes basados en esa foacutermula que se convierte en un campo maacutes del informe

FORMATO CONDICIONAL La aplicacioacuten de las foacutermulas al formato condicional consiste en que mediante una foacutermula es posible programar las caracteriacutesticas visuales de cualquier campo o seccioacuten del informe o incluso que aparezca o no en eacutel Continuando con el mismo ejemplo suponga que queremos resaltar aquellos pedidos que tardaron maacutes de 7 diacuteas en salir del almaceacuten Para ello vamos a resaltar en color rojo los valores correspondientes Seleccionamos la foacutermula pulsamos el botoacuten derecho del ratoacuten y elegimos la opcioacuten lsquoDar formato al camporsquo En el diaacutelogo que aparece activamos la pestantildea lsquoFuentersquo Lo que deseamos es cambiar el color del texto pero no incondicionalmente sino sujeto a una condicioacuten Por eso pulsamos el botoacuten de foacutermula situado a la derecha del desplegable correspondiente al color de la fuente Aparece el editor de foacutermulas y en eacutel debemos introducir la foacutermula que determinaraacute el color del texto En este caso la foacutermula es if DiacuteasHastaSalida gt= 5 then formula = crRed else formula = crBlack Las constantes crRed y crBlack aparecen en el panel de Funciones cuando se esteacute editando una foacutermula que deba producir un color como es el caso De un modo similar podemos programar cualquiera de las caracteriacutesticas visuales de los campos del informe En estos casos la foacutermula 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 condicioacuten En tal caso debemos utilizar la propiedad Suprimir (pestantildea lsquoComuacutenrsquo) del Editor de formato La foacutermula debe producir un resultado booleano y cuando su valor sea True el campo se suprimiraacute del informe Por uacuteltimo 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 ldquopijamardquo haciendo que la seccioacuten de Detalles tenga alternativamente fondo gris o blanco para cada fila del informe Para ello lance el Asistente de seccioacuten y seleccione la seccioacuten de Detalles Active luego la pestantildea lsquoColorrsquo y pulse sobre el botoacuten de foacutermula asociado al desplegable de color de fondo Introduzca la siguiente foacutermula if RecordNumber mod 2 = 1 then formula = crSilver else formula = crWhite RecordNumber es otra funcioacuten predeterminada de Crystal que produce un nuacutemero secuencial para cada registro del conjunto de datos (puede encontrarse bajo el nodo ldquoEstado de impresioacutenrdquo)

GRUPOS PERSONALIZADOS La siguiente aplicacioacuten de las foacutermulas es la que tiene que ver con la seleccioacuten de registros y grupos

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 23: Crystal Report - Curso Practico

23

Como ya hemos presentado anteriormente Crystal permite hacer una seleccioacuten tanto de los registros individuales como de los grupos que se utilizaraacuten al ejecutar el informe El Asistente de seleccioacuten nos permite especificar las condiciones que deberaacuten cumplir los registros o grupos en los casos de condiciones sencillas y se encarga de generar automaacuteticamente las foacutermulas correspondientes Pero cuando lo que queremos expresar va maacutes allaacute de las posibilidades cubiertas por el asistente es necesario pasar a la accioacuten y escribir la foacutermula nosotros mismos Para un ejemplo sencillo suponga que deseamos que el listado de pedidos (ademaacutes de los pedidos a partir de julio del antildeo 2004) incluya solamente los pedidos recibidos a traveacutes de Internet (aquellos para los que el campo SalesOrderHeaderOnlineOrderFlag es True) Simplemente lanzamos el Asistente de seleccioacuten (Crystal Reports | Report | Asistente de seleccioacuten o el botoacuten correspondiente en la barra de herramientas lsquoPrincipalrsquo) Pulsamos el botoacuten lsquoNuevohelliprsquo para antildeadir una nueva condicioacuten de seleccioacuten Y en el desplegable que aparece seleccionamos lsquoes Verdaderorsquo Si ahora pulsamos el botoacuten lsquoMostrar foacutermularsquo podremos ver la foacutermula correspondiente SalesOrderHeaderOrderDate gt= 172004 and SalesOrderHeaderOnlineOrderFlag Nota avanzada Como hemos comentado anteriormente es conveniente limitarse a foacutermulas de seleccioacuten sencillas siempre que sea posible pues Crystal Reports determina automaacuteticamente cuaacutendo es posible traducir una foacutermula de seleccioacuten en una claacuteusula WHERE de SQL para pasarla al motor de bases de datos lo que redunda en una mayor eficiencia

SELECCIOacuteN DE REGISTROS Y GRUPOS Otra aplicacioacuten sumamente uacutetil de las foacutermulas son los grupos personalizados o a medida De manera predeterminada los grupos de Crystal Reports estaacuten 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 condicioacuten 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 categoriacuteas los de menos de 25 Euros los que estaacuten entre 25 y 100 y los de maacutes de 100 Euros Debemos utilizar el botoacuten lsquoInsertar gruporsquo de la barra de herramientas lsquoInsertarrsquo (o seleccionar la opcioacuten correspondiente del menuacute) Como campo para agrupar seleccionamos SalesOrderHeaderTotalDue y como criterio de agrupacioacuten lsquoen orden especiacuteficorsquo Apareceraacute una nueva pestantildea en la que podremos crear nuestros grupos personalizados indicando para cada uno un nombre y la condicioacuten (foacutermula) de pertenencia de los registros a los grupos En nuestro caso llamemos a los grupos PEQUENtildeOS MEDIANOS y GRANDES y asociemos a cada grupo las condiciones correspondientes Al pulsar lsquoAceptarrsquo podremos comprobar que el grupo ha sido creado y la vista previa nos convenceraacute de que la agrupacioacuten se realiza correctamente

TOTALES ACUMULADOS CON CONDICIONES En el tema anterior estudiamos los totales acumulados pero no profundizamos en la posibilidad de asociarles foacutermulas para indicar cuaacutendo se desea evaluarlas y cuaacutendo 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 ordenacioacuten En este veremos que ya hay un criterio establecido el del grupo (recuerde la maacutexima ldquopara agrupar hay que ordenarrdquo) pero podremos establecer la fecha como criterio de ordenacioacuten secundario dentro de cada grupo Ahora seleccionemos nuestro total acumulado pulsemos el botoacuten derecho del ratoacuten sobre eacutel y seleccionemos lsquoEditar total acumuladorsquo En la zona lsquoRestablecerrsquo (inferior derecha) marquemos la opcioacuten

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 24: Crystal Report - Curso Practico

24

lsquoUse una foacutermularsquo y pulse el botoacuten de foacutermula correspondiente Introduzca la foacutermula formula = PreviousValue(SalesOrderHeaderOrderDate) ltgt SalesOrderHeaderOrderDate La funcioacuten predefinida PreviousValue nos da el valor del campo indicado en el registro anterior Es muy uacutetil para detectar situaciones de cambios de grupo y otras situaciones similares frecuentemente en combinacioacuten con otras funciones como OnFirstRecord (que devuelve True si estamos situados en el primer registro)

PARAacuteMETROS En este tema presentaremos los paraacutemetros que juegan un papel muy importante de cara a la programabilidad de los informes

INTRODUCCIOacuteN La inmensa mayoriacutea de los informes se disentildean para luego utilizarlos frecuentemente de manera perioacutedica Sin embargo cada nueva ejecucioacuten del informe necesitaraacute pequentildeos ajustes derivado del cambio de los datos de entrada del informe Si los paraacutemetros no existieran cada nueva ejecucioacuten requeririacutea una modificacioacuten previa del informe en el Disentildeador ndash un verdadero problema para la productividad Los paraacutemetros nos permiten precisamente definir informes adaptables en los que los datos de entrada cambiantes se solicitan inmediatamente antes de la ejecucioacuten Continuando con nuestro listado de productos de ejemplo supongamos que nos interesara poder ejecutar el informe para distintos valores de la fecha de inicio ndash ahora mismo el informe tiene ldquoclavadordquo el valor 172004 Pues bien lo ideal hubiera sido haber definido un paraacutemetro para esa fecha de inicio cosa que mostraremos a continuacioacuten

DEFINICIOacuteN Y USO DE PARAacuteMETROS Para definir un paraacutemetro se debe pulsar con el botoacuten derecho del ratoacuten sobre el nodo lsquoCampos de paraacutemetrorsquo del Explorador de campos y seleccionar la opcioacuten lsquoNuevorsquo En el diaacutelogo que aparece debemos introducir los siguientes datos 992256 Nombre del paraacutemetro Llamemos al paraacutemetro FechaInicio Para referirse luego al paraacutemetro desde foacutermulas etc se utilizaraacute la sintaxis FechaInicio 992256 Texto de la solicitud Antes de ejecutar un informe con paraacutemetros Crystal Reports preguntaraacute los valores a asignar a los paraacutemetros Aquiacute se debe introducir el texto que apareceraacute en el diaacutelogo de pregunta en este caso lsquoFecha de iniciorsquo 992256 Tipo de datos El tipo de datos del paraacutemetro en este caso Fecha 992256 Valores predeterminados Aquiacute podemos especificar para el paraacutemetro uno o maacutes valores por defecto que se mostraraacuten en el cuadro de diaacutelogo de solicitud de paraacutemetros para que el usuario no tenga que teclearlos 992256 Opciones Opciones avanzadas relacionadas con la utilizacioacuten de muacuteltiples valores Esa es una de las dos facetas de la utilizacioacuten de un paraacutemetro La segunda es su utilizacioacuten y para ello podemos hacer con el paraacutemetro todo lo que podemos hacer con cualquier otro campo arrastrarlo sobre el informe o utilizarlo en cualquier foacutermula En nuestro ejemplo la fecha de inicio forma parte de la foacutermula de seleccioacuten de registros Para hacer uso del paraacutemetro lanzamos el Asistente de seleccioacuten y sustituimos la fecha actualmente en uso por la sintaxis de uso del paraacutemetro FechaInicio Solo resta entonces mostrar la vista previa para cerciorarnos de que la definicioacuten del paraacutemetro ha sido aceptada Crystal nos solicitaraacute que indiquemos un valor para la fecha de inicio antes de mostrar el informe

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 25: Crystal Report - Curso Practico

25

Hay que sentildealar que (como veremos en el proacuteximo tema) las libreriacuteas NET de Crystal ofrecen la posibilidad de asignar desde programa valores a los paraacutemetros de modo que el cuadro de diaacutelogo no aparezca en pantalla

SUBINFORMES Otra posibilidad muy interesante que ofrece Crystal Reports es la de anidar un informe dentro de otro una caracteriacutestica que comuacutenmente se conoce como subinformes Para incorporar un informe como subinforme dentro de otro se utiliza el botoacuten lsquoInsertar subinformersquo de la barra de herramientas lsquoInsertarrsquo (o la opcioacuten correspondiente del menuacute) Esta posibilidad puede utilizarse por ejemplo para ldquoconcatenarrdquo un informe a continuacioacuten de otro insertaacutendolo en una subseccioacuten del pie de informe Tal aplicacioacuten es en general sumamente directa y la uacutenica opcioacuten interesante es la de integrar el subinforme completo cuando se ejecuta el informe externo o simplemente poner un hiperviacutenculo para que el subinforme se ejecute bajo demanda (lsquoa peticioacutenrsquo es el teacutermino que utiliza Crystal)

SUBINFORMES PARAMETRIZADOS La aplicacioacuten maacutes importante de los subinformes son los subinformes parametrizados En ellos un informe se integra como subinforme dentro de otro (normalmente en la seccioacuten de Detalles de eacuteste) y el informe externo (contenedor) comunica al interno a traveacutes de un paraacutemetro un valor que le indica a eacuteste uacuteltimo queacute 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 podraacute ser el de integrar dentro de la seccioacuten de Detalles del informe actual un subinforme que presente los detalles del pedido actual Esta teacutecnica tiene la ventaja de que podriacuteamos indicar que el subinforme se ejecute bajo demanda lo que reduciriacutea la carga sobre el motor de base de datos Para empezar inserte un subinforme en la seccioacuten de detalles del listado de pedidos Marque la casilla lsquoSubinforme a peticioacutenrsquo Indique que desea crear un nuevo subinforme con el Asistente llame al nuevo subinforme DetallesPedidorpt y pulse el botoacuten lsquoAsistente de informesrsquo Al disentildear el nuevo informe indicaremos que la tabla deseada es SalesSalesOrderDetail Elegiremos varios campos como ProductID (coacutedigo de producto ndash en la vida real necesitariacuteamos 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 liacutenea) Pulse lsquoFinalizarrsquo para terminar el disentildeo del informe Seraacute llevado nuevamente al diaacutelogo de insercioacuten de subinforme es hora de pasar a la pestantildea lsquoViacutenculorsquo para establecer la conexioacuten entre el informe y el subinforme En la pestantildea lsquoViacutenculorsquo debemos primero indicar el campo del informe contenedor cuyo valor se debe pasar al subinforme es SalesOrderHeaderSalesOrderID el coacutedigo del pedido A continuacioacuten debemos indicar el campo del subinforme que recibiraacute (a traveacutes de un paraacutemetro cuyo nombre propone el asistente) el coacutedigo del pedido cuyos detalles debe mostrar En nuestro ejemplo es SalesOrderID Y solo nos queda pulsar el botoacuten lsquoAceptarrsquo De la creacioacuten del paraacutemetro y el establecimiento de la foacutermula de seleccioacuten adecuada en el informe recieacuten creado se encarga el automaacuteticamente el asistente La presentacioacuten de la vista previa nos mostraraacute coacutemo funcionan los informes con subinformes bajo demanda al pulsar sobre el ldquohiperviacutenculordquo asociado a un pedido el subinforme con los detalles de dicho pedido se desplegaraacute en una nueva pestantildea del visor de informes

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WINDOWS En este primer tema relacionado con la programacioacuten de aplicaciones que utilicen informes se presentan los recursos fundamentales que hacen posible incorporar informes Crystal Reports en aplicaciones de escritorio

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 26: Crystal Report - Curso Practico

26

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan los fundamentos teoacutericos y las teacutecnicas comunes que se utilizan en la incorporacioacuten de informes Crystal a aplicaciones Windows Forms

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para este nuevo tema relacionado con la programacioacuten NET comenzaremos una nueva aplicacioacuten Windows Forms en la que incluiremos un informe Crystal sencillo puesto que ya hemos cubierto los temas relacionados con el disentildeo de informes Eso siacute el informe incluiraacute paraacutemetros ya que como hemos dicho los paraacutemetros son uno de los recursos fundamentales que ofrece Crystal a los desarrolladores de aplicaciones En Visual Studio 2005 cierre la solucioacuten que tenga abierta y seleccione Archivo | Nuevo | Proyecto Cuando aparezca el cuadro de diaacutelogo lsquoNuevo proyectorsquo elija Visual Basic | Aplicacioacuten de Crystal Reports lo que nos ahorraraacute ciertos pasos que ya hemos visto en el tema 1 Llame al proyecto Ejemplo2 y poacutengalo en el directorio adecuado Inmediatamente se presentaraacute el Asistente de informes de Crystal para que disentildeemos el (primer) informe que el proyecto contendraacute Definiremos en este caso un listado de pedidos similar al que ya hemos hecho anteriormente la tabla es SalesSalesOrderHeader y los campos que mostraremos son SalesOrderID OrderDate y TotalDue No incluiremos foacutermula de seleccioacuten ni paraacutemetros de momento lo haremos maacutes adelante Por ahora trabajaremos con un listado totalmente ldquoplanordquo Al finalizar el disentildeo del informe se nos presenta el entorno integrado de Visual Studio con una aplicacioacuten que en principio ya funciona como podemos comprobar iquestQueacute ha creado el asistente de proyectos Crystal para nosotros Si mostramos la vista Disentildeo del formulario Form1 veremos que en eacuteste contiene dos componentes 992256 Un componente no visual (por lo tanto situado en la banda inferior del disentildeador) llamado CrystalReport11 iquestA queacute clase pertenece este objeto Para responder a esta pregunta conviene pulsar el botoacuten lsquoMostrar todos los archivosrsquo en el Explorador de soluciones Veremos que nuestro informe CrystalReport1rpt tiene un archivo de VB dependiente y si abrimos ese archivo en la vista de Coacutedigo veremos que contiene la definicioacuten 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 eacutese En la siguiente seccioacuten hablaremos con maacutes detalle sobre este objeto 992256 Un componente visual que ocupa toda el aacuterea de la ventana y tiene como funcioacuten presentar un informe Crystal llamado CrystalReportViewer1 La clase a la que pertenece es CrystalReportViewer (cuyo espacio de nombres es CrystalDecisionsWindowsForms) Se trata ni maacutes ni menos que del visor de informes Crystal para Windows ndash 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 construccioacuten de estos objetos al crearse el formulario es suficiente para que veamos el informe al ejecutar la aplicacioacuten

EL MODELO DE OBJETOS DE CRYSTAL REPORTSNET El ejemplo anterior ya nos da una idea bastante completa de las libreriacuteas de clases para NET de Crystal Reports 992256 Por una parte una libreriacutea ofrece clases que representan a un informe como un todo (ReportDocument) y a todos los objetos que componen un informe Crystal o participan en eacutel Estas clases de propoacutesito general se concentran fundamentalmente en el ensamblado CrystalDecisionsCrystalReportsEngine

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 27: Crystal Report - Curso Practico

27

992256 En segundo lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Windows Forms Estas clases se almacenan en el ensamblado CrystalDecisionsWindowsFormsdll y entre ellas destaca una en especiacutefico ndash CrystalReportViewer que implementa el visor de informes Windows 992256 En tercer lugar otra libreriacutea ofrece clases para la presentacioacuten de informes en aplicaciones Web ASPNET Estas clases se almacenan en el ensamblado CrystalDecisionsWebdll y entre ellas destaca tambieacuten una en especiacutefico ndash una que tambieacuten se llama CrystalReportViewer aunque su espacio de nombres es diferente y que implementa el visor de informes para aplicaciones Web Hablaremos maacutes sobre esta clase en el siguiente tema Si busca los componentes de Crystal Reports instalados en el Cuadro de herramientas de Visual Studio veraacute que actualmente (estamos trabajando en una aplicacioacuten Windows) aparecen dos ReportDocument y CrystalReportViewer Un panorama similar se podraacute observar cuando trabajemos en una aplicacioacuten Web soacutelo que entonces se trataraacute 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 uacutenicamente a las clases de la primera libreriacutea cuyo uso es comuacuten 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 alguacuten modo en eacutel Por ejemplo incluye una clase ParameterField para representar las caracteriacutesticas de un paraacutemetro y la clase ReportDocument (que representa a un informe completo) ofrece una propiedad de tipo array ParameterFields() mediante la que podriacuteamos acceder a todos los paraacutemetros 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 geneacuterico sin ninguna caracteriacutestica conocida de antemano En Crystal a esta clase se la conoce bajo el nombre de informe no tipado Podriacuteamos trabajar con nuestro listado de pedidos a traveacutes de un objeto ReportDocument pero perderiacuteamos cierta informacioacuten especiacutefica de nuestro informe concreto y tendriacuteamos que referirnos a cualquier caracteriacutestica del informe a traveacutes de las propiedades y meacutetodos 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 ndash una clase especializada a partir de ReportDocument que solo vale para nuestro informe concreto pero que almacena informacioacuten sobre eacutel que nos facilitan la vida En particular los informes tipados contienen coacutedigo que se encarga automaacuteticamente de cargar el informe concreto que se almacena dentro del ejecutable en forma de recurso Observe en el coacutedigo fuente de CrystalReport1 la propiedad ResourceName Como otro ejemplo vea la definicioacuten de la propiedad Section1 de CrystalReport1 Observe ahora coacutemo el uso de la clase tipada facilita el acceso a la primera seccioacuten del informe Dim doc As ReportDocument = CType(CrystalReport11 ReportDocument) estas dos liacuteneas hacen lo mismo MessageBoxShow(CrystalReport11Section1Name) MessageBoxShow(docReportDefinitionSections(0)Name) Como habraacute comprendido la primera liacutenea de coacutedigo declara una variable geneacuterica 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 soacutelo para trabajos de iacutendole geneacuterica por ejemplo cuando queremos que el mismo componente apunte a diferentes informes durante la ejecucioacuten De hecho cuando se arrastra un ReportDocument del Cuadro de herramientas a un formulario Visual Studio nos

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 28: Crystal Report - Curso Practico

28

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 veraacute sus propiedades en la Ventana de propiedades Debemos mencionar dos muy importantes cuyo significado conviene conocer La primera de ellas es Accioacuten de generacioacuten Veraacute que su valor predeterminado es lsquoRecurso incrustadorsquo Eso significa que cuando la aplicacioacuten es compilada la definicioacuten del informe es almacenada como un recurso dentro del ensamblado principal del proyecto (en nuestro caso del ejecutable) Por lo tanto no necesitaremos desplegar fiacutesicamente el fichero rpt junto con el ejecutable cuando instalemos la aplicacioacuten a otros usuarios lo cual es maacutes coacutemodo y maacutes seguro Como inconveniente si necesitamos hacer modificaciones a un informe incrustado tendremos que recompilar la aplicacioacuten y volver a desplegar el ejecutable La otra opcioacuten de esta propiedad que se utiliza con cierta frecuencia es lsquoNingunarsquo 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 lsquoCopiar siemprersquo o lsquoCopiar si es posteriorrsquo con el objetivo de que el fichero rpt sea copiado al mismo directorio que el ejecutable o libreriacutea final Para un correcto funcionamiento de la aplicacioacuten el fichero rpt siempre deberaacute ir junto con el ejecutable La ventaja de este enfoque es que se podriacutea enviar una nueva versioacuten del informe al usuario sin necesidad de redesplegar toda la aplicacioacuten Y el peligro estaacute en que el informe podriacutea ser borrado o alterado con o sin mala intencioacuten Para cargar la definicioacuten de un informe externo a un objeto ReportDocument o una clase derivada (informe tipado) se utiliza el meacutetodo Load carga cualquier informe externo en un ReportDocument no tipado ReportDocument1Load(CrystalReport1rpt) ReportDocument1Refresh() CrystalReportViewer1ReportSource = reportDocument1

CONEXIOacuteN A LA BASE DE DATOS La clase ReportDocument (y por herencia todos los informes tipados que heredan de ella) ofrecen un meacutetodo SetDatabaseLogon que permite suministrar al motor de Crystal Reports la informacioacuten de conexioacuten necesaria para acceder a la base de datos donde estaacuten los datos que necesita el informe Este meacutetodo ofrece dos variantes fundamentales que permiten indicar 992256 a) Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos definidos dentro del informe 992256 b) Servidor Base de datos Usuario y contrasentildea El informe se ejecutaraacute contra el servidor y base de datos especificados Esta variante es maacutes uacutetil en situaciones donde tenemos una base de datos de desarrollo y otra de produccioacuten Si en nuestro ejemplo necesitaacuteramos suministrar informacioacuten de conexioacuten para ejecutar el informe deberiacuteamos desconectar el visor de informes de CrystalReport11 en tiempo de disentildeo y programar lo siguiente en el evento Load del formulario CrystalReport11SetDatabaseLogon(SQLExpress AdventureWorks sa kk) conexioacuten del visor en tiempo de ejecucioacuten CrystalReportViewer1ReportSource = CrystalReport11

PASO DE PARAacuteMETROS EN TIEMPO DE EJECUCIOacuteN

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 29: Crystal Report - Curso Practico

29

Una de las caracteriacutesticas favoritas de los desarrolladores es la posibilidad de pasar directamente valores de paraacutemetros a los informes de manera transparente Ante todo antildeadiremos dos paraacutemetros 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 esteacuten entre las fechas de inicio y fin indicadas por los paraacutemetros Llamaremos a los paraacutemetros FInicio y FFin y haremos que la foacutermula de seleccioacuten del informe sea SalesOrderHeaderOrderDate in FInicio to FFin Observe la utilizacioacuten de los operadores into (desdehasta) por parte del Asistente A continuacioacuten antildeadiremos las siguientes liacuteneas de coacutedigo al evento Load del formulario asignar valores a paraacutemetros CrystalReport11SetParameterValue(FInicio New DateTime(2003 9 1)) CrystalReport11SetParameterValue(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 meacutetodo SetParameterValue de ReportDocument espera dos valores el nombre del paraacutemetro y el valor a asignar respectivamente El segundo paraacutemetro es de tipo Object dado que los paraacutemetros pueden ser de distintos tipos Hay que comprobar siempre que enviamos datos de los tipos correctos al informe

EXPORTACIOacuteN DE INFORMES MEDIANTE COacuteDIGO Otra de las teacutecnicas comuacutenmente requeridas por los desarrolladores es la posibilidad de exportar el informe a un formato de presentacioacuten diferente tradicionalmente Adobe PDF o Microsoft Word o Excel Aquiacute de nuevo viene en nuestra ayuda la clase ReportDocument que ofrece varios meacutetodos que nos facilitan la tarea El meacutetodo Export() es el maacutes potente de la familia y a la vez el mas complejo de utilizar Permite especificar ademaacutes del destino de la exportacioacuten otras caracteriacutesticas de la exportacioacuten que son uacutetiles sobre todo cuando se exporta a Excel Adicionalmente tenemos los meacutetodos ExportToDisk() ExportToStream() y ExportToHttpResponse() que simplifican la exportacioacuten de informes a un fichero en disco un flujo de salida cualquiera o un flujo HTTP como el generado por una aplicacioacuten o servicio Web Para exportar nuestro informe a un fichero en formato PDF podremos escribir exportar a PDF CrystalReport11ExportToDisk( CrystalDecisionsSharedExportFormatTypePortableDocFormat _ CPEDIDOSPDF) El primer paraacutemetro es de un tipo enumerado que determina el formato de exportacioacuten

IMPRESIOacuteN DE INFORMES Para la impresioacuten de un informe desde coacutedigo de nuevo podemos utilizar un potente meacutetodo de la clase ReportDocument PrintToPrinter() Previamente se debe utilizar la propiedad PrintOptions (una propiedad con poca ldquocienciardquo y bastante ldquomigardquo sobre la que no daremos muchos detalles aquiacute) para seleccionar la impresora activa y establecer muacuteltiples opciones de impresioacuten Por ejemplo para enviar a mi impresora predeterminada una copia de todas las paacuteginas del informe debo escribir imprimir CrystalReport11PrintOptionsPrinterName = Dell Laser Printer 5210n CrystalReport11PrintToPrinter(1 False 0 0)

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 30: Crystal Report - Curso Practico

30

Los paraacutemetros de PrintToPrinter significan a) la cantidad de copias b) si se deben combinar o no las copias en caso de ser maacutes de una c) paacutegina de inicio d) paacutegina de fin Las paacuteginas de inicio y fin se deben poner a cero si se desea obtener copias completas

CONFIGURACIOacuteN DEL VISOR DE INFORMES El Visor de informes de Crystal Reports posee varias propiedades dignas de mencionar aquiacute La primera ReportSource tiene que ver con el origen a partir del que el visor obtiene el informe a mostrar las demaacutes tienen relacioacuten con la esteacutetica de presentacioacuten del informe 992256 ReportSource esta propiedad indica al visor de doacutende debe obtener el informe a mostrar Es una propiedad de tipo Object porque se le puede asignar diferentes valores 992256 Una cadena de caracteres que representa el nombre del fichero que contiene el informe Esta variante es la maacutes simple y primitiva de todas existe desde la primera versioacuten de la libreriacutea Utilizando esta opcioacuten es posible saltarse completamente el modelo de objetos de Crystal 992256 Un objeto de la clase ReportDocument (informe no tipado) o derivada de ella (informe tipado) Esta variante es la que estamos presentando aquiacute 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayStatusBar ndash si se debe mostrar o no la barra de estado 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas 992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 ShowCloseButton ndash mostrar o no el botoacuten de Cerrar 992256 ShowExportButton ndash mostrar o no el botoacuten de Exportar 992256 ShowGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 ShowGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 ShowPageNavigateButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 ShowPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 ShowRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 ShowTextSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 ShowZoomButton ndash mostrar o no el botoacuten de AcercarAlejar

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 informacioacuten En particular un informe Crystal puede obtener sus datos de un DataSet (conjunto de datos) de ADONET lo cual es muy conveniente porque las arquitecturas de muacuteltiples capas de uso comuacuten en la praacutectica actual favorecen la utilizacioacuten de objetos de este tipo para la transmisioacuten de informacioacuten entre capas y generalmente se los puede encontrar en la capa de presentacioacuten 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 oriacutegenes de datos a utilizar para un informe hay un nodo lsquoADONET DataSetsrsquo 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 Disentildeador de Crystal es capaz de acceder a ella para permitirnos seleccionar las tablas campos etc con los que queremos trabajar

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 31: Crystal Report - Curso Practico

31

A la hora de presentar el informe en tiempo de ejecucioacuten es necesario utilizar el meacutetodo SetDataSource () de la clase ReportDocument para conectar el informe con el objeto concreto que almacena el conjunto de datos Por ejemplo CrystalReport21SetDataSource(AdventureWorksDataSet) CrystalReport21Refresh() elimina datos guardados por el informe CrystalReport21Show()

DESPLIEGUE DE APLICACIONES WINDOWS QUE INCLUYAN INFORMES CRYSTAL Una vez terminado el desarrollo de una aplicacioacuten llega el momento del despliegue Con ese objetivo Visual Studio ofrece diferentes tipos de proyectos de instalacioacuten que permiten empaquetar los ficheros que se deben copiar al equipo de destino asiacute como la secuencia de comandos que se deben ejecutar en eacuteste para que la aplicacioacuten quede lista para funcionar en la maacutequina de destino En lo concerniente a Crystal Reports para desplegar correctamente cualquier aplicacioacuten NET que utilice informes Crystal es necesario incluir en el programa de instalacioacuten 992256 las libreriacuteas NET de Crystal Reports 992256 los ficheros RPT que sean externos a la aplicacioacuten Creemos un nuevo proyecto de instalacioacuten para desplegar nuestra reciente aplicacioacuten Ejemplo3 Para ello lo primero es utilizar Archivo | Nuevo proyecto y seleccionar la plantilla Proyecto de instalacioacuten debajo del nodo Otros tipos de proyectos | Instalacioacuten e implementacioacuten Llamemos al proyecto Instalar3 y pulsamos Aceptar Se presentaraacute un editor especializado en el que debemos especificar queacute ficheros accesos directos etc queremos colocar en queacute directorios del equipo de destino Generalmente el ejecutable y los ensamblados privados que componen la aplicacioacuten se colocan en la carpeta de la aplicacioacuten y opcionalmente se colocan accesos directos al ejecutable en el menuacute Programas o el escritorio del usuario Ante todo debemos seleccionar el nodo del proyecto en el Explorador de soluciones e introducir las propiedades baacutesicas del proyecto sobre todo Manufacturer (fabricante) y Product Name (nombre del producto) que determinaraacuten la carpeta de aplicacioacuten por defecto ([Archivos de programa][Fabricante] [NombreProducto]) Para agregar archivos a la carpeta de la aplicacioacuten pulsamos el botoacuten derecho sobre ella y seleccionamos la opcioacuten Agregar En este caso sencillo utilizamos la opcioacuten Archivo para antildeadir el uacutenico archivo necesario el ejecutable Ejemplo3exe (el informe Crystal utilizado estaacute como recurso incrustado) Ahora debemos seleccionar la opcioacuten Proyecto | Propiedades del menuacute de Visual Studio La mayor parte de las opciones del diaacutelogo que aparece son satisfactorias pero siacute debemos pulsar el botoacuten Requisitos previos que nos permite indicar queacute software debe incluirse en nuestro proyecto para instalarlo en la maacutequina de destino si no estuviera ya instalado Ademaacutes de NET Framework 20 (que ya deberaacute estar marcado) debemos marcar la casilla correspondiente a Microsoft Data Access Components 28 (necesario para NET) y la casilla de Crystal Reports para NET Framework 20 Pulsamos Aceptar dos veces para cerrar los cuadros de diaacutelogo y iexclya casi estaacute Solo nos queda seleccionar la opcioacuten Generar | Generar de Visual Studio para generar el proyecto de instalacioacuten El proyecto de instalacioacuten siempre consiste de una jerarquiacutea de carpetas con todos los recursos necesarios para la instalacioacuten empaquetados o no seguacuten las opciones que hayamos seleccionado En cualquier caso en el directorio raiacutez siempre se incluye un fichero Setupexe que es el que debemos ejecutar en la maacutequina de destino para proceder a la instalacioacuten de la aplicacioacuten

UTILIZACIOacuteN DE INFORMES EN APLICACIONES WEB

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 32: Crystal Report - Curso Practico

32

En este tema estudiaremos las particularidades relacionadas con la programacioacuten de aplicaciones Web que utilicen Crystal Reports Los mecanismos para la incorporacioacuten 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 programacioacuten que hemos visto anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten 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 programacioacuten (como veremos en el fondo se utiliza la misma clase ReportDocument) sino con las caracteriacutesticas relacionadas con la visualizacioacuten dado que las aplicaciones Web se ejecutan en un navegador como Internet Explorer El despliegue tambieacuten es muy similar ndash baacutesicamente se trata de hacer que las libreriacuteas NET de Crystal caigan ldquoen su sitiordquo cuando se ejecute el programa de instalacioacuten

TEacuteCNICAS FUNDAMENTALES Las diferentes subsecciones de esta seccioacuten presentan las teacutecnicas especiacuteficas que se utilizan al incorporar informes Crystal en aplicaciones Web ASPNET

INCORPORACIOacuteN DE UN INFORME A UNA APLICACIOacuteN Para mostrar coacutemo incorporar un informe Crystal Reports a una aplicacioacuten Web comenzaremos un nuevo sitio Web ASPNET ubicado en el sistema de archivos Al pulsar Archivo | Nuevo | Sitio Web veraacute que existe una plantilla lsquoSitio Web ASPNET de Crystal Reportsrsquo que nos hariacutea auacuten maacutes faacutecil la vida aquiacute vamos a evitarlo para estudiar el mecanismo a utilizar en el caso general Seleccione la plantilla geneacuterica lsquoSitio Web ASPNETrsquo 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 continuacioacuten agregaremos al proyecto un nuevo informe Crystal que llamaremos Paisesrpt y mostraraacute un listado sencillo de los paiacutesesregiones almacenados en la tabla PersonCountryRegion de AdventureWorks En el caso de las aplicaciones Web es conveniente colocar todos los informes del proyecto dentro de una carpeta comuacuten que llamaremos lsquoinformesrsquo Una vez disentildeado el informe podemos arrastrarlo hacia esa carpeta Llega la hora de configurar la paacutegina Web actual Defaultaspx para que muestre nuestro informe cuando ejecutemos la aplicacioacuten Para ello veamos primero queacute componentes debemos seleccionar del nodo lsquoCrystal Reportsrsquo del Cuadro de herramientas en el caso de una aplicacioacuten Web En primer lugar para mostrar un informe en una paacutegina ASPX necesitaremos un componente CrystalReportSource (lsquoorigen de informe Crystalrsquo) Se trata de un componente que encapsula un objeto de la clase ReportDocument que hemos estudiado antes dotaacutendonos 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 Disentildeo de la paacutegina ASPX A continuacioacuten pulsamos sobre el enlace a su utilidad de configuracioacuten y veremos que soacutelo ofrece una opcioacuten lsquoConfigurar el origen del informersquo donde debemos indicar a queacute informe del proyecto queremos asociarlo Entre las propiedades que ofrece la clase CrystalReportSource debemos destacar 992256 EnableCaching (booleana) y CacheDuration (entero que representa un entero en segundos) Si EnableCaching es verdadera el motor de CrystalReports ldquocachearaacuterdquo en la memoria del servidor el resultado de la ejecucioacuten de un informe durante el intervalo indicado en CacheDuration no teniendo que ejecutar el informe nuevamente si se recibe otra peticioacuten del informe antes de que expire el intervalo Esta posibilidad permite aumentar en gran medida la productividad de nuestros sitios Web 992256 Report Es una propiedad que integra varias caracteriacutesticas del informe como el nombre del fichero de informe los paraacutemetros y oriacutegenes de datos de los que se nutre Se trata mayormente de informacioacuten descriptiva para el tratamiento programaacutetico del informe recomendamos utilizar la propiedad ReportDocument

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 33: Crystal Report - Curso Practico

33

992256 ReportDocument No se ve en la ventana de propiedades porque es una propiedad de tiempo de ejecucioacuten 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 teacutecnicas que hemos estudiado anteriormente (conexioacuten a la base de datos aplicacioacuten de paraacutemetros utilizacioacuten de un DataSet como origen del informe)

CONFIGURACIOacuteN DEL VISOR DE INFORMES HTML Una vez configurado el objeto CrystalReportSource llega el momento de poner sobre la paacutegina ASPX el componente que permitiraacute mostrar en el navegador el resultado de la ejecucioacuten del informe Para ello necesitaremos el componente CrystalReportViewer (nodo lsquoCrystal Reportsrsquo 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 CrystalDecisionsWebCrystalReportViewer La tarea del componente CrystalReportViewer es generar coacutedigo HTML + Javascript que pueda ser mostrado por un navegador estaacutendar Le recomendamos ejecutar la aplicacioacuten Web y utilizar la opcioacuten Ver | Coacutedigo fuente del navegador para cerciorarse de que la interfaz de usuario estaacute ldquohechardquo 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 paacutegina ASPX automaacuteticamente se lanza el asistente para su configuracioacuten lo primero que debemos indicar es a queacute origen de informe queremos conectarlo (en nuestro caso el origen recieacuten creado) Esta conexioacuten se establece a traveacutes de la propiedad ReportSourceID del visor El resto de las propiedades del visor tiene que ver con la visualizacioacuten en siacute a continuacioacuten detallamos las propiedades maacutes importantes 992256 ReportSourceID - esta propiedad conecta al visor con el objeto ReportSource que determina el informe a mostrar 992256 SeparatePages ndash indica si los registros del informe deben separarse en paacuteginas o si todos deben ir contiguos como en una sola gran paacutegina 992256 ClientTarget ndash determina el coacutedigo que emitiraacute 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 queacute tipo de HTML generar en funcioacuten del navegador que hace la llamada 992256 PrintMode ndash el meacutetodo que se utilizaraacute para la impresioacuten local de los informes ActiveX o Pdf Se recomienda utilizar este uacuteltimo valor 992256 Dos propiedades booleanas permiten indicar si queremos que el visor presente cuadros de diaacutelogo emergentes para solicitar la informacioacuten que pueda faltarle para la ejecucioacuten del informe Teoacutericamente nunca deberiacuteamos dejar que estos diaacutelogos aparecieran sino que deberiacuteamos suministrar los datos por programa (por ejemplo en el evento Load de la paacutegina) utilizando los meacutetodos ya estudiados de la clase ReportDocument 992256 EnableDatabaseLogonPrompt ndash si debe solicitarse el usuario y contrasentildea de conexioacuten en caso necesario 992256 EnableParameterPrompt ndash si deben solicitarse valores para los paraacutemetros que carezcan de ellos 992256 A continuacioacuten tenemos tres propiedades booleanas que determinan si ciertas zonas del visor deben aparecer o no 992256 DisplayGroupTree ndash si se debe mostrar o no el Aacuterbol de grupos (en caso de que el informe tenga grupos) 992256 DisplayPage ndash si se debe mostrar o no la paacutegina del informe 992256 DisplayToolbar ndash si se debe mostrar o no la barra de herramientas

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 34: Crystal Report - Curso Practico

34

992256 Por uacuteltimo tenemos varias propiedades booleanas que determinan queacute botones de la barra de herramientas deben aparecer o no 992256 HasDrillUpButton ndash mostrar o no el botoacuten de Volver al informe anterior 992256 HasExportButton ndash mostrar o no el botoacuten de Exportar 992256 HasGotoPageButton ndash mostrar o no el botoacuten de Ir a paacutegina 992256 HasPageNavigationButtons ndash mostrar o no los botones de navegacioacuten por las paacuteginas 992256 HasPrintButton ndash mostrar o no el botoacuten de Imprimir 992256 HasRefreshButton ndash mostrar o no el botoacuten de Actualizar 992256 HasSearchButton ndash mostrar o no el botoacuten de Buscar texto 992256 HasToggleGroupTreeButton ndash mostrar o no el botoacuten de Mostrar Aacuterbol de grupos 992256 HasZoomFactorList ndash mostrar o no la lista de opciones de zoom

VISUALIZACIOacuteN DIRECTA EN FORMATO PDF Si probamos las opciones de Exportar o Imprimir del visor de informes Web veremos que presentan un cuadro de diaacutelogo para que el usuario final seleccione el formato de exportacioacuten o el rango de paacuteginas entre otras caracteriacutesticas Frecuentemente quisieacuteramos que la exportacioacuten a PDF (un formato de amplia popularidad) se produjera de manera automaacutetica y que en el navegador apareciera directamente el resultado Esta teacutecnica nos permitiriacutea incluso obviar la utilizacioacuten del visor Aquiacute mostraremos coacutemo hacerlo Sobre la paacutegina con la que estamos trabajando colocaremos un botoacuten y le asignaremos el tiacutetulo lsquoPDFrsquo Programe el evento Click del botoacuten de la siguiente forma Protected Sub Button1_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles Button1Click

nombre de fichero uacutenico Dim nombre As String = Ctemp amp SessionSessionID amp pdf exportamos a PDF CrystalReportSource1ReportDocumentExportToDisk( _ CrystalDecisionsSharedExportFormatTypePortableDocFormat nombre) enviamos el fichero PDF al navegador ResponseClearHeaders() ResponseClearContent() ResponseContentType = applicationpdf tipo MIME ResponseWriteFile(nombre) contenido ResponseFlush() ResponseClose()

End Sub Es esencial un nombre de fichero que sea uacutenico para cada sesioacuten de modo que no existan ldquointerferenciasrdquo entre varios posibles visitantes de la paacutegina

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 muchiacutesimo 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 instalacioacuten se debe utilizar un nuevo Proyecto de programa de instalacioacuten Web En general es un tipo de proyecto muy similar al anterior con modus operandi y resultados similares En el caso de una aplicacioacuten Web para su correcto despliegue es necesario incluir en el proyecto todos los ficheros que forman parte de la carpeta de la aplicacioacuten y sus subcarpetas

35

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

Page 35: Crystal Report - Curso Practico

35

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