8 de mayo de 2017

Extender informes en VFP 9.0 - Tiempo de Diseño (Parte 1/2)

Autor: Doug Hennig (http://www.stonefield.com)
Traducido por: Ana María Bisbé York


(Sesión "Extending the VFP 9 Reporting System: Design-Time" presentada por el autor en la Conferencia DevEssentials Kansas, 2004)

Resumen

Entre las novedades y mejoras del sistema de informes de VFP 9.0 está la posibilidad de extender el Diseñador de informes para proporcionar una escritura de informes más flexible, poderosa y fácil de utilizar por su equipo de desarrollo e incluso por sus usuarios finales. En este documento aprenderá sobre la nueva aplicación Report Builder, como captura y manipula eventos invocados por el Diseñador de informes, y cómo puede crear sus propios manipuladores para extender el Diseñador de Informes de VFP de manera que nunca antes imaginó.

Introducción

Uno de los mayores cambios en VFP 9.0 es la increíble mejoría hecha en el sistema de informes. Uno de los aspectos mejorados será expuesto en este documento: la capacidad de extender el Diseñador de informes.

El equipo de desarrollo de VFP tuvo varios objetivos en mente cuando trabajaron en las mejoras en tiempo de diseño, entre ellos:

  • Simplificar y mejorar la interfaz de usuario. En VFP 8.0 y anterior, había muchos diálogos relativos a informes. Algunos tenían una interfaz verdaderamente inusual y otros aun generaban más cuadros de diálogo. Puede ver un ejemplo de interfaz incómoda al hacer doble clic en un objeto de texto: esta acción mostraba la ventana propiedades para los objetos; pero no permitía cambiar la fuente ni el color del objeto. En VFP 9.0 hay pocos diálogos, porque todas las propiedades para un objeto se encuentran ahora en un solo lugar.
  • Nuevas características. En VFP 9.0 están disponibles novedades como la protección de informe y objetos, reutilización de Entorno de datos, posicionamiento absoluto y etiquetas en tiempo de diseño.
  • Extensible. VFP tuvo siempre un IDE muy extensible, pero VFP 9.0 rompió el record de extensibilidad. Ahora es posible reemplazar algunos o todos los diálogos del Diseñador de informes y cambiar completamente la interfaz de usuario y el comportamiento de los eventos de informe si desea.

Eventos de informes en tiempo de Diseño

Versiones anteriores de VFP brindaban una mínima posibilidad de personalizar el Diseñador de informes, prácticamente sólo la apariencia de la ventana en el que se mostraba el diseñador. Uno de los éxitos alcanzados en VFP 9.0 es proporcionar un mecanismo para entrar dentro del comportamiento del Diseñador de informes, de tal forma que su apariencia y comportamiento pueden ser personalizados lo más posible. Esto fue implementado con eventos en el Diseñador de informes, tales como abrir un informe, agregar un objeto, que se pasan a un componente Xbase, que puede realizar cualquier acción necesaria cuando ocurren eventos.

La nueva variable de sistema _REPORTBUILDER apunta a una aplicación (En este documento se le llama "report builder application"), que recibe la notificación sobre los eventos del Diseñador de informes. Cuando ocurre un evento de informes en tiempo de diseño y la variable _REPORTLISTENER apunta a una aplicación existente, el Diseñador de informes crea una sesión privada de datos y abre una copia del archivo FRX que está siendo editado actualmente en esa sesión de datos, entonces, llama a la aplicación del generador de informes (report builder application). De forma predeterminada, _REPORTBUILDER apunta a ReportBuilder.APP, que se encuentra en el directorio raíz de VFP; pero, si se desea, se puede sustituir por otra aplicación. Si se especifica una aplicación inexistente no se genera un error; pero, en ese caso, no se desatan los eventos. Cualquier aplicación especificada por _REPORTLISTENER debe ser modal por naturaleza porque el Diseñador de informes espera a llamarla y recibir de esa aplicación un valor que indica qué ocurre.

El Diseñador de informes pasa los siguientes parámetros a la aplicación del generador de informes cuando ocurre un evento

ParámetroTipoDescripción
ReturnFlagsNPasado por referencia con valor inicial -1. Se utiliza para devolver valores al Diseñador de informes.
EventTypeNUn entero que representa el evento que ha ocurrido.
CommandClausesOObjeto Empty con las propiedades que indican qué cláusulas fueron utilizadas en el comando CREATE / MODIFY REPORT
DesignerSessionIDNID de la sesión de datos del Diseñador de informes.

ReturnFlags se utiliza para devolver valores al Diseñador de informes. Los posibles valores se muestran en la tabla a continuación, junto con las constantes que representan esos valores, que deben ser definidas en FOXPRO.H en la versión 9.0. Los valores son flags de bit que, si se desea, se pueden sumar.

ValorConstanteDescripción
1FRX_REPBLDR_HANDLE_EVENTEl evento ha sido controlado por la aplicación del generador de informes, por lo que la acción predeterminada del Generador de informes no se realizará (es como una especie de NODEFAULT)
2FRX_REPBLDR_RELOAD_CHANGESLa aplicación del generador de informes hizo cambios en el cursor FRX por lo que el Diseñador de informes debe recargar los cambios en su copia interna del FRX.

EventType contiene un valor que identifica el evento que ha ocurrido. Los valores posibles, junto a las constantes que los representan y el tipo de evento (evento de informe, de objeto o de banda), se muestran en la siguiente tabla. La tabla indica además, si el evento se puede suprimir agregando 1 al parámetro ReturnFlags. "Debe eliminar registro" significa que una vez que debido a que un registro de objeto creado nuevo ya ha sido agregado al FRX, debe suspender la creación de un objeto, debe eliminar ese registro en el cursor FRX y establecer el parámetro ReturnFlags en 3 (el evento fue controlado y los cambios deben ser re-cargados).

ValorConstanteDescripciónTipoSe puede eliminar
1FRX_BLDR_EVENT_PROPERTIESSe ha invocado una ventana Propiedades, haciendo doble clic o por acción del menú (para el informe, objeto o banda)Informe,
Objeto,
Banda
Si
2FRX_BLDR_EVENT_OBJECTCREATESe ha creado un objeto o banda Objeto,
Banda
Si (debe eliminar)
3FRX_BLDR_EVENT_OBJECTCHANGESe ha movido o redimensionado un objeto (parece que se dispara sólo para bandas)Objeto, BandaSi
4FRX_BLDR_EVENT_OBJECTREMOVESe ha eliminado un objeto o banda Objeto,
Banda
Si
5FRX_BLDR_EVENT_OBJECTPASTEUno o más objetos se han pegado al informe desde el portapapeles. Este evento se dispara para cada objeto que ha sido pegadoObjetoSi (debe eliminar)
6FRX_BLDR_EVENT_REPORTSAVEEl informe ha sido guardadoInforme No
7FRX_BLDR_EVENT_REPORTOPENEl informe ha sido abiertoInforme No
8FRX_BLDR_EVENT_REPORTCLOSEEl informe ha sido cerradoInforme Si
9FRX_BLDR_EVENT_DATAENVEl entorno de datos ha sido abierto InformeSi
10FRX_BLDR_EVENT_PREVIEWMODESe ha invocado el modo Presentación preliminar (preview)InformeSi
11FRX_BLDR_EVENT_OPTIONALBANDSSe ha invocado el diálogo Bandas opcionalesInformeSi
12FRX_BLDR_EVENT_DATAGROUPINGSe ha invocado el diálogo Agrupación de datosInformeSi
13FRX_BLDR_EVENT_VARIABLESSe ha invocado el diálogo Variables InformeSi
14FRX_BLDR_EVENT_EDITINPLACESe ha presionado Ctrl.+E sobre un objeto etiquetaObjetoSi
15FRX_BLDR_EVENT_SETGRIDSCALESe ha invocado el diálogo Escala de rejillaInformeSi
16FRX_BLDR_EVENT_OBJECTDROPUno o más objetos han sido creados por operaciones arrastrar y soltar desde el Entorno de datos, una DBC o el Administrador de informes. Este evento se dispara una vez para cada objeto que ha sido creado, y si se crea una etiqueta, también se dispara una vez por cada etiqueta.ObjetoSi (debe eliminar)
17FRX_BLDR_EVENT_IMPORTDEDesde el menú informes se seleccionó "Load data environment" - Cargar entorno de datosInformeSi
18FRX_BLDR_EVENT_REPORTEl informe será impresoInformeSi
19FRX_BLDR_EVENT_QUICKREPORTDesde el menú informes se seleccionó "Quick Report" - Informe rápidoInformeSi

Las propiedades de CommandClauses se muestran en la siguiente tabla.

PropiedadTipoDescripción
AddTableToDEL.T. si la opción Add Table (Agregar tabla) al Entorno de datos se marcó en el diálogo del Quick Report
AliasL.T. si la opción Add Alias (Agregar alias) al Entorno de datos se marcó en el diálogo del Quick Report o se especificó la cláusula ALIAS en el comando CREATE REPORT FROM
FieldListOUna colección de campos numéricos que representan los campos especificados en el diálogo Quick Report o en la cláusula FIELDS del comando CREATE REPORT FROM
FileCEl nombre del archivo FRX abierto en el Diseñador de informes. Este archivo puede no existir realmente si se utiliza CREATE REPORT / LABEL.
FormL.T. si se escogió un diseño en el diálogo Quick Report o la cláusula FORM se especificó en el comando CREATE REPORT FROM y .F. si se especificó si un diseño de columna o COLUMN
FromCContiene un nombre de tabla especificado en el comando CREATE REPORT FROM
InScreenL.T. si la cláusula IN SCREEN fue especificada en el comando CREATE/MODIFY REPORT/LABEL
InWindowCEl nombre de la ventana especificada es la cláusula IN <nombre ventana> del comando CREATE/MODIFY REPORT/LABEL
IsCreateL.T. si el comando fue CREATE REPORT/LABEL o .F. para MODIFY REPORT/LABEL
IsReportL.F. si el comando fue CREATE REPORT/LABEL o .T. para MODIFY REPORT/LABEL
IsQuickReportFromMenuL.T. si se ha invocado Quick Report
NoEnvironmentL.T. si la cláusula NOENVIRONMENT fue especificada en el comando MODIFY REPORT/LABEL
NoOverwriteL.T. si la cláusula NOOVERWRITE fue especificada en el comando CREATE REPORT/LABEL
NoWaitL.T. si la cláusula NOWAIT fue especificada en el comando CREATE/MODIFY REPORT/LABEL
ProtectedL.T. si la cláusula PROTECTED fue especificada en el comando MODIFY REPORT/LABEL
TitlesL.T. si la opción Titles se marcó en el diálogo Quick Report o la cláusula TITLES se especificó en el comando CREATE REPORT FROM
WidthNNúmero de columnas especificado en el comando CREATE REPORT FROM
WindowCNombre de la ventana especificada en la cláusula WINDOW <nombre> en el comando CREATE/MODIFY REPORT/LABEL

La aplicación del generador de informes se ejecuta dentro de una sesión privada de datos que contiene el cursor FRX. El Diseñador de informes pasa su propio datassesion ID a la aplicación del generador de informes en caso que necesite acceder a las tablas abiertas en el Entorno de datos del Diseñador de informes.

El cursor FRX del Diseñador de informes creado por la aplicación del generador de informes tiene el alias FRX. El puntero de registro está en el registro del objeto para el que se invocó el evento, puede ser el registro Encabezado de informes (primer registro en el cursor) si es un evento de informe, en lugar de un evento de objetos. El registro para cualquier objeto seleccionado en el Diseñador de informes tiene el campo CURPOS = .T. Con esto hay una complicación, debido a que CURPOS se utiliza por el registro encabezado de informes para guardar el valor de la configuración Show Position (Mostrar posición), debe ignorar este registro si está buscando los registros con CURPOS = .T. Por ejemplo, para contar el número de objetos seleccionados utilice:

count for CURPOS and recno() > 1 

ReportBuilder.APP

De forma predeterminada, _REPORTBUILDER apunta a ReportBuilder.APP en el directorio raíz de VFP. Esta aplicación proporciona un framework para controlar eventos de informes en tiempo de diseño, además proporciona un nuevo conjunto de diálogos atractivos y funcionales que sustituye los nativos utilizados para el Diseñador de informes. ReportBuilder.APP puede ser distribuida con sus aplicaciones para proporcionar este comportamiento en entorno de ejecución.

Además de ser llamado automáticamente por el Diseñador de informes, puede llamar a ReportBuilder.APP manualmente para cambiar su comportamiento para la sesión actual de VFP (no escribe la configuración para ninguna localización externa, como una tabla, archivo INI o registro de Windows, así que con una excepción, que veremos enseguida, el estado no se conserva de una sesión a otra)

  • Si la llama sin parámetros o pasando 1, mostrará un diálogo en el que puede cambiar el comportamiento de la aplicación del generador de informes. Puede además hacer clic derecho en el diálogo Propiedades y escoger Opciones para llamar al cuadro de diálogo Opciones.
  • Para mostrar un informe pase 2 y opcionalmente el nombre de un archivo FRX.
  • Para utilizarlo como controlador de registro pase 3 y el nombre de un archivo DBF (veremos esto más tarde)

El cuadro de diálogo Opciones tiene las siguientes características:

  • Puede definir que ocurre cuando ReportBuilder.APP recibe un evento de informe. Las posibilidades son buscar una clase controladora en la tabla del controlador de registro, utilizar un controlador "depurador" para eventos (muestra un diálogo en el que se ve el FRX en un control Grid y permite modificarlo así como otros parámetros), utilizar un controlador "inspector de eventos" (muestra información sobre el evento y el FRX en la ventana MESSAGEBOX()), o ignorar los eventos de informe.
  • Puede especificar que tabla controladora de registro debe ser utilizada, o hacer una copia de una tabla interna (más adelante lo veremos)

Existen varias formas de extender la funcionalidad en el Diseñador de informes.

  • Puede sustituir ReportBuilder.APP con una aplicación propia cambiando el valor de _REPORTBUILDER.
  • Puede envolver ReportBuilder.APP cambiando _REPORTBUILDER a una aplicación propia y haciendo que la aplicación haga una llamada a ReportBuilder.APP. Para aquellos que utilizaron FoxPro 2.x, pudiera recordarle al GENSCRNX.
  • Puede registrar objetos controladores de eventos en la tabla registro ReportBuilder.APP. Sospecho que esta será la opción más popular porque ReportBuilder.APP proporciona un framework de generador de informe y permite enfocarse simplemente en el control de los eventos de informes.

Registrar controladores de eventos de informes

Si desea crear su propio controlador de eventos de informes que sea llamado por ReportBuilder.APP cuando se disparen eventos de objeto, se requieren dos pasos. El primer paso es crear una clase que implemente el comportamiento deseado. Puede tener un método Execute (Ejecutar) que acepte un evento de objeto como parámetro, porque es lo que espera ReportBuilder.APP. El segundo paso es registrar el controlador en la tabla de registro ReportBuilder.APP. Veremos la segunda tarea primero, luego dedicaremos el resto del documento discutiendo sobre la primera.

Cuando ocurre un evento de informe, ReportBuilder.APP mira en la tabla de registro para encontrar un controlador para el evento. De forma predeterminada utiliza la tabla del registro del controlador generada dentro del archivo APP. Esta tabla proporciona manipuladores para muchos eventos de informes entonces los diálogos del nuevo Diseñador de informes XBase se utilizan en lugar de los nativos. Sin embargo, si desea registrar sus propios controladores, tiene que decirle a ReportBuilder.APP que utilice otra tabla de registro de controlador.

Existen diferentes formas de hacerlo:

  • DO (_REPORTBUILDER) y haga Clic en el botón Create Copy (Crear copia) para escribir la tabla del registro del controlador interno y uno externo. De forma predeterminada, esta copia se llamará ReportBuilder.DBF. Cuando ReportBuilder.APP comienza, busca una tabla llamada ReportBuilder.DBF en el directorio actual o la ruta de VFP. Si encuentra esta tabla, la utiliza en lugar de la tabla interna. Entonces, simplemente al crear esa copia significa que el ReportBuilder.APP la utilizará sin tener que hacer nada más.
  • DO (_REPORTBUILDER) y haga Clic en el botón Choose (Seleccionar) para seleccionar la tabla a utilizar.
  • Como mencioné antes, DO (_REPORTBUILDER) WITH 3, <DBF a utilizar> para especificar la tabla del manipulador deseado sin ninguna interfaz de usuario.

Una vez que se ha especificado una tabla externa de registro del manipulador, puede agregar manualmente o modificar registros en esa tabla o en el diálogo Opciones del ReportBuilder.APP, haga clic en el botón Explore registry (Explorar registro) y modificar los registros en el diálogo resultante.

La tabla de registro del controlador tiene la siguiente estructura:

Nombre del campoTipoValoresDescripción
REC_TYPEC(1)E, F, G, H, o XEspecifica el tipo de registro (se detalla luego):
H: registro de controlador de evento de informe
F: registro de filtro de evento de informe
X: registro de controlador de salida
G: Registro de cobertura de GetExpresion (wrapper record)
E: Clase editor de extensión en tiempo de ejecución.
HNDL_CLASSC(25) Nombre de clase
HNDL_LIBC(25) Biblioteca de clases
EVENTTYPEI0 - 16 ó -1ID de tipo de evento de informe (-1 significa cualquier evento)
OBJTYPEI0 - 10 ó -1Tipo de objeto de informe (-1 para cualquier objeto)
OBJCODEI0 - 26 ó -1Código de objeto de informe (-1 para cualquier código)
NATIVEL.T. ó .F..T. para forzar el evento de informe que sea devuelto al Diseñador de informes para un comportamiento nativo
DEBUGL.T. ó .F..T. para forzar el controlador de depuración para que sea utilizado para esta combinación evento/objeto
FLTR_ORDRC(1)" ", "1", "2", ..Solo para controladores de filtros y salida, especifica el orden en que deben ser aplicados.
NOTESC(35)  No se utiliza por el ReportBuilder.APP.

Cuando ocurre un evento de informe, ReportBuilder.APP busca la clase controladora para instanciar buscando el registro donde EVENTYPE se corresponda con el ID de evento de informe (o sea igual a -1). OBJTYPE se corresponda con la columna OBJTYPE del registro seleccionado del FRX (o sea igual a -1) y OBJCODE se corresponda con la columna OBJCODE del registro seleccionado del FRX (o sea igual a -1). Debido a que ReportBuilder.APP utiliza el primer registro del controlador que encuentre que cumpla las condiciones, si desea implementar controladores propios, puede ser necesario eliminar o inhabilitar los controladores integrados (built-in).

Una forma en que puede inhabilitar el registro sin eliminarlo es cambiar EVENTTYPE a un valor no válido. Yo utilizo 100 como valor para EVENTTYPE para inhabilitar el registro, debido a que puedo re-habilitarlo fácilmente substrayendo 100.

Como puede ver en la tabla, REC_TYPE registra diferentes tipos de registros. Veamos los tipos posibles:

  • Un controlador de evento de informe controla un evento de informe.
  • Un filtro de evento de informe es una clase que obtiene una falla antes de lo que lo hace el controlador de eventos del informe. Un filtro de evento de informe es una clase del informe. Una vez que haya sido instanciado un único controlador, ReportBuilder.APP instancia la clase especificada en todos los registros filtrados, en el orden FLTR_ORDER, y llama su método HasHandled. Si algún filtro de objeto devuelve .T. desde este método (lo que significa que el filtro ha controlado el evento), entonces no ocurre ningún otro procesamiento y el Diseñador de informes es informado que el evento ha sido manipulado.

Como puede ver de esta descripción, aunque ambos pueden responder a eventos de informe, existe una gran diferencia entre filtros de eventos y controladores de eventos:

  • Los filtros son instanciados en cada evento de informe, mientras un controlador es instanciado sólo para el evento si ha sido registrado en la tabla de registro del controlador.
  • Todos los filtros se instancian en un evento, mientras hay un solo controlador.

Esto significa que los filtros son buenos para el comportamiento que se desea que ocurra en múltiples o todos los eventos, mientras los controladores son específicos para un tipo de evento.

  • Los controladores de salida son similares a la combinación de controladores de filtros y eventos, en que después que los otros procesos se han hecho, ReportBuilder.APP ejecuta todos los controladores de salida instanciando las clases adecuadas en el orden FLTR_ORDER y llamando al método Execute. Estos controladores son justamente para garantizar un comportamiento de limpieza post-evento.
  • GetExpresion proporciona un envoltorio para sustituir el diálogo GETEXPR.
  • Los editores de extensión en tiempo de ejecución, sustituyen el diálogo mostrado cuando hace clic en el botón Edit Settings (Modificar configuración) para la propiedad Run-time Extension en la ficha Otros de la ventana propiedades de un objeto.

Proceso de control de eventos de informe

Cuando se llama a ReportBuilder.APP porque ha ocurrido un evento de informe la aplicación hace lo siguiente:

  • Ejecuta cualquier filtro registrado como se ha descrito antes. Se suspende el procesamiento si alguno devuelve .T.
  • Trata de encontrar el controlador del evento utilizando el siguiente patrón de diseño.
    REC_TYPE="H", EVENTTYPE, OBJTYPE, OBJCODE ...
  • Si se encuentra un controlador, ReportBuilder.APP instancia y llama su método Execute. Si no hay ningún controlador, el evento se pasa al Diseñador de informe y se realiza el comportamiento nativo.
  • Si se encuentra un controlador, ReportBuilder.APP ejecuta todos los registros de controladores de salida como se ha descrito antes.

Interfaces de controlador

Los filtros de evento, controladores de evento y controladores de salida, envolturas GetExpression y editores de extensiones en tiempo de ejecución pueden basarse en cualquier clase y tener sólo un único método requerido.

Los métodos son:

  • Filtros: HasHandled (toevent). ReportBuilder.APP pasa a este método una referencia de objeto de evento, el que va a mirar más tarde, cuyas propiedades contienen información del evento. Para evitar futuros procesamientos, devuelve .T. desde este método, en tal caso, la propiedad ReturnFlags del evento debe estar establecida adecuadamente.
  • Controlador de evento: Execute(toevent). Este método también recibe un objeto evento. El valor devuelto no es importante; pero si lo es la propiedad ReturnFlags del objeto evento.
  • Controlador de salida: Execute(). El valor devuelto no es importante.
  • Envoltura GetExpression: GetExpression(tcDefaultExpr [, tcCalledFrom]). Donde tcDefaultExpr es la expresión predeterminada para el diálogo, tcCalledFrom indica de dónde ha sido llamado este método desde "PrintWhenExpression", "FieldExpression", "OLEBoundField", "OLEBoundExpression", "BandGroupOnExpression", "VariableValueToStore", o "VariableInitialValue". El valor devuelto es la expresión
  • Editores de Extensión en tiempo de ejecución. Igual que para controladores de eventos.

Objetos de eventos

ReportBuilder.APP pasa un objeto de evento al método HasHandled de los filtros y al método Execute de los controladores de evento. Este evento incluye como propiedades el parámetro pasado por el Diseñador de informes al ReportBuilder.APP, más alguna otra información útil.

PropiedadTipoDescripción
BuilderPathCRuta del ReportBuilder.APP.
CommandClausesOEl mismo objeto CommandClauses pasado al ReportBuilder.APP
DefaultRecnoIPuntero del registro en el cursor FRX
DefaultSessionIDISesión de datos del Diseñador de informes (el 4to parámetro pasado desde el Diseñador de informes)
EventTypeITipo de eventos (el 2do parámetro pasado desde el Diseñador de informes)
FRXCursorOObjeto auxiliar que contiene funciones para interactuar con el cursor FRX
FRXSessionIDISesión de datos en la que se abre el cursor FRX (la sesión predeterminada cuando se instancia el controlador de eventos.)
ObjCodeIValor del campo OBJCODE del registro seleccionado en el cursor FRX
ObjTypeIValor del campo OBJCTYPE del registro seleccionado en el cursor FRX
ProtectedL.T. si el Diseñador de informes se invocó con la cláusula PROTECTED
ReturnFlagsIEl valor de esta propiedad es devuelto por el Diseñador de informes en el primer parámetro pasado desde el Diseñador de informes. Inicialmente se establece igual a 1 (FRX_REPBLDR_HANDLE_EVENT), debe establecerlo a 3 si su clase hace cambios en el cursor FRX que necesite ser recargado al diseño (layout). (FRX_REPBLDR_HANDLE_EVENT + FRX_REPBLDR_RELOAD_CHANGES)
SelectedObjectCountICantidad de objetos seleccionados en el diseño de informes, determinado por CURPOS = .T. en el cursor FRX (no cuenta el registro cabecera)
SessionData OUna referencia al par Nombre-Valor del objeto controlador utilizado para guardar el dato entre llamados a ReportBuilder.APP
UniqueID Valor de el campo UNIQUEID del registro seleccionado en el cursor FRX


Tiene tres métodos públicos:

MétodoParámetrosDevuelveDescripción
GetEventTypeTexttiEventCDevuelve el nombre de un tipo de evento dado.
GetExtensionEditorNoneODevuelve una referencia a una clase editora de extensión en tiempo de ejecución como especificado en la tabla de registro del controlador.
GetTargetTypeTexttiObjType, tiObjCodeCDevuelve el nombre de un objeto dado tipo objeto / código objeto. Envuelve el método GetTargetTypeText() para el objeto FRXCursor.

Objeto ayudante FRXCursor

Este objeto, referenciado en la propiedad FRXCursor, proporciona métodos que puede encontrar útiles cuando trabaja con un FRX.

MétodoParámetrosDevuelveDescripción
BinStringToInttcBytesNDevuelve un equivalente del dato binario en una cadena de bytes.
BinToInttcValueIConvierte una cadena binaria a entero
CreateBandCursor[tcFRXAlias] LCrea un cursor con el alias "Bands" que contiene información útil sobre las bandas de informe.
CreateCalcResetOnCursor[tcFRXAlias]LCrea un cursor con el alias "Reset_On" que contiene información útil para cada opción en el cuadro combinado Calculation Reset.
CreateDefaultPrintEnvCursor[tcFRXAlias
[, tcDestAlias]]
LCrea un cursor de un registro nombrado "DefPrnEnv" con la misma estructura como el FRX, con la información de entorno predeterminado de impresora cargado en EXPR, TAG y TAG2
CreateGroupCursor[tcFRXAlias] LCrea un cursor con el alias "Groups" que contiene información útil sobre las agrupaciones de datos del informe.
CreateMemberDataCursor[tcFRXAlias
[, tcMDAlias]]
LCrea un cursor de un registro con los atributos del MemberData del informe, extrayendo y convirtiendo en XML desde el desde el campo STYLE actualmente seleccionado en el FRX.
CreateObjectCursor[tcFRXAlias
[, tiOption ]]
LCrea un cursor con el alias "Objects" que contiene información útil sobre los objetos de diseño del informe. Llama a CreateBandCursor() si es necesario. Los valores para tiOption son:
0 (predeterminado) todos los objetos en el FRX, ignorando los elementos agrupados
1: sólo registros seleccionados (CURPOS = .T.)
2: todos los objetos, mostrando los objetos agrupados como un único registro
3: ruptura o salto de elemento de grupo
Algunos registros pueden ser marcados para borrar (deleted). Utilice SET DELETED ON o ignore manualmente los registros marcados.
CreateVariableCursor[tcFRXAlias] LCrea un cursor con el alias "Vars" que contiene información útil sobre las variables de informe.
FRUToPixelstnFRU IDevuelve los píxeles correspondientes para un número dado de FRU (FixPro Reports Units, 1/10000 pulgadas)
GetBandFortcUniqueID
[, tlStart]
ODevuelve un objeto que contiene información sobre el inicio o fin de banda que rodea al objeto de informe dado.
GetFRUTextHeighttcText, tcTypeFace, tiSize
[, tcStyle]
NDevuelve la altura en FRU del texto y especificación de fuente dados.
GetFRUTextWidthtcText, tcTypeFace, tiSize
[, tcStyle]
NDevuelve el ancho en FRU del texto y especificación de fuente dados.
GetFRXTimeStampttDateTimeIDevuelve una marca de tiempo FoxPro para una fechahora dada.
GetObjectsInBandtcBandID [, tlRecnos] ODevuelve una colección de valores UNIQUE o números de registros (dependiendo del valor del segundo parámetro) para cada objeto contenido en una banda especificada.
GetReportAttributetcAttrib
[, tiAlternate]
ValueDevuelve un atributo dado del encabezado de informe. Algunos atributos tienen información asociada que se puede obtener pasando un segundo parámetro opcional de 1
GetSelectedObjectCountNingunoIDevuelve la cantidad de objetos actualmente seleccionados (CURPOS = .T.) en el cursor FRX.
GetTargetTypeTexttiObjType, tiObjCodeCDevuelve el nombre de un tipo de objeto o código de objeto dado
GetTimeStampStringtiTimeStampCConvierte una marca de tiempo de FoxPro en una cadena legible
HasBandtiObjCodeLDevuelve .T., si el informe contiene una banda del tipo dado.
HasDetailHeadertcDetailBandIDLDevuelve .T., si el registro de banda especificado tiene un registro de encabezado de banda asociado.
HasProtectionFlagtcBytes, tiFlagLDevuelve .T. si el dato binario dado (bytes) tiene un conjunto de flag de protección especificados.
InsertBandtiObjCode-Inserta una banda de un tipo dado en el cursor FRX. Asume que se ha seleccionado el cursor FRX y está posicionado en la localización correcta para insertar.
InsertDetailBandNinguno-Inserta un registro de Banda de detalle en el cursor FRX. Asume que se ha seleccionado el cursor FRX y está posicionado en el registro adecuado para insertar el registro de detalle.
InsertDetailHeaderFooterNinguno-Inserta un registro de Encabezado / Pie de Banda de detalle en el cursor FRX. Asume que se ha seleccionado el cursor FRX, que está posicionado en el registro de banda de detalle al que hay que agregar registro de Encabezado/Pie de Banda y que esta Banda de detalle aun no tiene registro de Encabezado/Pie de Banda
InsertSummaryBandtlNewPage, tlPageHeader, tlPageFooter- Inserta una banda Resumen (Summary) en el cursor FRX. Asume que se ha seleccionado el cursor FRX y que no tiene aun esta banda.
InsertTitleBandtlNewPage-Inserta una banda Title en el cursor FRX. Asume que se ha seleccionado el cursor FRX y que no tiene aun esta banda.
IntToBintiValueCConvierte un entero a una cadena binaria
IntToBinStringtiValue CDevuelve una cadena de bytes de una versión binaria de un entero.
PixelsToFRUtnPixelsNDevuelve el correspondiente valor FRU para un número determinado de píxeles
StoreMemberDataCursor[tcFRXAlias
[, tcMDAlias]]
LToma un cursor de un registro de los atributos de informe MemberData, convierte los atributos del MemberData XML y los guarda en el campo STYLE del registro actualmente seleccionado del FRX
SynchObjectPositions Ninguno L Reinicia los objetos no marcados para borrar en el FRX relativo al iniciar la banda en la que están. Asume que los cursores Bandas y Objetos han sido creados, la tabla actualmente seleccionada es el cursor FRX y no necesita restablecer el puntero registro.

No hay comentarios. :

Publicar un comentario

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