14 de septiembre de 2015

El Generador de informes de VFP 9.0 en acción - Parte 1

Autor: Cathy Pountney
Original en inglés: Visual FoxPro 9.0 Report Writer In Action
http://msdn.microsoft.com/library/en-us/dnfoxgen9/html/VFP9Reports2.asp
Traducido por: Ana María Bisbé York
Se aplica a: Visual FoxPro 9.0


Resumen

Como respuesta a la retroalimentación hecha por los usuarios, Microsoft ha mejorado significativamente el Generador de informes en VFP 9.0. Una de las mejoras más importantes es la extensibilidad, la que proporciona ganchos al Diseñador de informes y control sobre los mecanismos de salida: presentación preliminar e impresión. Este articulo muestra como entrar en estos ganchos y utilizarlos de la forma más ventajosa. Mi objetivo es mostrar un grupo de cosas ingeniosas que se pueden hacer y darle que pensar sobre rutas que puede explorar incorporando sus propias ideas.

Otra característica muy importante incorporada al producto es la capacidad de crear múltiples bandas de detalle de forma nativa. Este artículo explica algunos ejemplos de cómo utilizar informes con las múltiples bandas de detalle. Algunos son muy sencillos y nos ayudan a solucionar situaciones comunes que eran muy difíciles antes del Generador de informes de VFP 9.0

Contenido

  • Introducción
  • Múltiples Bandas de detalle
  • Sobre extensibilidad
  • Utilizar un Generador de informe
  • Utilizar Listeners
  • Utilizar Contenedor preliminar
  • Conclusión
  • Biografía

Introducción

Un prerrequisito para este artículo es haber leído previamente el artículo Lo nuevo del Generador de informes de VFP 9.0 (What's New in the Visual FoxPro 9.0 Report Writer), que se encuentra disponible en el sitio Web MSDN. Este artículo trata de las nuevas características de VFP 9.0 y brinda las instrucciones básicas para utilizarlas. Este artículo retoma lo que dejó aquel. Este artículo toma los aspectos específicos para utilizar esas nuevas características y avanzar creando informes que solucionen problemas de la vida real.

Primero, aprenderá algunas cosas sobre múltiples bandas de detalle. Luego, aprenderá sobre las nuevas características de extensibilidad en las secciones Utilizar Listeners y Utilizar Contenedor preliminar. Estas secciones muestran cómo crear informes que solucionen situaciones específicas como son forzar paginación y crear Tabla de contenidos al vuelo.

Utilizar múltiples bandas de detalle

Contar con la posibilidad de crear múltiples bandas de detalle es una de las mejoras más importantes y más solicitadas, así como las mejoras en extensibilidad en el Generador de informes de VFP 9.0. Las nuevas características permiten procesar múltiples tablas hijas para cada registro de la tabla padre. Existen posibilidades ilimitadas de lo que se puede hacer con esta nueva característica.

Informes sencillos

Un informe sencillo con múltiples bandas de detalle consiste en una tabla padre que conduce el informe y dos o más tablas hijas que están relacionadas con la tabla padre. El ejemplo mostrado en la Figura 1 es un ejemplo de informe sencillo con múltiples bandas de detalle.

Figura 1. Este ejemplo de informe con múltiples bandas de detalle tiene tres bandas separadas para cada usuario.

La tabla Customer es la tabla padre y contiene un registro para cada cliente de la compañía de seguros. Las tablas Members, Vehicles y Homes son las tablas hijas de la tabla Customer. La tabla Members guarda un registro para cada miembro de la familia del cliente. La tabla Vehicles guarda un registro para cada vehículo del cliente. La tabla Homes guarda un registro para cada vivienda del cliente. Cada tabla hija tiene relación con la tabla padre.

En este ejemplo, la tabla Customer es la tabla conductora. Si utiliza el Entorno de datos del informe para definir las tablas, establezca la propiedad InitialSelectedAlias igual a Customer. Si utiliza código para definir las tablas, asegúrese de que la tabla Customer está en el área de trabajo actual en el momento de ejecutar el informe.

Target alias – Alias destino - es el término utilizado para describir qué tabla es la tabla conductora para una banda de detalle en particular. En este ejemplo, la tabla Members es target alias para la banda de detalle 1, la tabla Vehicles es target alias para la banda de detalle 2, y la tabla Homes es target alias para la banda de detalle 3. Utilice el cuadro de diálogo Propiedades (Properties) de la correspondiente banda de detalle para establecer el target alias.

Cálculos

El ejemplo anterior mostró como imprimir datos de tres tablas hijas diferentes en un mismo informe. Sin embargo un informe con múltiples bandas de detalle no necesariamente necesita tener múltiples tablas hijas. La misma tabla hija puede ser utilizada en más de una banda de detalle.

Totales de grupos

Antes de VFP 9.0, era muy difícil imprimir subtotales en la banda encabezado de grupo (mostrado en la Figura 2). El dato tenía que ser procesado previamente para calcular los totales antes de ejecutar el informe. Con VFP9.0, no se requiere procesamiento previo.

Figura 2. Utilice un informe con múltiples bandas de detalle para imprimir subtotales de grupos al inicio del grupo.

Para crear el informe mostrado en la Figura 2, siga los siguientes pasos:

  1. Definir entorno de datos
    1. Agregar tabla Customer
    2. Agregar tabla Vehicles
    3. Establecer la propiedad InitialSelectedAlias a la tabla Customer.
  2. Crear un grupo de datos
    1. Hacer Expresiones de Agrupación (Data Group expresión) igual a Customer PK
    2. No coloque ningún objeto en la banda encabezado de grupo ni en banda pie de grupo.
  3. Crear bandas múltiples de detalle.
    1. Seleccione Bandas opcionales… (Optional Bands...) desde el menú Informe (Report)
    2. Haga Clic en el botón Agregar (Add) para agregar una o más bandas de detalle al informe.
    3. Haga Clic en Aceptar (OK) para salir del cuadro de diálogo.
  4. Definir una banda de detalle
    1. Haga doble clic en la barra gris de la banda de detalle 1 para invocar al cuadro de diálogo Propiedades (Properties)
    2. Establezca target alias igual a "Vehicles", recordando utilizar comillas.
    3. Marque la casilla de verificación Bandas de encabezado y pie asociadas (Associated header and footer bands)
    4. No coloque objetos en la banda de detalle 1
  5. Definir la banda pie para la banda de detalle 1
    1. Agregue a la banda los objetos customer name y address.
    2. Agregue a la banda los objetos total vehicles y total premiums.
    3. Agregue un objeto campo para el total de vehículos, establezca la expresión (expression) igual a vehicles.premium, establezca Tipo de cálculo (Calculation type) igual a Recuento (Count) y Basado en (Reset based on) igual a Detail1.
    4. Agregue un objeto campo para el total de premios, establezca la expresión (expression) igual a vehicles.premium, establezca Tipo de cálculo (Calculation type) igual a Suma (Sum) y Basado en (Reset based on) igual a Detail1.
  6. Definir la banda de detalle 2
    1. Hacer doble clic en la banda gris de la banda de detalle 2 para invocar el cuadro de diálogo Propiedades (Properties)
    2. Establezca target alias igual a "Vehicles", recordando utilizar comillas.
    3. Marque la casilla de verificación Bandas de encabezado y pie asociadas (Associated header and footer bands)
    4. Agregue cualquier otro objeto necesario en la banda de detalle 2.

La definición de informe descrita anteriormente, dice al Generador de informes de VFP 9.0, que procese dos veces la tabla Vehicles para cada cliente en la tabla Customer. La primera vez, calcula el total de registros y el monto en dólares para el cliente (customer) y lo imprime. El segundo pase de la tabla Vehicles imprime el detalle. Este proceso se repite para cada customer en la tabla Customer.

Porcentajes

Otro concepto en los informes es mostrar el porcentaje del total de cada línea de detalle, en la medida en que se imprimen las líneas. Esto puede ser realizado también con múltiples bandas de detalle como muestra la Figura 3.

Figura 3. Utilice un informe con múltiples bandas de detalle para imprimir porcentajes con cada línea de detalle.

Para crear el informe mostrado en la Figura 2, siga los siguientes pasos:

  1. Definir entorno de datos
    1. Agregar tabla Customer
    2. Agregar tabla Vehicles
    3. Establecer la propiedad InitialSelectedAlias a la tabla Customer.
  2. Crear un grupo de datos
    1. Hacer Expresiones de Agrupación (Data Group expresión) igual a Customer PK
    2. Coloque los objetos name y adress en la banda encabezado de grupo.
  3. Crear bandas múltiples de detalle.
    1. Seleccione Bandas opcionales… (Optional Bands...) desde el menú Informe (Report)
    2. Haga Clic en el botón Agregar (Add) para agregar una o más bandas de detalle al informe.
    3. Haga Clic en Aceptar (OK) para salir del cuadro de diálogo.
  4. Definir banda de detalle 1
    1. Haga doble clic en la barra gris de la banda de detalle 1 para invocar al cuadro de diálogo Propiedades (Properties)
    2. Establezca target alias igual a "Vehicles", recordando utilizar comillas.
    3. Marque la casilla de verificación Bandas de encabezado y pie asociadas (Associated header and footer bands)
    4. No coloque objetos en la banda de detalle 1
  5. Crear algunas variables de informe
    1. Cree una variable llamada rnTotalPremium, establezca Valor a almacenar (Value to store) igual a Vehicles.premium establezca Tipo de cálculo (Calculation type) igual a Suma (Sum) y Reiniciar basado en (Reset based on) igual a Detail 1
    2. Cree una variable llamada rnPercent, establezca Valor a almacenar (Value to store) igual a ROUND(100 * vehicles.premium / rnTotalPremium, 2) establezca Tipo de cálculo (Calculation type) igual a Ninguno (None)
  6. Definir la banda de detalle 2
    1. Hacer doble clic en la banda gris de la banda de detalle 2 para invocar el cuadro de diálogo Propiedades (Properties)
    2. Establezca target alias igual a "Vehicles", recordando utilizar comillas.
    3. Marque la casilla de verificación Bandas de encabezado y pie asociadas (Associated header and footer bands)
    4. Agregue cualquier otro objeto necesario en la banda de detalle 2.
    5. Agregue el objeto percent a la banda de detalle 2 con la expresión rnPercent.
  7. Definir la banda pie para la banda de detalle 2
    1. Agregar el objeto total premium, establecer la expresión (expression) igual a vehicles.premium, establezca Tipo de cálculo (Calculation type) igual a Suma (Sum) y Reiniciar basado en (Reset based on) igual a Detail 2
    2. Agregar el objeto total percent, establecer la expresión (expression) igual a rnPercent, establezca Tipo de cálculo (Calculation type) igual a Suma (Sum) y Reiniciar basado en (Reset based on) igual a Detail 2

La definición de informe descrita anteriormente, dice al Generador de informes de VFP 9.0, que procese dos veces la tabla Vehicles para cada cliente en la tabla Customer. La primera vez totaliza los premios (premium) para que puedan ser utilizados en el segundo pase. El segundo pase de la tabla Vehicles imprime el dato para el usuario, utilizando la variable de informe que fue calculada en la primera banda de detalle. Este proceso se repite para cada customer en la tabla Customer.

Sobre Extensibilidad

Antes de VFP 9.0, el motor del generador de informes controlaba todo, incluyendo el procesamiento de datos, la posición de los objetos, la generación, la impresión y la vista preliminar. No había forma de entrar en el motor de informes y personalizarlo, como se puede en otras áreas de VFP. Uno de los cambios más significativos en el Generador de informes es su nueva capacidad de extensibilidad. El Diseñador de informes (Report Designer), Motor de informes (Report Engine) y Contenedor preliminar (Preview Container) están expuestos al desarrollador.

Generador de Informes

El Generador de informes (Report Write) en VFP 9.0 incluye una nueva característica en tiempo de diseño llamada Builder Hooks. Varios eventos del Diseñador de informes (Report Designer) están expuestos en un componente Xbase independiente llamado Report Builder, puede ser invocado para ser manipulado. Esta aplicación puede ser utilizada para invocar nuestros propios cuadros de diálogo, aumentar el comportamiento nativo del Diseñador de informes o sobrescribir este comportamiento nativo.

VFP incluye una aplicación extendida en el Generador de Informes, que incluye nuevas características y proporciona una mejor interfaz de usuario para diseño de informes. El Generador de informes es controlado por una nueva variable del sistema, _REPORTBUILDER. Si esta variable está vacía, se muestra el cuadro de diálogo nativo. Para activar el gancho al generador, establezca esta variable a la aplicación correspondiente. Por ejemplo, para utilizar el Generador de informes que viene con VFP 9.0, utilice el siguiente comando:

_REPORTBUILDER = HOME() + "REPORTBUILDER.APP"

Nota: Al utilizar el Generador de impresión en tiempo de ejecución, asegúrese de distribuir el archivo con sus aplicaciones. Además sea consciente de que la ruta predeterminada es la del archivo vfp9r.dll. Puede utilizar config.fpw para establecer explícitamente la variable the _ReportBuilder al inicio de la aplicación.


Motor de informe (Report Engine) Listeners

En el nuevo sistema de salida (Object-Assisted Output), el motor de informe manipula tareas centradas en datos, como es el movimiento entre los límites y la evaluación de expresiones. Sin embargo, cuando llega el momento de crear la salida, el trabajo lo realiza una nueva clase base llamada ReportListener. La nueva clase genera el contenido del informe en forma más sofisticada, utilizando GDI+, y además ofrece a los usuarios Xbase la posibilidad de interactuar con el proceso de salida. La Figura 4 muestra cómo se ajustan todas las piezas.

Figura 4. Utilice la nueva clase ReportListener para crear informes más sofisticados.

Para utilizar una clase ReportListener, utilice la cláusula nueva del comando REPORT FORM como se muestra a continuación:

oListener = CREATEOBJECT("ReportListener")
oListener.ListenerType = 1 && Presentación preliminar, o 0 para Imprimir
REPORT FORM <name> <clauses> OBJECT oListener 

VFP 9.0 proporciona además una segunda técnica para utilizar una clase ReportListener. Puede establecer el valor para la nueva variable del sistema, _REPORTOUTPUT, al nombre de una aplicación que pueda determinar que clase ReportListener utilizar basada en el tipo de salida que se ha escogido.

Cuando se utiliza (Object-Assisted Output), un informe se procesa utilizando uno de dos modos fundamentales, en dependencia del valor de la propiedad ListenerType. Puede escoger entre estos dos modos print-appropriate (imprimir) y preview-appropriate (presentación preliminar), o page-at-a-time (una página cada vez) y all-pages-at-once (todas las páginas de una vez). En el primer modo, el Listener desencadena un evento OutputPage y prepara cada página, justo como si se enviara cada página a la cola de impresión.

En el segundo modo, el Listener prepara todas las páginas para la generación y las guarda en memoria (caché). Cuando esto finaliza, puede invocar el método OutputPage para preguntar qué página de todas incluidas en la salida por número de página.

Contenedor preliminar (Preview Container)

En VFP 9.0, otra pieza importante en el puzzle de extensibilidad es el Contenedor preliminar. Con este gancho, puede utilizar el nuevo contenedor preliminar que viene con VFP 9.0 o escribir su propio contenedor. El antiguo contenedor preliminar nativo está aún disponible cuando no se está utilizando la nueva salida asistida por objetos.

Una nueva variable de sistema, _REPORTPREVIEW, contiene el nombre de la aplicación que determina qué contenedor preliminar utilizar. De forma predeterminada, esta variable apunta a ReportPreview.app. Esta nueva aplicación contiene un gran número de mejoras sobre el antiguo contenedor preliminar incluyendo: más niveles de zoom, control de la barra de herramientas, control del encabezado, presentación de múltiples páginas, y mejor calidad utilizando GDI+. Las Figuras 5 y 6 muestran las diferencias entre la presentación antigua y la actual.

Figura 5. La salida en el contenedor preliminar antiguo no es tan sofisticada como quisiéramos.

Figura 6. El nuevo contenedor preliminar tiene mucha más calidad y opciones más sofisticadas.

Observe la diferencia en calidad entre los contenedores viejo y nuevo. El nuevo contenedor tiene las fuentes mucho más claras que el viejo. Puede comprobarlo utilizando GDI+ para la salida de la información. Observe además, la diferencia en la barra de herramientas anclada. El nuevo estilo de la barra de herramientas tiene opciones nuevas, incluyendo presentación de múltiples páginas.

Viejo contra nuevo

Un comando nuevo, SET REPORTBEHAVIOR, puede ser utilizado para encender o apagar la salida asistida por objetos (Object-Assisted Output). El motor generador de la nueva salida y la nueva superficie Preliminar tienen diferencias significativas entre los estilos de salida antiguo y actual. La alineación, interlineado, y el espaciado es diferente entre GDI y GDI+, con el que podrían haber cambios significativos sobre cómo se vean los informes existentes. Por tanto, se establece de forma predeterminada REPORTBEHAVIOR en 80, lo que apaga la salida asistida por objetos y el informe se procesa como antes de VFP 9.0.

Si desea activar la salida asistida por objetos de forma global, puede cambiar el valor de esta configuración en el cuadro de diálogo Opciones (Options) (mostrado en la Figura 4), o puede escribir el siguiente comando:

SET REPORTBEHAVIOR 90 

Figura 7. Utilizar la opción Comportamiento en tiempo de ejecución (Run-time behavior) en el cuadro de diálogo Opciones (Options) para cambiar la configuración de SET REPORTBEHAVIOR.

Cuando REPORTBEHAVIOR se establece en 90, el comando REPORT FORM automáticamente actúa como si pensara que se utiliza la cláusula OBJECT, sin cambios posteriores en su código. VFP utiliza la variable del sistema _REPORTOUTPUT para determinar qué aplicación utilizar para nominar la clase ReportListener apropiada para cada comando REPORT FORM.

Con las nuevas características de extensibilidad en el Generador de informes de VFP 9.0 (Report Writer), es posible tocar el Generador de informes (Report Builder), el Motor de informe (Report Engine), y el área preliminar (Preview surface). Puede activar globalmente las nuevas características o puede activarlas para informes individuales. Puede además dejarlas desactivadas y ejecutar los informes como si estuviera en las versiones anteriores de VFP.

Utilizar un Generador de informes (Report builder)

El Generador de informes es la parte del Report Writer que se utiliza en tiempo de diseño. Puede utilizar el Generador de informes que viene nativo con VFP 9.0, o crear uno propio. Esta sección le familiarizará con el Generador de informes nativo y comentará brevemente sobre cómo crear uno propio.

ReportBuilder.app

El nuevo Generador de informe, se llama ReportBuilder.app y viene con VFP 9.0. Su interfaz de usuario es mucho mejor que en versiones precedentes de VFP. Se implementó un estilo nuevo para cuadros de diálogo con marcos de página, lo que facilita cambiar las propiedades.

Cuadro de diálogo Propiedades de Informe

El Cuadro de diálogo Propiedades de Informe (Report Properties) utiliza un marco de página y páginas para todos los aspectos de propiedades de informe. Esto agiliza el trabajo, ya que no hay que estar abriendo y cerrando cuadros de diálogo, para algunos aspectos. Este cuadro de diálogo se invoca haciendo doble clic en un espacio no utilizado del informe, y seleccionando Propiedades… (Properties....) Puede ser invocado además al seleccionar Propiedades… (Properties...) del menú Informe (Report). Las figuras 8-14 muestran todas las páginas del Nuevo cuadro de diálogo Propiedades de Informe (Report Properties)

Figura 8. Utilice la página Configurar página (Page Layout) del cuadro de diálogo Propiedades de informe (Report Properties) para establecer columnas, márgenes, impresoras, etc.

Figura 9. Utilice la página Bandas Opcionales (Optional Bands) del cuadro de diálogo Propiedades de informe (Report Properties) para establecer Bandas Título y Resumen, y para definir múltiples bandas de detalle

Figura 10. Utilice la página Agrupar datos (Data Grouping) del cuadro de diálogo Propiedades de informe (Report Properties) para definir los grupos de datos.

Figura 11. Utilice la página Variables del cuadro de diálogo Propiedades de informe (Report Properties) para definir las variables de informe.

Figura 12. Utilice la página Protección (Protection) del cuadro de diálogo Propiedades de informe (Report Properties) para poder utilizar las ventajas de la protección en informes de VFP 9.0.

Figura 13. Utilice la página Regla/Cuadrícula (Ruler/Grid) del cuadro de diálogo Propiedades de informe (Report Properties) para configurar la regla y cuadrícula.

Figura 14. Utilice la página Entorno de datos (Data Environment) del cuadro de diálogo Propiedades de informe (Report Properties) para poder utilizar las ventajas de la reutilización de entornos de datos en informes de VFP 9.0.

Es un ahorro real de tiempo, tener todas estas propiedades de informe disponibles en un cuadro de diálogo.

Propiedades de objeto

Otra mejora en la interfaz de usuario es la implementación de marcos de página y páginas para las propiedades de objetos. Este cuadro de diálogo se invoca haciendo doble clic en un objeto. Las Figuras 15 a la 21 muestran todas las páginas para un objeto campo. Muchas de éstas son las mismas que para otros objetos como formas (shapes).

Figura 15. Utilice la ficha General del cuadro de diálogo Propiedades de campo (Field Properties) para configurar la expresión, posición, tamaño, etc.

Figura 16. Utilice la ficha Estilo (Style) del cuadro de diálogo Propiedades de campo (Field Properties) para configurar la fuente, color, y estilo de fondo del objeto.

Figura 17. Utilice la ficha Formato (Format) del cuadro de diálogo Propiedades de campo (Field Properties) para configurar el formato de expresión, varias opciones de formato y el nuevo modo de recortar para expresiones.

Figura 18. Utilice la ficha Imprimir cuando (Print when) del cuadro de diálogo Propiedades de campo (Field Properties) para definir la lógica de cuándo imprimir.

Figura 19. Utilice la ficha Calcular (Calculate) del cuadro de diálogo Propiedades de campo (Field Properties) para definir cualquier cálculo sobre el objeto.

Figura 20. Utilice la ficha Protección (Protection) del cuadro de diálogo Propiedades de campo (Field Properties) para aprovechar las ventajas de la protección en VFP 9.0.

Figura 21. Utilice la ficha Otros (Other) del cuadro de diálogo Propiedades de campo (Field Properties) para definir comentarios, datos del usuario, ToolTips, y extensiones en tiempo de ejecución.

De igual forma que en las Propiedades de informe, este cuadro de diálogo Propiedades de objeto con todo-en-uno es un ahorro real de tiempo.

Generador de informe propio

VFP 9.0 salió con un Generador de informe (Report Builder) Xbase, llamado ReportBuilder.app. Puede utilizar este generador o crear uno propio y establecer el valor de la variable del sistema _REPORTBUILDER para que apunte al Generador de informe personalizado. Escribir un Generador de informe (Report Builder) personalizado está fuera del alcance de este artículo, puede ver de qué forma Microsoft creó la aplicación ReportBuilder.app estudiando el código fuente que se incluye con VFP 9.0. El código fuente está en la carpeta HOME() + 'tools \xsource'.

Utilizar Listeners

VFP introduce una nueva clase base, llamada ReportListener, la que es un gancho dentro del motor de impresión. De forma nativa, esta clase manipula la generación, impresión y presentación preliminar. Por otro lado, puede ser subclaseada para agregar más funcionalidad, como es salida XML, HTML y TIFF, gráficos personalizados con GDI+ y otras muchas características.

Esta sesión describe la clase base ReportListener y la subclase liberada con las FFC VFP 9.0. También describe varias cosas que pueden hacerse con clases ReportListener, tales como: imprimir en rojo los números negativos, rotar texto, forzar paginación para mantener grupos de información en la misma página, crear Tabla de contenidos al vuelo, y mucho más.

Base Listener

La clase base ReportListener tiene varias propiedades que controlan la forma en que son procesados los informes. Aquí vemos algunas de las más comunes.

  • AllowModalMessages (predeterminado = .f.): Esta propiedad determina si ReportListener puede proporcionar mensajes modales como parte de su interfaz de usuario.
  • DynamicLineHeight (predeterminado = .f.): Esta propiedad determina si ReportListener debe utilizar el espaciado de líneas estándar del GDI+ acorde a las características de la fuente, o el espaciado fijo, como antes. Además, esta propiedad afecta tanto en la forma en que se pinta el color de fondo de los objetos de campo opacos como en el ancho del texto que se imprime (.t.), o el ancho del campo definido (.f.).
  • ListenerType: Esta propiedad determina que tipo de salida es generada.
    -1 = No generar salida
    0 = Enviar la salida, página a página, al controlador de impresora.
    1 = Preparar todas las páginas y enviar al contenedor preliminar.
    2 = Crea la salida en base a página a página; pero no lo envía a la impresora.
    3 = Crea la salida para todas las páginas; pero no la envía al contenedor preliminar
    4 = Proporciona salida XML
    5 = Proporciona salida HTML
  • PrintJobName: Esta propiedad indica el nombre utilizado cuando el trabajo de impresión es el saliente en la cola de impresión. Se utiliza en la barra de título del contenedor preliminar.
  • QuietMode (predeterminado = .f.): Esta propiedad determina si ReportListener puede proporcionar cualquier retroalimentación de usuario o interfaz de usuario.

He aquí un ejemplo de cómo instanciar una clase ReportListener, cambia estas propiedades y luego ejecuta un informe.

LOCAL ox AS ReportListener
ox = CREATEOBJECT('ReportListener')
ox.AllowModalMessages = .t.
ox.DynamicLineHeight = .t.
ox.ListenerType = 0
ox.PrintJobName = 'Mi Informe Especial'
ox.QuietMode = .t.
REPORT FORM MyReport OBJECT ox

Es un ejemplo sencillo de cómo cambiar la salida. La siguiente sección va a comentar varias vías adicionales para cambiar la salida utilizando subclases de ReportListener suministrada con VFP 9.0.

Listeners suministrados

VFP 9.0 libera una biblioteca de clases _ReportListener dentro de las clases Foundation, localizadas en la carpeta HOME() + 'FFC'. Contiene las siguientes clases ReportListener:

  • _ReportListener: Esta clase agrega control de errores, control de sesión, y otras tareas comunes de la clase base ReportListener en tiempo de ejecución. Proporciona la posibilidad de cadenas de series de informes así como el significado de delegar o compartir las actividades de salida a una cadena de Listeners herederos.
  • UpdateListener: Esta clase proporciona retroalimentación de usuario mientras se está generando la salida del informe.
  • UtilityReportListener: Esta clase agrega la posibilidad de controlar las tablas de configuración y los ficheros destino de salida.
  • DebugListener: Esta clase proporciona depuración en la salida para ayudar a los desarrolladores a comprender qué ocurre durante la ejecución de un informe asistido por objetos.
  • XMLListener: Esta clase proporciona salida XML a un informe. Es comentada con amplitud en la sesión titulada Salida XML.
  • XMLDisplayListener: Esta clase ajusta la configuración XML adecuadamente para las necesidades de la salida, y agrega capacidad de generar ficheros de imágenes.
  • HTMLListener: Esta clase aplica especificaciones de usuarios, ajustando a producción HTML, al proceso de generación de su clase padre XML. Este tema está descrito en la sesión titulada Salida HTML.

Estas clases pueden ayudar realmente a entender cómo trabaja el Report Listeners y puede brindarle un impulso a utilizarlo.

Las siguientes tres secciones describen cómo utilizar la clase ReportListener para generar salida XML, salida HTML, y múltiples tipos de salida de una vez.

Salida XML

La clase xmlListener en la librería de clases _ReportListener de la carpeta FFC crea una salida XML desde un informe. Esta clase tiene varias PMEs (Propiedades-Métodos-Eventos) que ofrecen mucha flexibilidad. He aquí un ejemplo de cómo utilizarla.

*-- Asegurarse de que no existe el archivo XML
ERASE MyXMLOutput.XML
 *-- Crear la clase Listener
SET CLASSLIB TO HOME() + 'FFC\_REPORTLISTENER'
ox = CREATEOBJECT('xmlListener')
 *-- Configurar algunas propiedades
ox.TargetFileName = 'MyXMLOutput'
 *-- Ejecutar el informe
REPORT FORM accounts OBJECT ox

Este ejemplo crea un archivo XML con la información RDL arriba, seguida por el dato.

Salida HTML

Otra clase incluida en la biblioteca de clase _ReportListener es una llamada htmlListener, la que envía la salida de un informe a HTML. Aquí hay un ejemplo de cómo utilizar esta clase.

*-- Asegurarse de que no existe el archivo HTML
ERASE MyHTMLOutput.HTM
*-- Crear la clase Listener
SET CLASSLIB TO HOME() + 'FFC\_REPORTLISTENER'
ox = CREATEOBJECT('htmlListener')
 *-- Configurar algunas propiedades
ox.TargetFileName = 'MyHTMLOutput'
 *-- Ejecutar el informe
REPORT FORM accounts OBJECT ox 
Successor Listeners

La clase _ReportListener que se encuentra en la librería de clases HOME() + ' \FFC \_ReportListener', contiene código para tratar con los oyentes herederos (successor listeners). El concepto de herederos permite encadenar más de un objeto ReportListener al mismo tiempo. Una de las ventajas de esta característica es la posibilidad de emitir dos tipos de salidas de informe diferente. Por ejemplo, un informe puede enviarse a presentación preliminar y se puede generar un XML al mismo tiempo. Para que esto ocurra el informe no tiene que ejecutarse dos veces. El siguiente código muestra cómo hacerlo.

*-- Utilizar FFC ReportListener
SET CLASSLIB TO HOME(1) + 'FFC\_ReportListener' 
*-- Definir la salida XML
loXML = CREATEOBJECT('XMLListener')
loXML.ListenerType = 4
loXML.QuietMode = .t.
loXML.TargetFileName = 'MyXMLOutput' 
*-- Definir la salida a presentación preliminar
loPreview = CREATEOBJECT('_ReportListener')
loPreview.ListenerType = 1 && Preview
loPreview.OutputType = 1 && Preview
loPreview.Successor = loXML 
*-- Ejecutar el informe
REPORT FORM accounts OBJECT loPreview 

Como puede ver, crear salida XML, salida HTML y múltiples salidas a la vez, es muy fácil cuando utiliza la clase ReportListener suministrada. Sin embargo, no es todo lo que debe hacerse. Como se describe en la siguiente sesión, puede crear su propia clase ReportListener para extender el Generador de informes, aún más.

Listeners propios

Las siguientes sesiones describen cómo crear su propia clase ReportListener para solucionar varias necesidades diferentes de informes de la vida real. Se explicará el concepto de directivas y cómo utilizarlas para alterar el color del texto, cambiar el tamaño de fuente del texto y rotar un texto. Aprenderá además a forzar cortes en números de página cuando los necesite, en lugar de cuando decida el Generador de informes. Finalmente, se explican algunos conceptos adicionales como son, la creación de archivos TIFF con múltiples páginas, imprimir formas x-up e imprimir caracteres de barra.

La Figura 22 muestra una captura de pantalla del Examinador de clases con la clase ReportListener utilizada en las secciones siguientes de este artículo. De esta forma se puede entender la jerarquía de todas las clases.

Figura 22. MyReportListeners es una librería de clases que contiene todas las clases necesarias en los ejemplos de esta sesión.

Listener propio: Directivas

Crear un listener genérico que pueda desglosar las directivas desde el campo USER en la tabla FRX de una sola forma para poder controlar varias de las tareas más comunes en los informes. El informe de ejemplo mostrado en la Figura 23 utiliza directivas para cambiar dinámicamente los colores de la fuente, rotar texto y reducir el tamaño de la fuente en descripciones largas.

Figura 23. Este ejemplo utiliza la directiva ROTATETEXT para el encabezado de columna Type, la directiva SQUEEZETEXT en la columna Description y la directiva REDNEGATIVE para la columna Balance.

El campo USER ha existido de siempre en el FRX; pero nunca había estado expuesto a los desarrolladores a través de la interfaz. El uso del nuevo Generador de informes provisto con VFP 9.0, ha cambiado esto. Al campo USER se puede acceder desde la ficha Otros (Other) del cuadro de diálogo Propiedades (Properties).

Para hacer que trabaje el concepto de directivas, es necesario seguir un grupo de reglas. La primera es en qué forma se introducen las directivas al campo USER del informe. Debe establecerse un patrón consistente para que pueda ser desglosado después. El patrón siguiente es utilizado en estos ejemplos:

*:LISTENER||<directivename>||<Parameter1>||<Parameter2>> 

Comienza con *:LISTENER para que identifique la línea como una directiva. Luego, utiliza un delimitador de caracteres de doble barra (||), seguido por el nombre de la directiva. Opcionalmente, puede haber otro delimitador con el primer parámetro, otro delimitador con el segundo parámetro, así hasta que no existan más parámetros.

Luego, es necesario crear una nueva clase basada en custom para cada directiva. Siga las convenciones de nombre para las clases que imitan el nombre de la directiva. En estos ejemplos, todas las directivas se llaman MyDirectives_, seguidas por el nombre de la directiva. Estas clases son llamadas por la clase ReportListener en el momento apropiado y hacen lo más fuerte del procesamiento especial. Donde quiera que se necesite una nueva directiva, simplemente se crea la nueva clase directiva. La clase ReportListener no necesita ser modificada porque está diseñada para ser genérica.

Finalmente, es necesario crear una clase ReportListener. Esta clase necesita interactuar entre los objetos del informe buscando las directivas. Cada vez que encuentre una directiva, necesita instanciar la correspondiente clase directiva de usuario y enlazarla al objeto. La clase ReportListener necesita tener código en varios métodos que llamen a los métodos correspondientes en la clase directiva de usuario para que haga el procesamiento especial.

Continua en: El Generador de informes de VFP 9.0 en acción - Parte 2

1 comentario :

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.