Es el primer artículo de una serie dedicada al nuevo Motor de informes en VFP 90. En el se describen algunas de las formas en que se consigue invocar al reportlistener como encargado de proporcionar la generación asistida por objetos.
VFP 9 - Novedades - Nuevo Motor de informes - ReportListenerpor Amby
Este es el primer artículo de una serie dedicada al Nuevo Motor de informes de Visual FoxPro 9.0. Primeramente, veremos cómo empieza todo y cómo desde el inicio, tenemos en nuestras manos, la posibilidad de adaptar y control el proceso de obtención de informes con Visual FoxPro 9.0. Luego, veremos, la secuencia de eventos, y dedicaremos varios escritos a describir el modo en que se puede accionar sobre la generación de informes en tiempo de ejecución y los ganchos que se pueden aplicar a estos eventos. Antes de VFP 9.0, la generación de Informes, era para el desarrollador un proceso monolítico, una caja negra en la que no era posible penetrar. A partir de esta versión, VFP cuenta con la Generación Asistida por objetos, lo que nos va a permitir conocer e interactuar sobre los eventos del Motor de informes. ¿Dónde comienza la generación de un informe en VFP? Pues en un comando REPORT FORM o LABEL FORM (en adelante, al referirme a REPORT FORM se aplica también para LABEL FORM) Este comando a partir de VFP 9.0 va a definir el objeto ReportListener ¿Qué es un objeto ReportListener? Es el encargado de proporcionar la generación asistida por objetos para los comandos REPORT FORM. En cuanto se ejecuta un comando REPORT FORM, el motor de informes envía información al objeto ReportListener instanciado, el que recibe la configuración que indica el comando REPORT FORM y tiene a su cargo la responsabilidad de aplicar esa configuración, evaluar cada elemento y generar el contenido del informe. Este objeto tiene propiedades y métodos asociados. No me voy a detener en su descripción, ya que además de estar descritos en la Ayuda de VFP 9.0, contamos con un excelente conjunto de artículos recomiendo leer para iniciarse y profundizar en esos temas: Extender los informes en VFP 9.0 en tiempo de diseño (Parte 1/2) (Doug Hennig) Traducción http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=55 Extender los informes en VFP 9.0 en tiempo de diseño (Parte 2/2) (Doug Hennig) Traducción http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=56 Extender los informes en VFP 9.0 en tiempo de ejecución (Parte 1/3) (Doug Hennig) Traducción http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=64 Extender los informes en VFP 9.0 en tiempo de ejecución (Parte 2/3) (Doug Hennig) Traducción http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=65 Extender los informes en VFP 9.0 en tiempo de ejecución (Parte 3/3) (Doug Hennig) Traducción http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=66 El Generador de informes de VFP 9.0 en acción Parte 1 (Cathy Pountney) Traducción http://www.portalfox.com/article.php?sid=1650 El Generador de informes de VFP 9.0 en acción Parte 2 (Cathy Pountney) Traducción http://www.portalfox.com/article.php?sid=1653 El Generador de informes de VFP 9.0 en acción Parte 3 (Cathy Pountney) Traducción http://www.portalfox.com/article.php?sid=1656 Lo nuevo del Generador de Informes en VFP 9.0 - Parte 1 (Cathy Pountney) Traducción http://www.portalfox.com/article.php?sid=1269 Lo nuevo del Generador de Informes en VFP 9.0 - Parte 2 (Cathy Pountney) Traducción http://www.portalfox.com/article.php?sid=1270 He dicho antes que “El comando REPORT FORM, a partir de VFP 9.0, va a definir el objeto ReportListener” Y justo aquí empiezan las dudas ¿Hay que definir siempre un reportlistener? ¿Cómo se define un objeto ReportListener? Veamos en detalle. ¿Hay que definir siempre un reportlistener? No, no es necesario. Si no se indica un objeto ReportListener específico o de usuario, siempre que se emplee el nuevo comportamiento aplicado a VFP 9.0, es decir, siempre que SET REPORTBEHAVIOR 90, el motor de informes invoca automáticamente a la aplicación, cuyo nombre se guarda en la nueva variable del sistema _REPORTOUTPUT, es decir al objeto ReportListener predeterminado. ¿Cómo se define un objeto ReportListener? Existen varias formas de instanciar un objeto ReportListener. Todo depende de las acciones que deseemos realizar. Instanciar un objeto ReportListener 1. No queremos indicar ninguna configuración especial, solamente solicitar el comportamiento predeterminado de VFP 9.0 SET REPORTBEHAVIOR 90
REPORT FORM repEjemplo TO PRINTER PROMPT PREVIEW En este caso, se indica que se aplique programación asistida por objetos, ya que se inicia con SET REPORTBEHAVIOR 90, y como no hay referencia a un objeto ReportListener de usuario, se emplea, como se ha dicho antes, el predeterminado. Además, al indicar la cláusula PREVIEW el Motor de informes invoca otro objeto: PreviewContainer para mostrar el PREVIEW. La aplicación cuyo nombre se guarde en la nueva variable del sistema _REPORTPREVIEW, se invoca para ello. 2. Deseamos indicar el modo de generación a aplicar al informe SET REPORTBEHAVIOR 80
REPORT FORM repEjemplo OBJECT TYPE 1
SET REPORTBEHAVIOR 90 La determinación del Modo de generación de las salidas de un informe, es una de las novedades en esta versión. Antes de VFP 9.0 se obtenían de una vez todas las páginas a mostrar / imprimir, incluso en aquellos casos que se indicaban filtros con la cláusula RANGE. A partir de VFP 9.0 existen diferentes modos de obtener las salidas, lo que está determinado por la propiedad ListenerType del objeto ReportListener:, para ello empleamos las cláusulas OBJECT TYPE del comando REPORT FORM En el ejemplo mostrado estamos indicando SET REPORTBEHAVIOR 80, para demostrar que independientemente del comportamiento existente, ya sea 80 ó 90, al emplear las cláusulas OBJECT TYPE n en el comando REPORT FORM, se indica una referencia al reportlistener predeterminado y se asigna 1 a la propiedad ReportListener.ListenerType 3. Queremos instanciar una clase reportlistener configurada previamente SET CLASSLIB TO ListenerBase
olistener = NEWOBJECT("ListenerBase", "ListenerBase")
olistener.ListenerType = 1 && Preview
REPORT FORM repEjemplo OBJECT olistenerEn artículos posteriores veremos cómo podemos crear una clase ReportListener personalizada para que responda a nuestras propias necesidades de generación de informes. Este ejemplo de configuración muestra cómo se instancia la clase de usuario creada previamente, a la que hemos llamado ListenerBase, y está basada en ReportListener. 4. Deseamos instanciar una clase ReportListener particular y configurar algunas de sus propiedades, en lugar de indicar las cláusulas del comando REPORT FORM * Damos a conocer la biblioteca de clases a emplear
SET CLASSLIB TO MyListeners
* declarar el objeto ReportListener deseado
olistener = NEWOBJECT("MyListener", "MyListeners")
* Configuramos las propiedades
olistener.ListenerType = 1 && Preview
* utilizar el objeto para generar el informe
REPORT FORM repEjemplo OBJECT olistener NOWAIT
* ox.CommandClauses.Prompt = .t.En este caso simula TO PRINTER PROMPT PREVIEW. Aquí vemos que no sólo instancia el objeto sino que asigna el valor a algunas propiedades en tiempo de ejecución. Para ello, sólo es necesario, declarar el objeto ReportListener deseado, configurar las propiedades y utilizar el objeto para generar el informe. La cláusula NOWAIT hace que no se detenga la ejecución hasta que cierre la ventana de presentación preliminar. Otro ejemplo de este mismo caso, puede ser el siguiente, donde indicamos que el tipo de salida será con formato HTML ya que estamos empleando el reportListener HTMLListener. Además indicamos el nombre que deseamos tenga el archivo de salida. * Damos a conocer la biblioteca de clases a emplear
SET CLASSLIB TO HOME() + "FFC\_REPORTLISTENER"
* declarar el objeto ReportListener deseado
oHTMListener = CREATEOBJECT("HTMLListener")
* configurar las propiedades
oHTMListener.TargetFileName = "MyFilename"
* utilizar el objeto para generar el informe
REPORT FORM myreport OBJECT oHTMListenerA lo largo de esta serie veremos ejemplos de lo que podemos lograr con el uso correcto de objetos ReportListener. Pero bueno, volvamos al tema del artículo que no es otro que la secuencia de eventos en la Generación de informes. Modos de generación Me detengo brevemente en este aspecto para dejarlo definido un poco mejor y que se comprenda la diferencia existente con respecto a versiones anteriores. La propiedad ReportListener.ListenerType define el modo de generación, por tanto, en dependencia del valor de esta propiedad tendremos los siguientes posibles valores y resultados. ListenerType = - 1 - No se Produce salida alguna ListenerType = 0 Preparar solamente una página y envía el resultado a la impresora configurada. ListenerType = 1 Prepara todas las páginas - En este caso, se preparan todas las páginas y no se desencadena el método OutputPage. Al finalizar la generación de todas las páginas se puede invocar este método para provocar la salida de las páginas, indicando un número de página determinado en cualquier orden cualquier cantidad de veces. La salida se realiza a la aplicación a la que apunta la variable de sistema _REPORTPREVIEW. No ocurre nada si no hay una aplicación disponible apuntada desde _REPORTPREVIEW ListenerType = 2 - Preparar solamente una página - No envía el resultado a la impresora. En este caso se desencadena el evento OutputPage en cuanto termina la generación de la página actual. Es eficiente sólo en el caso que necesitemos acceder a una página en concreto, por ejemplo, si se desea obtener la salida de informe con formato imagen. Cada vez que necesitemos obtener la salida de la página hay que regenerarla. ListenerType = 3 Prepara todas las páginas. No llama a la aplicación apuntada por _REPORTPREVIEW: Se invoca el evento OutputPage para indicar a qué dispositivo se debe enviar la salida. Soy consciente de que este artículo puede resultar complejo en una primera lectura, espero ir aclarando las dudas que surjan mediante los ejemplos que mostraré como parte de esta serie. Teniendo en cuenta que el tema del Motor de Informes en VFP 9.0 es un tema nuevo para todos, son bienvenidos los comentarios sobre la comprensión alcanzada por este artículo, posibles correcciones, dudas, aclaraciones, y vivencias experimentadas al trabajar con el objeto ReportListener. Espero que haya resultado de utilidad. Saludos, Ana María Bisbé York www.amby.net
|