Guía de Diccionarios de Datos
Transcripción
Guía de Diccionarios de Datos
Soluciones abiertas para un mundo cambiante Guía de Diccionarios de Datos www.Moose-Software.com • www.VisualDataflex.es Soluciones abiertas para un mundo cambiante Versiones documento Versión 1.0 Revisado por Andrea Guimarães Páginas Versión inicial. Traducido de “Data Dictionary Guide” de la ayuda de VDF 12.1 www.Moose-Software.com • www.VisualDataflex.es Fecha 31/01/2008 Guía de Diccionario de Datos Índice Introducción a los Diccionarios de Datos ........................................................................ 9 Usando Diccionarios de Datos mientras se desarrolla una aplicación ...................................... 9 Usando Diccionarios de Datos cuando se desarrolla una aplicación ......................................... 9 Trabajando con Diccionarios de Datos .............................................................................. 10 Creando clases de Diccionario de Datos ......................................................................... 10 Construyendo estructuras de Objeto de Diccionario de Datos............................................ 11 Restricciones y filtros .................................................................................................. 11 Usando los objetos de Diccionario de Datos ................................................................... 12 Usando objetos de Diccionario de Datos con las Aplicaciones de Windows .......................... 12 Usando Objetos de Diccionario de Datos con Aplicaciones Web ......................................... 13 Tablas, columnas y filas................................................................................................ 15 Consulte lo siguiente...................................................................................................... 15 Índices ......................................................................................................................... 16 Consulte lo siguiente...................................................................................................... 16 Relaciones .................................................................................................................... 17 Consulte lo siguiente...................................................................................................... 18 Identidad de disco y RowId .......................................................................................... 19 Tipo de datos de RowId .................................................................................................. 20 Funciones globales de RowId .......................................................................................... 21 La interfaz de Diccionario de Datos de RowId .................................................................... 22 Notas especiales ............................................................................................................ 22 Consulte lo siguiente...................................................................................................... 23 Transacciones, Bloqueos y soporte multi-usuario ......................................................... 24 Consulte lo siguiente...................................................................................................... 24 Buffers de fichero y Buffers de campos de DDO ............................................................ 25 Consulte lo siguiente...................................................................................................... 25 www.VisualDataflex.es Página 3 de 92 Guía de Diccionario de Datos Comandos tipo File-Field y Field ................................................................................... 26 Consulte lo siguiente...................................................................................................... 26 Los comandos de tablas (File) ...................................................................................... 27 Consulte lo siguiente...................................................................................................... 27 El API de base de datos ............................................................................................... 28 Consulte lo Siguiente ..................................................................................................... 28 El constructor de Diccionario de Datos (Define_Fields) ................................................ 30 Consulte lo siguiente...................................................................................................... 32 Definir los atributos de tabla de diccionario de datos ................................................... 33 Fijar su tabla principal (Main_File) ................................................................................... 33 Consulte lo siguiente ................................................................................................... 33 Campos clave (key Fields) .............................................................................................. 33 Key_Field_State ......................................................................................................... 34 Protect_key_State ...................................................................................................... 34 Consulte lo siguiente ................................................................................................... 34 Protección de grabación y borrado ................................................................................... 35 Read_Only_state ........................................................................................................ 35 No_Delete_State ........................................................................................................ 35 Cascade_Delete_State................................................................................................. 35 Validate_Foreign_File_State ......................................................................................... 36 Consulte lo siguiente ................................................................................................... 36 Definir los atributos de campo de diccionario de datos ................................................. 37 Opciones de campo (Field Options) .................................................................................. 37 Búsqueda automática (DD_AutoFind) ............................................................................ 38 Búsqueda automática GE (DD_AutoFind_GE) ................................................................. 39 UPPERCASE (DD_CapsLock) ......................................................................................... 39 Fuerza de escribir (DD_ForcePut) .................................................................................. 40 No-Enter (DD_NoEnter) ............................................................................................... 40 www.VisualDataflex.es Página 4 de 92 Guía de Diccionario de Datos No-Put (DD_NoPut) ..................................................................................................... 40 Display_Only (DD_DisplayOnly).................................................................................... 41 Retain(DD_Retain)...................................................................................................... 41 Retain-All (DD_RetainAll) ............................................................................................ 41 Skip-Found (DD_SkipFound) ........................................................................................ 42 Zero-Suppress (DD_Zero_Suppress) ............................................................................. 42 Require (DD_Required) ............................................................................................... 42 Find-Required (DD_FindReq) ........................................................................................ 42 Limpiar opciones de campo .......................................................................................... 43 Consulte lo siguiente ................................................................................................... 43 Validaciones de campo (Field Validations)......................................................................... 43 Casilla de verificación (Checkbox) ................................................................................. 44 Rangos (Range).......................................................................................................... 44 Verificación (Check) .................................................................................................... 45 Tablas de validación (Validation Tables) ........................................................................ 45 Tabla de validación (Validation Table) ........................................................................... 46 Descripción de validación de tabla (Description Validation Table) ...................................... 46 Tabla de validación de archivo (File Validation Table) ...................................................... 47 Tablas de validaciones de código (Code Validation Table) ................................................ 47 Métodos de validación de campo (File Validation Methods) ............................................... 47 Errores de validación de campo (Field Validation Errors) .................................................. 48 Consulte lo siguiente ................................................................................................... 49 Aspecto del campo......................................................................................................... 49 Máscaras (Masks) ....................................................................................................... 49 Etiquetas (Labels) ....................................................................................................... 49 Ayuda de estado (Status Help) ..................................................................................... 50 Controles de ventanas (Windows Controls) .................................................................... 50 Consulte lo siguiente ................................................................................................... 50 www.VisualDataflex.es Página 5 de 92 Guía de Diccionario de Datos Métodos de entrada y salida ........................................................................................... 51 Método de entrada ...................................................................................................... 51 Método de salida ........................................................................................................ 52 Consulte lo siguiente ................................................................................................... 53 Autoincremento del campo ............................................................................................. 53 Consulte lo siguiente ................................................................................................... 54 Listas de consultas (Lookup lists) .................................................................................... 54 Consulte lo siguiente ............................................................................................... 55 Definir atributos de campos foráneos en Diccionario de Datos ..................................... 56 Campos Foráneos clave .................................................................................................. 57 Consulte lo siguiente ................................................................................................... 58 Campos Foráneos indexados ........................................................................................... 58 Consulte lo siguiente ................................................................................................... 58 Campos Foráneos por defecto ......................................................................................... 58 Consulte lo siguiente ................................................................................................... 59 Definiendo Diccionarios de Datos de Padres, Hijos y relaciones externas ..................... 60 Consulte lo siguiente ................................................................................................... 60 Definiendo “tablas Padre” requeridas ............................................................................... 60 Consulte lo siguiente ................................................................................................... 61 Definiendo “tablas Hijo” requeridas .................................................................................. 61 Consulte lo siguiente ................................................................................................... 61 Requisitos para grabar (save) ......................................................................................... 62 Consulte lo siguiente ................................................................................................... 63 Requisitos para eliminar ................................................................................................. 63 Consulte lo siguiente ................................................................................................... 64 Cómo trabaja la estructura de validación DDO................................................................... 65 Modo de validación ..................................................................................................... 65 Consulte lo siguiente ................................................................................................... 66 www.VisualDataflex.es Página 6 de 92 Guía de Diccionario de Datos Sistema y tablas externas............................................................................................... 66 Definir eventos Del Diccionario de Datos ...................................................................... 68 Forward sending mensajes de evento ............................................................................... 69 Eventos de campo definidos por el usuario ........................................................................ 69 Consulte lo siguiente ................................................................................................... 69 Attach_Main_File ........................................................................................................... 70 Consulte lo siguiente ................................................................................................... 70 Backout y Update .......................................................................................................... 70 Consulte lo siguiente ................................................................................................... 72 Clear_Main_File............................................................................................................. 72 Consulte lo siguiente ................................................................................................... 72 Creating (crear) ............................................................................................................ 72 Consulte lo siguiente ................................................................................................... 73 Delete_Main_File ........................................................................................................... 73 Consulte lo siguiente ................................................................................................... 73 Deleting (borrar) ........................................................................................................... 73 Consulte lo siguiente ................................................................................................... 74 Field_Defaults ............................................................................................................... 74 Consulte lo siguiente ................................................................................................... 74 On new current Record ................................................................................................... 74 Notas especiales ......................................................................................................... 75 Consulte lo siguiente ................................................................................................... 75 Relate_Main_File ........................................................................................................... 75 Consulte lo siguiente ................................................................................................... 77 Save_Main_File ............................................................................................................. 77 Consulte lo siguiente ................................................................................................... 78 Update y Backout .......................................................................................................... 78 Consulte lo siguiente ................................................................................................... 79 www.VisualDataflex.es Página 7 de 92 Guía de Diccionario de Datos Validate_delete ............................................................................................................. 79 Consulte lo siguiente ................................................................................................... 80 Validate_Save ............................................................................................................... 80 Consulte lo siguiente ................................................................................................... 81 Consulte lo siguiente...................................................................................................... 82 Restricción relacionada con Relates To Constraints ...................................................... 83 Consulte lo siguiente...................................................................................................... 85 Restricciones de filtro................................................................................................... 86 Tipos de restricciones de filtro ......................................................................................... 86 El archivo de filtro de campo (File.Field Filter) ................................................................ 86 El filtro Constrain-As ................................................................................................... 87 Consulte lo siguiente ................................................................................................... 88 El proceso de creación de las restricciones (Constraint) ...................................................... 88 Consulte lo siguiente ................................................................................................... 89 Herencia de las restricciones ........................................................................................... 89 Poner restricciones “padre” en un “DDO hijo” ................................................................. 91 Consulte lo siguiente ................................................................................................... 91 Optimización de búsquedas de restricción ......................................................................... 91 La propiedad de ordenación ......................................................................................... 92 Consulte lo siguiente ................................................................................................... 92 www.VisualDataflex.es Página 8 de 92 Guía de Diccionario de Datos Introducción a los Diccionarios de Datos En Visual DataFlex, la implantación de las reglas de de negocio de su aplicación se expresan y administran completamente por Diccionarios de Datos. Los Diccionarios de Datos crean una capa entre la lógica de aplicación y los datos. Esto aporta las siguientes ventajas: • Permite a su aplicación interactuar más eficazmente con su base de datos. Los Diccionarios de Datos aumentan la información de su base de datos de forma independiente a los datos físicos. • Protege sus datos - los Diccionarios de Datos se aseguran de que solamente se añadan datos válidos. • Centraliza la lógica de aplicación - toda la información y las reglas en un solo lugar. Si tiene que hacer un cambio, hágalo solamente en un lugar y el resto se modificará solo. Los Diccionarios de Datos se definen como clases. Creará una clase de Diccionario de Datos para cada tabla. Estas clases serán usadas mientras esté desarrollando su aplicación. Usando Diccionarios de Datos mientras se desarrolla una aplicación Mientras esté desarrollando su aplicación, las herramientas de apoyo de Visual DataFlex usarán la información en sus clases de Diccionario de Datos para ayudarle en el proceso de desarrollo. Esta información será usada cuando cree vistas de entrada en Windows, informes y páginas web. Studio y sus asistentes usarán el Diccionario de Datos para determinar: • Qué tablas deben ser abiertas y cómo están conectadas. • Qué tipos de controles deben ser usados para un campo especial (por ejemplo: el tipo de línea, casilla de verificación…) • Qué etiquetas y contexto debe ser usado como ayuda para sus controles. • Qué listas de consultas (lookup lists) deben ser usadas, cómo deben ser usadas y cuál será su aspecto. Los Diccionarios de Datos facilitan crear aplicaciones sólidas, con buena apariencia y fácilmente mantenible. Usando Diccionarios de Datos cuando se desarrolla una aplicación Los Diccionarios de Datos se añaden a una aplicación creando Objetos de Diccionario de Datos (DDOs). A la hora de desarrollar una aplicación, los DDOs sirven para dos propósitos principales: • Coordinan la actividad de la base de datos – en los objetos de entrada de datos- (DEOs). • Proveen a un programa los servicios de validación y actualización de la base de datos. www.VisualDataflex.es Página 9 de 92 Guía de Diccionario de Datos Estos dos propósitos son distintos. Creando una estructura de DDOs, conectando los objetos de manera apropiada y a la vez conectando DEOs a esta estructura, garantizando la actividad de la base de datos de forma coordinada. Todas estas conexiones se programan a nivel de objeto. Las reglas de la base de datos se mantienen actualizadas porque son creadas en una clase de Diccionario de Datos con propiedades y con varios eventos definidos en el Diccionario de Datos. Esto se programa a nivel de clase. Trabajando con Diccionarios de Datos Trabajar con Diccionario de Datos consiste en: • Crear una subclase de Diccionario de Datos para cada tabla codificando las reglas de las bases de datos en estas clases. Esto se consigue creando propiedades, funciones y procedimientos. • Crear objetos (objetos de entrada de datos) en las vistas, objetos Web y otros componentes. Una estructura de DDO es un grupo de objetos de DD que se conectan para proporcionar el acceso sincronizado a tablas relacionadas. • Crear objetos (objetos de entrada de datos) ó métodos (funciones / procedimientos) dentro de las vistas, objeto Web u otro componente que se comunique con sus DDOs. Esto permitirá que vea, cree, edite o borre sus datos. Creando clases de Diccionario de Datos Creará una clase de Diccionario de Datos para cada tabla de su aplicación. Estas clases, basadas en la clase de DataDictionary, permiten que defina la información y se establezcan las reglas para una tabla. Poniendo estas reglas en un único lugar (una clase) no tendrá que repetirlas en cada componente que acceda a la tabla. Las reglas que puede especificar en esta clase son: • La estructura de la tabla. • Cómo se puede conectar a otras tablas. • Definir qué validaciones y propiedades se aplican a cada campo. • Qué reglas deben ser aplicadas durante grabaciones (saves), borrados (deletes) y actualizaciones (updates). • Otra información como los nombres de etiqueta o texto de ayuda. Todos los cambios de datos pasan por los DDOs. Antes de que se cambien los datos los Diccionarios de Datos los validan para usar las reglas, simples o complejas, que usted ha desarrollado en sus clases de Diccionario de Datos. Los Diccionarios de Datos son una clase tan importante que se ha desarrollado una herramienta visual, Database Builder, para crear y mantener esas clases. Pretendemos que utilice siempre esta herramienta para mantener sus Diccionarios de Datos. Database Builder crea el código fuente para estas clases. En algunos casos este código se genera automáticamente seleccionando las opciones apropiadas en el Database Builder mientras que en otros casos usted creará este código usando el editor de código del Database Builder. www.VisualDataflex.es Página 10 de 92 Guía de Diccionario de Datos Para más información acerca del funcionamiento de esta herramienta vea: Definiendo clases de Diccionario de Datos. Construyendo estructuras de Objeto de Diccionario de Datos Un conjunto de tablas relacionadas son representadas en su aplicación como una estructura de objeto (DDO) de Diccionario de Datos. Las estructuras de DDO son creadas dentro de varios objetos contenedores diseñados para manejar DDOs. Algunos de los objetos contenedores diseñados para esto son: • DbView: usados por aplicaciones de windows para la introducción de datos. • ReportView: usados para pedir informes. • BusinessProcess: éstos son utilizados por aplicaciones Windows y Web para manejar y procesar por lotes. • cWebBusinessProcess: usados en aplicaciones de Web que proveen todo el soporte posterior (Back end) para sus páginas HTML. • cWebService: usados en aplicaciones de Web para suministrar el soporte para los servicios Web (Web services). Las reglas para montar estructuras de DDO son las mismas para todos estos contenedores. Cada objeto de Diccionario de Datos debe ser creado y conectado a la estructura de forma apropiada. Esto es hecho a través DDOs hijo creando enlaces con los DDOs padre. Cuando se monta apropiadamente, las estructuras de DDO proveen acceso sincronizado a una jerarquía de datos. Según sea necesario se propagan mensajes entre varios objetos DD entregando de esta forma un comportamiento homogéneo y consistente para las operaciones de Buscar, Limpiar, Grabar y Borrar. Además se validan estas estructuras antes de permitir el cambiar datos. El Studio maneja por usted la creación de estructuras de DDOs. Para más información sobre estructuras de DDOs vea: Creando estructuras de Objeto de Diccionario de Datos (DDO). Restricciones y filtros Una tarea adicional de los DDOs es permitir que se puedan restringir y filtrar los registros dentro de un componente. Se soportan dos tipos de restricciones: • Cuando un DDO se relaciona con otro, usted podría querer que el DDO hijo muestre solamente los registros que se relacionan con el registro en curso en el DDO padre. A esto se llama Relates- To- Constraint o Restricción por Relación. • Una vista o informe puede necesitar solamente de un subconjunto de datos de cada vez. Podría, por ejemplo, especificar clientes y filtrar por una determinada región o provincia. A estos se les llama Filter Constraints o Restricción por filtro. Ambas clases de restricciones (se pueden combinar juntas) se definen dentro de sus estructuras de DDO. Para más información sobre restricciones y filtros vea: Restricciones y Filtros. www.VisualDataflex.es Página 11 de 92 Guía de Diccionario de Datos Usando los objetos de Diccionario de Datos El objeto que contiene una estructura de DDO también contiene, a su vez, todos los objetos y métodos necesarios para comunicarse con esos DDOs. Este proceso de comunicación está, por lo tanto, totalmente encapsulado. En algunos casos, esta comunicación ocurrirá entre un objeto de entrada de datos (DEO) y un DDO. Por ejemplo, una ventana contendrá DEOs que permiten que vea y edite sus datos. Cada DEO está asignado a un DDO y toda comunicación entre el DDO y el DEO es automática. En otros casos, la comunicación ocurrirá entre un método (procedimiento o función) y un DDO. Por ejemplo, un objeto de proceso de datos (Business Process Object o BPO), un objeto navegador de web o un objeto de servicio de Web contendrán una estructura de DDO y los métodos que usan el DDO. En todos los casos, los DDOs son usados para el mismo propósito. Tienen que permitirle hacer lo siguiente: • Buscar o borrar datos. • Proporcionarle información sobre el valor de un campo del DDO. • Producir cambios en un valor del campo de DDO. • Validar y grabar datos. • Validar y borrar datos. En una aplicación de Web, la conexión entre su DDO y DEO (su navegador) es indirecta, o procesada por lotes. Todos los cambios en un DDO son enviados al navegador en formato HTML como un solo evento. Todos los cambios en un DEO (el navegador) son enviados al DDO una sola petición de lote. Su Web Browser Object (WBO) coordina esta actividad. El mismo DDO es capaz de soportar diferentes interfaces (por ejemplo: controles de ventanas, páginas HTML, servicios Web) y por lo tanto, la habilidad del DDO de comunicarse con estas interfaces variará. Sin embargo, la lógica básica de DDO y los servicios de validación están soportados en todas las plataformas. Por ejemplo, las validaciones de campo son siempre ejecutadas antes de una grabación. Puede encontrar más información en cómo usar DDOs en: Usando objetos de Diccionario de Datos en sus componentes. Usando objetos de Diccionario de Datos con las Aplicaciones de Windows Las Aplicaciones de Windows contienen un tipo especial de objeto de entrada que está integrada con los DDO. A estos objetos se les llama Data Entry Object (DEOs) u objetos de entrada de datos. Cada DEO está unido a un campo en una tabla. Además, cada DEO especifica un DDO para que actúe como su servidor. Una vista constará de una estructura de DDO y un número de estos DEOs. Los mensajes, lanzados a menudo por la interacción de usuarios, son enviados del DEO a su servidor DDO. Los mensajes dicen al DDO que lleven a cabo una de las tareas de DDO que están en la lista de arriba (Buscar, Grabar, Borrar, etc…). Cuando el DDO haya terminado la operación solicitada, enviará los mensajes de notificación a todos los DEOs conectados. Los DEOs usarán estas notificaciones para actualizar sus datos y su apariencia. La sincronización entre DEOs y DDOs permite que estos www.VisualDataflex.es Página 12 de 92 Guía de Diccionario de Datos objetos de entrada sean completamente Data Aware (Consciente de Datos). Añadiendo muy poco código, podrá crear sofisticadas aplicaciones de entrada de datos. Las Aplicaciones Windows también pueden usar DDOs dentro de informes. Un informe definirá un DDO para actuar como su servidor. Todas las búsquedas serán manejadas automáticamente por mensajes enviados del informe al servidor DDO. No es necesario el uso de DDOs en informes. Hay aplicaciones que usan BPO para manejar actualizaciones personalizadas. Un BPO debe contener métodos personalizados que ejecuten los procesos. Cree su código en estos métodos para controlar la actividad entre el DDO y el proceso. Existe una interfaz completa de Diccionario de Datos que le permite escribir un código que ejecute los mismos tipos de tareas que las que hacen automáticamente los DEOS (por ejemplo: limpiar, buscar, modificar datos, grabar, borrar…). Usando Objetos de Diccionario de Datos con Aplicaciones Web Las aplicaciones Web usan objetos Web para manejar todos los procesos. Hay dos tipos de objetos Web: • Objetos de navegador web o Web Browser Object (cWebBusinessProcess) – Se emplean para interactuar con el navegador de web basado en páginas. • Objetos de Servicios Web o Web Service Objects (cWebService) – Se emplea para proveer servicios de web. Estos objetos están diseñados para contener las estructuras de DDO y los métodos que se comunican con esos DDOs. Un desarrollador interactúa con los DDOs de la misma forma con la que operan con un BPO en una aplicación windows. Los WBO esperan que la interfaz visual sea provista creando páginas HTML. Esas páginas son creadas (programadas) usando un servidor de páginas activas (ASP). Las páginas ASP hacen las llamadas en los WBO. Dentro del WBO cree los métodos para hacer lo que sea necesario. A continuación haga sus métodos disponibles a su página ASP publicando su Interfaz. Además, los WBO contienen una serie de interfaces que dan acceso a sus Diccionarios de Datos. Esto permite que lleve a cabo todas las funciones básicas del Diccionario de Datos (por ejemplo: buscar, borrar, grabar, limpiar,…) sin tener que escribir código en los WBO. Los WBO proveen soporte de servicio web. Un servicio web puede o no necesitar acceder al Diccionario de Datos. Si lo hacen, se puede añadir una estructura de DDO al servicio de objeto web o Web Service Object (WSO) y crear métodos que se comuniquen con los DDOs. www.VisualDataflex.es Página 13 de 92 Guía de Diccionario de Datos Diccionario de datos básico y conceptos de tabla 1. Tablas, columnas y filas 2. Índices 3. Relaciones 4. Identificador de registro y RowId 5. Transacciones, bloqueos y soporte multi-usuario 6. Buffers de fichero y Buffers de campo-DDO 7. Grupos de comandos File_field y Field 8. Comandos de ficheros 9. API de la base de datos www.VisualDataflex.es Página 14 de 92 Guía de Diccionario de Datos Tablas, columnas y filas Generalmente las bases de datos se definen como una colección de tablas. Las tablas constan de un juego de columnas designadas con un tipo de datos específicos y con una longitud determinada. Los datos en las tablas se denominan filas. Los mensajes de interfaz de Diccionarios de Datos usan la siguiente terminología para describir las bases de datos: • FILE- un “file” (archivo) hace referencia a una tabla. • FIELD- un “Field” (campo) hace referencia a un campo. • RECORD- un “Record” hace referencia a una fila de datos de una tabla. Los mensajes del Diccionario de Datos usan ficheros (files), campos (field) y registros (records) en sus nombres de interfaz. Algunos ejemplos de esto son “Main_File”, “Field_Options”, “File_Field_Current_Value”, y “OnNewCurrentRecord”. Mientras que la documentación usará algunos de estos términos indistintamente, el uso normal de estos será: • La tabla se usa cuando se consultan tablas de la base de datos. Solamente deberá ver la palabra “file" en los mensajes de interfaz. • El campo se usa cuando se consultan las columnas de una tabla y cuando se hace referencia a la entidad en el Diccionario de Datos que define una columna. Un Diccionario de Datos mantiene las estructuras de la información sobre la columna como valores, etiquetas, y opciones (“Field_Current_Value”, “Field_Label”, “Field_Options”) de cada tabla. Éstos serán referencias como campos (fields) dentro del Diccionario de Datos. • Los registros (records) se usan para hacer referencia a una fila de datos de una tabla. Consulte lo siguiente Diccionario de datos básico y conceptos de tabla www.VisualDataflex.es Página 15 de 92 Guía de Diccionario de Datos Índices En el Diccionario de Datos todas las búsquedas de información se producen usando índices. Los índices se utilizan para encontrar rápidamente registros individuales y para buscar en una tabla (hacia delante o hacia atrás) en un orden específico. Para ser usadas adecuadamente por los Diccionarios de Datos, cada anotación en los índices debe ser única. En otras palabras, los segmentos usados para crear un índice no deben admitir duplicados (deben poder identificar un registro). Generalmente la singularidad está asegurada si se añade el campo de clave primaria como el último segmento(s) del índice. Los índices se definen dentro del Database Builder con un número de índice. Ese número se usa en los Diccionarios de Datos y en el código de sus programas para determinar qué índice debería usarse. Consulte lo siguiente Diccionario de datos básico y conceptos de tabla www.VisualDataflex.es Página 16 de 92 Guía de Diccionario de Datos Relaciones Las relaciones sirven para "normalizar" sus datos. Algunos de los objetivos de la normalización son: 1. La eliminación de grupos repetitivos - Haga una tabla de consulta (lookup list) distinta para cada juego de atributos relacionados, y de una clave primaria a cada tabla. Por ejemplo, podría estar grabando contactos en sus clientes. No deberá guardar los contactos en la tabla de clientes; sin embargo pondrá la información de contacto en una tabla distinta y relacione cada registro con la clave primaria de su tabla de clientes. 2. Eliminar los datos redundantes- Si un atributo depende solamente de parte de una clave multisegmento, retírelo a una tabla distinta. Supongamos que cada contacto que tenga con un cliente es categorizado (llamada telefónica, correo, visita personal, etcétera). Deberá guardar el tipo de contacto en una tabla distinta y relacionar los contactos con los tipos de contactos. 3. Eliminar columnas que no sean dependientes de una clave- Si los atributos no contribuyen a una descripción de la clave, retírelos a una tabla distinta. Por ejemplo, suponga que está almacenando el nombre del cliente, dirección de “Empresa” y número de teléfono de “Empresa”. Estos atributos describen el lugar del trabajo del cliente, no el cliente, así que deberá crear una tabla de “Empresa” y quitar la información de “Empresa” de la tabla del cliente pasándola a esta nueva tabla relacionando la tabla de clientes con esta otra. Éstas son las primeras tres formas de la normalización de datos y son probablemente las tres que más desee aplicar comúnmente en su base de datos. Las relaciones se representan en Visual DataFlex usando el modelo de clave foránea (foreing key) y clave primaria (primary key): 1. Una relación debe ser definida de “tabla hijo” a “tabla padre”. Una “tabla hijo” define a un campo o conjunto de campos que se corresponden con un conjunto de datos en el “padre”. El tamaño y el tipo de datos de campo en el padre y el hijo deben ser los mismos. Esta relación se define usando el Database Builder. 2. Los valores de los campos relacionados en el padre (Ej. A, B y C) deben ser únicos y soportados por un índice cuyos segmentos son los mismos que los campos relacionados (A, B, C de arriba). El campo relacionado en la “tabla padre” es casi siempre su clave primaria y se refiere en el Diccionario de Datos como el campo clave (key field). 3. La “tabla hijo” generalmente tiene uno o más índices que permiten la búsqueda rápida por los campos relacionados. Esto quiere decir que los primeros segmentos en este hijo debe consistir de los campos a los que se relacionan. Los Diccionarios de Datos utilizan las relaciones en cuatro maneras: 1. Relacionar: cuando un Diccionario de Datos encuentra un registro, todos los DDOs “padre” encontrarán automáticamente todos los registros relacionados. El DDO “padre” de esos DDOs buscará y encontrará los registros relacionados en la estructura superior (lo que se dice normalmente “hacia arriba”). De esta forma el buscar/relacionar encuentra una estructura entera de registros relacionados. www.VisualDataflex.es Página 17 de 92 Guía de Diccionario de Datos 2. Agregados: antes de una grabación (save) o búsqueda (find) los valores de los campos relacionados al “padre” se mueven a los campos relacionados de los “hijos”. Este proceso de agregar (attach), asegura que la “tabla hijo” y la “tabla padre” se relacionen de forma apropiada durante las grabaciones. 3. Restricciones (filtros): una restricción (constrain) de una relación definida en la estructura de un Diccionario de Datos restringe la búsqueda de registros “hijo” a los relacionados al “padre”. Esta característica es usada exhaustivamente en aplicaciones tipo cabecera-detalle (por ejemplo en un sistema de introducción de pedidos en donde los detalles-líneas de pedido deben estar restringidos a un pedido). 4. Validaciones y grabaciones: una validación ocurre antes de que suceda una validación de grabación en el DDO Principal y en todos los DDOs “padre” relacionados. Además, la estructura de DDO es inspeccionada antes de la grabación. Si la estructura entera no está en su lugar, la validación fallará. Cuando ocurre una grabación (save), el registro en el DDO Principal y todos los registros de los DDOs “padre” son grabados como una única transacción. Básicamente, las relaciones en Diccionarios de Datos permiten que trabaje con una jerarquía de registros como una sola entidad. Consulte lo siguiente Diccionario de datos básico y conceptos de tabla www.VisualDataflex.es Página 18 de 92 Guía de Diccionario de Datos Identidad de disco y RowId Cada tabla necesita un identificador único que identifique cada registro. Este identificador se encarga de encontrar los registros y deberá hacerlo de la forma más rápida posible Algunas bases de datos tienen un identificador de registro incorporado en cada tabla. La base de datos de DataFlex y la de Pervasive.SQL atribuyen identificadores numéricos únicos a cada registro. Estos identificadores, referenciados como Recnum, establecen la manera más rápida posible de encontrar un registro. La mayoría de las bases de datos de SQL como SQL Server de Microsoft y DB2 de IBM no incorporan una identificación de registro. En vez de esto, las tablas en estas bases de datos contienen claves primarias y un índice que provee acceso rápido a cualquier registro a través de esta clave primaria. La clave primaria puede ser definida como una sola columna o una combinación de columnas. El tipo de datos de la columna(s) que forma(n) la clave primaria puede(n) ser de cualquier tipo(s). Si su base de datos soporta Recnum, puede usar comandos basados en Recnum y mensajes de Diccionario de Datos para identificar y buscar registros. // Low level commands using recnum Integer iTempRec Move Customer.Recnum to iTempRec Clear Customer : Move iTempRecnum to Customer.Recnum Find EQ Customer by recnum // Data Dictionary methods using recnum Integer iTempRec Integer iFile Get Current_Record of hoDDO to iTempRec Send Clear to hoDDO : Get Main_File of hoDDO to iFile Send Find_by_Recnum of hoDDO iFile iTempRec Si su base de datos usa una clave primaria como único identificador, podrá usar otros comandos y mensajes de Diccionario de Datos para identificar y buscar registros. // low level commands using primary key String sTempId Move Customer.Customer_Id to sTempId Clear Customer : Move sTempId to Customer.Customer_Id Find EQ Customer by 1 // find EQ by index 1 www.VisualDataflex.es Página 19 de 92 Guía de Diccionario de Datos // Data Dictionary methods using primary key String sTempId Get Field_Current_Value of hoDDO Field Customer.Customer_Id to sTempId Send Clear to hoDDO : Move sTempId to Customer.Customer_Id Send Find of hoDDO EQ 1 // find EQ mode and index 1 El ejemplo anterior supone que la clave primaria de la tabla de clientes es “Customer.Customer_Id” y su índice es el 1. Cada tabla tendrá una definición diferente para su clave primaria e índice de clave primaria. Dependiendo de su tabla necesitará modificar el código anterior para soportar una clave primaria diferente, diferentes nombres de campos, diferente índice de clave primaria y diferentes tipos de datos de clave primaria Hay una desventaja muy importante con los métodos anteriores. Se requiere una sintaxis diferente para bases de datos diferentes y para algunos casos también se requiere una sintaxis distinta para cada tabla. Esto quiere decir que es muy difícil escribir un código que pueda ser abstracto aplicado a cualquier tabla de cualquier base de datos. Este tipo de abstracción es un objetivo y requisito de la programación de Diccionario de Datos. Esto se resuelve introduciendo RowIds. El identificador de registro de cada tabla se correlaciona con un tipo especial de datos llamado RowId. Se define la correlación del identificador de registro al RowId al definir la tabla en Database Builder. Una vez correlacionado, un conjunto de comandos de RowId, funciones y métodos del Diccionario de Datos se usan para buscar e identificar registros. Esto permite usar la misma sintaxis con cualquier tabla. // Low level commands using RowId RowId riTempId Boolean bFound Move (GetRowId(Customer.File_Number)) to riTempId Clear Customer : Move (FindByRowId(Customer.File_Number,riTempId)) to bFound // Data Dictionary methods using RowId RowId riTempId Get CurrentRowId of hoDDO to riTempId Send Clear to hoDDO : Send FindByRowId of hoDDO riTempId Usando esta sintaxis de RowId, tendrá una sintaxis única que puede usar en cualquier tabla de cualquier base de datos. Una vez definido, simplemente programe usando RowId. Tipo de datos de RowId www.VisualDataflex.es Página 20 de 92 Guía de Diccionario de Datos RowId riTempId1 riTempId2 : Property RowId priLastId : Get priLastId to riTempId1 Move roTempId1 to riTempId2 Set priLastId to riTempId2 RowId es un tipo especial de datos que sirve para almacenar valores RowId. Este tipo de datos tiene un comportamiento. Puesto que el tipo de datos subyacentes puede ser de cualquier tipo o de cualquier combinación de tipos, no puede ser asociado a ningún otro tipo de datos o usado directamente para realizar cualquier tipo de evaluación. En vez de eso se entregan un conjunto de funciones globales de RowId y de métodos de Diccionario de Datos que permiten manipular RowId. Funciones globales de RowId Las siguientes funciones dan soporte de bajo nivel a RowId: FindByRowId Move (FindByRowId(iFile,riRowId)) to bFound GetRowId Move (GetRowId(iFile)) to riRowId NullRowId Move (NullRowId()) to riRowId IsNullRowId Move (IsNullRowId(riRowId)) to bIsNull IsSameRowId Move (IsSameRowId(riRowId1,riRowId2)) to bIsSame SerializeRowId Move (SerializeRowId(riRowId)) to sSerializedRowId DeSerializeRowId Move (DeSerializeRowId(sSerializedRowId)) to riRowId Estas funciones permiten que lleve a cabo cualquier evaluación de RowId que se necesite en un nivel bajo: Function RunOrderDtlReport RowId riHdrId Returns RowId RowId riEnd Boolean bFound Move (FindByRowId(OrderHea.File_Number,riHdrId)to bFound If bFound Begin Set priStartRowId To (NullRowId()) Get DoRunReport To iStat Get priEndRowId To riEnd End Else Begin Move (NullRowId()) To riEnd end Function_Return riEnd End_Function www.VisualDataflex.es Página 21 de 92 Guía de Diccionario de Datos La interfaz de Diccionario de Datos de RowId Los Diccionarios de Datos también proveen una interfaz completa para trabajar con RowId: Send FindByRowId Send FindByRowId of hoDDO iFile riRowId Send ReadByRowId Send ReadByRowId of hoDDO iFile riRowId Get CurrentRowId Get CurrentRowId of hoDDO to riRowId Get HasRecord Get HasRecord of hoDDO to riRowId Estos métodos, junto con las funciones globales de RowId se pueden usar para manejar cualquier tipo de programación de RowId usando Diccionario de Datos. Function RunOrderDtlReport RowId riHdrId Returns RowId RowId riEnd Boolean bFound Integer iMain Get Main_File of oOrderHea_DD to iMain Send FindByRowId of oOrderHea_DD iMain riHdrId Get HasRecord of oOrderHea_DD to bFound If bFound Begin Set priStartRowId To (NullRowId()) Get DoRunReport To iStat Get CurrentRowId of oOrderDtl_DD To riEnd End Else Begin Move (NullRowId()) To riEnd end Function_Return riEnd End_Function Notas especiales • No confunda RowId con clave primaria. Si su base de datos soporta campos de recnum, sus tablas probablemente todavía tendrán una clave primaria (Ej. tendrán un campo o conjunto de campos que están indexados de forma única) que será identificado en su clase de Diccionario de Datos activando la propiedad “Key_Field_State”. Ese es el campo que usará en las relaciones. Mientras esos campos, en teoría, podrían usarse para identificar RowId, no lo harán porque la definición interna de Recnum de la base de datos provee la manera más rápida de encontrar un registro. Le interesa siempre usar el método más rápido para encontrar los registros. Deberá usar siempre aquel método que su base de datos o controlador provea que es más rápido. www.VisualDataflex.es Página 22 de 92 Guía de Diccionario de Datos • RowId fue añadido en la versión 11.0 de Visual DataFlex. Antes de esta versión, todas las tablas tenían que soportar un Recnum (ej. todas las tablas tenían que soportar un campo numérico y único). La introducción de Rowid levanta esta restricción. La programación al estilo de Recnum todavía se soporta. Si un desarrollador sabe que todas sus tablas contendrán un Recnum, pueden continuar programando usando comandos y métodos de Recnum. Consulte lo siguiente Diccionario de Datos básico y conceptos de tablas www.VisualDataflex.es Página 23 de 92 Guía de Diccionario de Datos Transacciones, Bloqueos y soporte multi-usuario Las transacciones y el soporte de bloqueo de base de datos están embebidos directamente en el Diccionarios de Datos. Las actualizaciones de base de datos (grabaciones y borrados) son siempre, por lo tanto, seguros a nivel multi-usuario. Administrar las transacciones es un proceso automático que no requiere ningún esfuerzo adicional de programación por parte del desarrollador. Retroceso (Rollback) en las transacciones está también embebido en el Diccionario de Datos. Si por cualquier razón una transacción de grabación o borrado no puede ser terminada, se deshace la transacción entera y no se realiza ningún cambio en la base de datos. Se bloquea la base de datos durante una transacción. Las tablas que participan en la transacción estarán bloqueadas para escritura (write lock). Esto permite que otros usuarios lean datos de las tablas pero no que ellos escriban datos hasta que los bloqueos sean liberados. Los bloqueos se liberan cuando una transacción ha finalizado como una grabación exitosa (successfull commit) o con un retroceso fallido (failed rollback). Dependiendo de la Base de Datos los bloqueos se aplican a nivel de registro o a nivel de tabla. Los procesos de DDOs. Transacciones y Bloqueos se comentan con más detalle en Transacciones y Consulte lo siguiente Diccionario de Datos Básico y Conceptos de Tabla www.VisualDataflex.es Página 24 de 92 Guía de Diccionario de Datos Buffers de fichero y Buffers de campos de DDO Cuando se abre una tabla en una base datos, se crea una memoria intermedia (buffer) de fichero conteniendo los valores de los campos para un registro. La búsqueda (find) y limpieza (clear) de registros mueven datos de la tabla (.DAT) a este Buffer. Las grabaciones (save) mueven los datos del Buffer a la tabla. Se definen variables globales, llamadas “File.Filed” que dan acceso al programa a esos Buffers, permitiendo que los programadores accedan y cambien los datos del registro actual. // Move from file buffer to a variable Move Customer.Name to sName // Move from variable to the file buffer Move sName to Customer.Name Los DDOs (Data Dictionary Objects) mantienen actualizados los Buffers locales, que mantienen la información sobre el registro en curso del DDO. A estos se les llama Buffers de campo DDO (DDOField Buffer). Estos Buffers locales permiten a las aplicaciones soportar DDOs múltiples que usan la misma tabla. // Move from DDO-Field buffer to a variable Get Field_Current_Value of hoDDO Field Customer.Name to sName // Move from variable to the DDO-Field buffer Set Field_Changed_Value of hoDDO Field Customer.Name to sName Hay veces que quiere interactuar con los Buffers globales del archivo (.DAT) directamente y otras que quiere interactuar con los Buffers de campo DDO. Esto se comenta con detalle en Entendiendo Buffers de fichero y Buffers de campos de DDO. Consulte lo siguiente Diccionario de Datos básico y conceptos de tablas www.VisualDataflex.es Página 25 de 92 Guía de Diccionario de Datos Comandos tipo File-Field y Field La información del campo de Diccionario de Datos se almacena y se puede acceder a ella a través de una interfaz de campo. Esta interfaz requiere que pase como parámetros un identificador de campo y a veces un identificador de tabla. Estos parámetros deben ser pasados como valores enteros (Integers). Las palabras clave especiales, “Field” y “File_Field”, permiten que pase estos parámetros como nombres en lugar de números. El compilador cambiará estos por las constantes de números apropiadas. Algunos ejemplos de uso de estas palabras clave son: // use of the field keyword Get Field_Current_Value of oCustomer_DD Field Customer.Name to sName Set Field_Changed_Value of oCustomer_DD Field Customer.Name to sName // use of the File_Field keyword Get File_Field_Current_Value of oOrder_DD File_Field SalesP.Name to sName Set File_Field_Changed_Value of oOrder_DD File_Field SalesP.Name to sName Los comandos de tipo Field son usados con los mensajes de tipo Field. Use estos cuando el objeto de Diccionario de Datos (DDO) que recibe el mensaje “posea” el campo. En el ejemplo anterior, Customer.Name es definido dentro del DDO de oCustomer_DD. Los comandos de tipo “File_Field” son usados con los mensajes de tipo “File_Field”. Use estos cuando el objeto de Diccionario de Datos que recibe el mensaje quizás no “posea” el campo que puede pertenecer al DDO o a uno de sus DDOs padre. En el ejemplo anterior, SalesP.Name está definido dentro del DDO oOrder_DD pero el campo pertenece al DDO padre, oSales_DD. File_Field se usa en estas situaciones mientras que el DDO desviará el mensaje hacia el DDO apropiado. Para comprender con detalle los comandos tipo File_Field y Field consulten en Entiendo los comandos de tipo File_Field y Field. Consulte lo siguiente Diccionario de Datos básico y conceptos de tablas www.VisualDataflex.es Página 26 de 92 Guía de Diccionario de Datos Los comandos de tablas (File) El lenguaje de DataFlex soporta varios comandos que permiten que acceda a tablas directamente fuera de los Diccionarios de Datos. Esos comandos son: • Buscar • Borrar • Guardar a Disco • Borrar • Cerrar • Relaciónese • Attach Normalmente, cuando use Diccionarios de Datos no necesitará usar estos mandatos. En algunos de los eventos de Diccionario de Datos puede usarlos para manejar las operaciones personalizadas de bajo nivel. Por ejemplo, podría desear llevar a cabo alguno tipo de búsqueda personalizada en el proceso de “Relate_Main_File”. En estos casos podría usar estos comandos. Además, podría usar estos comandos y limitar el uso de un Diccionario de Datos. Es más probable hacer esto cuando se busquen registros. Usar un comando directo para grabar o borrar registros no es recomendable porque estaría evitando todas las reglas de validación que los DDOs hacen cumplir. Consulte lo siguiente Diccionario de datos básico y conceptos de tabla www.VisualDataflex.es Página 27 de 92 Guía de Diccionario de Datos El API de base de datos El lenguaje de DataFlex tiene un juego de comandos que permite consultar cualquier información sobre sus tablas. Estos son referidos como los atributos del Api de la base de datos. El comando de Get Attribute se emplea para consultar el valor de cualquier atributo de API. Puede usarlos para consultar información sobre: • Una tabla (nombre, descripción, número de campos, número de índices, número de registros). • El índice de una tabla (la cantidad de segmentos del índice, el valor de cada segmento). • El campo de una tabla (tipo de datos, longitud, puntos decimales, nombre del campo). En vez de crear una capa adicional de la interfaz de DDO para acceder a estos valores, es mejor que acceda a esta información directamente dentro de un DDO o de un componente usando el comando de Get_Attribute. La mayoría de estos atributos son de bajo nivel por lo que rara vez necesitará acceder a ellos. Si no puede encontrar un mensaje de DDO que devuelva la información que necesita, verifique los atributos de API. Dentro de una aplicación, lo más solicitado, aparte de los atributos de API, son la longitud de campo y el tipo de datos del campo. El comando Set_Attribute también puede usarse para cambiar atributos de la base de datos. Rara vez necesitaría hacer esto dentro de una aplicación. Consulte lo Siguiente Diccionario de datos básico y conceptos de tabla www.VisualDataflex.es Página 28 de 92 Guía de Diccionario de Datos Definir clases de Diccionario de Datos Antes de que pueda usar Diccionarios de Datos debe crear una clase para cada tabla en su aplicación. Database Builder se encargará de hacer esto. Aunque Database Builder es una herramienta de diseño visual, el resultado final de esta herramienta es el código fuente. Los Diccionarios de Datos son simplemente un código fuente basado en clases que se complican en su aplicación. El propósito de esta sección es describir las características de una clase de Diccionario de Datos y exponer la interfaz de Diccionario de Datos (ejemplo: exponer el código fuente). Esperamos que use Database Builder para mantener siempre actualizado sus Diccionarios. Parte del código dentro de las clases de Diccionario de Datos es creado y mantenido por el interfaz visual de Database Builder. Otras partes de la clase, en particular los eventos, requerirán que usted cree un código personalizado. Algunas de las propiedades y eventos descritos en esta sección también pueden ser definidas en el nivel de objeto de Diccionario de Datos. Cuando trabaje en el nivel de objeto necesitará saber cómo usar y codificar la interfaz. Una clase de Diccionario de Datos puede ser dividido en dos partes principales: • El constructor de Diccionario de Datos: consiste en fijar todos los atributos de Diccionario de Datos. Esto incluye los atributos de tabla, los atributos de campo, los atributos de campo externos (foreing field) y las relaciones de tablas “padre/hijo”. Todos estos atributos se mantienen fijando propiedades dentro de un procedimiento llamado “Define Fields”. • Eventos de Diccionario de Datos: se llaman varios eventos durante las operaciones del Data Dictionary: la búsqueda, grabar, eliminar y borrar. Estos eventos pueden ser creados para tratar los requisitos personalizados para una tabla. Estos requisitos incluyen fijar los valores por defecto, llevar a cabo las validaciones y controlar las relaciones entre tablas. Además, el desarrollador puede proporcionar los eventos personalizados y asignarlos a campos. Estos eventos son lanzados por las operaciones específicas como la validación de campo y navegación. Todos estos eventos son creados como funciones y procedimientos que el desarrollador debe crear. www.VisualDataflex.es Página 29 de 92 Guía de Diccionario de Datos El constructor de Diccionario de Datos (Define_Fields) El método de construcción especial, “Define_Fields”, se emplea para definir todos los atributos del Diccionario de Datos. Este método de construcción define los siguientes tipos de información: • Atributos de tabla: definen los atributos que son aplicables a la tabla entera. Esto conecta su Diccionario de Datos a una tabla específica y define las capacidades básicas del Diccionario de Datos. • Atributos de campo: definen atributos para cada columna en su tabla. Esto provee reglas de validación de campo, reglas de búsqueda y mucha información que es usada por los objetos de entrada de datos (DEOS). • Atributos de campo externos (foreing): definen los atributos para sus campos cuando el DDO se usa en un “padre” externo en la estructura DDO. • Relaciones de tabla “padre/hijo”: definen las reglas de relación entre tablas. Esto sirve para ayudar a construir estructuras DDO y verificar que estas estructuras sean capaces de soportar apropiadamente las actualizaciones de base de datos. Todos estos ajustes se crean y se mantienen actualizados usando Database Builder. El listado de abajo es un “Define_Fields” de muestra que fue creado usando Database Builder: Procedure Define_Fields Forward Send Define_Fields //DDB-Generated-Code-Location //DDB-DefineFieldStart Set Main_File To Orderhea.File_Number Set Foreign_Field_Options DD_KEYFIELD To DD_FINDREQ Set Foreign_Field_Options DD_INDEXFIELD To DD_NOPUT Set Foreign_Field_Options DD_DEFAULT To DD_DISPLAYONLY // Child (Client) file structure................ Send Add_Client_File Orderdtl.File_Number // Parent (Server) file structure............... Send Add_Server_File Customer.File_Number Send Add_Server_File Salesp.File_Number // External (System) file structure............. Send Add_System_File Ordsys.File_Number DD_LOCK_ON_NEW_SAVE_DELETE Define_Auto_Increment Ordsys.Order_Number To Orderhea.Order_Number // Field-based properties....................... // Orderhea.Order_Number Set Field_Options Field Orderhea.Order_Number To DD_AUTOFIND www.VisualDataflex.es Página 30 de 92 Guía de Diccionario de Datos Set Field_Prompt_Object Field Orderhea.Order_Number To (ORDERHEA_SL(Self)) Set Key_Field_State Field Orderhea.Order_Number To TRUE Set Status_Help Field Orderhea.Order_Number To "Order Number - New orders are assigned numbers automatically" // Orderhea.Customer_Number // Orderhea.Order_Date Set Field_Class_Name Field Orderhea.Order_Date To "dbSpinForm" Set Field_Entry_msg Field Orderhea.Order_Date To Entry_Order_Date Set Field_Mask Field Orderhea.Order_Date To "mm-dd-yyyy" Set Field_Mask_Type Field Orderhea.Order_Date To MASK_DATE_WINDOW Set Field_Prompt_Object Field Orderhea.Order_Date To (ORDERHEA_SL(Self)) Set Status_Help Field Orderhea.Order_Date To "Date on which the order was placed" // Orderhea.Terms //DDB/ Comment_Short Field Orderhea.Terms To "Where does this go?" Set Field_Class_Name Field Orderhea.Terms To "dbComboForm" Set Field_Label_Long Field Orderhea.Terms To "Terms" Set Field_Label_Short Field Orderhea.Terms To "Trm" Set Field_Value_Table Field Orderhea.Terms To (Terms_table(Self)) Set Status_Help Field Orderhea.Terms To "Payment terms" // Orderhea.Ship_Via Set Field_Class_Name Set Field_Value_Table Set Status_Help Field Orderhea.Ship_Via To "dbComboForm" Field Orderhea.Ship_Via To (Ship_Table(Self)) Field Orderhea.Ship_Via To "Shipping method" // Orderhea.Ordered_By //DDB/ Comment_Short Field Orderhea.Ordered_By To "This is just a suggested list. No parent files support this" Set Status_Help Field Orderhea.Ordered_By To "Order placed by" // Orderhea.Salesperson_Id Set Field_Label_Long Field Orderhea.Salesperson_Id To "Sales Person Id" Set Field_Label_Short Field Orderhea.Salesperson_Id To "Sales ID" Set Status_Help Field Orderhea.Salesperson_Id To "Sales Person who initiated the order" // Orderhea.Order_Total //DDB/ Comment_Short Field Orderhea.Order_Total To "Maintained by the Orderdtl DD" Set Field_Mask_Type Field Orderhea.Order_Total To MASK_CURRENCY_WINDOW Set Field_Options Field Orderhea.Order_Total To DD_DISPLAYONLY // Orderhea.Last_Detail_Num //DDB/ Comment_Short Field Orderhea.Last_Detail_Num To "This is the " //DDB-DefineFieldEnd End_Procedure // Define_Fields El constructor de “Define_Fields” puede usarse solamente en clases. No puede crear o aumentar “Define_Fields” dentro de un DDO. www.VisualDataflex.es Página 31 de 92 Guía de Diccionario de Datos Consulte lo siguiente Definir clases de Diccionario de Datos. www.VisualDataflex.es Página 32 de 92 Guía de Diccionario de Datos Definir los atributos de tabla de diccionario de datos Los atributos de tabla de diccionario de datos definen los atributos que son aplicables a la tabla entera. Estos atributos son: • Fijar su tabla principal (Set Main_File). • Definir sus campos clave (Key Fields). • Definir las protecciones de grabación y borrado. Fijar su tabla principal (Main_File) Set Main_File to Customer.File_Number Esto identifica la tabla del Diccionario de Datos. Debe ponerse siempre una vez, y una vez puesto no pueda ser cambiado. Poner esta propiedad es el requisito mínimo de un Diccionario de Datos. La clase de Diccionario de Datos más básica podría ser creada de la siguiente manera: Class cTheMostSimpleCustomer_DD is a DataDictionary Procedure Define_Fields Forward Send Define_Fields set Main_File to MyTable.File_Number End_Procedure End_Class Consulte lo siguiente Definir los atributos de tabla de Diccionario de Datos. Campos clave (key Fields) Set Protect_Key_State to true Set Key_Field_State Field Customer.Id to true Los campos clave son campos que han sido designados para identificar los registros en una tabla (ej. Customer_number en una tabla de cliente). La propiedad que se usa para designar el campo clave es “Key_Field_State”. www.VisualDataflex.es Página 33 de 92 Guía de Diccionario de Datos Una vez designados Foreign_Field_Options. los campos clave puede fijar opciones para todos ellos con Key_Field_State Set Key_Field_State Field Customer.Id to true Key_Field_State marca un campo como el campo principal para la tabla. Una ventaja de fijar esta alternativa puede ser prevenir los cambios en los datos guardados en el campo, es decir, no se pueden modificar los datos de un campo clave. Esto se conoce como protección de campo clave (Key Field Protection). La protección de campo de la clave primaria evita que los datos de los campos que componen la clave primaria se modifiquen una vez que el registro sea creado (por ejemplo: si la clave primaria de una tabla de clientes es cliente.código no interesaría modificar el código una vez que ya se haya creado el cliente). Generalmente pondría esta opción sobre campos de claves primarias como el campo de número de pedido en una tabla de cabecera de pedido o el campo de identificación del cliente en la tabla de clientes. Esto proporciona protección de orfandad impidiendo que sean modificados los campos de identificación usados en las relaciones “padre/hijo”. Si su clave primaria consta de varios campos, todos los campos de la clave deben ser marcados como campos clave. Los campos clave solamente están protegidos en una tabla si la propiedad de “Protect_Key_State” también está activada en el Diccionario de Datos. Protect_key_State Set Protect_Key_State to true Protect_Key_State determina si los campos que componen una clave primaria deben ser “protegidos” después de que hayan sido grabados por primera vez en un nuevo registro. Cuando estén marcados a verdadero (true), un campo identificado como parte de una clave no puede ser editado después de que haya sido grabado. Esto asegura que los “registros hijo” que se relacionan con un “registro padre” a través de una clave primaria, no se puedan por cualquier casualidad dejar “huérfano”. Los campos que componen una clave primaria son identificados usando la propiedad de campo “Key_Field_State”. Consulte lo siguiente Definir los atributos de tabla de Diccionario de Datos. www.VisualDataflex.es Página 34 de 92 Guía de Diccionario de Datos Protección de grabación y borrado Read_Only_state Set Read_Only_State to True Read_Only_State se usa para especificar que Diccionario de Datos no puede usarse directamente para grabar o borrar registros. Esto quiere decir que los mensajes “Request_Save” y “Request_Delete” enviados al DDO generarán un error y no llevarán a cabo ninguna actualización. Note que los registros en un Diccionario de Datos de solo lectura (Read_Only) pueden ser modificados o borrados indirectamente por mensajes enviados a otro Diccionario de Datos dentro de estructuras de objeto. Por ejemplo, si el DDO padre es la tabla de cliente y esta se marca como de solo lectura (Read_Only) y el DDO de la tabla de cabecera de pedidos no se marca como de solo lectura (Read_Only), entonces las grabaciones y borrados enviados al DDO de cabeceras de pedidos permitirán modificar estos datos de la tabla de clientes. Esto es necesario para mantener la integridad de la base de datos. Si quiere que una estructura entera de DDO sea solo de lectura, deberá fijar toda la estructura de DDOs. Read_Only_State es más probable que se fije en un objeto de Diccionario de Datos y no en una clase. No_Delete_State Set No_Delete_State to True No_Delete_State desactiva borrados directos de los registros. Esto quiere decir que el mensaje que “Request_Delete” enviado a este DDO generará un error y no llevará a cabo ninguna acción. Este mensaje no afecta a borrados de los registros que son parte de un borrado en cascada. Cascade_Delete_State Set_ Cascade_Delete_State to True Cascade_Delete_State especifica cómo afecta una orden de borrados (delete) a los registros relacionados de una tabla hijo, cuando el borrado se envía al “padre”. Si Cascade_Delete_State es verdadero, entonces los registros de la tabla hijo y todos los registros descendientes serán eliminados. Si la propiedad está a falso, se permitirá el borrado cuando no exista ningún registro “hijo”. Ambos métodos aseguran que ese registro “hijo” nunca se deje huérfano. www.VisualDataflex.es Página 35 de 92 Guía de Diccionario de Datos Validate_Foreign_File_State Set Validate_Foreign_File_State to False Antes de que ocurra una grabación, querrá validar todos los campos y esto lo puede hacer enviando el mensaje Request_Validate al DDO que va a llevar a cabo la grabación. Normalmente todos los campos de todas las tablas que participan en una grabación serán validados. Esto incluye campos que no tengan representación visual en la vista en curso y todos los campos en todas las tablas ascendentes (ejemplo: en una jerarquía nieto-padre-abuelo, nos referimos a las tablas “padre” y “abuelo” en relación al nieto). En casi todos los casos, se desea este nivel de protección de datos, y es potente característica del Diccionario de Datos. También en casos infrecuentes puede seleccionar niveles inferiores de protección de validaciones. El “Validate_Foreign_File_State” de propiedad determina si la validación de campo se debe aplicar a tablas foráneas (padre). Normalmente, querrá este nivel de validación por lo que el valor por defecto es verdadero. Configurar que su valor sea falso pasará por alto la validación de campo cuando la tabla sea usada como una tabla “padre” en una estructura de DDO. Esto hará que se supriman las validaciones en todas las tablas ascendentes. Poner esta propiedad fuera de los valores por defecto ignora la validación de campo y compromete la integridad de datos. Solamente deben ser usados bajo circunstancias cuidadosamente controladas. No use esta propiedad cuando busque soluciones rápidas para el diseño de base de datos. Las reglas especiales de validación condicionales pueden ser programadas directamente en sus rutinas de validación. Por ejemplo, podría desarrollar una rutina de validación que solamente aplicase una validación de campo a nuevos registros (verificar el estado con la propiedad de HasRecord del registro) o bien, podría crear rutinas de validación que pasasen por alto ciertos campos de forma selectiva cuando son foráneas (la variable global de tipo Entero_Integer_Operation_Origin nos dice que DDO empezó la grabación). En vez de romper una regla, intente definir este cambio de regla como parte de su conjunto de reglas. Al final, tendrá una mejor solución en todos los aspectos. Consulte lo siguiente Definir los atributos de tabla de Diccionario de Datos. www.VisualDataflex.es Página 36 de 92 Guía de Diccionario de Datos Definir los atributos de campo de diccionario de datos Los atributos de campo permiten que defina la información extensiva sobre cada campo en su tabla. Cuando desarrolle su aplicación, esta información será usada por el Studio y sus asistentes (wizards) para automatizar gran parte del proceso de desarrollo. Cuando ejecuten su programa, esta información será usada para ayudar con la navegación, ayudar con la entrada de datos, proporcionar ayuda al contexto, proveer las validaciones… Fijar los atributos de campo consiste en definirlos para: • Las opciones de campo (Field Options). • Las validaciones de campo (Field Validation). • Las apariencias de campo (Field Appearences). • Métodos de entrada y salida de campo (Field Entry and Exit Methods). • El incremento automático de campos (Auto-Increment Fields). • Las listas de consultas de campo (Field Lookup Lists). Opciones de campo (Field Options) La propiedad “Field_Options” se emplea para fijar varias alternativas para cualquier campo. Estas alternativas condicionan la variedad de atributos incluyendo encontrar los comportamientos (ej. Búsqueda automática “auto-find”, búsqueda requerida “find-required”…), los comportamientos de entrada de datos (ej. Siempre mayúsculas “Capslock”…) y comportamientos de actualización (NoPut, Force-Put). Estas opciones se definen con varias constantes de “DD” y se enumeran a continuación. Las alternativas mostradas abajo con un asterisco (*) son opciones de Búsqueda y pueden usarse solamente sobre campos indexados. Las otras opciones pueden ser empleadas con cualquier campo, con la excepción de campos extensos (Extended Fields). Auto-Find DD_AutoFind * Auto-Find GE DD_AutoFind_GE * Uppercase DD_CapsLock Display-Only DD_DisplayOnly Find-Required DD_FindReq * Force-Put DD_ForcePut www.VisualDataflex.es Página 37 de 92 Guía de Diccionario de Datos No-Enter DD_NoEnter No-Put DD_NoPut Retain DD_Retain Retain-All DD_RetainAll Required DD_Required Skip-Found DD_SkipFound Zero-Suppress DD_Zero_Suppress Por ejemplo, podría definir que un campo fuera Not-Put, Auto-Find y CAPSLOCK fijando las siguientes propiedades: Field_Options field Customer.Id to DD_NoPut Set Field_Options field Customer.Id to DD_AutoFind Set Field_Options field Customer.Id to DD_CapsLock Debido a que a menudo hay opciones múltiples que deben ser aplicadas al mismo campo, se le permite combinar múltiples opciones en una sola línea de la siguiente manera: Set Field_Options field Customer.Id to DD_NoPut DD_AutoFind DD_CapsLock “Field_Options” puede ser fijado y modificado a nivel de Objeto de DD (DDO). Cuando lo use a nivel de objeto, no podrá usar el mensaje de “Field_Options”. En vez de esto podrá usar “Field_Option” (fíjese que va en singular),” Field_Option_Clear” y “Field_Option_Toggle”. Para más información vea “Cambiar propiedades de campo dentro de DDO”. Set Field_Option field Customer.State to DD_Retain Set Field_Option_Clear field Customer.State to DD_Retain Set Field_Option_Toggle field Customer.State to DD_Retain Búsqueda automática (DD_AutoFind) Set Field_Options field Customer.Id to DD_AutoFind DD_AutoFind ejecuta una búsqueda automática por el índice principal (Main Index) del campo. Esta opción no funciona en un campo que no tenga índice principal. www.VisualDataflex.es Página 38 de 92 Guía de Diccionario de Datos Si se encuentra un registro cuyo valor en el índice principal concuerda exactamente con los valores de los Forms de entrada, se muestran los datos del registro. Si no se encuentra ningún registro, el cursor sale del Form de manera normal y no se mueve ningún registro al Buffer. No se declarará ningún error. Generalmente pondría esta opción en cada campo clave en su base de datos. Si desea buscar por un índice que no sea único, emplee Auto-Find GE. Cuando desee buscar un registro por un índice multisegmento, ponga DD_AutoFind en el último campo que participe en el índice. Si lo usa conjuntamente con Find_Required, Auto-Find exigirá al usuario que introduzca una clave que exista antes de continuar. Búsqueda automática GE (DD_AutoFind_GE) Set Field_Options field Customer.Id to DD_AutoFind_GE DD_AutoFind_GE lleva a cabo una búsqueda GE (mayor o igual a) por el índice principal de campo al salir del Form de entrada del campo. Esta alternativa no funciona en un campo que no tenga un índice principal. Si se encuentra un registro cuyo valor en el índice principal concuerda exactamente con los valores de los Forms de entrada, se muestran los datos del registro. Si no se encuentra ningún registro igual al que se está buscando, se busca el siguiente por ese índice y ese es el que se muestra. Auto-Find GE es útil para encontrar por anotaciones parciales a elementos o en índices con varios segmentos por claves del primer(os) segmento(s) en vez de todos ellos. Todos los índices no únicos son multi-segmento (estando compuestos, por lo menos, de un campo y del campo de identificación del registro). Puede usar “AutoFind-GE” en cualquier campo tanto si el índice principal de campo es único o si no lo es. Si está empleando “Auto-Find GE” en un índice multi-segmento, ponga la opción de “DD_AutoFind_GE” en el último campo del índice para el que desee introducir valores. Si cualquier campo que se antepone a uno con la alternativa de “DD_AutoFind_GE” en el índice, carece de un valor de entrada en su Form, el valor de ese campo será considerado vacío para los propósitos de la búsqueda. El registro encontrado será uno cuyo valor para el primero en ese campo sea el más bajo en el índice Si quiere ejecutar una búsqueda automática para encontrar una coincidencia exacta igual a (EQ) usa la opción AUTO_FIND. Auto-Find GE encontrará siempre un registro, a menos que la tabla esté vacía. UPPERCASE (DD_CapsLock) Set Field_Options field Customer.Id to DD_CapsLock www.VisualDataflex.es Página 39 de 92 Guía de Diccionario de Datos DD_CapsLock cambia, automáticamente, cualquier carácter que la entrada haya relacionado con el campo (en letras mayúsculas). No tiene efecto en los caracteres no-alfabéticos. Esto garantiza que todos ingresen datos en la entrada con letras mayúsculas. Fuerza de escribir (DD_ForcePut) Set Field_Options field Customer.Id to DD_ForcePut DD_ForcePut fuerza a los contenidos de los Forms de entrada de datos a que pongan en el buffer de registro de la tabla antes de una grabación incluso si no se ha hecho ningún cambio. Normalmente los contenidos de los Forms de entrada de datos, solo se ponen en El buffer si han sido cambiados en relación a lo que fue mostrado originalmente desde el disco. No-Enter (DD_NoEnter) Set Field_Options field Customer.Id to DD_NoEnter DD_NoEnter evita la introducción de datos a través de cualquier Form asociado con el campo. Nota especial: La opción Skip-Found (DD_SkipFound) tiene un efecto similar, excepto que permite que el cursor vaya a ese elemento si no se encontró ningún registro. No-Enter pasa por alto el Form sin considerar si se encuentra un registro. La alternativa DD_DisplayOnly es una combinación de DD_NoEnter y DD_NoPut. Aunque los datos no puedan ser introducidos desde el teclado a un Form controlado por No-Enter. Estos pueden ser movidos al Form bajo el control del programa. Esos serán pasados al buffer y grabados, cosa que no se hace con las opciones de campo Display_Only y No_Put. No-Put (DD_NoPut) Set Field_Options field Customer.Id to DD_NoPut DD_NoPut no permite que los datos se pasen de los Forms de entrada al buffer de registro del campo, incluso si se han introducido datos nuevos vía teclado. No-Put es útil para permitir que se introduzcan datos en un Form donde no desee permitir que se modifique el campo. Use la opción “No-Put” cuando quiera impedir que los usuarios cambien los datos. La alternativa DD_DisplayOnly es una combinación de DD_NoEnter y DD_NoPut. www.VisualDataflex.es Página 40 de 92 Guía de Diccionario de Datos Display_Only (DD_DisplayOnly) Set Field_Options field Customer.Id to DD_DisplayOnly DD_DisplayOnly hace que el cursor pase por alto el Form de entrada de datos asociado con este campo e impide que se modifique cualquier dato. El Form se mostrará como desactivado. DD_DisplayOnly es equivalente a la combinación de DD_NoEnter y DD_NoPut. // This is the same as DD_DisplayOnly Set Field_Options field Customer.Id to DD_NoEnter DD_NoPut Retain(DD_Retain) Set Field_Options field Customer.Id to DD_Retain DD_Retain (mantener) evita que los Forms de entrada de datos asociados al campo se limpien (vacíen) cuando el usuario inicia una operación que normalmente limpiaría todos los Forms de una vista. Si el usuario inicia la operación clear-all, entonces no se conservará absolutamente ningún dato. Es algo que habitualmente no se puede aplicar a todos los objetos en todas las vistas que usen una clase DD en concreto. En vez de eso, la opción de mantener (Retain) se debería basar en los requisitos específicos de entrada de datos de una vista. Por lo tanto se espera que Retain sea aplicado en nivel de objeto de DD y no como parte de la definición de clase. Retain-All (DD_RetainAll) Set Field_Options field Customer.Id to DD_RetainAll DD_RetainAll impide que los Forms de entrada de datos asociados con el campo se limpien (vacíen). Aunque los usuarios no puedan limpiar el Form, la entrada de datos sí podría hacerlo manualmente borrando carácter a carácter presionando la tecla “Limpiar”. Es algo que habitualmente no se puede aplicar a todos los objetos en todas las vistas que usen una clase DD en concreto. En vez de eso, la opción de mantener (Retain) se debería basar en los requisitos específicos de entrada de datos de una vista. Por lo tanto se espera que Retain sea aplicado en nivel de objeto de DD y no como parte de la definición de clase. www.VisualDataflex.es Página 41 de 92 Guía de Diccionario de Datos Skip-Found (DD_SkipFound) Set Field_Options field Customer.Id to DD_SkipFound DD_SkipFound previene la entrada de datos en los Forms de entrada de datos del campo si el buffer para la tabla tiene un registro activo. DD_NoEnter es una opción de campo similar. Sin embargo, pasa por alto el Form de base de datos en todos los casos, sin considerar si hay un registro activo en el buffer. Zero-Suppress (DD_Zero_Suppress) Set Field_Options field Customer.Id to DD_Zero_Suppress DD_Zero_Suppress limpia el Form de entrada de datos del campo si este es numérico con valor cero (0). DD_Zero_Suppress parecerá no funcionar en donde haya un valor absoluto pequeño en un Form. Por ejemplo, si un Form especifica valores enteros de visualización y un valor de campo inferior a 1 (por ejemplo 0,5) se mostrará cero en el Form. Solamente un valor que sea realmente cero (0) será mostrado como espacios en blanco. Require (DD_Required) Set Field_Options field Customer.Id to DD_Required DD_Required se asegura de que se introduzcan datos en un campo. Cualquier carácter o caracteres que se introduzcan en el Form de entrada de datos permitirán que el cursor se mueva al siguiente Form. Este requisito se aplicará también durante la validación de grabación. Find-Required (DD_FindReq) Set Field_Options field Customer.Id to DD_FindReq DD_FindReq impide que el cursor se vaya al siguiente Form de entrada de datos hasta que se encuentre un registro válido del campo asociado al Form. Una búsqueda fallida causa un Error 90 (por favor introduzca un registro válido). “Find required” no tiene ningún efecto si un registro activo para la tabla ya está en la vista. www.VisualDataflex.es Página 42 de 92 Guía de Diccionario de Datos Normalmente aplicaría Find Required como una opción de campo foráneo (Foreing-Field) en una “tabla padre” para asegurarse que se encuentra un registro relacionado antes de que ocurra una grabación en la “tabla hijo”. Una opción de Auto-Find en el campo con Find Required intentará encontrar el registro automáticamente cuando un usuario intente mover el cursor fuera del Form. Si la búsqueda automática tiene éxito el cursor continuará. Si no se encuentra el registro ocurrirá el Error 90 (limpia el Form de entrada de datos del campo si este es numérico con valor cero). “Find Required” con Auto-Find GE es innecesario. Auto Find GE siempre encuentra un registro en una tabla que no esté vacía. Este requisito de búsqueda se aplicará también durante la validación de grabación. Limpiar opciones de campo Se soportan mensajes opcionales para permitir que se limpien o alternen ciertas opciones de elementos: Field_Option_Clear (y File_Field_Option_Clear) limpia las opciones de campo pasadas por este mensaje Set Field_Option_Clear Field Customer.Name to DD_Retain Field_Option_Toggle (and File_Field_Option_Toggle) alternan las opciones de campo pasadas por este mensaje Set Field_Option_Toggle Field Customer.Name to DD_Retain Estos mensajes rara vez son usados en clases de Diccionario de Datos. Cuando sean usados se emplearán en los DDOs para controlar dinámicamente una vista de entrada de datos. Vea “Cambiar propiedades de campo con DDOs” para más información. Consulte lo siguiente Definir atributos de campo de Diccionario de Datos. Validaciones de campo (Field Validations) Las validaciones de campo se usan para verificar que un valor de campo combine con un valor válido. Se puede definir uno de los cuatro tipos de validaciones de campo: • Casilla de verificación (Checkbox): debe ser uno de dos valores, generalmente, verdadero o falso. • Rangos (Range): el valor introducido debe de estar dentro de un rango de números o fechas. www.VisualDataflex.es Página 43 de 92 Guía de Diccionario de Datos • Verificación (Check): el valor introducido debe encajar “match” con un elemento de una cadena de verificación. Una cadena de valores válidos separados por el carácter "|". • Tabla de validación: el valor introducido debe encajar “match” con un valor de un objeto de una tabla de validación. Una tabla de validación especial llamada “tabla de validación de clave” (Code Validation Table) provee una manera fácil de atribuir un juego de las claves y descripciones válidas a cualquier campo. Además, para cualquier campo puede definir un método personalizado de validación (Field Validation Method). Este método, una función, se asigna a un campo fijando el mensaje de validación de campo (Field Validation Message). Esta función se llama durante la validación. Si se detecta un error, la función debe generar uno y devolver un valor distinto de cero. Esta función permite que cree cualquier tipo de regla de validación que necesite. La validación de campo ocurre durante la navegación hacia delante (Forward Navigations) y las paradas. Usar validaciones de campo asegura que los datos que se están grabando en su base de datos son válidos. Casilla de verificación (Checkbox) Set Field_Checkbox_Values field Customer.Status to "A" "I" El mensaje “Field_Checkbox_Values” marca el campo para que se use con una casilla de verificación (Checkbox). Un campo de casilla de verificación puede almacenar uno de dos valores, un valor verdadero y uno falso. Si el campo se representa con una casilla de verificación (dbCheckbox), el control estará marcado cuando el campo con el que el valor se compare sea verdadero. Estará desmarcado cuando el campo con el que el valor se compare sea falso. Si el campo es representado por un control tipo Form (dbForm) la entrada de datos estará restringido al valor verdadero o al valor falso. Cuando hay un error de validación, el número de error y el texto especificado para el campo en la propiedad de “Field_Error” se usan para informar del error. Si no se define ningún texto, se informa con el texto de error estándar. Rangos (Range) Set Field_Value_Range.field Customer.discount to 0 60 El método de “Field_Value_Range” permite definir un valor mínimo y máximo para el campo. El campo y sus rangos deben ser numéricos o fechas. El valor “Desde” debe ser inferior al del “Hasta”. La validación se lleva a cabo después de que el usuario haya introducido los datos en el Form de entrada de datos del campo. Si falla la validación, entonces el usuario no podrá dejar el Form. (El usuario todavía puede salir del Form haciendo clic con el ratón en otro lugar de la pantalla). www.VisualDataflex.es Página 44 de 92 Guía de Diccionario de Datos Cuando ocurre un error de validación, el número de error y el texto especificado para el campo en la propiedad de “Field_Error” se emplean para informar sobre el mismo. Si no se define ningún texto, se informa con el texto de error estándar. La validación también se lleva a cabo cuando se graba un registro. Si falla la validación, se suspende la grabación. Verificación (Check) Set Field_Value_Check field Customer.region to " N|S|E|W" El mensaje de “Field_Value_Check” se emplea cuando la lista de valores válidos está limitada a un juego estático y pequeño de valores. Estas muestras están identificadas en una cadena de comprobación (Check String). Esto consta de una lista de valores válidos separados por el Símbolo "|". Por ejemplo, para posibles valores válidos A, B, C, se usaría la cadena “A|B|C”, mientras que para valores válidos Po, Ou, Lu se representaría con la cadena “Po|Ou|Lu” La validación se lleva a cabo después de que el usuario haya introducido los datos en el Form de entrada de datos del campo. Si falla la validación, entonces el usuario no podrá dejar el Form. (El usuario todavía puede salir del Form haciendo clic con el ratón en otro lugar de la pantalla). Además de usarse para validar, estos valores también pueden usarse con elementos de entrada Combo-Box. Si se asigna un dbComboForm a un campo que usa valores de verificación (Check), cada valor del String de verificación será cargado en la lista de combo (Combo-List). Set Field_Value_Check field Customer.state to "Po|Ou|Lu|SA" Quizás el ejemplo de “Customer.state” no sea probablemente una buena muestra de de este método de validación. Añadir nuevas provincias a esta lista requiere cambios de programa, y el String puede ponerse demasiado grande para ser práctico. En ese caso, querrá usar una tabla de validación (Validation Table). Cuando hay un error de validación, el número de error y el texto especificado para el campo en la propiedad de “Field_Error” se usan para informar del error. Si no se define ningún texto, se informa con el texto de error estándar. La validación de verificación (Check) es limitada. Una manera más flexible y reutilizable de especificar una lista de entradas válidas es usar una Tabla de Validación. Tablas de validación (Validation Tables) Set Field_Value_Table Field Customer.Status to oStatusTable Si un campo tiene que ser validado contra uno de dos valores, con un conjunto limitado de valores, o con un rango de valores, puede usar la casilla de verificación (Checkbox), Rangos (Rango) o Validaciones (Check). En muchos casos descubrirá que estas clases de validaciones www.VisualDataflex.es Página 45 de 92 Guía de Diccionario de Datos son demasiado limitadas para sus necesidades. En ese caso, puede usar tablas de validación de campo. Usar una tabla de validación de campo tiene las siguientes ventajas: • Especificar un número más grande de valores válidos de los que puede encajar en una cadena de valores válidos. • Especificar y mostrar una descripción para cada valor. • Puede mantener actualizada su lista de valores (los valores no tienen que ser codificados directamente en su programa). • Puede hacer las elecciones de lista opcionales (puede sugerir una lista de valores durante la introducción de datos pero a los usuarios no se les exiges hacer una selección de la lista). Cuando ocurre un error de validación, el número de error y el texto específico para el campo en la propiedad de “Field_Error” se emplean para informar sobre un error. Si no se define ningún texto, se informará con un texto estándar. El uso de tablas de validación da una flexibilidad tremenda. Más adelante se hablará con detalle de cómo usar tablas de validación. Por ahora abordaremos el tema de las clases primarias de Tablas de Validación: Tabla de validación (Validation Table) Esta clase permite que mantenga actualizada una lista de valores válidos. Object oStatusTable is a ValidationTable Procedure Fill_List Send add_table_value "O" Send add_table_value "C" Send add_table_value “D” End_Procedure End_Object Descripción de validación de tabla (Description Validation Table) Esta clase permite que mantenga actualizada una lista de valores válidos y sus descripciones asociadas. Object oStatusTable is a DescriptionValidationTable Set List_Title to "Customer Status" Procedure Fill_List Send add_table_value “O” "Opened” Send add_table_value “C” “Closed” Send add_table_value “D” "Flagged for Deletion” End_Procedure End_Object www.VisualDataflex.es Página 46 de 92 Guía de Diccionario de Datos Tabla de validación de archivo (File Validation Table) Esta clase le permite mantener actualizada una lista de valores y descripciones que puede ser fácilmente cargado desde una tabla Visual DataFlex específica. Object StatusTable is a FileValidationTable Set Main_File to CustStat.File_Number End_Object Tablas de validaciones de código (Code Validation Table) Esta clase permite que cargue sus valores de datos y descripción de la lista de claves de Visual DataFlex (Visual DataFlex Code List) Object oStatusTable is a CodeValidationTable Set Type_Value to "Status" End_Object Cualquiera de las tablas de validación de arriba puede ser conectada a un campo con el mensaje de “Field_Value_Table en un Diccionario de Datos. Set Field_Value_Table Field Customer.Status to oStatusTable Métodos de validación de campo (File Validation Methods) Set Field_Validate_msg field employee.pay_type to get_valid_pay_type La propiedad de “Field_Validate_msg” le deja asignar el mensaje a ser enviado cuando un campo debe ser validado. Este mensaje será el mensaje Id de una función y se llama cuando el programa necesita una validación. Este método de validación se usa cuando tiene que llevar a cabo validaciones complejas que pueden ser expresadas solamente con código. Debido a que es un proceso muy abierto, puede hacer prácticamente cualquier cosa. Si el valor es válido, la función debe devolver un cero. Si el valor no es válido, la función debe generar un error y devolver un valor distinto de cero. Este método de validación puede usarse en conjunto con otras técnicas de validación (casilla de verificación-Checkbox; Rangos-Range; Verificación-Check o Tabla de Validación-Table Validation) o como una sustitución de ellos. Deberá crear la función(s) de validación (s). Esta función pasa el número de campo y el valor del campo. La función puede usar estos valores cuando sea conveniente. Para este propósito, el valor de cualquier otro campo en el Diccionario de Datos puede ser obtenido mediante la propiedad de www.VisualDataflex.es Página 47 de 92 Guía de Diccionario de Datos “Field_Current_Value”. Es importante notar que la rutina de validación nunca necesitará acceder a un valor de un DEO. La información necesaria deberá poder ser encontrada en el DDO o en uno de los DDOs conectados con ella. Por ejemplo, si tiene la siguiente función: Function ValidateCredit Integer iField Number nValue ; Returns Boolean Boolean bErr String sCustRating // get the customer rating for this customer from DD buffer Get Field_Current_Value field Customer.Rating to sCustRating // If customer Rating is A1 their limit is 5000 If (sCustRating = "A1" and nValue> 5000) Begin Error DFERR_OPERATOR "Credit limit may not exceed $5000" Move True To bErr End Function_Return bErr End_Function Para usar esta función en el campo “Credit_Limit” de una tabla, debe establecer el método de validación (Field_Validate_msg) al “Handle Name” de la función. El “Handle Name” de una función es el nombre de la función con el prefijo “Get” (por ejemplo: Get_ValidateCredit). Set Field_Validate_msg field Customer. Credit_Limit to get_ValidateCredit El prototipo de declaración para un método de validación tiene la siguiente forma. Function_function_name integer iField type CurrentValue returns integer Dónde: • Function_name es el nombre de la función de validación; • iField es el número de campo del campo que envió function_name. El número de campo puede ser usado para recuperar cualquier información sobre el campo y TypeCurrentValue es el tipo de datos y el valor actual del campo que envió function_name. Esto le permite escribir funciones de validación de métodos generalizados que pueden ser usados por otros campos y tablas. Errores de validación de campo (Field Validation Errors) Set Field_Error field Customer.Credit_Limit to 200 Not a legal number" www.VisualDataflex.es Página 48 de 92 Guía de Diccionario de Datos El método Field_Error permite definir un número de error específico y enviar un mensaje siempre que la validación falle para el campo. Esto quiere decir que cada campo puede tener su propio mensaje de error de validación específico. El error es lanzado cuando una de las siguientes pruebas de validación falla: casilla de verificación-Checkbox; Rangos-Range; Verificación-Check o Tabla de Validación-Table Validation. Los métodos de validación deben tener sus propios textos de error codificados dentro de la función. Consulte lo siguiente Definir los atributos de campo de Diccionario de Datos. Aspecto del campo Máscaras (Masks) Set Field_Mask Field Orderhea.Order_Date to "mm - dd - yyyy" Set Field_Mask_Type Field Orderhea.Order_Date to MASK_DATE_WINDOW Las máscaras se emplean en las aplicaciones Windows de Visual DataFlex para: • Restringir la entrada de datos en un campo a un patrón definido de números, letras o caracteres de puntuación. • Proveer la visualización de los datos de un campo de acuerdo a formatos y patrones predefinidos. Por ejemplo, es posible mostrar valores de fecha con las abreviaturas como días de la semana o meses del año. La traducción de números a nombres es sensible a la Configuración Regional de Windows Las máscaras no son la validación y no deben ser usadas como una técnica de validación. Las máscaras se definen poniendo dos propiedades de campo: “Field_Mask_Type” y “Field_Mask”. Las máscaras se comentan con más detalle en “Máscaras en las aplicaciones de Windows”. Etiquetas (Labels) Set Field_Label_Long Field Orderhea.Terms To "Terms of Payment" Set Field_Label_Short Field Orderhea. Terms To "Terms" Se pueden asignar etiquetas largas y cortas a cada campo. Las etiquetas de campo largas y cortas se definen usando las propiedades de “Field_Label_Long” y “Field_Label_Short”. Cuando obtenga el valor de una etiqueta deberá usar la función “Field_Label”. www.VisualDataflex.es Página 49 de 92 Guía de Diccionario de Datos Get Field_Label Field DD_LABEL_SHORT to sHeaderName Get Field_Label Field DD_LABEL_LONG to sLabel La función “Field_Label” (y File_Field_Label) nos facilita flexibilidad adicional en determinar el valor de una etiqueta. • Si se pide el valor de la etiqueta larga y no se ha asignado el nombre de etiqueta larga, se obtiene el nombre del campo. • Si se pide el valor de la etiqueta corta y no se ha asignado el nombre de etiqueta corta, se obtiene el nombre de etiqueta largo. Se aplica la misma lógica cuando el Studio o los asistentes (Wizards) se usan para diseñar vistas e informes. El Studio usará la etiqueta larga al crear controles de tipo Form (por ejemplo., DbForm, dbComboForm). Sin embargo usa las etiquetas cortas al crear controles de estilo de columna (por ejemplo., DbGrid). Ayuda de estado (Status Help) Set Status_Help field Cust.Status to "Customer is (A) ctive or (I) nactive" “Status_Help” define una línea de texto de ayuda para el campo. Los objetos de entrada la usan para mostrar la ayuda en la barra de estado. Cuando el usuario cambia el cursor, un objeto de entrada de datos muestra la ayuda “Status Help” en la barra de estado. Introduzca el texto que ayude al usuario con información sobre el campo que va a introducir. Controles de ventanas (Windows Controls) Set Field_Class_Name field Cust.Address to "cDbAddressForm" “Field_Class_Name” asigna el nombre de clase de un control específico a cada campo. Por defecto, Studio usará esta información para determinar la clase del control que se crea siempre que el campo sea arrastrado en un componente. Este ajuste no evita que elija una clase de control diferente para el campo de una forma explícita en el Studio, o para cambiar la clase del control de una forma individual; es solamente el valor por defecto. Si deja este espacio en blanco, el Studio determinará el mejor control para usar para el campo. El Studio hace un buen trabajo al asignar el control correcto así que esta propiedad se dejará, generalmente, vacía. Puede asignar cualquier nombre de clase en este Form. Si pone en el nombre de una clase no estándar, entonces la clase debe ser registrada correctamente en Studio antes de que pueda ser usado. Consulte lo siguiente Definir los atributos de campo de Diccionario de Datos. www.VisualDataflex.es Página 50 de 92 Guía de Diccionario de Datos Métodos de entrada y salida Las propiedades de “Field_Entry_msg” y “Field_Exit_msg” son similares al “Field_Validate_msg” y son enviadas siempre que el cursor entre o salga de un elemento conectado con un campo. Crearía los procedimientos y luego atribuiría los nombres de procedimiento (procedure) a las propiedades de campo. Cuando se llaman se pasa el número de campo y el valor del campo. Al procedimiento (procedure) mientras devuelva un valor distinto a cero se podría parar la navegación, esto sería un uso anormal o poco habitual. Estos procedimientos se emplean, generalmente, para manejar procesos antes de entrar y después de salir. Método de entrada Set Field_Entry msg Field Customer.State To EntryCustomerState “Field_Entry_msg” permite que especifique el nombre de un método que se ejecuta siempre que el cursor se mueve un Form de entrada de datos conectado al campo. El método de entrada, un procedimiento, puede ser programado para llevar a cabo cualquier acción. Podrá usarlo para mostrar información especial o valores por defecto cada vez que el cursor vaya al campo. En Visual DataFlex, los procedimientos pueden devolver un valor entero. En el caso de un método de entrada (Entry method), si se devuelve un valor distinto de cero, se aborta la entrada del cursor al Form. Usar los métodos de entrada para controlar la navegación es muy desaconsejable. El método de entrada debe ser un procedimiento de la clase de Diccionario de Datos de la tabla. Por ejemplo si tiene el siguiente procedimiento: Procedure EntryOrderDate Interger iField Date dDate // Add a default date if the fields is blank Boolean bChanged Get Field_Changed_State iField to bChanged If (not (bChanged) AND dDate = 0) Begin SysDate dDate Set Field_Default_Value iField to dDate End End_Procedure Para usar este procedimiento en un campo fecha de una tabla, pondría el método de entrada de campo a “EntryOrderDate”. Estaría asignando el manejador de método “msg_EntryOrderDate” pero si se omite el prefijo "msg" este será proporcionado automáticamente. www.VisualDataflex.es Página 51 de 92 Guía de Diccionario de Datos Set Field_Entry_msg Field Orderhea.Order_Date To EntryOrderDate El prototipo de declaración para un método de entrada tiene el siguiente formato general. procedure procedureName integer iField type currentValue Dónde: • procedureName es el nombre del procedimiento; • iField es el número de campo del campo que envió “procedureName”. El número de campo puede usarse para obtener cualquier información sobre el campo. • Type y currentValue son el tipo y el valor actual del campo que envió “procedureName”. Los parámetros que se pasan al método de entrada permiten que escriba procedimientos generalizados que pueden ser reutilizados en otros campos y tablas. Método de salida Set Field_Exit_msg Field Customer.Zip To ExitAdjustZip “Field_Exit_msg” permite que especifique el nombre de un método que se ejecute siempre que el cursor se va de un Form de entrada de datos conectado al campo. El método de salida, un procedimiento, puede ser programado para llevar a cabo cualquier acción. Por ejemplo, podría usarlo para ajustar valores de algunos datos calculados que están en función del valor del campo introducido. En Visual DataFlex, los procedimientos pueden devolver un valor entero. En el caso de un método de salida, si se devuelve un valor distinto de cero se aborta la acción de salir del Form de entrada de datos. No se recomienda utilizar este evento para controlar la navegación. El método de salida debe ser un procedimiento de clase de Diccionario de Datos de la tabla. Por ejemplo si tiene el siguiente procedimiento: Procedure AdjustDisplayTotal Interger iField Interger iValue // This updates the extender Price field, which will update any // display balances.This is only done for display purposes.The // actual amount is updated to the field during the save. Interger iQty Number nAmnt Get Field_Current_Value Field Orderdtl. Qty_Ordered to iQty Get Field_Current_Value Field Orderdtl.Price to nAmnt Set Field_Current_Value Field Orderdtl. Extended_Price to (nAmnt * iQty) // note we set value, but not changed state! End_Procedure www.VisualDataflex.es Página 52 de 92 Guía de Diccionario de Datos Para usar este procedimiento sobre el campo apropiado de una tabla, pondría el método de entrada del campo a “AdjustDisplayTotal”. Estaría asignando el manejador de método “msg_AdjustDisplayTotal pero si se omite el prefijo “msg” este será proporcionado automáticamente. Set Field_Exit_msg Field Orderdtl.Qty_Ordered to Adjust_Display_Total El prototipo de declaración para un método de salida tiene el siguiente formato general. procedure procedureName integer iField type currentValue Dónde: • procedureName es el nombre del procedimiento; • iField es el número del campo que envió “procedureName”. El número de campo puede usarse para obtener cualquier información sobre el campo. • Type y currentValue son el tipo y el valor actual del campo que envió “procedureName”. Los parámetros que se pasan al método de salida permiten que escriba procedimientos generalizados que pueden ser reutilizados en otros campos y tablas. Consulte lo siguiente Definir los atributos de campo de Diccionario de Datos. Autoincremento del campo Cada registro en una tabla debe contener un campo o juego de campos que proporcionen una identificación única al registro. Esto sería la clave primaria. En algunos casos, el valor de la clave primaria debe ser introducido manualmente por el operador (Ej. Introducir una identificación de cadena única como parte de la entrada de datos). En algunos casos, la base de datos suministrará la calve primaria automáticamente al grabar el registro. En otros casos, el Diccionario de Datos debe suministrar esta identidad única cuando se grabe el registro por primera vez. El autoincremento (Auto-Incremento) del Diccionario de Datos nos da esta funcionalidad asignando números automáticamente y de forma secuencial a cada nuevo registro. Para que el Diccionario de Datos sepa cuál es el siguiente número a un nuevo registro debemos almacenar el último número asignado en una tabla externa. Para crear un campo autoincremento, necesitará definir en el Diccionario de Datos la tabla externa y el campo en esa tabla que se va a usar para almacenar ese número así como el campo ID (clave primaria) en su Diccionario de Datos. Para facilitar esta operación existe un comando llamado Define_Auto_Increment Define_Auto_Increment ordsys.last_cust_num to Customer.cust_number www.VisualDataflex.es Página 53 de 92 Guía de Diccionario de Datos En este ejemplo, el campo Ordesys.Last_Cust_Num tabla sistema se designa para incrementar y suministrar un valor al campo cust_number de la tabla Customer. El autoincremento funcionará correctamente solo si la tabla externa es una tabla de sistema (un solo registro) o una “Tabla Padre” con la que esté relacionada. Usará una tabla sistema si el identificador único es de un solo segmento como muestra en el ejemplo anterior con cust_number. Si está usando un campo de una tabla sistema, tiene que registrar esta tabla como una tabla externa de forma que se bloquee correctamente durante operaciones de grabación. Por ejemplo: Define_Auto_Increment ordsys.last_cust_num to Customer.cust_number Send Add_System_File ordsys.last_cust_num DD_LOCK_ON_NEW_SAVE_DELETE Puede usar una “tabla padre” relacionada si su identificador (ID) único es multi - segmento. Por ejemplo el ID de una estructura Cabecera-Detalle como en pedido-detalle pedido. Por ejemplo, el ID de una tabla de Detalle (Order-Detail) en una estructura Cabecera-Detalle (header-detail) podría ser el número del documento (Cabecera) y un número de orden de detalle asignado por una tabla sistema. Si el último número de detalle de cada cabecera fuera almacenado en la tabla Cabecera (OrderHea.Last_Detail_Num) el campo de Autoincremento se definiría como: Define_Auto_Increment OrderHea.Last_Detail_Num to OrderDtl.Detail_Number Solamente puede asignar un autoincremento campo por DDO. Si intenta atribuir dos, entonces de autoincremento del primer campo será ignorado. Si tiene que asignar campos de autoincremento adicional dentro de su Diccionario de Datos puede hacerlo fácilmente añadiendo un código personalizado al evento de “Creating” del Diccionario de Datos. Consulte lo siguiente Definir los atributos de campo de Diccionario de Datos. Listas de consultas (Lookup lists) Set Field_Prompt_Object field Customer.name to Cust_lkup Las listas de consulta se crean para poder buscar registros de una manera fácil en su aplicación. Típicamente cada tabla tendrá al menos una lista de consulta relacionada con ella. Las columnas en esta lista de consulta contarán, a menudo, con los campos más importantes de su tabla. Estos campos se ponen normalmente en un índice y las listas de consulta se diseñan para dejar buscar registros fácilmente por cualquiera de esos índices. Asignar campos en un Diccionario de Datos a una lista de consulta se hace fijando la propiedad de “Field_Prompt_Object”. Una vez asignadas, sus aplicaciones Windows fijarán esas listas de consulta a todos los objetos de introducción de datos que usan ese campo de forma automática. www.VisualDataflex.es Página 54 de 92 Guía de Diccionario de Datos Habitualmente creará sus objetos de lista de consulta antes de que los asigne a un “Field_Prompt_Object”. Debe saber el nombre del objeto de la lista de consulta antes de asignarlo. Existen asistentes que le permiten crear sus listas de consultas y asignarlos a los campos de Diccionario de Datos apropiados en un solo paso. Si está usando uno de los tipos de validación (casilla de verificación, rango, tabla de verificación o validación) es capaz de suministrar una lista de consulta por defecto; lo hace si no tiene una asignada explícitamente. Así que si asigna a un campo un “Field_Prompt_Object”, este se usará en vez de la lista suministrada para las validaciones extendidas. Consulte lo siguiente Definir los atributos de campo de Diccionario de Datos. www.VisualDataflex.es Página 55 de 92 Guía de Diccionario de Datos Definir atributos de campos foráneos en Diccionario de Datos Dentro de su DEO (Objeto de entrada de datos) el comando Entry_Item une una tabla y el valor del campo a un form o a una columna de una parrilla (grid). Esta tabla será la tabla principal del Diccionario de Datos del DEO, o la tabla “padre”. Cuando se use como una tabla padre, el Entry_Item se considera conectado con un campo foráneo. Es importante comprender el concepto de un campo foráneo. El siguiente ejemplo muestra un “Entry-Item” que no es foráneo seguido por uno que si lo es: // Part of an order entry view // Object oOrderNumber is a dbForm Set Server to oOrderhea_DD Entry_Item Orderhea. Order_number //this is not a foreing field : Object oCustomerName is a dbForm Set Server to oOrderhea_DD Entry_Item Customer.Name/ this is a foreing field : Un ejemplo de un campo extranjero es el campo “customer.Name” cuando sale en un view del Order Entry. Esto es debido a que es la tabla Order-Header la que provee el servidor de Diccionario de Datos; la tabla cliente (customer) en este ejemplo es “padre” del Order-Header. // Part of customer maintenance view // Object oCustomerName is a dbForm Set Server to oCustomer_DD Entry_Item Customer.Name// this is not a foreing field : Cuando el campo customer.Name sale en la vista del mantenimiento de clientes, no es un campo foráneo porque en este caso la tabla del cliente provee el servidor de Diccionario de Datos. Cuando el número de la tabla (File-Number) de Entry_Item no es el mismo que el número de la tabla principal del Diccionario de Datos, la tabla debe ser un antepasado (padre, abuelo, etcétera.). Si no lo es, probablemente, ha cometido un error. Los elementos de entrada de datos de tablas de ancestros (tablas padre, abuelo…) se usan generalmente de forma diferente a la entrada de datos de la tabla principal. Cuando se introduce un registro nuevo en la principal, los registros de la tabla padre no se modifican. Su función es proporcionar valores de campo (número de cliente, forma de pago…) en los que se basan las relaciones de la tabla principal a la tabla padre. Cuando se tiene que modificar la tabla padre www.VisualDataflex.es Página 56 de 92 Guía de Diccionario de Datos (añadir, modificar, borrar) dicha modificación se realiza en una vista diferente en la que la tabla (padre) es la tabla principal del DDO. Debido a esto, los campos foráneos requieren, a menudo, ajustes de opción de campo adicionales. Las opciones de campo foráneos pueden ser atribuidos a campos individuales aunque esto raramente se hace ya que hay multitud de formas más convenientes de hacerlo. Los campos foráneos pueden ser divididos en tres categorías. Éstas son: • Campos Clave (Key Field): es cualquier campo para el que la propiedad de Key_Field_State es verdadero (Clave primaria). • Campo Indexado (Indexed Field): es cualquier campo que no es un campo clave y es un segmento en uno o más de los índices de la tabla. • Campo por defecto (Default Field): es cualquier campo que no es un campo clave o un campo indexado. Definiendo opciones de campo foráneos para cada uno de estas categorías de campos (DD_KEYFIELD, DD_INDEXFIELD, DD_DEFAULT) proporciona a sus aplicaciones de introducción de datos los elementos necesarios sin programación adicional. Las propiedades de campo foráneos se añaden cualquier propiedad de opción regular de campo. Los siguientes ejemplos indican un uso típico de opciones de campo foráneas. Set Field_Options field Customer.id to DD_NoPut DD_AutoFind DD_CapsLock Set Field_Options field Customer.balance_due to DD_DisplayOnly : // define default foreing field options Set Foreign_Field_Options DD_KEYFIELD to DD_FindReq Set Foreign_Field_Options DD_INDEXFIELD to DD_NoPut Set Foreign_Field_Options DD_DEFAULT to DD_DisplayOnly En este ejemplo, las opciones de campo regulan (campo no foráneo) para “Customer_ID” serán No-Put, Auto-Find y Capslock. Sus opciones de campo foráneo serán No-Put, Auto-Find, Capslock y puesto que es un campo clave, Find-Required. Todas las opciones de campo regulares se pueden asignar como opciones de campo foráneos. En la práctica, las únicas opciones que probablemente vaya a poner son DD_NoPut, DD_NoEnter, DD_DisplayOnly, DD_AutoFind y DD_FindReq. Campos Foráneos clave Un campo clave, DD_KEYFIELD, es cualquier campo para el que la propiedad de Key_Field_State es verdadera. Cuando se usen como campos foráneos, probablemente, querrá que estos campos sean Find-Required, Auto-Find y No-Put. Esto quiere decir que debe encontrarse un registro Padre antes de poder grabar el Hijo y que si se introduce un valor en el campo se producirá una búsqueda automática (Auto-Find) y no se podrá modificar el valor de esta clave; eso si entra en un valor en el que el campo tiene un hallazgo automático y no puede cambiar este valor de tecla. Los ajustes para este campo foráneo serán: www.VisualDataflex.es Página 57 de 92 Guía de Diccionario de Datos Set Foreign_Field_Options DD_KEYFIELD to DD_FindReq DD_AutoFind DD_NoPut A menudo las opciones de campo principales del campo de la clave primaria ya han especificado Auto-Find y No-Put y debido a que estas opciones estándar de campos se añaden a las opciones de campos foráneos, únicamente necesitará ajustar: Set Foreign_Field_Options DD_KEYFIELD to DD_FindReq Consulte lo siguiente Definir Diccionario de Datos y atributos de campos foráneos. Campos Foráneos indexados Un campo indexado, DD_INDEXFIELD, es cualquier campo que no sea una clave primaria y que sea un segmento en uno o más índices de la tabla. Cuando se usa como campos foráneos estos campos son generalmente accesibles (para que pueda llevar a cabo búsquedas manuales) pero definido como no modificable (No-Put) de forma que no pueda modificar y grabar su valor. Los ajustes para este campo foráneo son: Set Foreign_Field_Options DD_INDEXFIELD to DD_NoPut Alternativamente, puede incluso decidir el que no se soporte búsquedas en estos campos, en cuyo caso los ajustes para estos campos foráneos serán: Set Foreign_Field_Options DD_INDEXFIELD to DD_DisplayOnly Consulte lo siguiente Definir Diccionario de Datos y atributos de campos foráneos. Campos Foráneos por defecto Un campo por defectos, DD_DEFAULT, es cualquier campo que no sea una clave primaria o un campo indexado. No querrá poder cambiar este campo y debido a que no hay índice relacionado con él, solamente lo podrá ajustar a Display-Only. Los ajustes para este campo foráneo serán: Set Foreign_Field_Options DD_DEFAULT to DD_DisplayOnly www.VisualDataflex.es Página 58 de 92 Guía de Diccionario de Datos Consulte lo siguiente Definir Diccionario de Datos y atributos de campos foráneos. www.VisualDataflex.es Página 59 de 92 Guía de Diccionario de Datos Definiendo Diccionarios de Datos de Padres, Hijos y relaciones externas Los Diccionarios de Datos tienen que saber cómo modelar relaciones. Esto se obtiene: • Definiendo todas las tablas “Padre” con las que se está relacionando. • Definiendo todas las tablas “Hijo” desde las que se está relacionando. • Definiendo todas las tablas extra que puedan ser necesarias. Una vez definido, sus objetos del Diccionario de Datos pueden usar esta información para verificar que las estructuras de DDO están configurados adecuadamente para operaciones de grabación y borrado. Consulte lo siguiente • Definiendo “tablas padre” • Definiendo “tablas hijo” • Requisitos para las grabaciones • Requisitos para los borrados • Cómo funcionan las estructuras de DDO de grabación. • Tablas sistema y tablas externas Definiendo “tablas Padre” requeridas Send Add_Server_File Customer.File_Number Un Diccionario de Datos tiene que estar al tanto de las tablas con las que está relacionado (también llamadas “tablas padre”). Identificando todas las “tablas padre” el Diccionario de Datos puede determinar si los DDOs (Objeto de Diccionario de Datos) han sido creados para todos estos padres y si esos DDOs padre están apropiadamente conectados con el DDO principal. El DDO padre también tiene una lista de “tablas padre” y estos DDOs padre hacen lo mismo para asegurarse de que sus DDOs padre existen y de que están apropiadamente conectados dentro de la estructura. Este proceso ocurre hacia la parte superior (hacia arriba) de la jerarquía de toda la base de datos. www.VisualDataflex.es Página 60 de 92 Guía de Diccionario de Datos Propagando esta comprobación hacia arriba se puede verificar si una estructura de Diccionario de Datos está completa. Si la estructura no está completa, ese DDO no podrá grabar o borrar registros. La información de la “tabla padre” también es utilizada por el Studio y por varios asistentes para ayudarle a construir sus aplicaciones. Por lo tanto es importante que esta información sea mantenida correctamente en su clase de Diccionario de Datos. Se añaden tablas a la lista de “tablas padre” relacionadas con el mensaje “Add_Server_File”. Envíe este mensaje a cada una de las “tablas padre” requerida. Consulte lo siguiente Definir relaciones externas Padre-hijo de Diccionario de Datos. Definiendo “tablas Hijo” requeridas Send Add_Client_File Orderdtl.File_Number Un Diccionario de Datos tiene que estar al tanto de las tablas que están relacionadas con él (también llamadas “tablas Hijo”). Identificando todas las “tablas hijo” el Diccionario de Datos puede determinar si los DDOs (Objetos de Diccionario de Datos) han sido creados para todos estos hijos y si esos DDOs hijo están apropiadamente conectados con el DDO principal. El DDO hijo también tiene una lista de “tablas hijo” y estos DDOs hijo hacen lo mismo para asegurarse de que sus DDOs hijo existen y de que están apropiadamente conectados dentro de la estructura. Este proceso ocurre hacia la parte inferior (hacia abajo) de la jerarquía de toda la base de datos. Propagando esta comprobación hacia abajo se puede verificar si una estructura de Diccionario de Datos está completa. Si la estructura no está completa, ese DDO no podrá borrar registros, puesto que no tiene los DDOs hijos para borrar en cascada los registros de las tablas hijos. La información de la “tabla hijo” también es utilizada por el Studio y por varios asistentes para ayudarle a construir sus aplicaciones. Por lo tanto es importante que esta información esté mantenida correctamente en su clase de Diccionario de Datos. Se añaden tablas a la lista de “tablas hijo” relacionadas con el mensaje Add_Client_File. Envíe este mensaje a cada una de las “tabla hijo”. Consulte lo siguiente Definir relaciones externas Padre-hijo de Diccionario de Datos. www.VisualDataflex.es Página 61 de 92 Guía de Diccionario de Datos Requisitos para grabar (save) El requisito de estructura de DDO para una grabación es simple. Para cada “tabla padre” definida en el DDO (con el método Add_Server_File) debe estar representado como un DDO en la estructura de objetos y deben estar conectados apropiadamente (con la propiedad DDO_Server). Los siguientes fragmentos de código muestran una clase de Diccionario de Datos y una estructura de DDO válida que admitiría grabaciones. Procedure Define_Fields Forward Send Define_Fields Set Main_File to Orderhea.File_Number : Send Add_Server_File Customer.File_Number Send Add_Server_File SalesP.File_Number Send Add_Client_File Orderdtl.File_Number End_Procedure : : Object oCustomer_DD is a Customer_DataDictionary End_Object // oCustomer_DD Object oSalesp_DD is a Salesp_DataDictionary End_Object // oSalesp_DD Object oOrderhea_DD is a Orderhea_DataDictionary Set DDO_Server to oCustomer_DD Set DDO_Server to oSalesp_DD End_Object // oOrderhea_DD Es un caso sencillo. Si cualquiera de los DDOs padre necesitase de padres”, sus DDOs también tendrían que estar presentes antes de permitir una grabación. Por ejemplo, suponga que el Diccionario de Datos del cliente haya sido definido de la siguiente manera: // Define_Fields in the customer DD class Procedure Define_Fields Forward Send Define_Fields set Main_File to Customer.File_Number : Send Add_Server_File Region.File_Number End_Procedure Ahora, la estructura del DDO de la lista de arriba ahora está incompleta. Está incompleta para Customer y por lo tanto está incompleta para OrderHea. No se admiten grabaciones en ninguno de los dos DDOs. Para que una estructura DDO sea válida necesitaría mostrarse así: www.VisualDataflex.es Página 62 de 92 Guía de Diccionario de Datos Object oRegion_DD is a Region_DataDictionary End_Object // oCustomer_DD Object oCustomer_DD is a Customer_DataDictionary Set DDO_Server to oRegion_DD End_Object // oCustomer_DD Object oSalesp_DD is a Salesp_DataDictionary End_Object // oSalesp_DD Object oOrderhea_DD is a Orderhea_DataDictionary Set DDO_Server to oCustomer_DD Set DDO_Server to oSalesp_DD End_Object // oOrderhea_DD Note que Add_Server_File se emplea para definir una “tabla padre” requerida dentro de un Diccionario de Datos y que esto ocurre en el nivel de clase. El uso de DDO_Server crea la conexión en el nivel de objeto. Add_Server_File define el requisito y DDO_Server lo cumple. Consulte lo siguiente Definir las relaciones externas Padre-hijo de Diccionario de Datos. Requisitos para eliminar El requisito de estructura de DDO para un borrado es algo más complicado. Debido a que los borrados pueden modificar los “registros padre”, la estructura “padre” del DDO debe estar completa. Si desea admitir borrados en cascada (el borrado de registros “hijo”) entonces la estructura de su DDO debe contener también todos los DDOs hijos requeridos para poder llevar a cabo el borrado en cascada. Por ejemplo: Procedure Define_Fields Forward Send Define_Fields Set Main_File to Orderhea.File_Number : Send Add_Server_File Customer.File_Number Send Add_Server_File Sales.File_Number Send Add_Client_File Orderdtl.File_Number End_Procedure : : Object oCustomer_DD is a Customer_DataDictionary End_Object // oCustomer_DD Object oSalesp_DD is a Salesp_DataDictionary End_Object // oSalesp_DD www.VisualDataflex.es Página 63 de 92 Guía de Diccionario de Datos Object oOrderhea_DD is a Orderhea_DataDictionary Set DDO_Server to oCustomer_DD Set DDO_Server to oSalesp_DD End_Object // oOrderhea_DD Object oOrderdtl_DD is a Orderdtl_DataDictionary Set DDO_Server to oOrderhea_DD End_Object // oOrderhea_DD Esta estructura de DDO ahora contiene los DDOs hijos requeridos y, por tanto, los borrados de los registros de OrderHea serán admitidos. Sin embargo estas estructuras, generalmente, no son tan simples. Si el DDO hijo (OrderDtl) contuviera “tablas padre” adicionales requeridas, entonces tienen que estar presentes esos DDOs hijos y sus respectivos DDOs padres. La estructura de DDO podría ser: Object oVendor_DD is a Vendor_DataDictionary End_Object // oVendor_DD Object oInvt_DD is a Invt_DataDictionary Set DDO_Server to oVendor_DD End_Object // oInvt_DD Object oCustomer_DD is a Customer_DataDictionary End_Object // oCustomer_DD Object oSalesp_DD is a Salesp_DataDictionary End_Object // oSalesp_DD Object oOrderhea_DD is a Orderhea_DataDictionary Set DDO_Server to oCustomer_DD Set DDO_Server to oSalesp_DD End_Object // oOrderhea_DD Object oOrderdtl_DD is a Orderdtl_DataDictionary Set DDO_Server to oOrderhea_DD Set DDO_Server to oInvt_DD End_Object // oOrderdtl_DD Consulte lo siguiente Definir relaciones externas Padre-hijo de Diccionario de Datos. www.VisualDataflex.es Página 64 de 92 Guía de Diccionario de Datos Cómo trabaja la estructura de validación DDO Cuando se produce una solicitud para grabar o borrar en un Diccionario de Datos, se valida su estructura de objeto y se asegura que todos los “padres” e “hijos” DDOs estén presentes y conectados de forma apropiada. Dependiendo del tipo de operación (“grabar”, “borrado sin cascada”, o “borrado con cascada”) se llevarán a cabo diferentes tipos de validaciones. Si la estructura de DDO en curso no está completa para la operación específica, se producirá un error y la operación se suspenderá. Verificar una estructura de DDO entera para una operación en particular puede ser un proceso complicado. Mientras se suministre a cada clase de Diccionario de Datos con una lista exacta de “tablas padre” y “tablas hijo” requeridas, este proceso se tratará automáticamente. Modo de validación Set Validate_Save_Structure_Mode to DD_VALIDATE_STRUCTURE_ONCE Set Validate_Delete_Structure_Mode to DD_VALIDATE_STRUCTURE_ONCE Hay propiedades que le permitirán modificar la forma validar la estructura de grabar y borrar. Puesto que dentro de una aplicación las estructuras de DDOs son generalmente estáticas, normalmente sólo se tiene que validar la estructura de grabación y borrado una vez. Esto se efectúa la primera vez que intenta grabar o borrar dentro de ese DDO. Éste es el valor por defecto. Dinámicamente tendrá que realizar esta validación cada vez que quiera ejecutar una validación o una grabación. Aunque esto es poco habitual, está soportado para que lo pueda hacer en los casos en que los necesite. También puede desactivar esta validación, pero siempre con precaución. Esto es un resumen de los modos de validación: DD_VALIDATE_STRUCTURE_ALWAYS El Diccionario de Datos verificará las estructuras de tabla cada vez que un registro se grabe / se borre. DD_VALIDATE_STRUCTURE_NEVER Se desactiva la validación estructuras de la “tabla padre”. DD_VALIDATE_STRUCTURE_ONCE El error. El Diccionario de Datos verificará las estructuras de tabla la primera vez que se intente grabar después de cargar la vista. Esto supone que la estructura no cambiará durante la sesión - normalmente una suposición segura. www.VisualDataflex.es de las Página 65 de 92 Guía de Diccionario de Datos Consulte lo siguiente Definir relaciones externas Padre-hijo de Diccionario de Datos. Sistema y tablas externas Send Add_System_File _Ordsys.File_Number DD_LOCK_ON_NEW_SAVE_DELETE Ciertas tablas deben conectarse a la estructura del servidor de datos para las cuales no hay razones para crear un objeto de Diccionario de Datos. Un ejemplo perfecto es una tabla de sistema que contiene un contador para propósitos de censo asignar claves de identificación únicas. Esas tablas deben ser registradas en el Diccionario de Datos como tablas externas. Cuando escriba el código en su Diccionario de Datos, que actualice una tabla no relacionada durante una transacción (Ej. Cuando el DDO está bloqueando tablas y registros), esta tabla se debe añadir a la lista de tablas externas de la clase de Diccionario de Datos. Esto levantaría los errores de cierre cuando su clave tratase de grabar una parada al archivo externo. Las tablas externas se declaran en las clases de Diccionario de Datos usando el mensaje Add_System_File. Si se usa una tabla externa, probablemente, se emplee dentro de uno o más de los siguientes eventos: Update, Backout, Creating, Deleting, Validate_Save y “Validate_Delete”. Si hace referencia a una tabla externa en estos eventos, necesita añadir esta tabla a la lista de tablas externas. Si usa el comando “Define_Auto_Increment” para definir un campo de Auto-Incremento y la tabla que suministra automáticamente ese Auto-Incremento es una tabla sistema, deberá añadirla a la lista de tablas externas. Send Add_System_File_ Ordsys.File_Number DD_LOCK_ON_NEW_SAVE_DELETE Define_Auto_Increment ordsys.last_cust_num to Customer.cust_number A menudo a las tablas de sistema no se les asigna un DDO sino que representan una excepción de la regla que dice que una subclase de Diccionario de Datos debe crearse y usarse para cada tabla en una aplicación. Puesto que las tablas de sistema contienen sólo un registro que puede ser usado por muchos usuarios, hay un parámetro que optimiza y determina cuándo debe bloquearse la tabla externa. Este parámetro tiene los siguientes valores: DD_Lock_On_All www.VisualDataflex.es Se bloquea borrados. en todas las grabaciones y Página 66 de 92 Guía de Diccionario de Datos DD_Lock_On_New_Save_Delete Se bloquea en las nuevas grabaciones y borrados. DD_Lock_On_Save Se bloquea en todas las grabaciones. DD_Lock_On_New_Save Se bloquea solamente en las grabaciones de nuevos registros. DD_Lock_On_Delete Se bloquea solamente en borrados. Para tablas de sistema que soporten números de serie de identificación únicos, DD_Lock_On_New_Save debe ser suficiente; para tablas de contadores secundarios que incrementan y disminuyen, se necesitarían los otros dos modos por lo que DD_Lock_On_All sería apropiado. Note que esta optimización de bloqueo solamente se aplica a la Base de Datos embebida de DataFlex. www.VisualDataflex.es Página 67 de 92 Guía de Diccionario de Datos Definir eventos Del Diccionario de Datos Parte del proceso de creación de Diccionario de Datos es definir los comportamientos personalizados de los eventos. Estos eventos permiten que personalice los procesos principales del Diccionario de Datos: Buscar (Find), Borrar (Clear), Guardar (Save) y Eliminar (Delete). Los eventos permiten que controle lo siguiente: • Llevar a cabo las validaciones y la comprobación de errores durante una grabación o un borrado. Si se genera un error, se cancela la grabación o borrado y se deshace cualquier cambio (Roll Back). • Use los eventos para mantener balances entre tablas relacionadas durante las grabaciones y borrados. • Use los eventos para definir y controlar las relaciones especiales entre tablas. • Use los eventos para llevar a cabo procesos especiales cuando se encuentren nuevos registros. Esto incluye poner valores por defecto para los nuevos registros. • Use eventos para llevar a cabo procesos especiales de grabación o borrado. Un evento puede ser usado por múltiples operaciones. Por ejemplo, el evento de “Backout” se convoca durante una grabación y un borrado. El evento de “Relate_Main_File” puede ser convocado por las grabaciones, borrados, búsquedas y limpiar (Clear). Algunos eventos se convocan siempre en un estado de bloqueo (Ej. “Update” y “Backout”) mientras que los demás eventos pueden (o no) ser convocados en un estado de bloqueo (Ej. Relate_Main_File). Los eventos predefinidos del Diccionario de Datos son: • Attach_Main_File • Backout • Clear_Main_File • Creating • Delete_Main_File • Deleting • Field_Defaults • OnNewCurrentRecord • Relate_Main_File • Save_Main_File • Update • Validate_Delete www.VisualDataflex.es Página 68 de 92 Guía de Diccionario de Datos • Validate_Save Forward sending mensajes de evento Antes de nada una consideración sobre lo que es “Forward send”. Traducido literalmente del inglés tendríamos algo similar a “enviar hacia adelante”. Debe enviar siempre los mensajes de evento. Aunque algunos de los eventos de Diccionario de Datos no se activan por defecto, otros eventos llevan a cabo tareas muy importantes y deben ser “Forward send”. A menos que quiera cancelar un comportamiento específico, es aconsejable que “Forward send” siempre sus eventos para aumentarlos (ampliar sus funcionalidades). Esto crea código robusto que trabajará la primera vez y que continuará trabajando cuando se hagan cambios. Así que mientras podríamos codificar un evento de la siguiente manera: // Incorrect Procedure Update Move (Customer.due + order.total) to Customer.due End_Procedure En vez de esto lo codificaremos con un “Forward send”: // correct Procedure Update Forward send Update Move (Customer.due + order.total) to Customer.due End_Procedure Eventos de campo definidos por el usuario Los Diccionarios de Datos permiten que defina eventos que deben ser llamados cuando un campo se valida o cuando se entra o sale de un formulario asociado a un campo determinado. Estos eventos se relacionan a campos que usan el “Field_Validate_msg”, “Field_Entry_msg” y “Field_Exit_msg” y se discuten en otros capítulos. En particular, los eventos de validación de campo pueden ser muy útiles. Consulte lo siguiente Definir clases de Diccionario de Datos. www.VisualDataflex.es Página 69 de 92 Guía de Diccionario de Datos Attach_Main_File Attach_Main_File lleva a cabo un attach. Se llama durante operaciones de grabación y borrado. Un “Attach” “mueve” los campos de datos relacionados de una “tabla padre” al DDO de una “tabla hija”. Esto asegura que los valores de relación entre tablas se mantengan actualizados correctamente. Note que este Attach solamente se aplica a los “DDOs padre” que están relacionados con este DDO. Si una “tabla padre” está relacionada con el de la tabla principal (Main Table) DDO pero no hay un padre DDO conectado al DDO, no ocurrirá ningún Attach. Puede usar este procedimiento parea crear Attaches adicionales, cancelándolos todos o creando unos propios. La siguiente muestra efectúa un Attach normal a no ser que uno de los Attach de campo se ignora. Procedure Attach_Main_File String sTempVal Move Vndr.Parent_Stat to sTempVal / / remember this value // El Attach normal hará un Attach de todas las “Tablas padre” // Incluyendo un Attach a Vndr.Parent_Stat. Queremos // ignorar este Attach Forward Send Attach_Main_File Move sTempVal to Vndr.Parent_State / / Deshaga este Attach End_Procedure Note que Attach_Main_File y Relate_Main_File no son verdaderos inversos entre ellos. Relate_Main_File no hace nada (la relación sucede como parte del “Find”). Attach_Main_File lleva a cabo el comando Attach. Si no hace un “Forward send” del mensaje, el Attach no ocurrirá. Cuando acceda a los valores de la tabla deberá acceder a al Buffer global de la tabla y no al Buffer local del DDO (es decir, use la sintaxis de “Move File.Field To Variable”). Para más información consulte “Comprendiendo Buffer de ficheros y Buffers de DDOs”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Backout y Update Los eventos de Update y Backout se usan para mantener balances de relación entre tablas. Update es llamado en las modificaciones y altas de registros, mientras que Backout es llamado en las modificaciones y borrados de registros. Update y Backout se emplean generalmente para ajustar las “tablas padre”. Backout, concretamente, se emplea para eliminar el efecto de una grabación mientras que la Update se usa para añadir el efecto de una grabación. www.VisualDataflex.es Página 70 de 92 Guía de Diccionario de Datos Los siguientes Update y Backout en un Diccionario de Datos ajustarían los totales de su padre, la tabla vndr. Procedure Update Forward Send Update Move (Checks.Total.+ Vndr.Total_Paid) to Vndr.Total_Paid End_Procedure Procedure Backout Forward Send Backout Move (Checks.Total- Vndr.Total_Paid) to Vndr.Total_Paid End_Procedure Cuando se graba un registro Nuevo (Alta) se llama Update (y no a Backout). Cuando se borra un registro (Elimina) se llama a Backout (y no a Update). Cuando se modifica un registro existente se llama a ambos (Update y Backout). La mayoría de las veces los contenidos de Update y Backout serán el inverso de sí mismos. Si no lo son, deberá revisar su lógica de forma cuidadosa. La mayoría de las veces lo que Update añada a un total, Backout se encargará de restarlo. Es posible que Backout y Update puedan ajustar totales de diferentes “tablas padre” durante una edición. Esto ocurriría si la edición causase que el “Registro padre” cambie. Los DDOs soportan esto. No asuma que los eventos de Update y Backout solamente se envían una vez durante una grabación. Si el “Registro padre” de un “Registro hijo” no se cambia, entonces Backout y Update se llaman una sola vez. En caso de que se cambie el “Registro padre” de un “Registro hijo”, entonces Backout y Update se llaman más de una vez. Por ejemplo: supongamos que nuestra tabla de clientes está relacionada con una tabla de zonas geográficas de forma que un cliente pertenece a una zona y una zona tiene múltiples clientes. En este caso, nuestra “tabla hijo” es la tabla de clientes y la “tabla padre” es la de zonas. Supongamos que en la tabla de zonas llevamos un total de ventas de cada zona que es la suma de las ventas de cada uno de los clientes de esa zona. Si a un cliente le cambiamos de zona (a un “Registro hijo” le cambiamos el padre) entonces Update y Backout se llaman más de una vez. El proceso de mantener integridad relacional cuando se cambia el registro padre de un hijo es bastante complejo y ambos eventos pueden ser llamados múltiples veces para la misma tabla (para diferentes registros). Si un cambio en un registro debe ajustar totales en un “Registro padre” y “abuelo” (Ejemplo: el importe de una línea ajusta los totales de la factura, y esta a su vez el crédito consumido del cliente), es mejor dejar que un Diccionario de Datos actúe sobre su padre(s) inmediato(s) (líneas sobre factura y factura sobre cliente). Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. www.VisualDataflex.es Página 71 de 92 Guía de Diccionario de Datos Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Clear_Main_File Clear_Main_File efectúa un clear sobre la tabla principal del Diccionarios de Datos. Normalmente, querrá realizar un “Forward send” de este mensaje y después cualquier tipo de aumento. Si desea que este evento limpie (clear) una tabla adicional debe contar el Diccionario de Datos sobre esto enviando el mensaje Request_Clear_File: Procedure Clear_Main_File Forward Send Clear_Main_File Clear AuxFile Send Request_Clear_File AuxFile.File_Number End_Procedure Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Creating (crear) Creating es llamado como parte del proceso de grabación y se llama cuando se va a grabar un nuevo registro. El comportamiento por defecto de este evento es para manejar “Autoincrementos” cuando este está definido en la clase con el comando “Define_Auto_Increment”. Por este motivo debe asegurarse reenviar el evento (Forward send) Este evento puede usarse para efectuar cualquier procesamiento adicional requerido para un nuevo registro. Procedure Creating Forward send Creating Send LogNewRecordData End_Procedure www.VisualDataflex.es Página 72 de 92 Guía de Diccionario de Datos Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Delete_Main_File El evento de Delete_Main_File efectúa el borrado (delete) del registro. Delete_Main_File está pensado para aumentarse Normalmente, querrá siempre reenviar (Forward send) este mensaje. Si no se reenvía no se borra el registro. Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos Deleting (borrar) Deleting se llama durante el proceso de borrado (delete). Se envía antes del mensaje de Backout. Procedure Deleting Forward send Deleting Send LogDeletedRecord End_Procedure Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. www.VisualDataflex.es Página 73 de 92 Guía de Diccionario de Datos Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Field_Defaults El evento de Field_Defaults sirve para soportar los ajustes de los valores por defecto después de un Clear. Puede fijar cualquier valor de campo, que se reflejará en los DEOs y será guardado con el registro nuevo. Puesto que el ajuste de los valores por defecto se codifican en un procedimiento, se pueden crear reglas complicadas. El ajuste de un valor por defecto no es reconocido como un cambio de datos por el Diccionario de Datos; por lo tanto, el ajuste de los valores por defecto no generará un mensaje de aviso de "pérdida de datos". Procedure Field_Defaults Forward Send Field_Defaults Set Field_Changed_Value field Customer.State to “FL” Set Field_Changed_Value field Customer.Discount to (Discount(self)) Set Field_Changed_Value field Customer.City to "Miami" End_Procedure Los valores por defecto también pueden fijarse a la entrada de un DEO creando un método Field Entry y poniéndolo con la propiedad de Field_Entry_msg. Ese método podría poner el valor por defecto usando el mensaje de Field_Default_Value. Consulte lo siguiente Definir eventos de Diccionario de Datos. On new current Record “On new current Record” puede considerarse como un evento Post-Find/Clear/Save/Delete, puesto que se llama después de cada Find, Clear, Save y Delete. Ocurre siempre que CurrentRowId cambie. www.VisualDataflex.es Página 74 de 92 Guía de Diccionario de Datos A “On new current Record” se pasan dos parámetros de RowId: el RowId del registro viejo y el RowId del registro nuevo. Observando estos dos parámetros, puede decir si el DDO ha encontrado un registro o si está creando uno nuevo (si el nuevo RowId es nulo). No puede usar este procedimiento para cambiar el RowId en curso ya que este mensaje se envía para notificar un cambio que va a ocurrir. No puede abortar el cambio. “On new current Record” se envía cuando el registro en curso está cambiando, con dos excepciones: si se inicia un DDO y el registro que está establecido es nulo, se llamará “On new current Record” (el registro antiguo = nuevo registro nulo= nulo). Después de una grabación, se llama a “On new current Record” de todos los DDOs que participaron en la grabación, incluso si el registro no cambió. Si lo necesita podrá comprobar esta condición con “Operation_Mode” y ver si es “Mode_Saving”. Procedure OnNewCurrentRecord RowId riOldRec RowId riNewRec Forward Send OnNewCurrentRecord riOldRec riNewRec // Asumiendo que deseamos atrapar grabaciones de registros nuevos If (Operation_Mode = Mode_Saving AND ; IsSameRowId (riOldRec, riNewRec)) Begin : End Else.... End_Procedure Notas especiales • Este mensaje debe ser reenviado (Forward Send). • Este evento no existe en la versión 10.1 de Visual DataFlex. En vez de dicha versión se emplea el New_Current_Record. A este evento se le pasan los números de registro (Integers) en lugar de RowIds. El evento de New_Current_Record todavía se convoca pero se considera obsoleto. “On new current Record” es su sustituido preferido. Consulte lo siguiente Definir eventos de Diccionario de Datos. Relate_Main_File Por defecto, Relate_Main_File no hace nada. Ocurre después de que el “Relate” normal se haya ejecutado. Es un evento que permite ejecutar relaciones personalizadas después de que su registro principal se haya encontrado y relacionado. Si va a encontrar registros nuevos en Relate_Main_File, debe notificar que el DDO ha encontrado este nuevo registro. Esto se hace enviando el mensaje de Request_Relate (si se encuentra el www.VisualDataflex.es Página 75 de 92 Guía de Diccionario de Datos registro) o Request_Clear_File (si el registro no se encontró). Request_Relate también ejecutará un Relate el registro recién encontrado. Esto es particularmente verdadero si el DDO está actualizando el “DDO padre” del registro que ha encontrado. El siguiente código que mostramos a continuación encuentra un “Registro padre” y notifica al DDO que lo ha encontrado. (Nota: esta es lo que habitualmente se llama “Sofi Find” y no debe confundirse con “Sofi Relate”) Procedure Relate_Main_File Boolean bMustFind Integer iFile iStatus Get Main_File to iFile Get_Attribute DF_FILE_STATUS of iFile to iStatus Forward Send Relate_Main_File If (iStatus = DF_FILE_INACTIVE) begin Move True to bMustFind end Else if (Vndr.Soft_id <>SoftFile.Soft_id) begin Move True to bMustFind end If bMustFind Begin / / Solamente relaciona SoftFile si es necesario Clear SoftFile Move Vndr.Soft_ID to SoftFile.Soft_Id Find eq.SoftFile.Soft_Id End Get_Attribute DF_FILE_STATUS of SoftFile.File_Number to iStatus If (iStatus<>DF_FILE_INACTIVE) begin Send Request_Relate SoftFile.File_Number End Else begin Send Request_Clear_File SoftFile.File_Number End End_Procedure Note la optimización de este procedimiento. La búsqueda en SoftFile se lleva a cabo sólo si: el Buffer de SoftFile está vacío o si el registro en el Buffer no es el que queremos (los valores relacionados no son los mismos). Se recomienda optimizar sus búsquedas dentro de Relate_Main_File. Debido a que los DDOs no pueden saber qué está haciendo este procedimiento, no hay, tampoco, ninguna manera de optimizar estas búsquedas. En el momento en que un DDO piense que la relación personalizada de un registro pudiese ser incorrecta, enviará Relate_Main_File. Esto sucede a menudo. Por eso es importante que optimice sus búsquedas (un proceso sencillo) para no ralentizar sus operaciones de base de datos. Preste atención pues Relate_Main_File no siempre encuentra registros que se relacionan con el registro actual. Cuando se cambia el “registro padre” de un “registro hijo”, Relate_Main_File se llamará durante el proceso de grabación para encontrar registros relacionados con el “padre www.VisualDataflex.es Página 76 de 92 Guía de Diccionario de Datos nuevo” y el “padre antiguo”. Debido a esto, CurrentRowId (o el obsoleto Current_Record) no debe usarse en los procedimientos de Relate_Main_File. Dentro de Relate_Main_File debe de hacerse referencia al valor real del Buffer del fichero o el RowId (usar la función de GetRowId) de la tabla. Se puede usar OnNewCurrentRecord para hacer el seguimiento de cambios en CurrentRowId. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Save_Main_File Save_Main_File sirve para grabar el fichero principal. Puede usar Save_Main_File para tablas adicionales no relacionadas o para procesar cambios adicionales en su tabla. Save_Main_File se llama para cada tabla que se graba en una operación del Diccionario de Datos. Este método puede llamarse incluso si no hay ningún cambio para grabar. En tal caso, la grabación física en la base de datos no ocurrirá aunque se llame el evento. En este ejemplo, queremos grabar la fecha y hora en cada registro grabado. Puesto que fijar la fecha y la hora en un campo puede causar que un registro no modificado se grabe, únicamente cambiaremos dicho valor si se modifica el registro. Si se modifica el Buffer del fichero, marcaremos el registro con la fecha y hora. Procedure Save_Main_File Boolean bChanged Interger iFile Get Main_File to iFile Get_Attribute DF_FILE_CHANGED of iFile to bChanged // Solamente marcamos el registro si este se ha modificado. Esto asume // que las funciones Crnt_Date y Crnt_Time ya existen. If (bChanged) Begin / / if record is changed at all Get Crnt_Date to Vndr.Date_Stamp Get Crnt_Time to Vndr.Time_Stamp End // now do the normal save behavior Forward Send Save_Main_File End_Procedure Normalmente, siempre haremos un Forward Send de este mensaje. Si el mensaje no se envía, la grabación no tendrá lugar. Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. www.VisualDataflex.es Página 77 de 92 Guía de Diccionario de Datos Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. Update y Backout Los eventos de Update y Backout se usan para mantener balances de relación entre tablas. Update es llamado en las modificaciones y altas de registros, mientras que Backout es llamado en las modificaciones y borrados de registros. Update y Backout se emplean generalmente para ajustar las “tablas padre”. Backout, concretamente, se emplea para eliminar el efecto de una grabación mientras que la Update se usa para añadir el efecto de una grabación. Los siguientes Update y Backout en un Diccionario de Datos ajustarían los totales de su padre, la tabla vndr. Procedure Update Forward Send Update Move (Checks.Total.+ Vndr.Total_Paid) to Vndr.Total_Paid End_Procedure Procedure Backout Forward Send Backout Move (Checks.Total- Vndr.Total_Paid) to Vndr.Total_Paid End_Procedure Cuando se graba un registro Nuevo (Alta) se llama Update (y no a Backout). Cuando se borra un registro (Elimina) se llama a Backout (y no a Update). Cuando se modifica un registro existente se llama a ambos (Update y Backout). La mayoría de las veces los contenidos de Update y Backout serán el inverso de sí mismos. Si no lo son, deberá revisar su lógica de forma cuidadosa. La mayoría de las veces lo que Update añada a un total, Backout se encargará de restarlo. Es posible que Backout y Update puedan ajustar totales de diferentes “tablas padre” durante una edición. Esto ocurriría si la edición causase que el “Registro padre” cambie. Los DDOs soportan esto. No asuma que los eventos de Update y Backout solamente se envían una vez durante una grabación. Si el “Registro padre” de un “Registro hijo” no se cambia, entonces Backout y Update se llaman una sola vez. En caso de que se cambie el “Registro padre” de un “Registro hijo”, entonces Backout y Update se llaman más de una vez. Por ejemplo: supongamos que nuestra tabla de clientes está relacionada con una tabla de zonas geográficas de forma que un cliente pertenece a una zona y una zona tiene múltiples clientes. En este caso, nuestra “tabla hijo” es la tabla de clientes y la “tabla padre” es la de zonas. Supongamos que en la tabla de zonas www.VisualDataflex.es Página 78 de 92 Guía de Diccionario de Datos llevamos un total de ventas de cada zona que es la suma de las ventas de cada uno de los clientes de esa zona. Si a un cliente le cambiamos de zona (a un “Registro hijo” le cambiamos el padre) entonces Update y Backout se llaman más de una vez. El proceso de mantener integridad relacional cuando se cambia el registro padre de un hijo es bastante complejo y ambos eventos pueden ser llamados múltiples veces para la misma tabla (para diferentes registros). Si un cambio en un registro debe ajustar totales en un “Registro padre” y “abuelo” (Ejemplo: el importe de una línea ajusta los totales de la factura, y esta a su vez el crédito consumido del cliente), es mejor dejar que un Diccionario de Datos actúe sobre su padre(s) inmediato(s) (líneas sobre factura y factura sobre cliente). Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos Validate_delete La función Validate_Delete se llama justo antes de que tenga lugar un borrado. Se bloquean todas las tablas que participan en el borrado. Si se genera un error o se devuelve un valor distinto de cero, se detiene el borrado. Una operación de borrado eliminará el registro de la tabla principal y todos los registros relacionados de las tablas descendientes (hijos, nietos, etc). Esto se hace para evitar registros huérfanos. Esta comprobación solamente ocurre si Cascade_Delete_State es verdadero y si hay una relación “padre- hijo” entre tablas y la estructura de DDO es correcta. El Validate_Delete solamente se envía al DDO de la tabla principal sobre la que se quiere efectuar el borrado. Si se aprueba el Validate_Delete, el registro de la tabla principal y todos sus “registros hijos” serán eliminados. Si está prohibiendo supresiones en cascada, es esencial que envíe (Forward Send) el mensaje Validate_Delete. La verificación del borrado en cascada sucede como parte de este envío (Forward Send): Function Validate_Delete returns Integer Integer iError Forward get Validate_Delete to iError If (not (iError)) Begin If (Customer.status = "A") Begin Error 306 “Cannot delete active record” End www.VisualDataflex.es Página 79 de 92 Guía de Diccionario de Datos End Function_Return iError End_Function Todas las tablas de los DDOs participantes se bloquean durante Validate_Delete. Por lo tanto, la función debe ser rápida y no debe requerir nunca una introducción de datos por parte del usuario. La excepción de esto es el comando de Error. Un error generado durante el Validate_Delete será diferido hasta que las operaciones de borrado hayan retrocedido (Roll Back) y las tablas hayan sido desbloqueadas. Un error en cualquiera de los eventos de borrado (Validate_Delete, Deleting, Backout, Delete_Main_File, etcétera.) indica un retroceso de la transacción (Transaction Roll Back). Éste es un proceso especial. Cuando esto ocurra el código pendiente de ejecutarse de la función no se procesará. Este mensaje se llama siempre en un estado de bloqueo. En este evento no pida ninguna introducción de datos al usuario. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos Validate_Save Validate_Save se usa como la validación final de un registro antes de grabarlo. Se envía a cada tabla en la estructura de DDO que participará en la grabación. Ocurre cuando la base de datos está bloqueada y todos los valores de campo han sido actualizados. Puede consultar directamente el valor de cualquier buffer de fichero.campo y si cualquier valor o combinación de valores son inválidos, puede detener la grabación declarando un error o devolviendo un valor distinto de cero. Los datos en el buffer del fichero son exactamente los que van a ser grabados. La excepción para esto es que los attach del buffer del fichero no han ocurrido todavía. Esto quiere decir que un buffer de una ”tabla hijo” podría no contener la información del padre para poner en el amortiguador de archivo durante el evento Attach_Main_File. El evento Attach_Main_File ocurre después de Validate_Save. Todas las tablas de los DDOs participantes se bloquean durante Validate_Save. Por lo tanto, la función debe ser rápida y no debe requerir nunca una introducción de datos por parte del usuario. La excepción de esto es el comando de Error. Un error generado durante el Validate_Save será diferido hasta que las operaciones de grabación hayan retrocedido (Roll Back) y las tablas hayan sido desbloqueadas. www.VisualDataflex.es Página 80 de 92 Guía de Diccionario de Datos Normalmente, un Validate_Save fallido generará un mensaje de error, como en el ejemplo de abajo. Function Validate_Save returns Integer integer iError If (Invt.Qtv < 0) Begin Error DFERR_OPERATOR "Insufficient Inventory on hand' End Forward get Validate_Save to iError Function_Return iError End_Function Un error en cualquiera de los eventos de grabación (Validate_Save, Update, Backout, Save_Main_File, etcétera.) indica un retroceso de la transacción (Transaction Roll Back). Éste es un proceso especial. Cuando esto ocurra el código pendiente de ejecutarse de la función no se procesará. Debido a que los buffers para todas las tablas que están participando han sido actualizados, no deberá buscar (find), limpiar (clear), borrar (delete) o modificar ningún buffer de fichero. Esto no debe de confundirse con la validación de campo (Field Validation). La validación de campo ocurre antes de que la base de datos se bloquee y antes de que los campos sean actualizados en el buffer del fichero. La validación de campo puede usarse para manejar la mayoría de las validaciones. Validate_Save se emplea, solamente, para manejar validaciones especiales que solamente puedan ser comprobadas en un estado de bloqueo y con datos actualizados. Este mensaje se convoca en un estado de bloqueo. No lleve a cabo ninguna actuación por parte del usuario en este evento. Si declara un error, la transacción se deshará (Roll back). Los errores deben generarse usando el comando de error. Para más información consulte “Manejo de error en las transacciones”. Cuando acceda a los valores de la tabla debe acceder al Buffer global y no al Buffer local de DDO (debe usar la sintaxis del tipo “Move File.File to Var). Para más información consulte “Comprendiendo Buffers globales y Buffers locales de DDO”. Consulte lo siguiente Definir eventos de Diccionario de Datos. www.VisualDataflex.es Página 81 de 92 Guía de Diccionario de Datos Restricciones y (constraints y filtros) filtros Una restricción (Constraint) es una limitación sobre los registros de una tabla que van a ser visibles para un componente del programa (ej: una vista, un objeto de Web, un informe…). Hay dos razones por las que podría querer limitar los registros en un DDO: • Cuando un DDO se relaciona con otro. Podría querer que el “DDO hijo” solamente mostrase los registros que se relacionan con el “DDO padre”. Esto se denomina restricción relacionada con “Relates-To Constraint”. • Una vista o un informe puede estar centrado en un subconjunto de registros. Podría especificar de qué clientes y de qué regiones se muestra la información. Esto se denomina “Filtros por restricción” (Filter Constraints). Consulte lo siguiente La restricción a la hora de desarrollar el proceso. Herencia de las restricciones. Optimización de la búsqueda de las restricciones. www.VisualDataflex.es Página 82 de 92 Guía de Diccionario de Datos Restricción relacionada con Relates To Constraints Set Constrain_File To Customer.File_Number Una relación con restricciones solamente se emplea cuando se quieren mostrar los “registros hijos” relacionados con un DDO de una “tabla padre”. El ejemplo clásico de una restricción relacionada lo podemos encontrar en el sistema “Order Entry” (ejemplo estándar de VDF) en donde en una rejilla se muestran los registros detalle (líneas de pedido) que pertenecen a un pedido (cabecera de pedido). Las restricciones relacionadas se definen usando la propiedad de Constrain_File en un “DDO hijo”. Esto se hace estáticamente en el nivel de objeto de DD. El siguiente ejemplo restringiría todos los registros de pedido a un registro de cliente: Object oCustomer_DD Is A Customer_DataDictionary End_Object / / oCustomer_DD Object oOrderHea_DD Is A OrderHea_DataDictionary Set DDO_Server To oCustomer_DD Set Constrain_File To Customer.File_Number End_Object / / oOrderHea_DD Los Diccionarios de Datos manejan las restricciones relacionadas de una manera muy especial. Cuando una restricción relacionada está activa, las reglas de propagación para Buscar (Find) y limpiar (Clear) son diferentes. Esto se comenta con detalle en “Propagación de DDO y restricciones relacionadas”. Se deben cubrir varios requisitos para que las restricciones relacionadas funcionen de forma apropiada: • Una relación debe estar definida entre la “tabla hijo” y la “tabla padre”. Dicha relación debe definirse dentro de Database Builder. Esto requiere que la ”tabla hijo” defina el campo o los campos que se relacionan con su correspondiente conjunto de campos en la “tabla padre”. • El valor del campo/campos con los que está relacionado en la “tabla padre” deben de ser únicos e identificar un registro. En definitiva, esos campos con los que está relacionado deben de formar un índice por sí mismos. • La “tabla hijo” deberá tener uno o más índices que permitan Búsquedas rápidas por los campos relacionados. Esto quiere decir que los primeros segmentos en esta “tabla hijo” deben contener los campos relacionados. • El “DDO hijo” debe de estar apropiadamente conectado con el “DDO padre”, poniendo la propiedad de DDO_Server en el hijo. Las reglas 1 y 2 son reglas estándar usadas para definir cualquier relación “padre-hijo” de forma correcta. La regla 3 hace posible que los DDOs encuentren, rápidamente, registros relacionados. www.VisualDataflex.es Página 83 de 92 Guía de Diccionario de Datos Permite que los DDOs salten a un índice para encontrar el primer registro (o el último) relacionado y saltando fuera del índice cuando se encuentra el último (o primero). Puede usar otros índices no optimizados para encontrar los “registros hijo” relacionados, pero esto no es aconsejable con tablas con un gran volumen de datos pues las prestaciones no serán satisfactorias. En nuestro ejemplo anterior, esto requeriría: • La tabla Order contiene un campo (OrderHea.Customer_number) que encaja con un campo similar en Customer (Customer.Customer_Number). • La relación para la tabla Order se define en el Database Builder. • La Tabla Customer contiene un índice basado en Customer.Customer_Number. • La tabla Order contiene al menos un índice cuyo primer segmento es OrderHea.Customer_Number (OrderHea.Customer_Number x OrderHea.Order_Number). • El Order DDO, oOrderHea_DD debe definir oCustomer_DD como un “DDO padre” y usar el mensaje set DDO_Server. Object oCustomer_DD Is A Customer_DataDictionary End_Object / / oCustomer_DD Object oOrderHea_DD Is A OrderHea_DataDictionary Set DDO_Server To oCustomer_DD Set Constrain_File To Customer.File_Number End_Object / / oOrderHea_DD Las restricciones relacionadas se puede aplicar en múltiples niveles. En el siguiente ejemplo, los pedidos (orders) son restringidas a clientes y los detalles del pedido (Order-Detail) restringidas al pedido. Object oCustomer_DD Is A Customer_DataDictionary End_Object / / oCustomer_DD Object oOrderHea_DD Is A OrderHea_DataDictionary Set DDO_Server To oCustomer_DD Set Constrain_File To Customer.File_Number End_Object / / oOrderHea_DD Object oOrderDtl_DD Is A OrderDtl_DataDictionary Set DDO_Server To oOrderHea_DD Set Constrain_File To OrderHea.File_Number End_Object / / oOrderDtl_DD Estas clases de restricciones se usan habitualmente en informes y en entrada de datos tipo cabecera-detalle. Por ejemplo, encontraría primero un cliente luego un pedido (que es el hijo del cliente), posteriormente encuentra los detalle del pedido que son “hijos” del pedido. www.VisualDataflex.es Página 84 de 92 Guía de Diccionario de Datos Los Diccionarios de Datos soportan “Relleno automático” (Auto-Fill) que pueden ser usados conjuntamente con restricciones relacionadas. Una Búsqueda en un Diccionario de Datos padre relacionado siempre, notifica este cambio al Diccionario de datos hijo relacionado. Debido a que el “DDO hijo” debe contener un registro limitado válido, si Auto_Fill_State es verdadero se podrá encontrar el primer registro legítimo. Este comportamiento de relleno automático (Auto-Fill) se usa de entrada de datos para rellener las parrillas de detalle (Detail Grids) Es una buena regla usar solamente las restricciones relacionadas estrictamente necesarias. Este tipo de restricción (constraint) no es necesario ni para las grabaciones (saves) ni para los borrados (deletes). Solamente se utiliza para buscar registros Consulte lo siguiente Restricciones y filtro. www.VisualDataflex.es Página 85 de 92 Guía de Diccionario de Datos Restricciones de filtro Las restricciones de filtro representan todas las restricciones no relacionadas y que sirven para filtrar los registros por cualquier conjunto de restricciones. Las restricciones de filtro se definen dentro de un DDOs en el método OnConstrain y son especificadas dentro de este método usando el comando de Constrain. Object oCustomer_DD Is A Customer_DataDictionary Procedure OnConstrain Constraint Customer.Status Eq "A" End_Procedure End_Object / / oCustomer_DD Las restricciones de filtro son aditivas. Si se definen múltiples restricciones dentro de un evento de OnConstrain, se deben cumplir todas las restricciones para encontrar un registro. Las restricciones de filtro también se añaden a restricciones relacionadas. En el siguiente ejemplo, solamente se encontrarán las órdenes si: se están relacionado con el cliente en curso, i el tipo de orden es N, y si la empresa de transporte es “FEDEX”: Object oCustomer_DD Is A Customer_DataDictionary End_Object / / oCustomer_DD Object oOrderHea_DD Is A OrderHea_DataDictionary Set DDO_Server To oCustomer_DD Set Constrain_File To Customer.File_Number Procedure OnConstrain Constrain OrderHea.Shipper eq "FEDEX" Constrain OrderHea.Type eq “N” End_Procedure End_Object / / oOrderHea_DD Las restricciones del “DDO padre” las heredan sus “DDOs hijos”. Puede que este comportamiento por defecto no sea siempre deseado y puede ser desactivado configurando la propiedad de pbInheritConstraints a falso. Tipos de restricciones de filtro El mandato de Constrain soporta dos tipos principales de restricciones de filtro: El archivo de filtro de campo (File.Field Filter) El archivo de filtro de campo se emplea para especificar que el valor de un campo de una tabla debe tener un valor específico. Tiene el formato general de: www.VisualDataflex.es Página 86 de 92 Guía de Diccionario de Datos Constrain {filename.fieldname} {mode} {value} Algunos ejemplos de filtros de campo son: Constrain OrderHea.Shipper eq "FEDEX" Get pbLowerDate to dLowerDate Constrain OrderHea.Date gt dLowerDate Get psStatusConstraint to sStat If (sStat<> "") Begin Constrain Customer.Status eq sStat End Los filtros de campo se crean y se evalúan cuando se crea una restricción y no cada vez que se encuentra un registro. Esto tiene ciertas ventajas. Debido a que el motor de restricción sabe qué campo está siendo filtrado y qué tipo de evaluación está siendo aplicada, es capaz de determinar si la restricción, teniendo en cuenta el índice usado para la búsqueda, puede ser optimizado. Si puede ser optimizado, la búsqueda del registro mucho más rápida. El filtro Constrain-As El filtro Constrain-As se emplea para especificar que el registro se ajuste a unos criterios definidos por una expresión. Tiene el formato general de: Constrain {filename} As ( expression) Algunos ejemplos del filtro Constrain-As son: Constrain Customer As (Uppercase(Customer.Name) Contains "DATA") Constrain Customer As ( (Customer.Name Contains "DATA") Or ; ( (Customer.Type = "COMPUTER") And ; (Customer.Area_Code Matches "3?5") )) Constrain Customer As (TestValidity(Self)) La expresión debe devolver un valor de verdadero o falso. Si es verdadero, el registro es válido y si no es filtrado. La restricción de expresión (Expresion Constraint) es la más flexible. Puede escribir cualquier expresión que desee, de cualquier nivel de complejidad. Generalmente, usará las expresiones de comparación con “And/Or”. También puede llamar a las funciones dentro de la expresión. Sin embargo, debido a su flexibilidad, esto es también el tipo de restricción más lento. La expresión se evalúa cada vez que se encuentra un registro. Además, debido a que el motor de restricción no tiene ni idea de qué está haciendo en realidad la expresión, una restricción de expresión no puede www.VisualDataflex.es Página 87 de 92 Guía de Diccionario de Datos ser optimizada (no puede saltar fuera de un índice). Por lo tanto puede ser muy lento en tablas grandes. Si un archivo de filtro de campo puede hacer el mismo trabajo, es preferible que lo use. El filtro Constrain-As puede usarse conjuntamente con otros filtros. Si los otros filtros son capaces de optimizar una búsqueda, el motor de restricción usará esas optimizaciones para llevar a cabo entrada y salida de índice. Esto puede reducir el número de registros que tienen que ser evaluados usando el filtro Constrain-As y pueden dar un rendimiento satisfactorio. Object oCustomer_DD Is A Customer_DataDictionary End_Object / / oCustomer_DD Object oOrderHea_DD Is AOrderHea_DataDictionary Set DDO_Server To oCustomer_DD Set Constrain_File To Customer.File_Number Procedure OnConstrain Constrain OrderHea.Type eq “N”" Constrain OrderHea (OrderHea.Shipper= "FEDEX" or OrderHea.Shipper=”UPS”) End_Procedure End_Object / / oOrderHea_DD Consulte lo siguiente Restricciones y filtros. El proceso de creación de las restricciones (Constraint) Generalmente, un conjunto de Constraint se crea una vez y se usa muchas veces. Normalmente, el proceso de creación ocurre automáticamente cuando se activa una vista o un informe. Este proceso de creación es automático y por lo general no necesitará preocuparse por él. Podría tener restricciones que cambian dependiendo de la introducción de datos u otras circunstancias. Por ejemplo, podría querer que algunos usuarios llenen la tabla de clientes con su país y luego restrinjan el DDO a ese país. Asegúrese de que este cambio de restricciones se refleje en los DDOs. Esta reconstrucción se hace enviando el mensaje Rebuild_Constraints a todos los DDOs que lo requieran. El método Rebuild_Constraints hace lo siguiente: • Borra las Restricción que estableció para el DDO que recibió el mensaje • Envía OnConstrain al DDO que recibe el mensaje y añade todos los comandos Constrain al conjunto de Restricciones. • Si se pone la propiedad de Constrain_File en el DDO, añade una Restricción Relates-To al conjunto de Restricciones. • Si los pbInheritConstraints del DDO son verdaderos, repite los pasos del 2 al 4 para todos los “DDO padre”. www.VisualDataflex.es Página 88 de 92 Guía de Diccionario de Datos Generalmente, después de cambiar una restricción puede descubrir que su registro en curso no cumple con las Restricciones que acaba de aplicar. Debido a esto, necesitará encontrar un nuevo primer registro después de reconstruir una restricción. En el siguiente ejemplo, un DEO envía un mensaje a su DDO para pasar dos parámetros, el nuevo valor de restricción y el índice a utilizar para encontrar un nuevo primer registro: Object Customer_DD is a Customer_DataDictionary Property String psStatusConstraint Procedure ConstraintByStatus string sStar integer iIndex Set psStatusConstraint to sStat Send Rebuild_Constraints Send Find FIRST_RECORD iIndex End_Procedure Procedure OnConstrain Sting sStat Get psStatusConstraint to sStat If (sStat<> "") Begin Constrain Customer.status eq sStat end End_Procedure End_Object Consulte lo siguiente Restricciones y filtros. Herencia de las restricciones Normalmente un DDO heredará las restricciones de su “DDO padre”. Una restricción se forma o se reconstruye cuando el mensaje Rebuild_Constraints se envía a un DDO. Rebuild_Constraints crea una restricción de expresión interna que contiene todas las reglas para filtrar el DDO. Bajo circunstancias normales Rebuild_Constraints hace lo siguiente: • Limpia las restricciones en curso para el DDO. • Envía el mensaje Constrain al DDO lo que dispara el evento OnConstrain. • Ejecuta todos los comandos de Restricción Constrain/Constraint dentro del evento de OnConstrain. Cada restricción (constraint) se añade a la expresión de restricción (constraint) interna del DDO. • Después de enviar OnConstrain, hay que verificar si la propiedad de Constrain_File es distinta de cero. Si esto es así se crea una restricción relacionada (Relates-To Constraint). • Este proceso (pasos del 2 al 4) se repite del DDO a la tabla para cada “DDO padre” y esto se repite para cada padre en la estructura de DDO. www.VisualDataflex.es Página 89 de 92 Guía de Diccionario de Datos Una vez finalizado el DDO contiene una expresión de Restricciones que consiste en todas las restricciones (Constraint) definidas en el DDO principal y de todas las restricciones definidas en todos los “DDOs padre”. El DDO principal hereda todas las restricciones de todos sus padres, abuelos… Cuando se encuentra un registro y se relacionan los padres, entonces se ejecuta la expresión de restricción contra estos registros. Si falla cualquier restricción, incluyendo las “restricciones padre”, el registro se considera no válido. Por lo tanto, si se encuentra un registro principal y uno de sus “registros padre” contiene una restricción no válida, ese registro principal se considera no válido. La mayor parte de las veces este método funciona. Hay veces que la herencia de las restricciones puede interferir en el proceso. Considere una entrada de pedidos en el sistema. En el típico sistema, su registro de detalle se relaciona con una cabecera de orden y una “tabla padre” de artículos. Asumiendo que quiere limitar los registros de existencias a artículos que están activos (Ej. Constrain Invt.Status eq "A"), esto es perfectamente válido para nuevos pedidos. Sin embargo, si carga un pedido antiguo que contiene artículos, esos artículos no saldrían en su lista de líneas de pedido, lo que podría ser confuso. En tal caso, puede ordenar a los DDOs para que no hereden las restricciones configurando la propiedad de pbInheritConstraints. Cuando esto ocurra, todas sus líneas del pedido se mostrarán (porque la “restricción padre” no se usa). Sin embargo, si tratara de seleccionar un nuevo registro de artículo, la restricción de artículos se cumpliría (porque la restricción una búsqueda de artículos se ejecuta por el DDO de existencias.) Por ejemplo, considere que una estructura de DDO de pedido contiene una restricción en el DDO de artículos que sirve para filtrar todos los registros bajo cierto precio. Cuando seleccione los registros de Invt filtrará solamente aquellos que puedan ser escogidos. En el DDO de detalle del pedido (Líneas de pedido), las restricciones no se heredan. Por lo tanto los pedidos se mostrarán correctamente con todos los registros de detalle incluso si el detalle apunta a un artículo (Invt) no válido (se asume que era válido cuando se creó el pedido). Object oVendor_DD is a Vendor_DataDictionary End_Object // oVendor_DD Object oInvt_DD is a Invt_DataDictionary Set DDO_Server to oVendor_DD Procedure OnConstrain Constrain invt.Unit_price gt 100 End_Procedure End_Object // oInvt_DD Object oCustomer_DD is a Customer_DataDictionary End_Object // oCustomer_DD Object oSalesp_DD is a Salesp_DataDictionary End_Object // oSalesp_DD Object oOrderhea_DD is a Orderhea_DataDictionary Set DDO_Server to oCustomer_DD Set DDO_Server to oSalesp_DD End_Object // oOrderhea_DD Object oOrderdtl_DD is a Orderdtl_DataDictionary www.VisualDataflex.es Página 90 de 92 Guía de Diccionario de Datos Set DDO_Server to oOrderhea_DD Set DDO_Server to oInvt_DD Set Constrain_File to Orderhea.File_Number // Constraints from parent (like Invt) will not be applied Set pbInheritConstraints to false End_Object // oOrderdtl_DD Set Main_DD to oOrderhea_DD Set Server to oOrderhea_DD Poner restricciones “padre” en un “DDO hijo” Si decide heredar las restricciones, también puede poner “restricciones padre” dentro de un “DDO hijo”. Deberá usar el Filtro Constrain-As como filtro para hacerlo. Por ejemplo, su DDO de detalle del pedido podría contener lo siguiente: Set pbInheritConstraints to False Procedure OnConstrain // La tabla del Constrain DEBE de ser el nombre del DDO de la tabla principal // pero la expresión puede referirse a un DDO padre Constrain OrderDtl AS (Invt.Active="A") End Algunos desarrolladores prefieren usar esta técnica porque guarda todas las restricciones para un DDO en un único sitio (Ej. No tiene que buscar en el “DDO padre” para filtros adicionales). Consulte lo siguiente Restricciones y filtros Optimización de búsquedas de restricción Si el DDO tuviera que recorrer toda la base de datos para cada búsqueda, los usuarios podrían esperar mucho tiempo para localizar un registro o conjunto de registros. El DDO intentará optimizar la búsqueda usando el índice que haya indicado y entrando directamente a esta “parte” del índice. Siempre que se ejecute una búsqueda, las restricciones son evaluadas con el índice en uso para ver si se puede hacer cualquier optimización. Este proceso es automático y no tiene que programar nada. Sin embargo, si el índice en curso no puede ayudar en la búsqueda, el DDO podría tener que recorrer toda la tabla. Si la tabla tiene muchos registros, esto podría ser lento. Debería comprobar siempre que las búsquedas están optimizadas adecuadamente para el índice que está usando (o por lo menos debería saber que las búsquedas no están optimizadas). Las técnicas para probar esto se comentan en “Depurando DDOs”. www.VisualDataflex.es Página 91 de 92 Guía de Diccionario de Datos La propiedad de ordenación Set Ordering to 3 Cuando use restricciones y filtros, a menudo solamente será óptimo un índice. Cuando esto suceda, asegúrese de que esté usando ese índice. Puede forzar el DDO para que use siempre un índice concreto. Haga esto poniendo la propiedad de ordenación del DDOs a este número de índice. Normalmente, el valor de esta propiedad es - 1, lo que permite que use cualquier índice solicitado por el mensaje de búsqueda. Object oOrderHea_DD is an OrderHea_DataDictionary End_Object Object oOrderDtl_DD is an OrderDtl_DataDictionary Set DDO_Server to oOrderHea_DD Set Constrain_File to oOrderHea.File_Number Set Ordering to 1 // este es el único índece que puede ser optimizado End_Object Consulte lo siguiente Restricciones y filtros. www.VisualDataflex.es Página 92 de 92