Sunteți pe pagina 1din 425

Curso GeneXus 9.

0
Diciembre de 2006

MONTEVIDEO URUGUAY CHICAGO USA MEXICO CITY MEXICO SAO PAULO BRAZIL

Av. 18 de Julio 1645 P.4 +598 2 402-2082 400 N. Michigan Ave. Suite 1600 +(312) 836-9152 Calle Leibnitz N 20, desp. 801 +52 55 5255-4733 Rua Samuel Morse 120 Conj. 141 +55 11 5502 6722

Copyright ARTech Consultores S. R. L. 1988-2006. Todos los derechos reservados. Este documento no puede ser reproducido de ninguna forma sin el consentimiento expreso de ARTech Consultores S.R.L. La informacin contenida en este documento es para uso personal del lector. MARCAS REGISTRADAS ARTech y GeneXus son marcas registradas de ARTech Consultores S.R.L. Todas las otras marcas mencionadas en este documento son propiedad de sus respetivos titulares.

Contenido
Introduccin terica ........................................................................................................ 1 Objeto transaccin........................................................................................................ 31 Nomenclatura GIK ............................................................................................ ...45 Tipos de datos..................................................................................................... 51 Dominios ............................................................................................................ 55 Anlisis de impacto, reorganizar, especificar, generar............................................... 64 Modos en ejecucin.............................................................................................. 72 Integridad referencial ........................................................................................... 73 ndices ............................................................................................................... 76 Manejo de nulos ................................................................................................. 81 Tabla base y tabla extendida ................................................................................ 85 Descripciones en vez de cdigos ........................................................................... 89 Reglas ................................................................................................................ 94 Tipos de dilogo ................................................................................................ 106 Atributos frmula ....................................................................................................... 115 Frmulas horizontales ....................................................................................... 120 Frmulas verticales ........................................................................................... 123 Comunicacin entre objetos ......................................................................................... 130 Orden de ejecucin de reglas y frmulas ....................................................................... 139 Eventos de disparo ........................................................................................... 145 Orden de ejecucin .................................................................................... 151, 152 Eventos en transacciones ................................................................................... 160 Integridad transaccional .............................................................................................. 169 Objetos reporte y procedimiento .................................................................................. 181 Objeto web panel ....................................................................................................... 252 Patterns .................................................................................................................... 312 Subtipos.................................................................................................................... 335 Structured Data Types (SDTs)...................................................................................... 359 Business Components ................................................................................................. 379 Knowledge Manager.................................................................................................... 391 Puesta en produccin .................................................................................................. 396 Introduccin a metodologa GeneXus ............................................................................ 400

Nota al estudiante
Con el objetivo de brindar a los desarrolladores GeneXus una fuente nica de informacin potenciada con una ingeniera de bsqueda que les permita acceder rpida y fcilmente a la informacin tcnica (release notes, manuales, tips, whitepapers, etc.) sobre los diferentes productos que desarrolla ARTech, se cre la GXDL (GeneXus Developer Library), una biblioteca que centraliza toda esta informacin tcnica. Puede ser consultada online o puede ser utilizada en forma local mediante una sencilla instalacin: http://www.gxtechnical.com/gxdl. Por sugerencias o comentarios cursogenexus@artech.com.uy. acerca de la presente edicin, escrbanos a la direccin

Departamento de Capacitacin ARTech

INTRODUCCIN TERICA

Herramientas y Metodologas
REALIDAD

BASE DE DATOS

PROGRAMAS

Nuestra tarea como profesionales de la informtica consiste en desarrollar y mantener aplicaciones para apoyar al usuario en su actividad. Para realizar esta tarea existen diferentes herramientas y metodologas. GeneXus es una herramienta para el desarrollo de aplicaciones sobre bases de datos. Su objetivo es permitir la implantacin de aplicaciones en el menor tiempo y con la mejor calidad posible. A grandes rasgos, el desarrollo de una aplicacin implica tareas de anlisis, diseo e implementacin. La va de GeneXus para alcanzar el objetivo anterior es liberar a las personas de las tareas automatizables (como el diseo de la base de datos), permitindoles as concentrarse en las tareas realmente difciles y no automatizables (como comprender los problemas del usuario). GeneXus emplea una metodologa que tiene un enfoque muy diferente al de las metodologas ms comnmente utilizadas. Por tanto, aprender a utilizar GeneXus adecuadamente va ms all de conocer un nuevo lenguaje: lo ms importante es aprender su metodologa.

Modelado de la realidad a partir de las visiones de los usuarios


MODELO DE LA REALIDAD

Satisface Ingeniera Inversa

BASE DE DATOS

PROGRAMAS

VISIONES DE USUARIOS

El primer problema al que nos enfrentamos en el desarrollo de aplicaciones es la obtencin del conocimiento de la realidad. Nadie dentro de la empresa conoce los requerimientos y el alcance de la aplicacin a desarrollar como un todo. Entonces, cmo logramos obtener el conocimiento de la realidad de una forma lo suficientemente objetiva y detallada al mismo tiempo, que nos permita construir un modelo corporativo? Este conocimiento se encuentra en cada una de las visiones de los usuarios. Cada usuario conoce bien los objetos con los que trabaja cotidianamente, la informacin que se maneja en ellos, las reglas que deben seguirse, los clculos que deben realizarse. Por lo tanto, el punto de partida de la metodologa GeneXus es: describir las visiones de los usuarios para modelar el sistema; y a partir del modelo de la realidad definido, GeneXus construye el soporte computacional -base de datos y programas- en forma totalmente automtica.

Comparacin de Metodologas

Para fijar ideas, comparemos las metodologas tradicionales ms utilizadas actualmente, con la metodologa utilizada por GeneXus, conocida como metodologa incremental. Las metodologas tradicionales difieren entre s en varios aspectos, pero tienen una caracterstica en comn: separan el anlisis de los datos del de los procesos. A continuacin veremos un esquema general que podra aplicarse a cualquiera de las metodologas tradicionales actuales y estudiaremos sus problemas.

Metodologa Tradicional

ANLISIS DE DATOS

REALIDAD

MODELO DE DATOS

BASE DE DATOS GENERACIN/ INTERPRETACIN

ANLISIS FUNCIONAL ESPECIFICACIN FUNCIONAL

PROGRAMAS PROGRAMACIN

La primera tarea que se realiza generalmente es el Anlisis de Datos, donde se estudia la realidad en forma abstracta, identificando los objetos existentes y sus relaciones y se obtiene como resultado un Modelo de Datos con las entidades y relaciones encontradas (Modelo ER). Es fcil ver que existe una correspondencia muy simple entre el modelo de datos y la base de datos necesaria para soportarlo. La siguiente tarea entonces, es disear esa base de datos, partiendo del modelo de datos. Construir un sistema integrado, requiere de un modelo de datos corporativo, y dependiendo del tamao de la empresa, sta puede resultar una tarea de enorme complejidad. Cuando esto ocurre, la complejidad suele atacarse dividiendo el sistema en mdulos (divide and conquer), cada uno de los cuales soluciona los problemas operativos de un rea especfica de la empresa. De esta forma la tarea de modelado se simplifica notablemente, pero como contrapartida los mdulos operan sin una real integracin, lo que provoca que exista informacin redundante, con todos los problemas que ello acarrea. En caso de que luego se intente realizar la integracin de esos mdulos, habr que realizar modificaciones sobre los modelos de datos, lo que a pesar de su complejidad es una tarea realizable. Sin embargo las modificaciones que debern efectuarse sobre los programas asociados tienen un costo tan elevado que suelen tornar inviable la integracin. Con la divisin del sistema en mdulos la empresa tendr resueltos sus problemas operativos, pero aparecern indefectiblemente problemas de carencia de informacin que permita orientar la gestin y la toma de decisiones de alto nivel. En la rbita gerencial la informacin que se necesita es principalmente de naturaleza corporativa, por lo que la divisin del sistema en mdulos no satisface las necesidades actuales de obtencin de informacin. GeneXus soluciona este problema, brindando herramientas y una metodologa que hacen posible y sencilla la creacin y mantenimiento de sistemas corporativos.

Una vez obtenido el modelo de datos, el siguiente paso de una metodologa tradicional es disear la base de datos. Existe una transformacin trivial entre un buen modelo de datos y el diseo de la base de datos necesaria para soportarlo. Sin embargo, el modelo de datos no es suficiente para desarrollar los programas de aplicacin, ya que el mismo describe los datos, pero no los comportamientos. Se recurre, entonces, a una tarea llamada Anlisis Funcional, donde se estudia la empresa desde el punto de vista de las funciones existentes, y el resultado de dicha tarea es una Especificacin Funcional. Sera deseable que la especificacin funcional fuera independiente de la especificacin de datos, lo que no ocurre en las metodologas estudiadas. Las modificaciones en el diseo de la base de datos implican la necesidad de revisar las especificaciones funcionales, siendo esta la causa fundamental de los grandes costos de mantenimiento que tienen estos sistemas. Una vez que se cuenta con la base de datos y la especificacin funcional, ya estn dadas las condiciones para crear los programas de la aplicacin. Para ello se cuenta hoy en da con varias alternativas: Programacin en lenguajes de tercera y cuarta generacin (L3G, L4G) Generacin/Interpretacin Desde un punto de vista conceptual no hay diferencia entre la programacin en lenguajes de 3ra. y de 4ta. generacin. En ambos casos el analista debe estudiar el problema, transformarlo en un algoritmo y codificarlo en el lenguaje de programacin elegido. La principal diferencia radica en que en los lenguajes de 4ta. generacin se escribe mucho menos cdigo (aproximadamente 10 veces menos) y, como consecuencia, la productividad es mucho mayor y el nmero de errores cometidos es mucho menor. El problema de que las descripciones de los procesos dependen de la base de datos afecta a ambos por igual, por lo que se concluye que los lenguajes de 4ta. generacin permiten aumentos de productividad muy grandes sobre los de 3ra. en la tarea de desarrollo, pero no ayudan en la etapa de mantenimiento. Otra alternativa es la utilizacin de un generador: una herramienta que puede interpretar una especificacin funcional y producir automticamente los programas. Aqu existe una diferencia conceptual importante con el caso anterior. En este caso el analista describe el problema de una forma declarativa (no existe algoritmo ni codificacin procedural alguna). Por ello la especificacin funcional debe ser formal y rigurosa. Existen actualmente en el mercado varias herramientas de esta clase. Existe asimismo otra categora de herramientas conceptualmente idntica: la de aquellas que simplemente interpretan la especificacin. La programacin en ambos casos es totalmente automtica, por lo que el aumento de productividad sobre las herramientas de 3ra. y 4ta. generacin es muy grande. El problema visto -las descripciones de los procesos dependen de la base de datos- afecta tambin a las aplicaciones generadas mediante estas herramientas. Como consecuencia, los Generadores e Intrpretes (como los lenguajes de 4ta. generacin) no ayudan lo suficiente en la tarea de mantenimiento. En definitiva, desde el punto de vista del mantenimiento ninguna de las herramientas ayuda mucho, dado que en todas ellas se utilizan descripciones de procesos que pueden perder su validez cuando existen modificaciones de archivos y que, por ello, deben ser revisadas y mantenidas manualmente. El costo de mantenimiento, claro est, difiere enormemente entre las distintas alternativas vistas, ya que en el caso de la utilizacin de Generadores o Intrpretes, una vez modificadas las especificaciones funcionales la generacin de los programas es automtica. Si el siguiente postulado: puede obtenerse una base de datos estable fuera verdadero, los problemas anteriores seran irrelevantes. Sin embargo, sobran contraejemplos que hablan de lo contrario. Conclusiones: No es posible hacer de forma abstracta un modelo de datos detallado de la empresa y con el suficiente nivel de detalle y objetividad porque nadie la conoce como un todo. Por el contrario, es necesario recurrir a mltiples interlocutores, cada uno de los cuales aporta su propia subjetividad. Como consecuencia, durante todo el ciclo de vida de la aplicacin se producen cambios en el modelo.

Aun si se considerara la situacin ideal, en la cul se conocen exactamente las necesidades y por tanto es posible definir la base de datos ptima, el modelo, de todas formas, no podr permanecer esttico, ya que debe acompaar la evolucin de la empresa. Todo esto sera poco importante si la especificacin funcional y la base de datos fueran independientes. Sin embargo, dado que la especificacin funcional se refiere a la base de datos, las inevitables modificaciones en esta ltima, implican modificaciones (manuales) en la primera. Las principales consecuencias de lo anterior son los altos costos de mantenimiento: en la mayora de las empresas que trabajan de una manera convencional se admite que el 80% de los recursos que tericamente estn destinados al desarrollo, realmente se utilizan para hacer mantenimiento de las aplicaciones ya implementadas. Dado que es muy difcil en este contexto determinar y propagar las consecuencias de los cambios de la base de datos sobre los procesos, es habitual que en vez de efectuarse los cambios necesarios, se opte por introducir nuevos archivos redundantes con la consiguiente degradacin de la calidad de los sistemas y el incremento de los costos de mantenimiento.

Metodologa GeneXus

Los fundadores de ARTech han desarrollado una amplia actividad de consultora internacional en diseo de grandes bases de datos, trabajando con verdaderos modelos corporativos con cientos de tablas. En su trayectoria, se convencieron de que no deba perderse ms tiempo buscando algo que no existe: las bases de datos estables. Luego de importantes investigaciones, desarrollaron una teora, organizaron una metodologa e implementaron una herramienta para posibilitar el desarrollo incremental y permitir la convivencia con las bases de datos reales inestables- a un costo mnimo.

Desarrollo con GeneXus

REALIDAD
DESCRIPCIN DE OBJETOS

Utilizando GeneXus, la tarea bsica del analista es la descripcin de la realidad. Slo el ser humano puede desarrollar esta tarea ya que slo l puede entender el problema del usuario. El analista GeneXus trabaja en alto nivel, en vez de realizar tareas de bajo nivel como: disear archivos, normalizar, disear programas, programar, buscar y eliminar los errores de los programas. Para comenzar el desarrollo de una aplicacin con GeneXus, el primer paso consiste en crear un nuevo proyecto o base de conocimiento. Una vez creada una nueva base de conocimiento (en ingls: knowledge base; abreviado: KB), el siguiente paso es describir las visiones de los usuarios. Para ello se deben identificar los objetos de la realidad (prestando atencin a los sustantivos que los usuarios mencionan en sus descripciones, como por ejemplo: clientes, productos, facturas) y pasar a definirlos mediante objetos GeneXus. Con la definicin de estos objetos, GeneXus puede extraer el conocimiento y disear la base de datos y los programas de la aplicacin en forma automtica.

10

Desarrollo con GeneXus

REALIDAD

DESCRIPCIN DE OBJETOS

BASE DE DATOS

BASE DE CONOCIMIENTO

PROGRAMAS

A partir de los objetos definidos en la base de conocimiento, GeneXus genera automticamente tanto los programas de creacin / reorganizacin de la base de datos como los programas de la aplicacin. Luego, si un objeto de la realidad cambia, si se identifican nuevas o diferentes caractersticas del mismo, o si se encuentran objetos an no modelados, el analista GeneXus debe reflejar dichos cambios en los objetos GeneXus que correspondan, y la herramienta se encargar automticamente de realizar las modificaciones necesarias tanto en la base de datos como en los programas asociados. La metodologa GeneXus es una metodologa incremental, pues parte de la base de que la construccin de un sistema se realiza mediante aproximaciones sucesivas. En cada momento el analista GeneXus define el conocimiento que tiene y luego cuando pasa a tener ms conocimiento (o simplemente diferente) lo refleja en la base de conocimiento y GeneXus se ocupar de hacer automticamente todas las adaptaciones en la base de datos y programas. Si GeneXus no fuera capaz de realizar automticamente las modificaciones en la base de datos y programas conforme se realicen cambios que as lo requieran, el desarrollo incremental sera inviable.

11

Comparacin de Metodologas
ANLISIS DE DATOS

REALIDAD
DESCRIPCIN DE OBJETOS

MODELO DE DATOS

BASE DE DATOS GENERACIN/ INTERPRETACIN ANLISIS FUNCIONAL

BASE DE CONOCIMIENTO

ESPECIFICACIN FUNCIONAL

PROGRAMACIN

PROGRAMAS

Como se ha visto, existen varios caminos para la implementacin de aplicaciones: 1. Programacin utilizando lenguajes de 3era. generacin. 2. Programacin utilizando lenguajes de 4ta. generacin 3. Generacin / interpretacin automtica de la especificacin funcional. 4. Desarrollo incremental. La productividad en el desarrollo de aplicaciones aumenta de arriba a abajo. Disminuir en gran forma el mantenimiento de las aplicaciones (datos y programas), slo se consigue con el desarrollo incremental.

12

Objetos GeneXus (ms importantes)


Transacciones (Trns) Reportes (Rpts) Procedimientos (Procs) Work Panels (Wkps) Web Panels (Wbps)

y hay ms, que veremos...

Una vez creada una base de conocimiento, el siguiente paso consiste en comenzar a describir los objetos de la realidad mediante objetos GeneXus. Los objetos GeneXus ms importantes son: Transacciones Permiten definir los objetos de la realidad que el usuario manipula (ej: clientes, productos, proveedores, facturas, etc.). Son los primeros objetos en definirse, ya que a travs de las transacciones, GeneXus infiere el diseo de la base de datos. Adems de tener por objetivo la definicin de la realidad y la consecuente creacin de la base de datos normalizada, cada transaccin tiene asociada una pantalla para ambiente windows y otra para ambiente Web, para permitir al usuario dar altas, bajas y modificaciones en forma interactiva a la base de datos. El analista GeneXus decidir si trabajar en ambiente windows, Web, o ambos, y GeneXus generar los programas para ello. Reportes Permiten recuperar informacin de la base de datos, y desplegarla ya sea en la pantalla, en un archivo o impresa en papel. Son los tpicos listados o informes. No permiten actualizar la informacin de la base de datos1. Procedimientos Tienen las mismas caractersticas que los reportes, pero a diferencia de stos, permiten adems la actualizacin de la informacin de la base de datos. Work Panels Permiten al usuario realizar interactivamente consultas a la base de datos, a travs de una pantalla. Ejemplo: un work panel permite al usuario ingresar un rango de caracteres, y muestra a continuacin todos los clientes cuyos nombres se encuentran dentro del rango. Son objetos muy flexibles que se utilizan exclusivamente en ambiente windows y se prestan para mltiples usos. No permiten la actualizacin de la base de datos, sino solo su consulta1. -----------------------------------------------------------------------------------------------------1 No es inherente a este tipo de objetos la modificacin de la base de datos, pero como veremos ms adelante, existen unos componentes llamados business components que lo harn posible, rompiendo con su naturaleza de solo consulta.

13

Web Panels Son similares a los work panels, salvo que son usados a travs de browsers en ambiente Internet/Intranet/Extranet. Existen algunos tipos ms de objetos GeneXus, algunos de los cuales veremos en este curso, como los Subtype Groups y los Structured Data Types, que si bien son objetos que se definen en la base de conocimiento (KB) mediante el mismo procedimiento que los ya mencionados, tienen algunas caractersticas que los diferencian de la mayora de ellos, como el hecho de no generar programas propios, sino que su conocimiento es reutilizado dentro de los otros objetos.

14

Proceso de desarrollo de una aplicacin con GeneXus


Transacciones (Trns) Reportes (Rpts) Procedimientos (Procs) Work Panels (Wkps) Web Panels (Wbps)

Base de Conocimiento Base de Conocimiento

Base de Datos

Los primeros objetos que se definen son las transacciones, ya que es a partir de ellas que GeneXus extrae el conocimiento necesario para disear el modelo de datos normalizado (en 3era. forma normal). Luego se van definiendo los dems objetos que correspondan.

15

Creacin de la Base de Datos


Transacciones (Trns) Reportes (Rpts) Procedimientos (Procs) Work Panels (Wkps) Web Panels (Wbps)

Base de Conocimiento Base de Conocimiento

Base de Datos

Programas Creacin BD

GeneXus genera automticamente los programas necesarios para crear la base de datos y los ejecuta. De esta manera obtenemos la base de datos creada por GeneXus en forma automtica.

16

Generacin de los Programas de la aplicacin


Transacciones (Trns) Reportes (Rpts) Procedimientos (Procs) Work Panels (Wkps) Web Panels (Wbps)

Base de Conocimiento Base de Conocimiento

Base de Datos

Programas de Aplicacin
(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Luego, GeneXus genera programas de aplicacin para interactuar con la base de datos previamente creada.

17

Resultado final en la Etapa de Desarrollo


Transacciones (Trns) Reportes (Rpts) Procedimientos (Procs) Work Panels (Wkps) Web Panels (Wbps)

Base de Conocimiento Base de Conocimiento

Base de Datos

Programas de Aplicacin
(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Una vez creada la base de datos y generados los programas, contamos con una aplicacin pronta para ejecutar.

18

Las visiones de los usuarios cambian


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Base de Conocimiento Base de Conocimiento

Base de Datos

Nueva Nueva Base Base de de Datos Datos

Programas de Aplicacin
(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Durante el ciclo de vida de la aplicacin, surgir repetidamente la necesidad de hacer modificaciones en la base de conocimiento, ya sea porque las visiones de los usuarios cambian, porque se deben hacer correcciones, o simplemente agregar nuevo conocimiento. Las modificaciones que se realicen sobre la base de conocimiento sern analizadas por GeneXus para evaluar si es necesario efectuar cambios en la base de datos (por ejemplo: modificacin/creacin de tablas/ndices), o no. En caso de detectar cambios para efectuar en la base datos, GeneXus detallar los mismos en un reporte de anlisis de impacto (IAR: Impact Analisis Report), que es un reporte que explicita todos los cambios sobre tablas, ndices, datos, etc. que habra que realizar para reflejar la nueva realidad. Asimismo, en el reporte de anlisis de impacto se informan los eventuales problemas que los cambios en cuestin podran ocasionar, como inconsistencias o redundancias.

19

Anlisis de Impacto Totalmente Automtico


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Anlisis de impacto

Base de Conocimiento Base de Conocimiento

Base de Datos

Nueva Nueva Base Base de de Datos Datos

Programas de Aplicacin
(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Algunas veces la nueva base de datos coincide con la anterior. Otras veces esto no ocurre, y la base de datos debe sufrir alguna modificacin para representar la nueva realidad. El analista debe estudiar el reporte de anlisis de impacto y resolver si desea realizar efectivamente los cambios en la base de datos, o renunciar a ello dejando la base de datos como estaba.

20

Generacin de Programas de Reorganizacin de la Base de Datos


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Programas de Reorganiz.

Base de Conocimiento Base de Conocimiento

Base de Datos

Nueva Nueva Base Base de de Datos Datos

Programas de Aplicacin
(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Si el analista opta por aplicar los cambios propuestos, decimos que opt por reorganizar la base de datos. Utilizamos este trmino para referirnos a la accin de aplicar cambios fsicos sobre la base de datos. GeneXus generar los programas que implementan las modificaciones sobre las estructuras fsicas de la base de datos, y mediante su ejecucin nos brindar la nueva versin de la base de datos con los cambios efectuados.

21

Anlisis automtico del impacto de los cambios sobre los programas


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Base de Conocimiento Base de Conocimiento

Anlisis de Impacto sobre los programas

Nueva Base de Datos

Nuevos Programas de Aplicacin


(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Ya sea que se requiera reorganizar la base de datos o no, considerando las nuevas definiciones introducidas y a pedido del analista, GeneXus estudiar el impacto de los cambios sobre los programas actuales. El analista podr seleccionar sobre cules objetos quiere realizar el anlisis (si sobre todos, los que hayan sufrido cambios, o algunos en particular) y para cada objeto analizado, GeneXus indicar si es necesario realizar cambios en su programa de aplicacin, o no.

22

Generacin automtica de nuevos programas


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Base de Conocimiento Base de Conocimiento

Generacin de programas

Nueva Base de Datos

Nuevos Programas de Aplicacin


(Trns, Rpts, Procs, Wkps, Wbps, DVs)

Por ltimo, a pedido del analista, GeneXus proseguir con la generacin/regeneracin de los programas de aplicacin que sean necesarios, obteniendo as una nueva versin de la aplicacin.

23

Nueva realidad, con los cambios en la aplicacin


Nuevas Transacciones Nuevos Reportes Nuevos Procedimientos Nuevos Work Panels Nuevos Web Panels

Base de Conocimiento Base de Conocimiento

Nueva Base de Datos

Nuevos Programas de Aplicacin

De modo que nuevamente contaremos con una aplicacin pronta para ejecutar, con los cambios aplicados.

24

Metodologa Incremental
Consiste en construir una aplicacin mediante aproximaciones sucesivas.

DEFINICION INICIAL

La construccin automtica de la base de datos y programas, permite a GeneXus aplicar esta metodologa de desarrollo, conocida como metodologa incremental. Como ya hemos explicado, este proceso se realiza mediante aproximaciones sucesivas.

25

Modelos
Dentro de una base de conocimiento coexisten varios modelos En particular, existe un modelo que se crea automticamente al crear una nueva base de conocimiento: el modelo de Diseo

BASE DE CONOCIMIENTO modelo de Diseo

El modelo de Diseo corresponde a la representacin lgica del sistema, esto es, permite describir la aplicacin sin implementarla. Esto significa que no existir una base de datos fsica asociada a este modelo, as como tampoco programas de aplicacin ejecutables. Estos ltimos existirn solo a un nivel conceptual o lgico. Son los objetos GeneXus que el analista haya definido dentro de este modelo los que principalmente describen al sistema. En particular, de las transacciones especificadas1 GeneXus obtiene el diseo lgico de la base de datos, y ellas, en conjunto con el resto de los objetos definidos, constituyen la descripcin lgica de los programas. Los programas sern el resultado de la codificacin de los objetos GeneXus en el lenguaje de programacin elegido por el analista, sobre una base de datos fsica. Pero esta implementacin (base de datos y programas), que es enteramente realizada por GeneXus, dnde se realiza? Aqu es donde entran en juego los otros modelos que pueden definirse dentro de la base de conocimiento. Cada uno de estos otros modelos, contendrn una implementacin del sistema.

-------------------------------------------------------------------------------------------------1 En conjuncin con los grupos de subtipos (objetos Subtype Group) y los ndices de usuario.

26

Modelos
Existen otros modelos que son creados en forma explcita por el analista Por qu tener varios de estos modelos, en lugar de uno solo?
Entre otras razones: para tener cualquier nmero de implementaciones del mismo sistema, asociadas a diferentes plataformas o ambientes (por ejemplo: iSeries, PC, Client/Server, Web, etc.). BASE DE CONOCIMIENTO modelo de Diseo

otro modelo

otro modelo

otro modelo

A diferencia del modelo de Diseo que es creado automticamente, estos otros modelos son creados en forma explcita por el analista. Al hacerlo, ste debe ingresar los datos de la plataforma o ambiente de implementacin correspondiente (lenguaje de programacin, DBMS, etc.) para que GeneXus pueda implementar el sistema para ese modelo. Los objetos GeneXus definidos en el modelo de Diseo se copian al nuevo modelo y stos son los que GeneXus codifica para dicho modelo de acuerdo a su plataforma.

27

Tipos de Modelo
Cada modelo tiene un tipo:

Design (Diseo): Un slo modelo en la misma base de conocimiento. No tiene base de datos ni programas de aplicacin asociados. Prototype/Production (Prototipo/Produccin): Puede haber varios modelos en la misma base de conocimiento. Cada uno de estos modelos tiene una base de datos asociada y programas de aplicacin que se generan para la plataforma o ambiente elegido.

Por cada base de conocimiento, habr un y solo un modelo de Diseo, cuya caracterstica fundamental es que representa al sistema conceptualmente. Los otros dos tipos se parecen mucho entre s, dado que todo modelo de Prototipo o Produccin tiene asociada una plataforma o ambiente que le permite implementar fsicamente el sistema, siendo sta la caracterstica fundamental que diferencia a estos modelos del de Diseo. La principal diferencia entre ellos es conceptual (no funcional) y radica en el uso que se hace de los mismos: - Un modelo de Prototipo se utiliza en la etapa de desarrollo, justamente para prototipar la aplicacin de all su nombre- probando lo modelado, haciendo modificaciones, volviendo a probar. -Un modelo de Produccin, por el contrario, se utiliza en la etapa de puesta en produccin, cuando el prototipo fue aprobado y la aplicacin o los cambios efectuados ya pueden ser llevados al cliente. Cuando una aplicacin implementada en GeneXus ha sido puesta en produccin, necesariamente deber haber al menos 3 modelos definidos en la base de conocimiento: - el de Diseo, pues se crea automticamente al crear la base de conocimiento, - uno de Prototipo, utilizado para ir desarrollando y probando la aplicacin, - uno de Produccin, pues es necesario tener una imagen fiel de la aplicacin que se lleva al cliente, en la plataforma de produccin, como veremos oportunamente.

28

Ciclos de desarrollo

Diseo

Prototipo

Produccin

En el desarrollo incremental de una aplicacin, pasaremos repetidamente del modelo de Diseo al modelo de Prototipo con el que estemos probando la aplicacin, y de ste nuevamente al modelo de Diseo. Con menor frecuencia se pasar al modelo de Produccin. Ciclo de prototipacin El bucle Diseo-Prototipo se recorre repetidamente, construyendo y probando sucesivos prototipos. Ciclo de produccin El bucle Diseo-Produccin se recorre menos frecuentemente, ya que este ciclo corresponde a la puesta en produccin del sistema y esto se realiza solamente cuando el prototipo ha sido aprobado o luego de haber instrumentado y probado algn cambio.

29

Ventajas de la Prototipacin
Permite ver resultados en forma temprana Permite el seguimiento de los requerimientos del usuario Deteccin de errores en forma temprana Logra el compromiso de los usuarios con el desarrollo Sistemas de mejor calidad

Toda comunicacin es susceptible de errores: El El El El usuario olvida ciertos detalles analista no toma nota de algunos elementos usuario se equivoca en algunas apreciaciones analista malinterpreta algunas explicaciones del usuario

Como la implementacin de sistemas es habitualmente una tarea que insume bastante tiempo, y muchos de estos problemas slo son detectados en las pruebas finales del sistema, el costo en tiempo y dinero de solucionarlos se torna muy grande. Sabido es que la realidad no permanece esttica, por lo que no es razonable suponer que se pueden mantener congeladas las especificaciones mientras se implementa el sistema. Sin embargo, debido al tiempo que suele insumir la implementacin, muchas veces esto se hace y se acaba implementando una solucin relativamente insatisfactoria. El impacto de estos problemas disminuira mucho si se consiguiera probar cada especificacin inmediatamente y saber cul es la repercusin de cada cambio sobre el resto del sistema. Una primera aproximacin a esto, ofrecida por diversos sistemas, es la posibilidad de mostrar al usuario formatos de pantallas, informes, etc., animados por mens. Esto permite ayudar al usuario a tener una idea de qu sistema se le construir, pero al final siempre se presentan sorpresas. Una situacin bastante diferente sera la de poner a disposicin del usuario para su ejecucin, una aplicacin funcionalmente equivalente a la deseada hasta en los mnimos detalles. Y esto es lo que ofrece GeneXus! Un prototipo GeneXus es una aplicacin pronta funcionalmente equivalente a la aplicacin de produccin. As es que la aplicacin puede ser totalmente probada antes de ponerse en produccin; y durante las pruebas, el usuario final puede probar de una forma natural no solamente formatos de pantallas, informes, etc., sino tambin frmulas, reglas del negocio, estructuras de datos, etc., y trabajar con datos reales. Esto solo es posible gracias a la construccin automtica que realiza GeneXus del soporte computacional (base de datos y programas).

30

OBJETO TRANSACCIN

El anlisis de toda aplicacin GeneXus comienza con el diseo de las transacciones. Las transacciones permiten definir los objetos de la realidad. Para identificar cules transacciones deben crearse, se recomienda prestar atencin a los sustantivos que el usuario menciona cuando describe la realidad. Adems de tener por objetivo la definicin de la realidad y la consecuente creacin de la base de datos normalizada, las transacciones, al igual que la mayora de los objetos GeneXus que estudiaremos, provocan la generacin de programas. En particular los programas correspondientes a las transacciones tienen por objeto permitir dar altas, bajas y modificaciones en forma interactiva en las tablas que tengan implicadas, controlando estos programas la integridad referencial de los datos (ya sea en ambiente Win y/o Web segn lo indique el analista GeneXus).

31

Elementos
Para una transaccin se definen:
Estructura Form GUI-Windows Form Web Reglas Eventos Subrutinas Propiedades Documentacin Ayuda

Algunos elementos de las transacciones, que iremos viendo son: Estructura: Permite definir los atributos (campos) que componen la transaccin y la relacin entre ellos. A partir de la estructura de las transacciones, GeneXus inferir el diseo de la base de datos: tablas, claves, ndices, etc. Form GUI-Windows: Cada transaccin contiene un Form (pantalla) GUI-Windows (Graphical User Interface Windows) mediante el cual se realizarn las altas, bajas y modificaciones en ambiente Windows. Form Web: Cada transaccin contiene un Form (pantalla) Web mediante el cual se realizarn las altas, bajas y modificaciones en ambiente Web. Reglas: Las reglas permiten definir el comportamiento particular de las transacciones. Por ejemplo, permiten definir valores por defecto para los atributos, definir chequeos sobre los datos, etc. Eventos: Las transacciones soportan la programacin orientada a eventos. Este tipo de programacin permite definir cdigo ocioso, que se activa en respuesta a ciertas acciones provocadas por el usuario o por el sistema. Subrutinas: Permiten definir rutinas locales a la transaccin. Propiedades: Permiten definir ciertos detalles referentes al comportamiento de la transaccin. Documentacin: Permite la inclusin de texto tcnico, para ser utilizado como documentacin del sistema. Ayuda: Permite la inclusin de texto de ayuda, para ser consultado por los usuarios en tiempo de ejecucin de la transaccin. Algunos de estos elementos tambin estn asociados a otros tipos de objetos GeneXus.

32

Estructura

Ejemplo: Se necesita registrar informacin de proveedores.

Se define transaccin Supplier, con estructura: SupplierId* SupplierName SupplierAddress SupplierPhone Identificador de proveedor Nombre de proveedor Direccin de proveedor Telfono de proveedor

La estructura de una transaccin permite definir qu atributos la integran y cmo estn relacionados. A modo de ejemplo, si en una aplicacin se necesita registrar informacin de proveedores, claramente habr que definir una transaccin, a la que podemos dar el nombre Supplier, y su estructura podra ser la siguiente: SupplierId* SupplierName SupplierAddress SupplierPhone Esta lista de nombres (uno de los cuales est sucedido del smbolo asterisco) corresponde a los atributos que interesa mantener acerca de los proveedores. Entonces, creamos una transaccin de nombre Supplier cuya estructura se compone de los atributos SupplierId, SupplierName, SupplierAddress y SupplierPhone. Esto significa que cada proveedor se identificar por un cdigo SupplierId (lo que queda determinado por el asterisco a continuacin del atributo1), tendr un nombre SupplierName, una direccin SupplierAddress y un telfono SupplierPhone. Para cada atributo definido en la estructura, deberemos indicar cosas tales como su tipo de datos, descripcin y algunos detalles ms que veremos.

-------------------------------------------------------------------------------------------------------------El asterisco corresponde a una notacin terica que utilizamos para indicar que el atributo es identificador. Como veremos, nuestro asterisco en GeneXus aparece representado por un cono de llave y el usuario podr configurarlo mediante un men contextual que le ofrecer esta posibilidad.
1

33

Estructura
Vista de la estructura en GeneXus:

Atributos Clave En la pgina anterior hemos explicado que el asterisco a continuacin del atributo SupplierId indica que se trata del identificador de la transaccin. Toda transaccin debe tener un identificador, esto es, un atributo o conjunto de atributos que definan la unicidad. En el ejemplo no podrn existir dos proveedores con el mismo valor de SupplierId. En definitiva se trata del concepto de clave primaria, en tanto, para hacer la eleccin de los atributos que la componen, se deben tener en cuenta los requisitos del objeto de la realidad. En los casos en los cuales no se pueda determinar un identificador, se debe optar por crear un atributo artificial (no existente en la realidad), y que su valor se asigne internamente, por ejemplo, en forma correlativa. Como se puede observar en el editor de transacciones de GeneXus, un cono de llave representa el asterisco que nosotros utilizamos como notacin terica.

Atributo descriptor El cono con una lupa representa al atributo que mejor describe o representa a la transaccin. En otras palabras sera el atributo que tiene mayor carga semntica en la transaccin. Por defecto el primer atributo en la estructura de la transaccin que sea de tipo de datos character, se definir como atributo descriptor. Es posible definir a otro atributo como descriptor utilizando el men popup correspondiente, as como no definir ninguno.

34

Estructura
Ejemplo: Se necesita registrar informacin referente a facturas de venta. Se define transaccin Invoice, con estructura:
InvoiceId* Identificador de factura CustomerId Identificador de cliente CustomerName Nombre de cliente InvoiceDate Fecha de factura InvoiceTotal Importe total de factura ( ProductId* Identificador de producto ProductDescription Descripcin de producto ProductPrice Precio de producto InvoiceLineQuantity Cantidad de producto llevada en la lnea InvoiceLineAmount ) Importe de lnea de factura

Niveles de una transaccin La transaccin Invoice consta de dos niveles: el primer nivel queda implcito por lo que no necesita un juego de parntesis; el segundo nivel corresponde al conjunto de atributos que se encuentra entre parntesis1. El hecho de definir un segundo nivel significa que existen varias instancias del mismo, para cada instancia del nivel anterior. En el ejemplo, un cabezal de factura tiene varios productos. Cada nivel de una transaccin define un grupo de atributos que deben operar en conjunto, es decir, se ingresan, se eliminan o se modifican conjuntamente en la base de datos. Llamaremos transaccin plana a una transaccin de un solo nivel. As, la transaccin Supplier es una transaccin plana. En cambio, la transaccin Invoice tiene dos niveles. Es comn hablar de cabezal para referirnos al primer nivel y de lneas para referirnos al segundo. Para cada nivel de la transaccin, se debe indicar cules de sus atributos actan como identificador. El identificador de cada nivel puede estar compuesto de un solo atributo, como es el caso de las transacciones que hemos visto hasta ahora, o puede estar conformado por varios atributos. En la transaccin Invoice el atributo InvoiceId es el identificador del primer nivel, y el atributo ProductId es el identificador del segundo nivel. Esto ltimo significa que para un nmero de factura dado, InvoiceId, no puede repetirse el valor del atributo ProductId en distintas lneas. Una transaccin puede contener varios niveles paralelos, as como anidados.

-------------------------------------------------------------------------------------------------------------1 Al igual que el asterisco es una notacin terica que representa que el atributo que lo antecede es identificador en la transaccin, el juego de parntesis tambin es utilizado como notacin terica, para representar que los atributos contenidos forman parte de un nivel anidado, y que tiene una representacin visual en GeneXus distinta, pero que indica lo mismo.

35

Estructura
Vista de la estructura en GeneXus

En GeneXus queda visualmente claro el nivel correspondiente a las lneas de la factura. A cada nivel de una transaccin se le debe asignar un nombre, tipo1 y descripcin (salvo al primer nivel, que recibe como nombre el de la transaccin). Niveles paralelos y anidados Una transaccin puede tener varios niveles de anidacin, as como niveles paralelos. Por ejemplo, en el hipottico caso de que una factura pueda abonarse en varios pagos, podramos definir dos tipos de estructura, dependiendo de lo que se quiera representar: InvoiceId* CustomerId CustomerName InvoiceDate InvoiceTotal (ProductId* ProductDescription ProductPrice InvoiceLineQuantity InvoiceLineAmount) (InvoicePaymentDate* InvoicePaymentAmount) InvoiceId* CustomerId CustomerName InvoiceDate InvoiceTotal (ProductId* ProductDescription ProductPrice InvoiceLineQuantity InvoiceLineAmount (InvoicePaymentDate* InvoicePaymentAmount))

Fecha de pago Importe pagado

Con la estructura de la izquierda se define que una factura tiene muchos productos y muchos pagos, pero no hay una relacin directa entre los productos y los pagos (a no ser el hecho de pertenecer a la misma factura). En la estructura de la derecha se registran los pagos por producto llevado. Es sencillo comprender que el segundo y tercer nivel de la transaccin de la izquierda, son paralelos. Ambos se encuentran anidados al primer nivel, pero entre ellos, son paralelos. En la estructura de la derecha, son todos niveles anidados.

-------------------------------------------------------------------------------------------------------------Como veremos luego, el tipo que se define para un nivel de una transaccin, ser utilizado para trabajar con business components, concepto relacionado a las transacciones.
1

36

Definicin del modelo de datos a partir de las estructuras de las transacciones


Transaccin Supplier
SupplierId* SupplierName SupplierAddress SupplierPhone

Transaccin Invoice
InvoiceId* CustomerId CustomerName InvoiceDate InvoiceTotal ( ProductId* ProductDescription ProductPrice InvoiceLineQuantity InvoiceLineAmount )

Tabla INVOICE
InvoiceId* CustomerId CustomerName InvoiceDate InvoiceTotal

Tabla SUPPLIER
SupplierId* SupplierName SupplierAddress SupplierPhone

Tabla INVOICELINE
InvoiceId* ProductId* ProductDescription ProductPrice InvoiceLineQuantity InvoiceLineAmount

GeneXus utiliza la estructura de las transacciones para capturar el conocimiento necesario para definir automticamente cul es el modelo de datos que debe crear. Para poder realizar la normalizacin de la base de datos llevndola a 3era. forma normal, GeneXus debe extraer las dependencias funcionales existentes entre los atributos definidos en la base de conocimiento. En la base de conocimiento de nuestro ejemplo, hemos definido a la transaccin Proveedores y de su estructura GeneXus extrae las siguientes dependencias funcionales: SupplierId {SupplierName, SupplierAddress, SupplierPhone}

Dadas estas dependencias funcionales, GeneXus determina que debe crear una tabla que tendr por defecto el mismo nombre que la transaccin (SUPPLIER)1, y que estar conformada ni ms ni menos que por los cuatro atributos anteriores, siendo SupplierId la clave primaria de la misma:

SUPPLIER

SupplierId

SupplierName

SupplierAddress

SupplierPhone

Diremos que la transaccin Supplier tiene asociada la tabla SUPPLIER en el entendido de que cuando se ingresen, modifiquen o eliminen datos por medio de la transaccin, stos se estarn almacenando, modificando o eliminando fsicamente en la tabla asociada.

-----------------------------------------------------------------------------------------------------------En la documentacin, para distinguir el nombre de una tabla del nombre de una transaccin escribiremos el nombre de la tabla todo en mayscula.
1

37

A partir de la estructura de la transaccin Invoice, GeneXus determina que debe crear dos tablas: Tabla INVOICE, correspondiente al primer nivel de la transaccin:

INVOICE

InvoiceId

CustomerId

CustomerName

InvoiceDate

InvoiceTotal

Clave primaria: InvoiceId Tabla INVOICELINE correspondiente al segundo nivel de la transaccin:

INVOICELINE

InvoiceId

ProductId

ProductDescription InvoiceLineAmount

ProductPrice

InvoiceLineQuantity Clave primaria: {InvoiceId, ProductId} Clave fornea: InvoiceId ya que las dependencias funcionales son: InvoiceId

{CustomerId, CustomerName, InvoiceDate, InvoiceTotal} {ProductDescription, ProductPrice, InvoiceLineQuantity, InvoiceLineAmount}

{InvoiceId, ProductId}

Observemos que la clave primaria de la tabla INOVICELINE es la concatenacin del identificador del primer nivel, InvoiceId, con el identificador del segundo nivel, ProductId. El caso es general: la clave primaria de la tabla correspondiente a un nivel n de una transaccin se obtiene de concatenar los identificadores de los n-1 niveles anteriores anidados, con el identificador de ese nivel. GeneXus asigna un nombre predeterminado a las tablas que crea. A la tabla asociada al primer nivel de una transaccin le asigna el mismo nombre que el de la transaccin; y a las tablas de niveles subordinados les asigna la concatenacin de los nombres de los niveles. Por esto es que la tabla asociada al segundo nivel de la transaccin Invoice recibe el nombre INVOICELINE, dado que el nombre del primer nivel es el de la transaccin, INVOICE, y el del segundo nivel es LINE. Los nombres de las tablas pueden ser modificados por el analista GeneXus cuando as lo desee.

38

Al definir las nuevas transacciones:


Transaccin Customer
CustomerId* CustomerName CustomerAddress CustomerGender

Sexo del cliente

Transaccin Product
ProductId* ProductDescription ProductPrice ProductStock

Luego de haber modelado la transaccin Invoice, nos damos cuenta que hay informacin de clientes y de productos que nos interesa mantener independientemente de las facturas. Es decir, los clientes y los productos son dos objetos de la realidad independientes de las facturas, por lo tanto creamos las dos nuevas transacciones Customer y Product detalladas arriba. Dependencias funcionales Con estas nuevas transacciones definidas, aparecen nuevas dependencias funcionales: CustomerId ProductId {CustomerName, CustomerAddress, CustomerGender} {ProductDescription, ProductPrice, ProductStock}

que conducen directamente a la creacin de dos nuevas tablas:

CUSTOMER

CustomerId

CustomerName

CustomerAddress

CustomerGender

Clave primaria: CustomerId y:

PRODUCT

ProductId

ProductDescription

ProductPrice

ProductStock

Clave primaria: ProductId

39

Normalizacin: cambios en las tablas


Tabla INVOICE
InvoiceId* CustomerId CustomerName InvoiceDate InvoiceTotal

Tabla CUSTOMER
CustomerId* CustomerName CustomerAddress CustomerGender

Tabla SUPPLIER
SupplierId* SupplierName SupplierAddress SupplierPhone

Tabla INVOICELINE
InvoiceId* ProductId* ProductDescription ProductPrice InvoiceLineQuantity InvoiceLineAmount

Tabla PRODUCT
ProductId* ProductDescription ProductPrice ProductStock

El conjunto total de dependencias funcionales existentes requiere que deban realizarse algunas modificaciones en las tablas INVOICE e INVOICELINE diseadas previamente para que el diseo de la base de datos permanezca en 3era. forma normal1. Si representamos sobre las tablas CUSTOMER e INVOICE las dependencias funcionales encontradas para sus atributos:

podemos ver claramente que INVOICE viola la 3era. forma normal (existe una dependencia funcional transitiva): InvoiceId CustomerId InvoiceId CustomerId CustomerName CustomerName

por lo tanto GeneXus normaliza, quitando el atributo CustomerName de la tabla INVOICE:

Ahora CustomerName solo estar en la tabla CUSTOMER. ------------------------------------------------------------------------------------------------------------------1

Por ms informacin sobre las formas normales (3era. forma normal, etc.) le recomendamos la lectura del documento Fundamentos de bases de datos relacionales, el cual est incluido en el captulo de Anexos del curso GeneXus no presencial. De lo contrario, puede pedrselo al docente.

40

Ahora veamos las dependencias funcionales encontradas en las tablas PRODUCT e INVOICELINE:

podemos percibir claramente que la tabla INVOICELINE est violando la 3era. forma normal (existen atributos que estn dependiendo en forma parcial de la clave primaria): ProductId ProductDescription ProductDescription ProductId ProductPrice ProductPrice

{InvoiceId, ProductId}

{InvoiceId, ProductId}

Por lo tanto GeneXus normaliza, quitando los atributos ProductDescription y ProductPrice de la tabla INOVICELINE:

ProductDescription y ProductPrice solo quedarn en la tabla PRODUCT.

41

GeneXus establece las relaciones por los nombres de atributos


CONCEPTOS IGUALES DEBEN TENER EL MISMO NOMBRE
Transaccin Invoice InvoiceId* CustomerId CustomerName Transaccin Invoice InvoiceId* InvoiceCustomerId Transaccin Customer CustomerId* CustomerName Transaccin Customer CustomerId*

SI NO

CONCEPTOS DIFERENTES NO DEBEN TENER EL MISMO NOMBRE


Transaccin Invoice InvoiceId* Date CustomerId CustomerName Transaccin VendorInvoice VendorInvoiceId* Date SupplierId SupplierName

NO

Conceptos iguales deben tener el mismo nombre y conceptos diferentes deben ser nombrados diferentes. GeneXus establece las relaciones a travs de los nombres de los atributos, de modo que cuando encuentra atributos de igual nombre en distintas transacciones, entiende que se trata del mismo concepto, y mediante dicho conocimiento es que puede normalizar. En el ejemplo que venimos viendo, cuando GeneXus encuentra el atributo de nombre CustomerId tanto en la transaccin Customer como en la transaccin Invoice, analiza que: el atributo se llama igual en ambas transacciones, as que se refiere al mismo concepto. En la transaccin Customer, CustomerId est marcado como identificador, lo que significa que ser clave primaria en la tabla fsica CUSTOMER; entonces en la tabla fsica INVOICE ser clave fornea. El atributo CustomerName, por su parte, tambin se encuentra tanto en la transaccin Customer como en la transaccin Invoice, pero a diferencia de CustomerId, no est marcado como identificador en ninguna transaccin del modelo; por tanto GeneXus entiende que se trata de un atributo secundario. Las dependencias funcionales indican que a CustomerName lo determina CustomerId: InvoiceId CustomerId CustomerId CustomerName as que GeneXus incluir CustomerName en la tabla fsica CUSTOMER (y no en la tabla fsica INVOICE). Atributos primarios y secundarios Un atributo se califica como primario cuando el mismo es identificador en alguna transaccin del modelo. En el ejemplo que venimos viendo, CustomerId es un atributo primario ya que es identificador en la transaccin Customer. CustomerName, en cambio, es un atributo secundario ya que no es identificador en ninguna transaccin del modelo.

42

Atributos almacenados e inferidos Al definir las transacciones Customer y Product, hemos incluido en ellas ciertos atributos que no hemos eliminado de la transaccin Invoice. Los atributos CustomerId y ProductId, se incluyeron en las transacciones Customer y Product respectivamente, y al ser denotados como identificadores de las mismas, pasaron a ser atributos primarios. El atributo CustomerName, por su parte, se agreg en la transaccin Customer; y los atributos ProductDescription y ProductPrice se incluyeron en la transaccin Product. Estos son atributos secundarios. Todos estos atributos han quedado en ms de una transaccin: se han dejado en la transaccin Invoice tal como se haban definido en un principio, y se han incluido en las transacciones Customer y Product respectivamente, porque nos hemos percatado de la necesidad de crear estos objetos. A continuacin presentamos las 3 estructuras de las transacciones en cuestin, para poder visualizarlas juntas:

Probablemente usted no comprenda la razn por la cual los atributos secundarios CustomerName, ProductDescription y ProductPrice se han dejado en la estructura de la transaccin Invoice. La explicacin es la siguiente: las estructuras de las transacciones no son equivalentes a estructuras de tablas fsicas. En las estructuras de las transacciones se pueden incluir ciertos atributos que no estarn en la o las tablas fsicas asociadas, ya que a la hora de reorganizar la base de datos GeneXus analizar el conjunto total de dependencias funcionales existentes en la base de conocimiento, y crear -o modificar, segn el caso- las tablas fsicas, dejndolas en 3 forma normal. Ahora, con qu finalidad hemos dejado los atributos secundarios CustomerName, ProductDescription y ProductPrice en la estructura de la transaccin Invoice? Los hemos dejado para poder incluirlos en alguno de los forms (GUI-Windows y/o Web) asociados a la transaccin Invoice y as poder visualizar los valores de dichos atributos en tiempo de ejecucin. Dichos atributos, como hemos explicado, no quedarn almacenados ni en la tabla INVOICE, ni en la tabla INVOICELINE; sin embargo, en tiempo de ejecucin cuando el usuario ingrese a travs de alguno de los forms (GUI-Windows y/o Web) un valor de CustomerId (atributo que s se almacenar en la tabla INVOICE siendo clave fornea), a continuacin se mostrar el CustomerName correspondiente. Decimos que el atributo CustomerName es un atributo inferido en la transaccin Invoice, ya que su valor no se encuentra almacenado en ninguna de las tablas asociadas a la transaccin, sino que se infiere es decir, se obtiene- de la tabla CUSTOMER, dado el valor del atributo CustomerId. Anlogamente, los atributos ProductDescription y ProductPrice tambin son inferidos en la transaccin Invoice, ya que no se encuentran almacenados en las tablas asociadas a la misma, sino que sus valores se infieren de la tabla PRODUCT, para ser mostrados en pantalla.

43

Es conveniente usar padrones para los nombres de atributos


Facilitan la tarea de nombrado Facilitan la tarea de integracin de bases de conocimiento Facilitan la lectura del cdigo generado

44

Nombrado de atributos: Nomenclatura GIK


Componente de Entidad + Categora Categor [+ Calificador + Complemento]

y en ingls:

ARTech ha definido un estndar para la nomenclatura de atributos: el GeneXus Incremental Knowledge Base (GIK) que es utilizado por la comunidad de usuarios GeneXus. En esta nomenclatura, el nombre de un atributo se forma con 4 componentes (algunos opcionales, sealados entre parntesis rectos): Componente de Entidad + Categora [+ Calificador + Complemento] A continuacin describimos en qu consiste cada componente: Componente de Entidad (u Objeto):Una Entidad es un actor (ej: Customer), objeto o evento (ej: Vendor Invoice, factura de venta) que interviene en una aplicacin dada, representado por una transaccin Genexus2. Un Componente de Entidad, representa a cualquier nivel subordinado o paralelo que defina la entidad. Ejemplo: la factura tiene los siguientes componentes, Invoice (cabezal), InvoiceLine (lneas de la solicitud). Se sugiere un largo de un entorno de 10 caracteres para representar el componente de la Entidad. Categora: Es la categora semntica del atributo, es decir, define el rol que el mismo asume dentro del objeto y dentro del entorno de la aplicacin. Se sugiere que no supere los 10 caracteres. Ejemplos: Id (identificador), Code (cdigo), Name (nombre), Date (fecha), Description (descripcin), Price (precio), Stock. -------------------------------------------------------------------------------------------------------------1 Para pases que utilicen lenguas en las que los adjetivos suelan colocarse despus del sustantivo. En el ingls esto es al revs, por lo que la categora (el sustantivo) va al final. 2 O un conjunto de Transacciones paralelas y/o subordinadas, de las que hablaremos ms adelante.
1

45

Calificador: Es cualquier adjetivo o adverbio, en el entorno de 10 caracteres, que agregue diferenciacin conceptual al nombre del atributo para hacerlo nico. En general refiere al texto que califica la categora: Fecha de vencimiento, Ejemplos: Start (inicial), End (final), Due (vencimiento) Complemento: Texto libre hasta completar la cantidad de caracteres significativos (30) para el nombre. Tal como se muestra en la transparencia, algunos ejemplos de nombres de atributos son:

Nota 1: Las letras maysculas permiten establecer fronteras entre los componentes que forman a los nombres de atributos. Nota 2: Para cada componente se pueden utilizar la cantidad de caracteres que se deseen, aunque se sugiere utilizar 10 y que el nombre completo del atributo no supere los 30.

46

Demo
Creacin de base de conocimiento Creacin de transacciones

Para crear una base de conocimiento, se debe seleccionar en la barra de men de GeneXus, el tem File / New Knowledge Base. A continuacin aparecer un dilogo que solicitar la ubicacin y nombre de la base de conocimiento a crear. Una vez creada la base de conocimiento, la misma quedar abierta en el modelo de Diseo, para que se empiecen a crear las transacciones. Antes que nada debemos posicionarnos (haciendo clic simplemente) en la carpeta Objects del rbol que se encuentra en la divisin izquierda de la pantalla, ya que los objetos que vayamos creando irn quedando dentro de dicha carpeta. La creacin de objetos, se realiza mediante el tem Object / New Object de la barra de men de GeneXus. Al seleccionar el tem Object / New Object se desplegar un dilogo en el cual se deber elegir el tipo de objeto que se desea crear (en este caso el tipo de objeto: transaccin), dar un nombre al objeto que se est creando (por ejemplo: Customer), una descripcin larga, y se podrn indicar algunas cosas ms que iremos viendo. Una vez creada la transaccin, la misma quedar abierta para que se defina su estructura.

47

Definicin de atributos

Para definir un atributo, simplemente se debe digitar en el primer campo de una lnea (o rama) de la estructura, el nombre del atributo que se desea crear. Mediante la tecla de tabulacin se puede pasar a los siguientes campos para indicar el tipo de datos del atributo, as como su descripcin, si admitir valores nulos de la base de datos, y en el caso que el mismo vaya a ser una frmula (concepto que veremos en breve), cmo calcularla. Con la tecla Enter se puede pasar a la siguiente lnea, para definir otro atributo. Una vez definidos los atributos en la estructura de la transaccin, solamente restar guardar / salvar los cambios. Si se necesita modificar el nombre de un atributo, su tipo de datos, descripcin, nulabilidad, o frmula, bastar con hacer doble clic sobre el campo implicado, y el mismo se habilitar y se podr editar. Luego se debern guardar/salvar los cambios, nuevamente. Para indicar que uno o ms atributos son identificadores en la transaccin, se los debe seleccionar y presionar CTRL + K; en consecuencia aparecern con un smbolo de llave. Para definir que comienza otro nivel en la transaccin, se debe digitar CTRL + L, y automticamente se producir una indentacin y el usuario deber darle nombre a ese nivel, as como definir el nombre de su tipo de datos1 y una descripcin para el nivel. Para indicar que un atributo de uno de los niveles de la transaccin ser el atributo descriptor, se lo debe seleccionar y presionar CTRL+D. GeneXus cuenta con mens pop up2, que son mens que se abren cuando el usuario est posicionado en determinado contexto y da clic con el botn derecho del mouse. Por ejemplo, al hacer clic con el botn derecho del mouse sobre un atributo de la estructura, se abre un men pop up sobre el atributo seleccionado, que ofrece varias utilidades, como por ejemplo indicar que el atributo es clave (opcin Toggle key), quitarlo de la estructura, pasarlo a un siguiente nivel de anidacin, etc. Cada atributo tiene propiedades. Algunas de ellas (las fundamentales y obligatorias) son las que se ofrecen directamente en la estructura para su ingreso inline. Para acceder al dilogo que permite configurar todas las propiedades de un atributo, se debe seleccionar el tem Properties del men contextual. ---------------------------------------------------------------------------------------------------Veremos su utilidad cuando estudiemos los business components. 2 Tambin llamados contextuales dado que varan segn el contexto.
1

48

La posibilidad de modificar las propiedades de un atributo solo estar disponible en el modelo de Diseo, ya que es en este modelo de la base de conocimiento en el que se disean y editan las transacciones y atributos. El dilogo de configuracin de las propiedades de un atributo tiene 4 solapas: General, Control Info, Help y Documentation. 1) General: Contiene informacin general del atributo. Name: Es el nombre del atributo. Se utiliza para identificarlo. Description: La Descripcin o ms propiamente Nombre largo es una descripcin ampliada del atributo. Debe identificar bien al atributo, con independencia del contexto, y principalmente debe ser entendible por el usuario final. Debe ser un identificador global del atributo, es decir, no se le debe asignar a dos atributos en la base de conocimiento la misma descripcin, ya que ser a travs de esta descripcin que el usuario final podr seleccionar atributos para definir sus propias consultas a la base de datos, con GeneXus Query, ejecutando reportes dinmicos (tema bastante simple, pero que no se abordar en este curso). Relacionadas a esta propiedad, estn las propiedades Title y Column Title, que por defecto toman el mismo valor que se especifica en Description, pudindose modificar. Estas propiedades se describen a continuacin: Title: La descripcin que se ingrese aqu ser colocada por defecto al lado del atributo cada vez que se utilice en salidas planas como en el primer nivel de los forms de las transacciones, o en reportes generados con el Report Wizard. El valor de esta propiedad inicialmente se hereda de la propiedad Description del atributo, pudiendo ser modificada por el programador. Column Title: La descripcin que se ingrese aqu ser colocada por defecto como ttulo del atributo cada vez que se lo incluya en la columna de un grid (grilla). El valor de esta propiedad inicialmente se hereda de la propiedad Description del atributo, pudiendo ser modificada por el programador. Domain: Permite asociarle un dominio1 al atributo. Al hacerlo, ciertas propiedades del atributo se deshabilitarn (como Data Type y Length) tomando los valores del dominio. En caso de que el atributo no pertenezca a un dominio, el programador dejar el valor [none] en esta propiedad, y las correspondientes al tipo de datos del atributo estarn habilitadas para ser ingresadas. Data Type: Permite indicar el tipo de datos del atributo. Aqu se podr elegir uno de los tipos de datos soportados por GeneXus. Dependiendo del tipo de datos que se seleccione habr ciertas propiedades, u otras, para configurar. Length: Permite indicar el largo del atributo. Si en la propiedad Data Type se indica que el atributo es numrico, entonces se deber tener en cuenta que el largo incluya las posiciones decimales, el punto decimal y el signo. Esta propiedad estar deshabilitada cuando el tipo de datos elegido no requiera establecer un largo (por ejemplo, si se trata del tipo de datos Date). Decimals: Si en la propiedad Data Type se indica que el atributo es numrico, se ofrecer esta propiedad, para que se especifique la cantidad de decimales. El valor 0 en este campo, indicar que se trata de un entero. Signed: Si en la propiedad Data Type se indica que el atributo es numrico, se ofrecer esta propiedad para que se indique si manejar signo o no. El valor por defecto es False, lo que indica que no se representarn valores negativos. Value Range: Permite indicar un rango de valores vlidos para el atributo. Por ejemplo: 1:20 30: - significa que los valores vlidos son entre 1 y 20; y 30 o mayor. 1 2 3 4 - significa que los valores vlidos son 1, 2, 3 o 4. 'S' 'N' - significa que los valores vlidos son 'S' o 'N'. Picture: Permite indicar el formato de edicin para la entrada y salida del atributo. Dependiendo del tipo de datos del atributo, aparecern determinadas propiedades bajo esta categora. GeneXus provee ms propiedades para los atributos que las recin mencionadas. Dependiendo del valor que se elija para determinada propiedad, se ofrecern ciertas propiedades relacionadas, u otras. Recomendamos para la lectura de otras propiedades, acceder al Help de GeneXus.

-------------------------------------------------------------------------------------------------------------------------------1 Los dominios se abordarn ms adelante en el curso, pero a modo de resumen, el objetivo de los dominios es realizar definiciones de datos genricas. Por ejemplo: se puede definir un dominio de nombre Precio y tipo de datos Numeric(10,2) y luego asociarle este dominio a todos los atributos que almacenan precios. Esto tiene la ventaja de que si despus se desea modificarlo a por ejemplo Numeric(12,2), hay que modificar solamente la definicin del dominio y automticamente todos los atributos basados en ese dominio heredan el cambio.

49

2) Control Info A un atributo se le puede asociar un tipo de control. Los tipos de controles posibles son: - Edit - Radio Button - Check Box - Combo Box - List Box - Dynamic Combo Box - Dynamic List Box La asociacin de cierto tipo de control a un atributo, sirve para especificar el tipo de control por defecto que se utilizar para el atributo cada vez que se lo incluya en un form. Cuando se define un atributo el tipo de control que tiene asociado es Edit, pudiendo el programador cambiarlo a cualquiera de los otros tipos. En la solapa Control Info del dilogo de edicin de las propiedades de un atributo es donde el programador podr cambiar el tipo de control asociado al atributo y dependiendo del tipo de control seleccionado, se solicitar distinta informacin complementaria. Luego, cada vez que se agregue el atributo en un form se presentar automticamente con el tipo de control que tenga asociado aqu. Nota En caso de asociar al atributo el tipo Edit, se podr especificar que disfrace sus valores, mostrando los de otro atributo (propiedad InputType), e incluso que sugiera los valores posibles al usuario, a medida que ste vaya digitando (propiedad Suggest), entre otras, como veremos luego, cuando estudiemos Descripciones en lugar de cdigos. Tambin se puede elegir el color de la fuente de letra que se desea asociar por defecto al atributo, as como el color de fondo, de modo que cada vez que se agregue el atributo en un form, se presente automticamente con los colores que se le hayan asociado. 3) Help Esta solapa permite que el programador ingrese un texto de ayuda asociado al atributo, para que el usuario final pueda consultarlo en tiempo de ejecucin. Si el usuario final solicita ayuda (presionando F1), estando posicionado en el atributo, se le desplegar el texto que se haya ingresado aqu. Ms adelante, veremos otros temas relacionados al help de una aplicacin GeneXus. 4) Documentacin Esta solapa permite que el programador ingrese documentacin tcnica del atributo, til para los desarrolladores.

50

Tipos de Datos
Numeric, Character, Date VarChar
- Equivalente a Character, salvo en la forma en que se almacena en la BD. - Propiedades Maximum Length y Avarage Length asociadas.

Long Varchar

- Permite almacenar textos largos, comentarios, etc. (memo).


DateTime

- Permite almacenar una combinacin de fecha y hora.


Blob
- Permite almacenar cualquier tipo de informacin: texto, imgenes, videos, planillas, etc., en la base de datos. - Win / Web ofrecen manipulacin distinta de este tipo de datos

Numeric: Permite almacenar datos numricos. Cuando se selecciona este tipo de datos se debe indicar la cantidad total de dgitos del nmero, la cantidad de posiciones decimales, y si permite signo o no. Ejemplo: Si definimos que el tipo de datos del atributo InvoiceTotal es numrico de largo 10, con decimales 2, y sin signo, estamos especificando que representar nmeros con hasta 7 dgitos en la parte entera y 2 decimales (7 dgitos en la parte entera + punto + 2 dgitos para los decimales = 10 dgitos). Character: Permite almacenar cualquier tipo de texto (caracteres y dgitos). Para este tipo de datos, se debe indicar el largo. Ejemplo: El atributo CustomerName que utilizamos para almacenar el nombre de un cliente, es de tipo Character y si sabemos que nunca un nombre tendr ms de 20 caracteres, podemos fijar el largo: 20. Date: Permite almacenar una fecha. Ejemplo: El atributo InvoiceDate que utilizamos para almacenar la fecha de una factura, ser de este tipo de datos. El formato a utilizar para las fechas (da-mes-ao, mes-da-ao), se configura en forma genrica para todo el modelo dentro de un tipo especial de objeto, el objeto Language correspondiente al lenguaje en el que se generar el modelo. El objeto language existe para poder tener una misma aplicacin traducida en cualquier lenguaje. La eleccin de presentar el ao con 2 dgitos o 4, se configura con la propiedad Picture de cada atributo.

51

VarChar: Permite almacenar texto de largo variable. Su funcin, en contraposicin al Character, es optimizar el almacenamiento en la base de datos. Cuando se selecciona el tipo de datos VarChar en el dilogo de definicin del atributo se agregan las 2 siguientes propiedades: Maximum Length y Average Length. La primera es para indicar el largo mximo de caracteres que se podrn almacenar, mientras que la segunda es para indicar el largo promedio de caracteres que se suele almacenar por lo general. Ejemplo: Cuando se define un atributo de tipo Character y largo 60, si se le ingresa un dato que ocupa 25 caracteres, la capacidad restante de almacenamiento del atributo (35 caracteres) se rellena con blancos. El tipo de datos Varchar, en cambio, optimiza el almacenamiento de la siguiente forma: se le define Average Length (por ejemplo: 25), y Maximum Length (por ejemplo: 60); entonces, si el dato tiene largo menor o igual que 25, se lo almacena en el campo (rellenado con blancos) mientras que en los casos que el dato sea de largo mayor que 25, se almacenan los primeros 25 caracteres en el campo, y el resto en un rea de overflow. Como contrapartida a la ventaja de la optimizacin del almacenamiento, para los casos en que se utilice el rea de overflow, ser necesario realizar un acceso adicional tanto para la lectura como para la escritura del dato. El tipo de datos Varchar es equivalente al tipo Character en todos los sentidos, salvo en la forma en que se almacena en la base de datos. Se le pueden aplicar todas las funciones y operadores existentes para el tipo de datos Character. Si el DBMS no soporta este tipo de datos, se crear el atributo de tipo Character. Long Varchar: Permite definir un atributo memo; es decir, se utiliza normalmente para almacenar textos largos, comentarios, etc. Al seleccionar este tipo de datos, se debe indicar un largo mximo. Existen dos funciones para manipular este tipo de datos: GXMLines y GXGetMLi. GXMLines retorna la cantidad de lneas que tiene un atributo Long Varchar, teniendo como parmetros el nombre del atributo, y la cantidad de caracteres que se desea considerar por lnea. Ejemplo: &cantlin = GXMLines( AtribMemo, 40 ). GXGetMLi por su parte, extrae una lnea del atributo Long Varchar (para luego imprimirla, por ejemplo); teniendo como parmetros el nombre del atributo, el nmero de lnea deseado, y la cantidad de caracteres que se desea considerar por lnea. Ejemplo: &txt = GXGetMLi( AtribMemo, 1, 40 ). Generalmente se usan estas 2 funciones en combinacin, ya que primero se suele consultar la cantidad de lneas que tiene cierto atributo Long Varchar, indicando la cantidad deseada de caracteres por lnea, y luego se prosigue extrayendo el contenido de las lneas, utilizando un bucle hasta llegar a la ltima lnea, y de esta forma se imprimen, por ejemplo. DateTime: Permite almacenar una combinacin de fecha y hora. La propiedad Picture de este tipo de datos, permite elegir qu se desea mostrar de la fecha, y qu se desea mostrar de la hora. Acerca de la fecha se puede elegir: no manejarla, manejarla y presentar el ao con 2 dgitos, o manejarla y presentar el ao con 4 dgitos. Acerca de la hora se puede elegir: manejar solo 2 dgitos para la hora (no manejando minutos ni segundos), manejar 2 dgitos para la hora y 2 dgitos para los minutos (no manejando segundos), o manejar 2 dgitos para la hora, 2 dgitos para los minutos y 2 dgitos para los segundos. Los valores anteriores no afectan la forma de almacenar el tipo de datos sino especficamente la forma de aceptar o mostrar su contenido. Nota: En caso de no manejar la fecha, sino solo la hora, el valor de fecha que quedar en el campo ser el mnimo soportado por el DBMS, y ser reconocido por GeneXus como fecha vaca o nula. En lo que respecta a la hora, los valores no aceptados (minutos y/o segundos) sern almacenados con valor cero. Blob: Ante el creciente manejo de imgenes digitalizadas, videos, planillas as como documentos de todo tipo, las aplicaciones requieren cada vez ms mantener y trabajar con este tipo de informacin. El tipo de datos Blob permite almacenar esta diversidad de informacin en la propia base de datos, aprovechando as los diferentes mecanismos de integridad y control que proveen los DBMSs. Este tipo de datos solamente se puede utilizar cuando se cuenta con un DBMS. Dependiendo de si se implementa la aplicacin en ambiente Win o Web, ser la forma de manipulacin de un atributo de este tipo de datos. El ambiente Web ofrece ms funcionalidades para trabajar con atributos de tipo Blob de forma muy amigable. Para profundizar en el conocimiento de este tipo de datos puede dirigirse al Help de GeneXus.

52

Definicin de variables
En todo objeto GeneXus es posible definir variables. Las variables son nicamente visibles dentro del objeto; es decir, son locales.

Para definir variables en determinado objeto, estando dentro del mismo, se debe presionar el botn de la barra de herramientas Fast Access de GeneXus, y se abrir el dilogo de definicin de variables, mostrado en la transparencia. Este dilogo muestra variables definidas por defecto (como por ejemplo la variable Today que contiene la fecha del sistema) para el objeto, y permite definir variables nuevas mediante los botones Add y Add Based On.

Botn Add Al seleccionar el botn Add, se abre el siguiente dilogo para la definicin de una variable:

Este dilogo solicita el nombre de la variable, su descripcin, tipo de datos y largo, o dominio, de forma anloga a cuando se define un atributo. La propiedad Dimensions permite indicar si la variable ser escalar o si se tratar de un vector (1 dimensin) o matriz (2 dimensiones). El valor que ofrece por defecto esta propiedad es escalar.

53

Botn Add Based On El botn Add Based On ofrece una forma rpida de definir una variable. Cuando se selecciona, se despliega un dilogo que muestra todos los atributos definidos en la base de conocimiento; en dicho dilogo, simplemente se debe seleccionar un atributo, y a continuacin se definir automticamente una variable con el mismo nombre y la misma definicin que el atributo. Vale aclarar que se pueden seleccionar varios atributos, crendose en tal caso una variable por cada atributo seleccionado, con sus mismas caractersticas. Botones Edit, Remove, Copy, Paste El botn Edit permite editar una variable que se haya seleccionado previamente, mientras que el botn Remove, permite borrar una o ms variables que se hayan seleccionado a la vez. El botn Copy ofrece la posibilidad de copiar en el portapapeles la definicin completa de las variables que se hayan seleccionado previamente, para luego poder pegar dichas definiciones de variables en otro objeto de la base de conocimiento, con el botn Paste de este mismo dilogo; es decir, en el objeto destino, se deber entrar a este mismo dilogo, y presionar el botn Paste.

Por otra parte, es posible definir variables dentro del editor de cdigo de cada objeto (source, eventos, etc.), haciendo uso del men contextual (botn derecho) luego de escribir el nombre de la variable. Esto es, al escribir &nombreDeVariable (ej: &x) y presionar botn derecho del mouse, se abrir el siguiente men contextual:

Tambin es posible editar variables luego de definidas, de esta misma forma. Si al escribir &nombreDeVariable (ej: &x), la misma ya existe definida para el objeto, el men contextual mostrar:

Al seleccionar la opcin Define se abrir el mismo dilogo que al presionar el botn Add. Anlogamente, al seleccionar la opcin Edit de este men, se abrir el mismo dilogo que al presionar el botn Edit del dilogo de definicin de variables mostrado en la transparencia.

54

Dominios
Objetivo: Realizar definiciones genricas. Cundo debemos usar dominios?
Atributos y/o variables con la misma definicin

Ejemplo: ProductPrice: Precio de producto InvoiceLineAmount: Importe total de lnea Dominio Price: Numeric(10.2)

Atributos

Es comn tener en una base de conocimiento atributos que comparten definiciones similares pero que no tienen relacin entre s. Por ejemplo, es comn definir todos los nombres como atributos de tipo character y largo 20; o todos los importes, como atributos de tipo numrico y largo 10.2. El objetivo de los dominios es permitir realizar definiciones genricas. A modo de ejemplo, el atributo InvoiceLineAmount es de tipo numrico y largo 10.2, y al mismo tiempo, el atributo ProductPrice es del mismo tipo y largo, en la misma base de conocimiento. De modo que podramos definir un dominio de nombre Price, que sea de tipo numrico con largo 10.2, y a cada uno de los atributos anteriores le asignaramos dicho dominio. La ventaja de hacerlo as es que si en el futuro surge la necesidad de cambiar la definicin de los atributos que representan importes, haramos el cambio una sola vez (en el dominio Price), propagndose ste automticamente a los atributos InvoiceLineAmount y ProductPrice por pertenecer a l. As como podemos asociarle a un atributo un dominio, tambin lo podemos hacer para una variable. Un mismo dominio puede asignarse tanto a atributos como a variables, ya que su objetivo es exactamente el mismo. Cmo definir un dominio? Existen varios caminos: 1) El tem: Advanced / Domain de la barra de men de GeneXus ofrece un dilogo para realizar el mantenimiento de los dominios de la base de conocimiento; esto es: crear dominios, modificarlos y eliminarlos (la eliminacin de un dominio solo se permitir si el mismo no est asignado a ningn atributo ni variable). 2) Dado que en la pantalla de configuracin de las propiedades de un atributo es donde se le asigna a un atributo un dominio existente, en dicha pantalla se ofrece un botn para crear un dominio nuevo. dem con el dilogo de definicin de variables. 3) En la estructura de la transaccin es posible definir un nuevo domino en el campo de definicin del tipo de datos de un atributo, simplemente escribiendo sobre esa misma lnea, el nombre del dominio, y asignndole el tipo de datos. Por ejemplo, digitando Price = Numeric(10.2) sobre la columna Type del atributo que se est definiendo, queda tambin definido el dominio de nombre Price, con el tipo de datos Numeric(10.2). Estos accesos para trabajar con dominios solo se encuentran habilitados en el modelo de Diseo de la base de conocimiento, al igual que todas las funcionalidades que puedan implicar modificaciones en la base de datos fsica.

55

Forms
Cada transaccin tiene asociado un form GUIWindows y un form Web.

Ambos forms son creados por defecto al grabar la estructura de la transaccin, pudiendo ser modificados por el programador.

Para cada transaccin, GeneXus crea un form GUI-windows y un form Web, los cuales sern la interfaz con el usuario, en ambiente windows y Web respectivamente. Ambos forms son creados por defecto por GeneXus al momento de grabar la estructura de la transaccin, y contienen todos los atributos incluidos en la misma, con sus respectivas descripciones, adems de algunos botones. Si bien son creados por defecto, es posible modificarlos para dejarlos ms vistosos, cambiar por ejemplo controles de tipo edit a otros tipos de controles, agregar y/o quitar botones, etc. Para editar el form GUI-windows de una transaccin, se debe seleccionar la solapa Form que se encuentra en la barra de edicin del objeto, mientras que para editar el form Web, se debe seleccionar la solapa Web Form en la misma barra.

56

Form GUI-Windows de la transaccin Invoice

GRID

A travs del form de la transaccin (GUI-Windows o Web segn el ambiente de trabajo) el usuario podr ingresar, modificar y eliminar registros en tiempo de ejecucin. En el ejemplo se muestra el form GUI-Windows correspondiente a la transaccin de facturas (Invoice).

57

Form Web de la transaccin Invoice

Control Error Viewer exclusivo de Web botn Get

GRID

En el ejemplo se muestra el form Web correspondiente a la transaccin Invoice. A travs de este form el usuario final podr ingresar, modificar y eliminar facturas en la aplicacin Web. Pueden verse algunas diferencias en el diseo grfico del form Web respecto al form Win, pero podemos ver que todos los controles que estn en el form Win, tambin lo estn en el Web. El recproco no se cumple: el botn Get al lado de la clave primaria aparece en el form Web y no en el Win que hemos visto1. El control Error Viewer aparece tambin solamente en el form Web. Y el grid correspondiente a las lneas de la factura, contiene en el form Web una primera columna con un check box, que el grid del form Win no la incluye. Comentaremos a continuacin el control Error Viewer. Sobre el botn Get entenderemos el por qu de esta diferenciacin un poco ms adelante, cuando estudiemos el dilogo con validacin a nivel del cliente. Con respecto al check box tambin veremos este tema ms adelante, cuando estudiemos la ejecucin. En una aplicacin con interfaz Win, los mensajes que deban mostrarse al usuario en tiempo de ejecucin se desplegarn en una ventana de Windows independiente, que no programamos nosotros. En Web, en cambio, los mensajes2 deben mostrarse dentro de la pgina HTML que contiene el form de la transaccin. Es por este motivo que existe el control Error Viewer, para poder ubicar y programar el lugar donde queremos que los mensajes generales le sean desplegados al usuario final de una transaccin Web. Podremos especificar entre otras cosas el lugar donde queremos que este control se ubique dentro del form, su tipo de letra, color, etc. Existen algunas diferencias ms entre ambos forms, pero son menores dado que representan formas distintas de realizar lo mismo: por ejemplo, mientras que el botn para confirmar las acciones y comenzar la grabacin de los registros de la transaccin en el form Win tiene como texto Confirm, en el Web su texto es Apply Changes. Anlogamente, mientras el botn para eliminar todo (cabezal y lneas) tiene como texto solo Delete en el form Win, en el Web dice Delete All. La funcionalidad es la misma. Por ltimo vale mencionar que en el form Web se puede percibir el botn Check, que permite chequear que todo lo que ha ingresado el usuario hasta el momento sea correcto. Ms adelante, cuando estudiemos cmo se trabaja en ejecucin con las transacciones, arrojaremos ms luz sobre estos asuntos. ----------------------------------------------------------------------------------------------------------------------Ms adelante cuando estudiemos el dilogo con validacin a nivel del cliente, veremos que en ambiente Win se podr optar por trabajar con dicho dilogo o no, y dependiendo de ello, el botn Get estar presente en el form o no. 2 Cuando estudiemos el dilogo con validacin a nivel del cliente en Web, veremos que muchos de los mensajes se desplegarn en cajas de texto sobre la pantalla, especficamente sobre los campos que el usuario haya ingresado y en los que se deba informar de algo al usuario. Es decir, funcionarn de manera combinada el control Error Viewer junto con los mensajes interactivos en cajas de texto.
1

58

Paletas de herramientas para diseo de forms Win y Web


Insertar controles:

Cortar, copiar y pegar controles:

Alinear, distribuir y uniformizar los tamaos de los controles (solo disponible para form GUI-Windows):

Podemos definir un control como un rea de la interfaz con el usuario, que tiene una forma y un comportamiento determinado. Existen distintos controles: - Form: Un form puede verse en s mismo como un control. - Texto: Permite colocar texto fijo (por ejemplo las descripciones de los atributos en el form Win: Customer Name, Customer Id, o cualquier otro texto). - Atributo/Variable: Permite colocar atributos o variables. - Lnea: Con este control se dibujan lneas horizontales o verticales (form Win). - Recuadro: Permite definir recuadros de distintos tamaos y formas (form Win). - Grid: Permite definir grillas de datos. - Botn: Permite incluir botones en los forms. - Bitmap: Permite definir bitmaps estticos. La mayora de los controles anteriores (salvo lnea y recuadro) estn disponibles tanto para ser utilizados en interfaz GUI-Windows como Web. A su vez el tab control es un control que solo est disponible para ser utilizado en interfaz GUI-Windows, mientras que otros controles solo pueden utilizarse en interfaz Web (text blocks, tablas, grids freestyle, Error Viewer, etc.). Tab Control: tiene una o varias solapas, en las cuales se pueden distribuir controles. Cada solapa tiene un ttulo y un rea til para que se le incluyan controles. El uso de este control es til para los casos en los cuales se quiere distribuir los datos en distintos grupos, para presentarlos de forma amigable para el usuario. Por ejemplo, si queremos dividir la informacin de la transaccin Customer en 2 solapas: una para ingresar los datos generales del cliente, y otra para ingresar los datos comerciales, podemos insertar en el form un Tab Control con dos solapas, y distribuir los controles de texto, atributo, etc. en cada una de ellas. Paleta de herramientas para insertar controles: Cuando se est editando un form, se encuentra disponible una paleta de herramientas que ofrece los controles posibles de insertar en el mismo. Simplemente se deber seleccionar en la paleta de herramientas el control que se desee insertar en el form, para lo cual se deber hacer clic en el cono que lo represente; seguidamente se deber hacer clic en el form, en el lugar que se desee ubicar el control, y se insertar el control elegido en el lugar del form que se haya indicado; en caso de ser necesario, se abrir el dilogo correspondiente a las propiedades del control, para que se indiquen aquellas que sean de carcter obligatorio.

59

Controles en form Web


Cada control del form Web podr tener una clase asociada, de un objeto theme (tema) determinado, asociado al objeto. Al crear una KB, se crea por defecto el tema Default y todos los objetos que se creen tendrn este tema. Esto permitir independizar el diseo de la interfaz, de la programacin.
Existe el Editor de temas, un utilitario que usarn los diseadores grficos del sitio Cada tema tendr definidas muchas clases para cada tipo de control El analista solo asocia un tema al objeto, y una clase a cada control del form y puede olvidarse del diseo de los mismos.

El control hereda el diseo de la clase del tema al que est asociado

Una de las ventajas de las aplicaciones con interfaz Web frente a las mismas aplicaciones con interfaz GUIWindows, refiere a los aspectos de diseo. Las aplicaciones Web, programadas en HTML, pueden llegar a ser verdaderamente vistosas. Para lograr separar los aspectos de diseo grfico de un sitio web, de los aspectos de programacin propiamente dichos, existe un tipo de objeto llamado Theme (Tema, en espaol), y un utilitario independiente para editar objetos de este tipo, el Editor de Temas. Este utilitario puede tambin invocarse desde GeneXus mediante el tem Tools/Theme Editor estando en el modelo de diseo. El objetivo de esta separacin es poder paralelizar el desarrollo de un sitio Web, permitindole al programador abocarse a las tareas de programacin, y apoyarse en un diseador grfico para que defina las cuestiones de diseo. De esta manera el diseador grfico configurar el tema elegido por el programador, utilizando este utilitario independiente, y el programador slo deber aplicarlo a los objetos de su base de conocimiento (para esto existe una propiedad de nombre Theme a nivel de modelo y otra propiedad de nombre Theme a nivel de cada objeto1 ). Un objeto tema contendr un conjunto de clases, para cada tipo de control de los que pueden aparecer en el form Web de un objeto GeneXus. Por ejemplo, tendr varias clases para el control botn, algunas para el control atributo, una clase para el control Error Viewer, etc. Cuando se crea una base de conocimiento, automticamente aparecer dentro de la carpeta Objects (que contendr todos los objetos GeneXus que se vayan creando) un objeto de tipo Theme cuyo nombre es Default. Este tema contiene un conjunto de clases asociadas a los distintos controles existentes2. Los objetos con form Web que se vayan creando tendrn por defecto asociado este Theme, y cada control que aparezca en sus forms tendr asociado una clase de ese tema, para este control.

------------------------------------------------------------------------------------------------------------Al final de este captulo se mencionar que al igual que cada atributo tiene un conjunto de propiedades configurables por el programador, as cada modelo y cada objeto. Por ejemplo, la propiedad Theme se encontrar para configurar en los dilogos de propiedades asociados a cada modelo Web y a cada objeto que tenga form Web (transacciones y Web Panels). 2 No solo existen clases para los controles en un tema, pero de esto no nos ocuparemos en este curso.
1

60

Controles en form Web


Ejemplo: transaccin Customer con tema Default

De este modo, cuando el analista crea la transaccin Customer e ingresa su estructura, al grabar podr apreciar que el form Web tendr automticamente el aspecto que se muestra en la pantalla de arriba a la izquierda. Quin dio formato a todos los controles si no lo hizo el analista explcitamente? Pues bien, todas las transacciones tendrn asociado por defecto el theme Default y todos los controles que se coloquen en el form, tendrn clases de este tema asociadas. Si sobre el botn Apply Changes, con el botn derecho del mouse se editan sus propiedades, se abrir un dilogo (que se presenta abajo a la izquierda) y en el mismo se puede observar la propiedad Class, que tiene configurada la clase BtnEnter que es una clase de botn. Esta propiedad puede ser cambiada por el analista (podemos ver que se trata de un combo box). All cliquear el combo box podremos ver una lista de clases posibles para ese botn (son las que figuran en el tema asociado), pero tambin aparece la opcin (none) para no asociarle clase alguna. Esto es lo que hemos seleccionado en la pantalla de la derecha (el valor none para la propiedad Class del botn) y podemos ver su repercusin inmediata en el botn en el form. Si se comparan los dos dilogos de propiedades del control Apply Changes, donde lo nico que ha sido modificado explcitamente por el analista ha sido la clase, podemos ver que implcitamente se han modificado algunas propiedades (el BackColor, ForeColor, BorderWith, etc.). Esto se debe a que estas propiedades se heredan de la clase una vez definida, pero si el analista as lo desea, puede modificarlas para ese control botn, independizndolo de seguir el comportamiento de su clase. Sobre este tema podr profundizar si as lo desea en el curso Desarrollo de Aplicaciones para Internet, tanto presencial como no presencial. Aqu solamente pretendemos tener un barniz del uso de los temas y las clases de los controles.

61

Demo
Cmo crear un modelo dentro de la base de conocimiento?
WIZARD MANUAL

Para definir un nuevo modelo -a excepcin del de Diseo, que se crea automticamente-, debe seleccionarse la opcin File / New Model. GeneXus provee de un wizard para guiar al usuario en los pasos de creacin del nuevo modelo. Si el usuario prefiere no utilizar el wizard e ingresar los distintos datos sin esta gua, deber presionar el botn Manual Creation de la primera pantalla del wizard, y ste se cerrar y se abrir el dilogo Model Properties. A continuacin se detalla parte de la informacin que se deber ingresar: Information Name: Nombre del modelo que se est definiendo. Type: Tipo de modelo (Prototipo o Produccin). Language: Idioma en el que saldrn impresos los textos de los botones, mensajes, etc., que son generados automticamente por GeneXus en los programas de la aplicacin. Los lenguajes soportados son: Espaol, Ingls, Italiano, Portugus y Chino. El valor del lenguaje solo puede modificarse en el modelo de Diseo de la base de conocimiento; los dems modelos heredarn este valor y no podrn modificarlo. Se debe suministrar informacin del ambiente o plataforma para el modelo que se est definiendo: Environment Language: Este es el lenguaje en el cul sern generados los programas usados para la creacin y reorganizacin de la base de datos, y tambin es el lenguaje predeterminado en el que sern generados todos los objetos. Pueden definirse ambientes secundarios en la solapa Environments del dilogo, que permitirn generar algunos de los objetos en otros lenguajes. Los lenguajes soportados por GeneXus son: .NET, .NET Mobile, C/SQL, Cobol para iSeries, Java, RPG para iSeries, Visual Basic, Visual FoxPro.

62

User Interface: Una vez que el lenguaje ha sido elegido, se puede seleccionar el tipo de interfaz que se quiere usar para el ambiente principal: Win o Web Form. Existen lenguajes que solo soportan un tipo de interfaz. DBMS: Aqu se debe seleccionar el DBMS (Database Manager System) sobre el cul operarn los programas en ejecucin. La lista solo incluir aquellos soportados por el lenguaje e interfaz previamente seleccionados. Target Path: Directorio donde estarn ubicados los programas generados. Este directorio ser creado bajo el directorio de la base de conocimiento. El valor predeterminado es DATAnnn, donde nnn representa el nmero de modelo (GeneXus numera secuencialmente los modelos a medida que se van creando). A continuacin se muestra una tabla con los valores de DBMSs posibles para cada lenguaje:

Properties Haciendo clic en el botn Properties se pueden configurar las propiedades para el lenguaje seleccionado. Solemos llamar a estas propiedades: propiedades a nivel del modelo o ms reducido: propiedades del modelo. DBMS Options Haciendo clic en el botn DBMS Options se puede configurar la informacin requerida para el acceso a la Base de Datos (Data Source, etc.) para el lenguaje y DBMS seleccionados. Execution Haciendo clic en este botn, se pueden especificar configuraciones de ejecucin para el lenguaje seleccionado. Save/Load Estos botones permiten almacenar la informacin de las propiedades del modelo en un archivo (y luego recuperarlo). La extensin predeterminada de este archivo es GMP (GeneXus Model Properties). From Model Permite copiar la informacin en forma directa, desde otro modelo de Prototipo / Produccin dentro de la base de conocimiento. Una vez creado un modelo, es posible modificar sus propiedades. Para ello, se debe seleccionar la opcin File / Edit Model, y se presentar el dilogo Model Properties. Suele ser usual acceder al dilogo Model Properties, en especial para utilizar los botones Properties, DBMS Options y Execution para configurar sus propiedades con los valores particulares que se requiera para el modelo. Sin embargo no es usual cambiar en el dilogo Model Properties lo configurado en la seccin Enviroment (ya que si se desea probar la aplicacin para otra plataforma / ambiente, la forma correcta de proceder es crear otro modelo para la plataforma deseada).

63

Qu son los conceptos...?


Anlisis de Impacto Reorganizar Especificar Generar

Cuando se pasa a un modelo de Prototipo o Produccin en una base de conocimiento, GeneXus compara las definiciones realizadas en el modelo de Diseo, con respecto a las definiciones que existan en el modelo al cual se est ingresando. Por ejemplo, si se est ingresando a un modelo de Prototipo o Produccin recientemente definido (y por ende vaco), todos los objetos definidos en el modelo de Diseo sern nuevos para dicho modelo. Y las transacciones definidas, tal como es su objetivo, provocarn la creacin de las tablas que corresponda en la base de datos asociada al modelo de Prototipo o Produccin. Esta comparacin que hace GeneXus entre las definiciones del modelo de Diseo de una base de conocimiento y las definiciones de cierto modelo de Prototipo o Produccin al cual el programador pasa, se llama anlisis de impacto. Este nombre es autodescriptivo: GeneXus analiza el impacto causado por las definiciones del modelo de Diseo sobre un modelo de Prototipo o Produccin. El resultado del anlisis de impacto es un reporte de anlisis de impacto (IAR: Impact Analisis Report) que informa al programador qu cambios fsicos o estructurales habra que realizar en la base de datos asociada al modelo de Prototipo o Produccin en cuestin. Si el programador est de acuerdo con los cambios estructurales informados en el reporte de anlisis de impacto, podr proseguir, pasando a reorganizar la base de datos. El trmino reorganizar refiere a efectuar cambios fsicos en la base de datos. Si en cambio el programador encuentra que algo de lo informado en el reporte de anlisis de impacto no era lo que pretenda lograr, podr no efectuar la reorganizacin, y volver al modelo de Diseo para realizar las redefiniciones que crea convenientes. Cuando se decide efectuar una reorganizacin GeneXus genera programas (en el lenguaje elegido en la definicin de la plataforma del modelo) que implementan las modificaciones a realizar en la base de datos. La ejecucin de estos programas tiene por resultado la obtencin de una nueva versin de la base de datos con los cambios efectuados.

64

Inmediatamente despus de reorganizar la base de datos, se copiarn automticamente las nuevas definiciones del modelo de Diseo al modelo de Prototipo o Produccin en el cual se est trabajando (destino); esto se llama Copy Model y significa que el modelo de Prototipo o Produccin quedar con exactamente las mismas definiciones que el modelo de Diseo. El siguiente paso ser obtener los programas de aplicacin asociados a los objetos GeneXus. Para ello el programador GeneXus deber especificar y generar los programas de aplicacin. Especificar un objeto componen: estructura, definiciones, la validez navegacin, en el cual significa que GeneXus analizar todo lo definido en cada uno de los elementos que lo forms, u otros elementos segn corresponda. GeneXus verificar la sintaxis de las de lo definido, y como resultado de la especificacin mostrar al usuario un listado de informar la lgica que ha interpretado, y si hay alguna advertencia o error.

Luego de especificar un objeto (o conjunto de objetos) y verificar el listado de navegacin resultante, el programador podr indicar a GeneXus que prosiga con la generacin de los programas de aplicacin. Generar un objeto, significa que GeneXus escribir lneas de cdigo que implementen la programacin del mismo, en el lenguaje elegido. Otro ejemplo Como hemos explicado, cuando se pasa a un modelo de Prototipo o Produccin GeneXus realiza una comparacin de las definiciones del modelo de Diseo con respecto a las definiciones que existan en el modelo al cual se est pasando. Esto es, un anlisis de impacto. Si se pasa a un modelo de Prototipo o Produccin al cual ya se haba pasado anteriormente alguna vez, seguramente dicho modelo ya tenga algunas definiciones1 , a diferencia del ejemplo anterior en el cual se trataba de un modelo nuevo y vaco. Si por ejemplo el modelo de Prototipo o Produccin al cual se est pasando tiene definida una transaccin Customer con la estructura: Customer CustomerId* CustomerName CustomerAddress CustomerGender

Numeric(6) Character(20) Character(30) Character(1)

y en el modelo de Diseo se encuentran definidas las transacciones Customer y Product con las siguientes estructuras: Customer CustomerId* CustomerName CustomerAddress CustomerGender CustomerEMail Product ProducId* ProductDescription ProductPrice ProductStock

Numeric(4.0) Character(30) Character(30) Character(1) Character(30)

- Numeric(4.0) - Character(20) - Numeric(10.2) - Numeric(4.0)

el anlisis de impacto determinar que en el modelo de Prototipo al cual se est ingresando, se deber: 1.Agregar el atributo CustomerEMail en la tabla CUSTOMER de la base de datos. 2.Agrandar el largo del atributo CustomerName a Character(30) en la tabla CUSTOMER de la base de datos. 3.Crear la tabla PRODUCT con sus atributos en la base de datos. Estos cambios se informarn en un reporte de anlisis de impacto (IAR: Impact Analisis Report), y el programador deber estudiarlo para decidir si efectuar la reorganizacin o no.

------------------------------------------------------------------------------------------------------------------------1 Cabe la posibilidad de que en una base de conocimiento haya algn modelo de Prototipo o Produccin sin objetos. Esto puede ocurrir por el simple motivo de que se haya creado un modelo, pero luego no se haya ejecutado una reorganizacin en el mismo, ni se hayan copiado las definiciones del modelo de Diseo (Copy Model) tampoco. Sin embargo, el ejemplo trata de un modelo Prototipo en el cual ya se ha ejecutado una reorganizacin y seguidamente se han copiado las definiciones del modelo de Diseo (Copy Model) al mismo.

65

En el caso de decidir reorganizar la base de datos, seguidamente se copiarn automticamente las nuevas definiciones del modelo de Diseo al modelo de Prototipo, quedando ste con exactamente las mismas definiciones que el modelo de Diseo. (Copy Model). Por ltimo slo restar que el programador GeneXus especifique y genere los programas correspondientes a los objetos que hayan sufrido cambios. Concluyendo, hemos explicado varios conceptos que son muy importantes, viendo una primera aplicacin de ellos, y luego una segunda aplicacin de los mismos, con el objetivo de entender qu realiza cada una de estas operaciones y en qu orden se ejecutan.

66

tem Build de la barra de men de GeneXus

Opciones del tem Build para especificar y generar El tem Specify se habilitar cuando se est en un objeto abierto; el objetivo de este tem es especificar el objeto activo. El tem Specify..., abrir un dilogo de seleccin de objetos para seleccionar cules objetos se desean especificar. Y el tem Build All..., permitir especificar todos los objetos del modelo. Vale aclarar que ser exactamente lo mismo seleccionar el tem Specify... y elegir todos los objetos del modelo para ser especificados, que seleccionar directamente el tem Build All.... Cmo indicar que se desea generar los objetos? Luego de especificar uno o varios objetos -mediante cualquiera de los tems anteriores- GeneXus presentar un listado de navegacin por cada objeto especificado; cada listado de navegacin informar cul fue la lgica interpretada para el objeto, y si ser necesario generar el programa de aplicacin asociado al mismo, o no1. La ventana que contiene los listados de navegacin incluir un botn de nombre Generate, que podr ser seleccionado por el programador para continuar con la generacin de los programas de aplicacin que sean necesarios. Adems del botn Generate, se ofrecer tambin un botn Cancel. Es importante tener claro que en caso de seleccionarlo, quedar pendiente la generacin de los programas de aplicacin asociados a los objetos que fueron especificados; esto significa que en la siguiente oportunidad que el programador seleccione el botn Generate as haya especificado en ese momento un solo objeto o varios- se generarn adems de los programas que correspondan ser generados en esa ocasin, todos los programas pendientes de generacin, por haberse especificado anteriormente sin continuar con la generacin2.

-------------------------------------------------------------------------------------------------------------------El motivo por el cual un listado de navegacin podr informar que no ser necesario generar el programa asociado a un objeto, es que el objeto no haya sufrido cambios con respecto a la ltima vez que se gener, y por ende el programa generado antes seguir estando vigente ahora.
1 2

Por esto solemos decir que podemos elegir qu objetos especificar, pero no cules generar.

67

En qu modelos se especifican y generan los objetos? Diseo? Prototipo? Produccin? En los tres tipos de modelos es posible especificar los objetos, pero solamente en los modelos de Prototipo y Produccin se podrn generar los programas de aplicacin asociados a ellos. Recordemos que todo modelo de Prototipo o Produccin tiene asociada una plataforma (base de datos, lenguaje de programacin, interfaz GUI-Windows / Web). En cambio, el modelo de Diseo no tiene asociada una plataforma y por tanto no se generar para el mismo base de datos ni programas. Es por esto que en el modelo de Diseo el programador podr especificar objetos con el nico objetivo de estudiar los listados de navegacin resultantes y con ello poder analizar la lgica interpretada por GeneXus para los mismos. Sin embargo, luego de estudiar listados de navegacin en el modelo de Diseo, no ser posible generar (no se ofrecer el botn Generate). Es en los modelos de Prototipo y Produccin en los que a continuacin de la especificacin de los objetos se ofrecer el botn Generate en la ventana que contiene los listados de navegacin, para que el programador pueda continuar con la generacin de los programas de aplicacin, en la plataforma definida para el modelo. Qu objetos GeneXus se suelen especificar y generar? Todos? Algunos? Solamente es necesario especificar los objetos que hayan sufrido cambios; esto es, objetos nuevos que se hayan definido, u objetos existentes que se hayan modificado. Surge la necesidad en este momento de explicar un punto de suma importancia: en qu modelo de una base de conocimiento se deben realizar las distintas definiciones y/o modificaciones de objetos. nicamente en el modelo de Diseo de una base de conocimiento se podrn definir o editar transacciones, definir o editar atributos, y realizar modificaciones en las estructuras de las transacciones en general (incluyendo definiciones de dominios, ndices y subtipos1). Para ser ms exactos diremos que todas las operaciones que puedan provocar cambios estructurales en las tablas de la base de datos podrn realizarse solamente en el modelo de Diseo. En modelos de Prototipo y Produccin estarn deshabilitadas las operaciones de este tipo, y para realizarlas el programador deber pasar al modelo de Diseo de la base de conocimiento. En modelos de Prototipo / Produccin se podrn realizar definiciones que no provoquen cambios estructurales en las tablas de la base de datos (por ejemplo, crear o modificar objetos reportes, procedimientos, work panels, etc.; modificar reglas o forms de las transacciones, etc.1) y automtica e instantneamente se estarn realizando las mismas definiciones en el modelo de Diseo. Cul es la forma de trabajo entonces? Inicialmente se comienza a trabajar en el modelo de Diseo de una base de conocimiento. Se definen las primeras transacciones y dems objetos y definiciones que se consideren oportunas. Luego el analista deber crear un modelo de Prototipo para probar la ejecucin de las definiciones realizadas; habr un anlisis de impacto, reorganizacin, actualizacin del modelo de Prototipo (Copy Model), y el analista especificar y generar los programas de aplicacin. Se podr ejecutar la aplicacin definida hasta el momento, y luego de ello se continuar trabajando en el modelo de Prototipo. Todas las definiciones y/o modificaciones de objetos que se efecten en el modelo de Prototipo, se efectuarn automticamente en el modelo de Diseo tambin; de modo que ambos modelos irn quedando instantneamente con exactamente las mismas definiciones (sincronizados). Por este motivo es que aconsejamos trabajar en el modelo de Prototipo. Cuando surja la necesidad de realizar definiciones que puedan afectar el diseo de la base de datos (por ejemplo, crear una nueva transaccin, modificar la estructura de una transaccin existente, modificar un dominio, etc.), habr que pasar necesariamente al modelo de Diseo; pero si no, recomendamos trabajar en el modelo de Prototipo, ya que automticamente el modelo de Diseo se estar actualizando tambin.

-------------------------------------------------------------------------------------------------------------------1 Ms adelante en el curso se irn introduciendo estos temas.

68

Qu pasa si trabajamos en el modelo de Diseo? Si en el modelo de Diseo realizamos al menos una definicin que implique modificar el diseo de la base de datos, cuando el programador pase al modelo de Prototipo, GeneXus detectar que habr cambios fsicos para hacer. Habr un anlisis de impacto, reorganizacin y actualizacin del modelo de Prototipo (Copy Model), y lo nico que le restar hacer al analista ser especificar y generar los objetos nuevos (que nunca hayan sido especificados y generados), y los objetos existentes que hayan sido modificados luego de su ltima especificacin. Sin embargo si se trabaja en el modelo de Diseo solamente definiendo objetos que no implicarn modificar estructuralmente la base de datos, cuando el programador pase al modelo de Prototipo, GeneXus no detectar cambios fsicos para hacer, y no efectuar ninguna operacin, ni siquiera la actualizacin del modelo de Prototipo (Copy Model). De modo que las definiciones y modificaciones que se hayan hecho en el modelo de Diseo, no se copiarn automticamente al modelo de Prototipo, y ser responsabilidad del programador hacerlo, seleccionando uno de los tems posibles para ello1. Es sumamente importante que un modelo de Prototipo/Produccin con el cual se est trabajando en determinada etapa (veremos que podrn haber modelos en una base de conocimiento con los cuales no se est trabajando momentneamente), est actualizado con respecto al modelo de Diseo (es decir, que siempre que se trabaje en el modelo de Diseo, al pasar al modelo de Prototipo, se ejecute la operacin Copy Model, ya sea automticamente luego de ejecutar una reorganizacin, o a pedido del analista si no hubo reorganizacin). Si se pasa a un modelo de Prototipo/Produccin y ste no se actualiza con las definiciones del modelo de Diseo (Copy Model), los objetos del modelo de Prototipo/Produccin al cual se pas estarn desactualizados. Si se especifican y generan estos objetos, deber comprenderse que se tratar de definiciones viejas; y si se ejecuta la aplicacin generada, no se vern las nuevas definiciones realizadas, ya que las mismas quedaron hechas en el modelo de Diseo, pero falt que fueran copiadas al modelo de Prototipo, y recin luego de ello, se tendran que haber especificado y generado. Adems, si el analista llegara a modificar objetos desactualizados en el modelo de Prototipo, la prxima vez que realice una actualizacin del modelo de Prototipo (Copy Model), se perdern las modificaciones realizadas en versiones viejas de los objetos, ya que se traern las versiones de los objetos del modelo de Diseo. Concluyendo, hemos recomendado en qu modelo definir qu objetos, cundo habr que pasar de un modelo a otro, y cules pasos seguir. Como dijimos anteriormente, si bien es posible hacerlo en Diseo, la especificacin de los objetos suele realizarse en el modelo de Prototipo. En el modelo de Diseo no se generan programas a continuacin de las especificaciones, y el nico motivo por el cual se podra necesitar especificar algn objeto, sera porque se vaya a seguir trabajando en el modelo de Diseo realizando definiciones, y se necesite corroborar la lgica interpretada por GeneXus acerca de uno o varios objetos que se hayan definido. De modo que no es necesario, ni mucho menos obligatorio, estar especificando los objetos en el modelo de Diseo. En los modelos de Prototipo y Produccin, en cambio, lgicamente ser necesario especificar y generar los objetos que hayan sufrido cambios, previamente a la ejecucin de la aplicacin. Otras opciones del tem Build Todas las opciones que se describen a continuacin se encuentran disponibles nicamente para modelos de Prototipo y Produccin. Build / Impact Database Al seleccionar esta opcin, se ejecutar un anlisis de impacto para el modelo en el cual se est trabajando. Seguidamente se desplegar el reporte de anlisis de impacto correspondiente. Build / Impact From Un anlisis de impacto siempre se efecta comparando las definiciones del modelo de Diseo con las definiciones del modelo actual o destino. No obstante, esta opcin permite realizar un anlisis de impacto tomando cualquier modelo definido en la base de conocimiento como base, en relacin al modelo actual. Al seleccionar esta opcin se desplegar un dilogo para seleccionar cul de todos los modelos definidos en la base de conocimiento se desea tomar como base para realizar un anlisis de impacto para el modelo actual. Es fundamental tener bien claras todas las acciones posibles que pueden desencadenarse al efectuar un anlisis de impacto:

------------------------------------------------------------------------------------------------------------------Existen algunas opciones del men que permiten hacer esto, con algunas variaciones y son las que se presentan al final de esta pgina, bajo el ttulo Otras opciones del tem Build.
1

69

Sin embargo, puede ocurrir que no se desee ejecutar un anlisis de impacto, ni reorganizacin consecuente, ni actualizacin total del modelo actual, sino que solo se deseen copiar algunos de los objetos del modelo de Diseo al modelo actual.

Build / Impact Objects Se desplegar la lista de objetos que tengan diferencias en el modelo de Diseo con respecto al modelo actual y se podrn seleccionar algunos de ellos, para copiarlos al modelo actual. Importante: Deber tenerse en cuenta que aunque la lista muestre todos los objetos que tengan diferencias en el modelo de Diseo con respecto al modelo actual, slo podrn ser copiados aquellos objetos que usen la misma estructura de base de datos en ambos modelos. Por ejemplo, una transaccin no podr copiarse al modelo actual si se le ha agregado un nuevo atributo (en el modelo de Diseo) y an no se ha efectuado la reorganizacin correspondiente. Resulta sencillo de entender que no sea posible solamente copiar una transaccin al modelo actual, si la misma tiene implicada una reorganizacin pendiente para hacer. Para cada objeto de la lista que se haya seleccionado e intentado copiar al modelo actual, se informar si fue posible realizar la copia o no (y en caso negativo, el motivo).

Build / Create Database Se ejecutar un anlisis de impacto para el modelo en el cual se est trabajando, con la particularidad de que se analizar el impacto causado por las definiciones del modelo de Diseo, sobre el modelo actual como si estuviera vaco. En consecuencia el reporte de anlisis de impacto informar que se debern crear todas las tablas con sus estructuras vacas.

70

Ejecucin de las aplicaciones

Build / Run:

Bajo el tem Build de la barra de men de GeneXus, se encuentra la opcin Run para ejecutar las aplicaciones generadas. Al seleccionar Build/Run o F5, se desplegar el dilogo de ejecucin (Execution Dialog) mostrado arriba. El dilogo de ejecucin ofrece todos los programas posibles de ser compilados y ejecutados. Estos son: 1) Developer Menu: Es un programa que GeneXus genera automticamente, y el mismo contiene invocaciones a todos los objetos del modelo, para poder ser ejecutados, y testeados. 2) Objetos que se hayan definido main: Todo objeto puede ser definido main, lo cual significa que ser el principal de un ejecutable. GeneXus generar un ejecutable que contendr al objeto mismo y a todos los que ste llame. Esto permitir ejecutarlo independientemente (en lugar de ejecutarlo mediante el Developer Menu).

71

Modos de las transacciones en tiempo de ejecucin


Al ejecutar una transaccin se pueden distinguir los siguientes modos, dependiendo de la operacin que se realice:
Modo Insert: Indica que se est efectuando una insercin Modo Update: Indica que se est efectuando una actualizacin Modo Delete: Indica que se est efectuando una eliminacin Modo Display: Indica que se est efectuando una consulta

Dependiendo del ambiente de generacin, habr algunas diferencias en lo que se refiere a la operativa de las transacciones en tiempo de ejecucin. No obstante, ms all de la plataforma, cada vez que se realice una operacin de insercin, actualizacin, eliminacin, o consulta a la base de datos a travs de una transaccin, habr un modo asociado.

72

INTEGRIDAD REFERENCIAL

73

Diagrama de Bachman

COUNTRY
1

CountryId* CountryName

CUSTOMER

CustomerId* CustomerName CountryId

El concepto de integridad referencial es un concepto que tiene que ver con las bases de datos relacionales. Se refiere a que debe haber consistencia entre los datos de las distintas tablas de una base de datos relacional. Las tablas de una base de datos relacional se encuentran relacionadas por atributos que tienen en comn. Estas relaciones implican que los datos de las tablas no son independientes, sino que al insertar, modificar y eliminar registros en una tabla, se deben tener en cuenta los datos de las otras tablas para que siempre se conserve la consistencia de la informacin en la base de datos. Si tenemos un modelo de datos relacional con las tablas: COUNTRY (CountryId, CountryName) Clave Primaria: CountryId CUSTOMER (CustomerId, CustomerName, CustomerAddress, CustomerGender, CountryId) Clave Primaria: CustomerId Clave Fornea: CountryId (COUNTRY) El hecho de que el atributo CountryId en la tabla CUSTOMER sea una clave fornea con respecto a la tabla COUNTRY, establece una relacin entre ambas tablas. La relacin entre ellas puede verse en el diagrama que mostramos arriba (Diagrama de Bachman). En el Diagrama de Bachman, la flecha simple representa la existencia de una instancia de la tabla apuntada, para cada instancia de la otra (es decir, que para cada cliente existe un y solo un pas). La flecha doble representa la ocurrencia de varias instancias de la tabla apuntada, para cada instancia de la otra tabla (es decir, que para cada pas, existen muchos clientes). Se dice que la relacin entre la tabla COUNTRY y la tabla CUSTOMER es 1 a N (1 a muchos). Recprocamente, la relacin entre CUSTOMER y COUNTRY es N a 1 (muchos a 1).

74

Diagrama de Bachman
COUNTRY
1 N
Hay que verificar existencia del COUNTRY referenciado.

CUSTOMER

En transaccin Customer: si se inserta nuevo registro, o si se modifica el CountryId de un registro

COUNTRY
1 N

En transaccin Country: si se quiere eliminar un registro

CUSTOMER

Hay que verificar la no existencia de ningn CUSTOMER que lo referencie.

En la terminologa GeneXus, decimos que existe una relacin de subordinacin entre ambas tablas. Decimos que: COUNTRY est superordinada a CUSTOMER CUSTOMER est subordinada a COUNTRY Significando que: Cuando se crea o modifica un registro en la tabla subordinada (CUSTOMER), debe existir el registro relacionado en la tabla superordinada (COUNTRY). Cuando se elimina un registro en la tabla superordinada (COUNTRY), no deben existir registros relacionados en la tabla subordinada (CUSTOMER).

Debido a esta relacin entre las tablas, la informacin contenida en ellas no es independiente, y es necesario realizar controles para que los datos sean consistentes. A estos controles se les llama de Integridad Referencial y bsicamente son los siguientes: Cuando se inserta o modifica un registro en la tabla CUSTOMER, el valor ingresado en el atributo que es clave fornea (CountryId), debe existir como valor de clave primaria de un registro en la tabla COUNTRY. Cuando se elimina un registro en la tabla COUNTRY, no deben existir registros en la tabla CUSTOMER cuyos valores de la clave fornea (CountryId), sean iguales al valor de la clave primaria del registro que se desea eliminar. GeneXus genera los programas asociados a las transacciones, incluyendo en el cdigo generado estos controles de Integridad Referencial. Por esta razn, si el usuario final inserta (o modifica) un cliente a travs de la transaccin "Customer", se validar automticamente que el valor ingresado en el cdigo de pas CountryId, exista como clave primaria de un registro en la tabla COUNTRY. En caso de fallar este control de integridad referencial, un mensaje se le desplegar al usuario indicndole que no se encontr ese pas.

75

ndices

Los ndices son vas de acceso eficientes a las tablas. GeneXus crea automticamente algunos de ellos, y los otros debern ser creados por el programador cuando ste as lo determine, basndose en criterios de optimizacin. Existen cuatro tipos de ndices en GeneXus: Primarios Forneos De usuario Temporales

De todos ellos, los nicos que no son creados automticamente por GeneXus son los de usuario. En cuanto a los tipos de ndices que son creados por GeneXus, la diferencia que hay entre ellos es el momento en que son creados y el tiempo durante el cual se mantienen. - Los ndices primarios y forneos son creados al momento de crear o reorganizar las tablas que componen la base de datos, y de ah en ms son mantenidos automticamente por GeneXus. - Los ndices temporales, en cambio, son creados al ejecutar las aplicaciones, para acceder a tablas ordenadas por algn atributo o conjunto de atributos para el/los que no existe un ndice de usuario creado; stos se crean en tiempo de ejecucin de las aplicaciones, se utilizan, y luego se eliminan. NDICES PRIMARIOS Y FORNEOS GeneXus crea para cada tabla un ndice por su clave primaria (ndice primario), y un ndice por cada clave fornea que la tabla tenga (ndices forneos). Por qu crear ndices primarios y forneos para las tablas desde el comienzo en forma automtica, siendo que luego deben ser mantenidos? Sean las tablas COUNTRY y CUSTOMER, que vimos un par de pginas atrs, creadas en nuestro modelo de datos a partir de las estructuras de las transacciones "Country" y "Customer. Existe entre estas tablas una relacin 1-N, que viene dada por el hecho de que el atributo CountryId en la tabla CUSTOMER es una clave fornea con respecto a la tabla COUNTRY.

76

ndices primarios y forneos


CountryId* CountryName
PK

ICountry

ICustomer CustomerId* CustomerName ... FK ICustomer1 CountryId

PK

CountryId CountryName 1 2 3 Uruguay United States China

CustomerId 4 1 3 2

CustomerName Ana Diez Juan Prez Mara Donoso Jessica Deep

CountryId 1 1 1 2

Si en transaccin Country queremos eliminar United States:

El programa debe buscar sobre CUSTOMER si registro con CountryId = 2 para hacer eficiente esta bsqueda: ndice forneo (ICustomer1)

Por existir esta relacin, GeneXus incluye en los programas asociados a las transacciones "Country" y "Customer", los controles de integridad referencial pertinentes. Estos controles son: Si el usuario final inserta o modifica un cliente a travs de la transaccin "Customer", se validar automticamente que el valor ingresado en la clave fornea CountryId exista como clave primaria de un registro en la tabla COUNTRY. En caso de fallar este control de integridad referencial, se le indicar al usuario que no se encontr ese pas. Para controlar esto, se debe buscar en la tabla COUNTRY la existencia de un registro que tenga ese valor de CountryId como clave primaria; dado que se debe consultar la tabla COUNTRY, buscando por la clave primaria, resulta evidente que la bsqueda puede optimizarse si existe un ndice por la clave primaria en dicha tabla. Si el usuario final intenta dar de baja un pas a travs de la transaccin Country, se validar automticamente que no existan clientes con dicho pas asociado, como clave fornea; en caso de encontrar un registro en la tabla CUSTOMER, cuyo valor de clave fornea CountryId sea el que se desea eliminar, se le indicar al usuario que no es posible eliminar el pas (ya que de lo contrario quedaran datos inconsistentes en la base de datos). Para controlar esto se debe consultar la tabla CUSTOMER, buscando por la clave fornea CountryId. Esta bsqueda ser ptima si existe un ndice por CountryId en la misma. Control de unicidad de clave primaria Otro control que GeneXus tambin incluye en los programas asociados a las transacciones es la unicidad de la clave primaria; esto es, en ninguna tabla podrn existir dos registros con el mismo valor en la clave primaria. Para controlar esto, cuando el usuario final intenta insertar un registro se valida automticamente que el valor ingresado para la clave primaria no exista ya como clave primaria de otro registro en la tabla. Para hacer esta bsqueda con eficiencia, se debe utilizar el ndice primario de la tabla. Concluyendo, GeneXus al crear cada tabla de la base de datos crea tambin su ndice primario, y un ndice forneo por cada clave fornea que la tabla contenga. La creacin de estos ndices permite realizar los controles de integridad referencial y de unicidad de clave primaria accediendo a las tablas de forma eficiente.

77

ndices de usuario
Los crea el analista sobre una tabla. Deber categorizarlos segn si aceptar valores repetidos (duplicate) o no (unique).

Si en la realidad modelada, un mismo nombre se puede repetir para dos clientes:


CustomerId 1 2 3 CustomerName Ana Ana Mara CountryId 1 2 1

NDICES DE USUARIO Estos ndices deben ser definidos explcitamente por automticamente. Se dividen en duplicate y unique. el analista. No son definidos

Un ndice de usuario duplicate es aquel que se define para atributos de una tabla para los que pueden existir varios registros con el mismo valor en los mismos (es decir, se define para atributos que no son una clave candidata). Este tipo de ndices se define fundamentalmente para acceder a los datos ordenados por determinados atributos de forma eficiente. A modo de ejemplo, suponiendo que el nombre de cliente no es clave en la tabla CUSTOMER (sus valores se pueden repetir) podremos definir un ndice de usuario duplicate por el atributo CustomerName, siendo muy til para realizar consultas y listados que se necesite salgan ordenados por nombre. Un ndice de usuario unique se utiliza para especificar que un conjunto de atributos es clave candidata en una tabla (diferente de la clave primaria). Esta es la forma de representar claves candidatas en el modelo de datos. Con ello logramos que GeneXus incorpore automticamente el control de unicidad correspondiente en las transacciones asociadas. A modo de ejemplo, si el nombre de cliente no se puede repetir, la forma de representarlo y lograr que GeneXus lo controle automticamente es definiendo en la tabla CUSTOMER un ndice de usuario unique por el atributo CustomerName.

78

ndices de usuario
Si un mismo nombre no puede repetirse (es por tanto un atributo clave de la tabla)
CustomerId 1 2 3 CustomerName Ana Diez Ana Prez Mara Rua CountryId 1 2 1

La forma de definir claves candidatas en el modelo de datos es a travs de ndices unique. GeneXus pasar a incorporar controles en las transacciones, utilizando el ndice, para no permitir la insercin de registros duplicados.
Si se intenta ingresar un nuevo cliente con nombre Ana Prez la transaccin dar un error de registro duplicado.

ndices unique (claves candidatas) En una tabla de la base de datos pueden existir varios conjuntos de atributos cuyos valores sean nicos en la realidad. Se dice que cada uno de esos conjuntos es una clave de la tabla. Luego, el analista elige una de las claves como la clave primaria. GeneXus identifica la clave primaria de la tabla de acuerdo a los atributos que fueron calificados por el analista con el smbolo de llave. Supongamos que en la realidad adems de poder identificar a un cliente por su cdigo, tambin se lo puede identificar por su cdula de identidad. En este caso tanto el atributo CustomerId como el atributo CustomerSSN (donde se almacena la cdula de identidad) seran claves de la tabla CUSTOMER. Al indicar que CustomerId es el identificador de la transaccin, GeneXus crear automticamente un ndice primario por dicho atributo y controlar la unicidad de los valores ingresados para el mismo. Y qu suceder con la cdula de identidad del cliente? Al ser este atributo clave, quisiramos que GeneXus obrara de igual manera, no permitiendo que se ingrese un registro, si es que ya existe otro con el mismo valor de cdula de identidad (CustomerSSN). Para poder controlar esto de forma eficiente, GeneXus debera contar con un ndice por cada atributo clave. La forma de definir en GeneXus que un atributo o conjunto de atributos es clave alternativa o candidata y que por lo tanto se debe chequear su unicidad, es definiendo un ndice de usuario compuesto por ese atributo o conjunto de atributos, y calificndolo de unique en lugar de duplicate, que es el valor por defecto de un ndice de usuario. A partir de all, GeneXus incluir en la lgica de la transaccin ese control de unicidad utilizando ese ndice definido por el usuario. En resumen, las transacciones GeneXus realizan automticamente los siguientes controles: Integridad referencial Unicidad de clave (tanto primaria como candidatas)

79

ndices temporales
Son creados automticamente, bajo ciertas condiciones, cuando son necesarios, y se eliminan cuando termina la ejecucin del objeto que los cre. Si se desea acceder a los datos ordenados por determinados atributos, pero no se desea crear un ndice permanente para ello: GeneXus crear un ndice temporal.
Se crean solamente en algunas plataformas (como Visual FoxPro con base de datos local, o en iSeries). En otras plataformas, las consultas para las cuales se quiere obtener el resultado ordenado por determinados atributos, y no existe el ndice de usuario, son resueltas por el DBMS correspondiente sin la creacin de ndices temporales.

El usuario puede resolver dejar de utilizar un ndice temporal, creando un ndice de usuario.

NDICES TEMPORALES Si se desea acceder a los datos ordenados por determinados atributos, pero no se desea crear un ndice permanente para ello (por ejemplo, porque se trata de una consulta que se realiza con muy poca frecuencia), entonces, dependiendo de la plataforma, se crear un ndice temporal.

80

Manejo de nulos

Para cada atributo no inferido, ni identificador en la estructura de una transaccin, es posible definir si admitir nulos o no, en la tabla asociada

La permisin o no del valor <NULL> en la base de datos es muy importante en el modelo relacional. Permitir el valor null para un atributo dado, significa que puede, bajo ciertas circunstancias, ser ignorado dado que es valor no especificado. Por otro lado, si un atributo no permite valor null, un valor vlido siempre deber asignarse a l. La propiedad Nulls (presentada como columna en el editor de estructuras de transacciones), permite configurar para cada atributo si admite o no valor null en la tabla asociada. Los atributos para los cuales puede configurarse esto, es para aquellos almacenados en la(s) tabla(s) asociada(s) a la transaccin (es decir, no inferidos) siempre y cuando no sean atributos primarios en dichas tablas (ya que por definicin las claves primarias no soportan valor null). Resumiendo: el objetivo de esta propiedad es definir qu valor se va a almacenar en la base de datos cuando no digitemos nada en el campo (el valor <NULL> o el valor empty).

81

Manejo de nulos
Valores posibles que ofrece la propiedad Nulls: - No: el atributo en la tabla asociada, no permitir valor null
- Yes: el atributo en la tabla asociada, s admitir valor null
Valor por defecto

Atributos parte de la clave primaria no soportan valor null (propiedad Nulls = No, siempre) Atributos clave fornea s, y esto tendr repercusin en los controles de integridad referencial.

Los valores posibles de configurar para la propiedad Nulls son: No: significa que el atributo no permitir el valor null en la tabla asociada (valor por defecto) Yes: significa que el atributo s admitir el valor null en la tabla asociada La definicin de nulls es utilizada por GeneXus al momento de crear / reorganizar las tablas de la base de datos, ya que el soporte o no soporte de nulabilidad de los atributos en su tabla, se define a nivel de la base de datos. O sea que modificar el valor de la propiedad Nulls para un atributo implicar ejecutar una reorganizacin (para redefinir a nivel de la base de datos el soporte de nulabilidad del atributo en su tabla).

82

Manejo de nulos
Repercusin en controles de integridad referencial CountryId* CountryName CountryId* CityId* CityName CustomerId* CustomerName CountryId CityId

FK compuesta

1) CountryId y CityId con propiedad Nulls=No


Se realizan los chequeos de IR mostrados arriba

2) CityId con propiedad Nulls=Yes


Se agrega un control de IR en CUSTOMER realizar chequeo contra COUNTRY. si se deja nulo CityId, se

Repercusin en controles de integridad referencial La definicin de nulls para atributos que conforman una clave fornea le dice a GeneXus cun fuerte es la referencia a la otra tabla. Si ninguno de los atributos que componen una clave fornea permiten valores nulos (caso 1), se tratar de una referencia fuerte (tambin conocida como not null reference), ya que establece que la FK deber siempre apuntar a un registro existente de la tabla referenciada. Por el contrario, una clave fornea que tenga al menos un atributo que soporte nulos (caso 2), establece una referencia dbil (tambin conocida como null reference), ya que si alguno de los atributos que conforman la clave fornea son nulls, entonces la referencia no ser chequeada. Cuando una clave fornea es compuesta y estn permitidos los nulos para algunos de sus atributos, pueden aparecer nuevas referencias (no chequeadas en caso de tratarse de referencias fuertes) si los atributos que restan componen tambin una clave fornea. Un ejemplo es el que presentamos arriba, donde en caso de que el usuario deje nulo el valor de CityId para un cliente, se realizar el chequeo de IR contra COUNTRY, para asegurarse que el pas ingresado sea correcto.

83

Manejo de nulos
Diferencia entre valor empty y null para atributos:
empty: es un valor (0 para Numeric, para Character, etc.) null: si est permitido, no es un valor. Significa que el valor debe ser considerado como: no especificado no disponible no asignado desconocido

Mtodos segn si atributo permite null o empty:


IsEmpty IsNull SetEmpty SetNull

Mtodos para trabajar con nulos y vacos IsEmpty, IsNull: devuelven true en caso de que el atributo contenga valor empty o null respectivamente. SetEmpty, SetNull: configuran en el atributo el valor empty o null, respectivamente. Ejemplos: * error(You must specify a name) if CustomerName.IsEmpty(); * msg(Warning: You didnt specify a Country) if ContryId.IsNull();

84

TABLA BASE Y TABLA EXTENDIDA

85

Tabla Base y Tabla Extendida


Definicin
Dada una tabla X de la base de datos, a la cual llamamos tabla base, se denomina tabla extendida de la misma al conjunto de atributos conformado por: Atributos que pertenecen a la tabla X. Atributos de toda tabla Y, tal que la relacin entre la tabla extendida determinada hasta el momento y la tabla Y sea N-1.

Los criterios de normalizacin del diseo de la base de datos apuntan a minimizar la posibilidad de inconsistencia en los datos. Una base de datos diseada de esta manera tiene una serie de ventajas importantes (tal es as que actualmente la normalizacin de datos es un estndar de diseo), pero se deben tener en cuenta tambin algunos inconvenientes. El inconveniente ms notorio es que los datos se encuentran dispersos en muchas tablas, y por lo tanto cuando se quieren hacer consultas ms o menos complejas a la base de datos, se debe consultar una cantidad importante de tablas. As, por ejemplo, si el siguiente Diagrama de Bachman representa nuestro modelo de datos:

para listar las facturas sera necesario consultar las tablas: INVOICE e INVOICELINE (lneas de Facturas), CUSTOMER, COUNTRY y PRODUCT. Para simplificar esta tarea GeneXus utiliza el concepto de tabla extendida. Llamamos tabla base a cualquier tabla de la base de datos en la cual estemos posicionados en determinado momento; y dada cierta tabla base, su tabla extendida comprender a todos los atributos de la propia tabla base, ms todos los atributos de las tablas que tengan informacin relacionada unvocamente con la tabla base (relacin N-1 desde la tabla base, directa e indirectamente).

86

Tabla Base y Tabla Extendida


INVOICE
InvoiceId* InvoiceDate CustomerId

CUSTOMER
CustomerId* CustomerName CountryId

COUNTRY
CountryId* CountryName

INVOICELINE
InvoiceId* ProductId* InvoiceLineQuantity InvoiceLineAmount

PRODUCT
ProductId* ProductDescription ProductPrice ProductStock

Utilizando el Diagrama de Bachman es fcil determinar cul es la tabla extendida correspondiente a una tabla base cualquiera: Partiendo de la tabla base, se deben seguir las relaciones N-1, (es decir, se deben seguir las flechas que tienen punta doble partiendo desde la tabla base, y punta simple en el otro extremo). Todas las tablas a las cuales se pueda llegar siguiendo las flechas que representan relaciones N-1 desde la tabla base, formarn parte de su tabla extendida.

87

Tabla Base y Tabla Extendida

Para cada tabla de nuestro modelo de datos, describimos cul es su tabla extendida.

88

Descripciones en vez de Cdigos

Country Transaction CountryID* CountryName Customer Transaction CustomerID* CustomerName CountryID CountryName
Este atributo no es CountryName, sino CountryId disfrazado de CountryName. Se muestra (y acepta) en ejecucin el valor de CountryName, mientras que lo que se almacena es CountryId.

Hasta ahora hemos visto que el usuario final debe manipular los cdigos con los que el sistema identifica a sus entidades. Por ejemplo, a la hora de ingresar un nuevo cliente a un sistema, vimos que el usuario final ingresa el cdigo del pas de ese cliente y a continuacin se le muestra en forma inferida, el nombre correspondiente a ese pas. Para ello debe memorizar un cdigo que no tiene demasiada carga semntica (ninguna cuando stos son numricos) o apelar a prompts para poder buscar por descripcin o nombre y recuperar as el cdigo a ser colocado en el campo. Sin embargo no es necesario condenar al usuario a que manipule cdigos. Puede manipular las descripciones, que son las que contienen la semntica y el programa se encargar del resto. Es posible (tanto en Win como Web, Java y .Net) que el usuario trabaje en pantalla con la descripcin, CountryName, y que automticamente se resuelva la manipulacin del cdigo, CountryId. Cmo? Modificando el valor de la propiedad InputType del atributo CountryId. El usuario ver en pantalla el CountryName, pero el atributo que muestra esos valores no es CountryName! Por el contrario, es el atributo: CountryId disfrazado de CountryName. Mientras el usuario escribe Uruguay internamente se realiza una bsqueda en la tabla COUNTRY para recuperar el cdigo correspondiente a ese nombre. Ese valor, en nuestro ejemplo, 1, es el que realmente queda almacenado all. Pero para el usuario esto es absolutamente transparente. Para que esto pueda lograrse, deber haber una relacin biunvoca entre el cdigo (o identificador) y la descripcin. Es decir, para cada descripcin solo existir un cdigo asociado. En el ejemplo, no deber haber dos o ms pases con el mismo nombre y distinto identificador, porque en ese caso no es posible realizar el matcheo. Dicho en otras palabras: el atributo descriptivo deber ser una clave candidata de la tabla, es decir, deber existir un ndice unique para ese atributo. En caso de no existir, en el listado de navegacin de la transaccin se mostrar la siguiente advertencia: Spc0107 Candidate Key CountryName for CountryId may have duplicated values. y en ejecucin, si el usuario selecciona un valor duplicado (para el que existen varios CountryId) dar un error Country is ambiguous, dado que no sabr con cul quedarse.

89

Descripciones en vez de Cdigos


Propiedad InputType del atributo identificador
Valores posibles: Values
atributo real: lo que muestra es su contenido

Descriptions

atributo disfrazado: toma las descripciones de otro atributo, aunque su contenido sigue siendo el propio.

En la figura se muestra el dilogo de definicin del atributo CountryId. Como podemos ver, en la solapa Control Info del dilogo de definicin del atributo, aparece la propiedad InputType. Esta propiedad solo se ofrece cuando el atributo est asociando a un control de tipo Edit (no Radio Button, Combo, etc.). Esta propiedad puede tomar uno de dos valores: Values: representa el comportamiento conocido, es decir, el control en el form en ejecucin mostrar los valores que contiene (cdigos). Descriptions: aqu es donde le indicamos que queremos que disfrace sus valores en ejecucin, mostrndole al usuario no sus valores reales, sino los asociados y definidos en la propiedad que se habilita: Descriptions from. En la propiedad Descriptions from se debe indicar de qu atributo se tomarn las descripciones. Evidentemente este atributo no puede ser cualquiera: debe tener una relacin biunvoca con el que estamos definiendo, y adems, debe ser un atributo de descripcin, es decir, un atributo cuyo tipo de datos sea Character o Varchar. De lo contrario se arrojar el siguiente error de especificacin: spc0112: Item value %1 for control %2 must be Character or VarChar.

90

Como en casi todos los casos, cuando una propiedad tiene que ver con la forma en que un atributo funciona a nivel de pantalla (control), existe la posibilidad de configurar su comportamiento: 1- En forma centralizada: Es decir, a nivel de la definicin del atributo en s (en la solapa Control Info asociada a la definicin del atributo), para que aplique por defecto en todos los forms en donde el atributo est presente como control 2- En forma particular: Es decir, para un control atributo en concreto de un form determinado (en la solapa Control Info asociada a la definicin del control).

Definicin en forma centralizada (a nivel del atributo) En el caso de configurar la propiedad IntputType a nivel de atributo, en toda transaccin en la que este atributo sea clave fornea (FK), GeneXus colocar en el form de la transaccin, el valor de la propiedad Title, del atributo elegido como descriptor (en este caso el title de CountryName) y a su lado al atributo identificador (en este caso la FK CountryId), que mostrar los valores de CountryName, pero almacenar los de CountryId. Como resulta evidente, ya no es necesario que en el form se coloque el atributo real CountryName, porque el atributo CountryId se disfraz de l. El usuario no sabr que mientras l est seleccionando o escribiendo un nombre de pas, en realidad lo que se est grabando en ese atributo es el cdigo o identificador correspondiente. GeneXus quita automticamente del form el atributo descriptor al momento en que la FK es definida con InputType= Description. Sin embargo, el atributo descriptor debe estar presente en la estructura de la transaccin, pues de lo contrario dar el siguiente error al especificar: Spc0109 CountryName is (part of) a candidate key. It must be referenced in the transactions structure. En la transaccin en la que el atributo identificador con InputType=Description es clave primaria, como resulta evidente, no toma ningn efecto esta propiedad. Es decir, en la transaccin Country el atributo CountryId se ver en ejecucin conteniendo cdigos, y el atributo CountryName esperar ser ingresado con datos del usuario.

91

Descripciones con autocomplete


Propiedad Suggest

Podemos hacer que en lugar de que el usuario tenga que recordar los valores existentes para ingresar uno correcto, se le sugieran los valores posibles para ese control, de modo que l pueda elegir el que deseaba y que ser necesariamente correcto. Aqu estamos combinando 2 propiedades: InputType y Suggest, lo que no es obligatorio.

La propiedad Suggest posibilita brindarle una ayuda til al usuario final, para que elija en tiempo de ejcucin para un control edit, entre un conjunto de valores posibles y no tenga que recordar exactamente el valor. Al igual que la propiedad InputType, aplica a controles edit y puede ser usada tanto en transacciones, como en Web y Work panels, objetos de los que hablaremos ms adelante. Habilitando la propiedad Suggest en un control edit, se conseguir que una lista de posibles valores para ese control sea desplegada al usuario, debajo del control. La lista de sugerencias puede ser calculada de un modo incremental (la lista ser actualizada con las entradas del usuario) o haciendo pedidos explcitos (el usuario manualmente tendr que hacer un pedido para que se calculen las sugerencias y se le muestren). La actualizacin de la lista es asincrnica y los tiempos de clculo dependen de la calidad de la conexin. Esta propiedad es independiente de la propiedad InputType, aunque la utilizacin combinada de ambas producir aplicaciones con interfaces mucho ms amigables para el usuario.

92

Descripciones con autocomplete


Propiedad Suggest
El control para CountryId disfrazar sus valores por los de CountryName, que ahora le sern sugeridos al usuario a medida que vaya digitando letras del nombre Valores posibles: Incremental No OnRequest

Si miramos un par de pginas atrs, cuando vimos la propiedad InputType, tenamos la misma pantalla de propiedades para el atributo CountryId, solo que el valor que tenamos especificado en la propiedad Suggest era el valor por defecto: No. En ese caso el usuario tena que digitar el nombre del pas sin recibir ayuda alguna. Si se cambia el valor de esta propiedad a Incremental u OnRequest se brindar ayuda al usuario para que elija en tiempo de ejecucin entre los valores posibles y no tenga que recordar exactamente el valor. Valores de la propiedad Suggest: Incremental: Se le irn sugiriendo al usuario los valores que correspondan con lo que haya digitado hasta el momento. Es incremental, puesto que va reduciendo el rango de lo mostrado interactivamente a medida que el usuario va agregando letras a lo que lleva digitado hasta el momento. OnRequest: La nica diferencia que tiene el valor Incremental es que en este caso no es interactivo. El usuario ingresar el substring que recuerde de la palabra y luego pedir explcitamente las sugerencias de las palabras que empiecen por o contengan esa cadena. Por ejemplo, si el usuario final sabe que un cliente que est buscando tiene apellido Prez, pero no recuerda el nombre, puede escribir Prez y pedir las sugerencias. Si tuviera configurado el valor Incremental en esta propiedad, entonces al digitar P de Prez ya se le traeran todos los nombres de clientes que empiezan con P y se ira afinando la bsqueda a medida que siga escribiendo letras. No: no sugiere nada. Este es el valor por defecto, y en este caso el usuario no recibir ningn tipo de ayuda para ingresar el valor en el campo. Para lograr que el usuario trabaje con descripciones en lugar de cdigos, otra posibilidad es configurar que el atributo CountryId utilice el control: combo box dinmico (indicndose tambin en este caso, que se muestren los nombres de los pases existentes en la tabla COUNTRY (CountryName), mientras que al momento de seleccionar uno en el combo, quedar el cdigo correspondiente en el atributo CountryId.

93

Reglas
Se utilizan para definir el comportamiento de las transacciones. Algunas reglas: Default Asignacin Msg Error Noaccept Add Subtract Serial Update Pueden incluir: atributos, variables, constantes y funciones. Son LOCALES a la transaccin. Programacin DECLARATIVA.

Las reglas, en el objeto transaccin, cumplen un rol muy importante ya que permiten programar su comportamiento (por ejemplo: asignar valores por defecto, definir controles sobre los datos, etc.). Se escriben de forma declarativa, es decir que el orden en el que se escriben no significa que sea el orden en el que se ejecutarn. Pueden involucrar a los atributos definidos en la estructura de la transaccin1, as como a variables definidas dentro del objeto, constantes y funciones. Son solo vlidas dentro de la transaccin en la que estn definidas, es decir, son locales.

-------------------------------------------------------------------------------------------------------1 Todas las reglas de transacciones pueden involucrar atributos de las tablas base asociadas a la transaccin; y la mayor parte de ellas puede tambin involucrar atributos de las tablas extendidas de dichas tablas base. Para poder referenciar un atributo en una regla, el mismo deber estar incluido en la estructura de la transaccin (ya sea que pertenezca a alguna de las tablas base asociadas a la transaccin, o a sus tablas extendidas).

94

Algunas reglas vlidas para transacciones son:

Default
OBJETIVO: Permite asignar un valor por defecto a un atributo o variable; el valor por defecto inicializar al atributo o variable si se est realizando una insercin por medio de la transaccin (modo Insert), pero el usuario final podr cambiarlo si ese valor no es el que desea. SINTAXIS: Default( att | &var, exp ); DONDE: att: es un atributo perteneciente a alguna de las tablas base asociadas a la transaccin. var: es el nombre de una variable. exp: es una expresin que puede involucrar constantes, funciones, variables u otros atributos. FUNCIONALIDAD: Esta regla asigna el valor de la expresin exp como valor por defecto del atributo att o variable var, cuando la transaccin se ejecuta en modo Insert. Esta regla no es vlida para atributos que forman parte de la clave primaria de alguno de los niveles de la transaccin, porque es disparada luego de que la clave es ingresada (ya que solo en ese momento el modo es conocido y esta regla se dispara solo en modo Insert). EJEMPLOS: Default( InvoiceDate, &today ); /*Regla definida en la transaccin Invoice*/

Cuando se est insertando una factura nueva, se sugiere como valor de InvoiceDate el valor contenido en la variable del sistema today. Default( InvoiceDate, Today()); /*Regla definida en la transaccin Invoice*/

Anloga a la anterior, solo que en lugar de utilizar la variable del sistema today, se utiliza la funcin Today que devuelve la fecha correspondiente al da. Default( InvoiceLineAmount, ProductPrice*InvoiceLineQuantity); /* Regla definida en Invoice */ Cuando se est insertando una lnea de factura, se sugiere que el atributo InvoiceLineAmount (importe de la lnea) tome el valor resultante de evaluar la expresin ProductPrice*InvoiceLineQuantity (precio del producto por cantidad llevada del mismo). Nota: El tipo de datos de la expresin debe coincidir con el tipo de datos del atributo o variable

Regla de asignacin
OBJETIVO: Permite asignar a un atributo o a una variable, el valor de una expresin. SINTAXIS: att | &var = exp [if cond] [on evento/momento de disparo]; DONDE: att: es un atributo perteneciente a alguna de las tablas base asociadas a la transaccin, o a sus tablas extendidas (debe estar declarado en la estructura). var: es el nombre de una variable. exp: es una expresin que puede involucrar constantes, funciones, variables u otros atributos, y debe ser del mismo tipo que att o var. cond: es una expresin booleana (puede contener los operadores lgicos and, or, not) evento/momento de disparo: es uno de los eventos predefinidos de GeneXus disponibles para reglas de transacciones, que permiten definir el momento especfico de ejecucin de una regla. FUNCIONALIDAD: Una regla de este tipo permite asignar al atributo o variable de la izquierda, el valor resultante de evaluar la expresin. Como puede verse, la condicin es opcional; de no ponerla, la asignacin se realiza siempre. La asignacin a un atributo, implica su actualizacin en el registro que corresponda. Se pueden definir reglas de asignacin a atributos de alguna de las tablas bases asociadas a la transaccin, e incluso de sus tablas extendidas. Esto significa que pueden actualizarse atributos inferidos en una transaccin (siendo necesario declararlos en la estructura). EJEMPLO: InvoiceLineAmount = ProductPrice*InvoiceLineQuantity; /*Regla definida en la transaccin Invoice*/

Si el importe de cada lnea de una factura se calcula siempre multiplicando el precio del producto por la cantidad llevada del mismo, podemos utilizar esta regla de asignacin para liberar al usuario de realizar el clculo.

95

Error
OBJETIVO: Permite desplegar un mensaje de error si la condicin se satisface. Sirve para definir los controles que deben cumplir los datos. SINTAXIS: Error( msg | &var | character expresion, msgId ) if cond [on evento/momento de disparo]; DONDE: msg: es un string con un mensaje de error a desplegar. var: es el nombre de una variable de tipo character, que contiene un string con un mensaje de error a desplegar. character expression: es una expresin cuyo tipo resultante es character y que ser desplegada. msgId: es un string (sin espacios en blanco ni comillas) que ser utilizado solo si la transaccin es definida tambin como business component1. cond: es una expresin booleana (que puede contener los operadores lgicos and, or, not) evento/momento de disparo: es uno de los eventos predefinidos de GeneXus disponibles para reglas de transacciones, que permiten definir el momento especfico de ejecucin de una regla. FUNCIONALIDAD: Esta regla despliega el mensaje del parmetro msg, var o character expresion, si la condicin cond que se evala resulta verdadera. El mensaje de error se despliega en una ventana popup cuando el ambiente de trabajo es Windows y en el control Error Viewer y/o un cuadro de texto cuando el ambiente de trabajo es Web, deteniendo cualquier actualizacin a la base de datos. Cuando la transaccin se ejecuta como business component1, de dispararse el error, generar una entrada en el SDT messages, con identificador msgId. EJEMPLOS: Error(No se permiten clientes sin nombre) if CustomerName.isEmpty(); /*Regla definida en la transaccin Customer*/ Se evala la condicin CustomerName.isEmpty(), y si sta se satisface, se despliega el mensaje No se permiten clientes sin nombre en pantalla. No se permite continuar hasta que el usuario ingrese un nombre en el campo CustomerName o abandone la transaccin (en cuyo caso no se har en la base de datos actualizacin alguna). Error(No se permite eliminar facturas) if Delete; /* Regla definida en la transaccin Invoice */ Se necesita prohibir la eliminacin de facturas. Con esta regla, si el usuario intenta realizar una eliminacin, la condicin dar True y se disparar la regla, evitando la eliminacin.

Msg
OBJETIVO: Permite desplegar un mensaje de advertencia si la condicin se satisface. SINTAXIS: Msg( msg | &var | character expresion, msgId) if cond [on evento/momento de disparo]; DONDE: msg, var, character expresion, msgId, cond, evento/momento de disparo: son los mismos que para la regla error. Observar que la sintaxis es exactamente la misma. FUNCIONALIDAD: Esta regla se utiliza para presentar mensajes de advertencia al usuario. Despliega el mensaje del primer parmetro, si la condicin se satisface, anlogamente a la regla Error; pero a diferencia de esta ltima, permite continuar con la ejecucin si la condicin sigue satisfacindose. Del mismo modo, si la transaccin es business component1, de dispararse la regla genera entrada en el SDT messages. Los mensajes de advertencia se despliegan en una ventana popup en ambiente Windows y en el Error Viewer o cuadro de texto en ambiente Web. EJEMPLO: Msg( No se permiten clientes sin nombre ) if CustomerName.isEmpty(); /*Regla definida en la transaccin Customer*/ Se evala la condicin CustomerName.isEmpty(), y si sta se satisface se despliega el mensaje No se permiten clientes sin nombre. A diferencia de lo que ocurre con la regla Error, aqu s se permite continuar la ejecucin, pues no se trata de un error sino de una advertencia.

-------------------------------------------------------------------------------------------------------------------------------1 Estudiaremos este tema ms adelante en el curso.

96

Noaccept
OBJETIVO: Permite indicar que los atributos no aceptarn valores por parte del usuario (sern solo de salida). SINTAXIS: Noaccept( att1[, atti]) [if cond]; DONDE: atti: es un atributo perteneciente a alguna de las tablas bases asociadas a la transaccin. cond: es una expresin booleana (puede contener los operadores lgicos and, or, not). evento/momento de disparo: es uno de los eventos predefinidos de GeneXus disponibles para reglas de transacciones, que permiten definir el momento especfico de ejecucin de una regla. FUNCIONALIDAD: En una transaccin, todos los atributos que pertenecen a las tablas base asociadas a la transaccin, por defecto son aceptados. Si queremos que algunos atributos con estas caractersticas no sean aceptados, entonces contamos con la regla Noaccept. EJEMPLO: Noaccept( IvoiceDate) if Update; /* Regla definida en la transaccin Invoice */ Si se est modificando una factura (modo Update), no se permite que se modifique su fecha.

Subtract
OBJETIVO: Sustrae el valor de un atributo al valor de otro atributo, si se satisface la condicin especificada. SINTAXIS: subtract(att1, att2) [if cond]; DONDE: att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la transaccin, o a sus tablas extendidas (y deben estar declarados en la estructura) cond: es una expresin booleana (que puede contener los operadores lgicos and, or, not). FUNCIONALIDAD: La sustraccin se realiza teniendo en cuenta el modo en el que se est trabajando en la transaccin (Insert, Update o Delete). En modo: - Insert: se le sustrae al valor del atributo att2, el valor del atributo att1 - Delete: se le suma al valor de att2, el valor del atributo att1 - Update: se le sustrae al valor del atributo att2, la diferencia entre el valor nuevo y el viejo de att1 EJEMPLO: En la transaccin Invoice, cada vez que se ingresa una lnea con un producto que se est comprando, se debe disminuir el stock del mismo, segn la cantidad llevada. Esto podra hacerse en forma sencilla con la siguiente regla de asignacin: ProductStock = ProductStock InvoiceLineQuantity; Si prestamos atencin, sin embargo, vemos que esta regla no nos sirve, pues no est condicionada a un modo particular, razn por la cul se disparar tanto cuando se est insertando una nueva lnea en la factura, como cuando se est eliminando o modificando una ya existente. Y en estos ltimos dos casos es incorrecto disparar la regla. De hecho, cuando se est eliminado una lnea existente, debe realizarse la operacin contraria, es decir, se debe devolver al stock lo que se haba quitado cuando se insert la lnea. Lo correcto entonces, teniendo en cuenta todos los casos posibles sera tener 3 reglas: ProductStock = ProductStock InvoiceLineQuantity if Insert; ProductStock = ProductStock + InvoiceLineQuantity if Delete; ProductStock = ProductStock + old(InvoiceLineQuantity) InvoiceLineQuantity if Update; Aqu estamos utilizando la funcin old, que devuelve el valor almacenado del atributo (es el valor antes de modificarlo). Para evitar tener que hacer todo esto, GeneXus provee la regla subtract que se encarga de hacer la asignacin correcta de acuerdo al modo. Entonces podemos sustituir las 3 asignaciones anteriores, por: subtract( InvoiceLineQuantity, ProductStock); Esta regla tiene la inteligencia para, dependiendo del modo, restar o sumar.

97

Add
OBJETIVO: Suma el valor de un atributo al valor de otro atributo, si se satisface la condicin especificada SINTAXIS: add( att1, att2) [if cond]; DONDE: att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la transaccin, o a sus tablas extendidas (y deben estar declarados en la estructura). cond: es una expresin booleana. FUNCIONALIDAD: La adicin se realiza teniendo en cuenta el modo en el que se est trabajando en la transaccin (Insert, Update o Delete). En modo: - Insert: se le suma al valor del atributo att2, el valor del atributo att1 - Delete: se le sustrae al valor de att2, el valor del atributo att1 - Update: se le suma al valor del atributo att2, la diferencia entre el valor nuevo y el viejo de att1 EJEMPLO: Definimos en la transaccin Customer, un atributo de nombre CustomerTotalPurchases, para registrar el importe total de compras efectuadas por el mismo. El comportamiento que se desea es que cada vez que se cree una factura para un cliente dado, se le sume el total de la factura (InvoiceTotal) al total de compras efectuadas por el cliente (CustomerTotalPurchases). Al igual que vimos en la regla subtract, no debemos olvidar que en la transaccin Invoice podemos tambin eliminar y modificar facturas, y no solo crearlas; por lo tanto es importante tener en cuenta el modo de trabajo en la transaccin (Insert, Update, Delete). GeneXus nos libera de tener que considerar nosotros a los modos, teniendo que escribir las siguientes tres reglas de asignacin en la transaccin Invoice: CustomerTotalPurchases = CustomerTotalPurchases + InvoiceTotal if Insert; CustomerTotalPurchases = CustomerTotalPurchases InvoiceTotal if Delete; CustomerTotalPurchases = CustomerTotalPurchases old(InvoiceTotal) + InvoiceTotal if Update; y en su lugar nos provee de la regla add, que se encarga de sumar o restar, dependiendo del modo. As es que si en la transaccin Customer agregamos el atributo CustomerTotalPurchases (total de compras del cliente): CustomerId* CustomerName CustomerAddress CustomerGender ... CustomerTotalPurchases y en la transaccin Invoice inferimos al atributo CustomerTotalPurchases, ya que pertenece a la tabla extendida y podemos definir la regla: add( InvoiceTotal, CustomerTotalPurchases ); y logramos el comportamiento deseado, que es: si se inserta una factura (Insert): se le suma al valor del atributo CustomerTotalPurchases el valor del atributo InvoiceTotal si se elimina una factura (Delete): se le sustrae al valor del atributo CustomerTotalPurchases el valor del atributo InvoiceTotal si se modifica una factura (Update): se le suma al valor del atributo CustomerTotalPurchases, la diferencia entre el valor nuevo y el viejo de InvoiceTotal

98

Serial
OBJETIVO: Permite numerar serialmente atributos numricos. SINTAXIS: Serial( att1, att2, step); DONDE: att1: es un atributo perteneciente a alguna de las tablas base asociadas a la transaccin (es decir, no inferido), que desea autonumerarse (debiendo estar declarado en la estructura). att2: Tiene que pertenecer a una tabla directamente superordinada a la del atributo att1. step: es el paso o incremento de la serializacin. FUNCIONALIDAD: El propsito de esta regla es asignar un nmero correlativo a att1 cada vez que se inserta un registro en la tabla a la que pertenece att1. Se toma el valor de att2 (att2 contiene el ltimo nmero utilizado en la autonumeracin), se le suma el valor del parmetro step, y el valor resultante se asigna tanto al atributo att1 del nuevo registro, como al atributo att2 para conservar el ltimo nmero asignado. Es decir, cuando se est insertando un registro por medio de una transaccin en la cual se ha definido la regla: Serial(att1, att2, step);, se accede al att2 (habr un solo valor de este atributo relacionado, pues pertenece a una tabla directamente superordinada1), se le suma el valor step, y se asigna el valor obtenido tanto a att1 del registro que va a ser insertado, como a att2 perteneciente a una tabla directamente superordinada con respecto a la tabla que contiene a att1. Si se disea a la transaccin Invoice conteniendo un Nmero de Lnea de Factura (atributo InvoiceLineId) como identificador nico del segundo nivel, la estructura de la transaccin sera: InvoiceId* CustomerId CustomerName InvoiceDate InvoiceLastLineId (InvoiceLineId* ProductId ProductDescription ) En este diseo el atributo ProductId no es identificador nico del nivel, sino clave fornea nicamente. Cada lnea tiene un nmero de lnea que la identifica en forma nica, y es posible ingresar el mismo producto en distintas lneas. Podra ser til asignar por medio del sistema, nmeros correlativos al campo InvoiceLineId, definiendo la regla: serial(InvoiceLineId, InvoiceLastLineId, 1); El primer parmetro de la regla serial define cul es el atributo a numerar automticamente, en el segundo parmetro debe indicarse un atributo cuya funcin es guardar el ltimo valor asignado hasta el momento, y por ltimo el tercer parmetro es para indicar el incremento (en este caso se incrementa de uno en uno). El segundo parmetro (en el ejemplo InvoiceLastLineId) debe pertenecer a una tabla directamente superordinada a la tabla que contiene el atributo que se desea numerar automticamente (InvoiceLineId). La regla serial lo requiere as. En el ejemplo, se puede observar que InvoiceLastLineId se encuentra en la tabla de clave InvoiceId*, la cual es directamente superordinada respecto a la tabla que contiene el atributo a numerar (InvoiceLineId). Es decir, cada factura tendr en el cabezal un atributo que almacenar el ltimo nmero de lnea asignado hasta el momento (InvoiceLastLineId). La regla serial est implementada de forma tal que

99

necesita este atributo (para fijarse el ltimo nmero utilizado, sumarle el incremento, y asignar el prximo nmero a la nueva lnea). Consideracin: La regla serial es til a la hora de autonumerar lneas, no as cabezales (por ejemplo identificadores de facturas, de clientes, etc.). El motivo es el siguiente: para utilizar la regla serial, se requiere definir un atributo en una tabla directamente superordinada; esto resulta bien sencillo si se desean autonumerar lneas ya que alcanza con incluir este atributo en el nivel de la estructura inmediatamente superior al del atributo a autonumerar. Sin embargo, si lo que se quiere numerar automticamente es un atributo del primer nivel (cabezal), all no existe un nivel inmediatamente superior en la estructura; esto no es un problema sin solucin ya que para definir una relacin de superordinacin/subordinacin entre tablas, no solo est la posibilidad de disearlo en una misma estructura de transaccin con ms de un nivel; tambin transacciones distintas con atributos en comn, provocan la creacin de tablas relacionadas, y por ende, con relaciones de superordinacin / subordinacin entre ellas. El siguiente diseo incluye a una tabla de nombre NUMBER superordinada a las tablas INVOICE y CUSTOMER:

NUMBER

NumberCode* NumberLast

InvoiceId* CustomerId* INVOICE CUSTOMER InvoiceDate CustomerName NumberCode NumberCode CustomerId Como se puede observar, la tabla NUMBER tiene solamente 2 atributos: NumberCode que sera un cdigo para almacenar el tipo de nmero que se brinda (nmero de factura, nmero de cliente, etc.) y NumberLast para almacenar el ltimo nmero dado para cada NumberCode. La estructura de la tabla NUMBER sera: NumberCode* CUSTOMER INVOICE NumberLast 20 10 ltimo identificador de cliente asignado ltimo identificador de factura asignado

Para obtener este diseo, deberamos definir una transaccin Number con estructura: NumberCode* NumberLast Y relacionarla con las transacciones en las cuales se utilizara la regla serial:

InvoiceId* InvoiceDate CustomerId CustomerName NumberCode NumberLast (InvoiceLineId* ProductId ProductDescription )

Inferido: est en la tabla NUMBER directamente subordinada

CustomerId* CustomerName NumberCode NumberLast

100

Finalmente, agregando en la transaccin Invoice las siguientes reglas, lograramos autonumerar las facturas: serial(InvoiceId, NumberLast, 1); equal(NumberCode, INVOICE); La regla equal asigna un valor (INVOICE) a un atributo (NumberCode) cuando se ejecuta la transaccin en modo insert, y filtra los registros que tengan dicho valor en el atributo, cuando se ejecuta la transaccin en modo update y delete. Y en la transaccin Customer la situacin es anloga; con las reglas siguientes podemos autonumerar clientes: serial( CustomerId, NumberLast, 1 ); equal( NumberCode, CUSTOMER ); Sin embargo, contamos con una solucin mucho ms simple para autonumerar cabezales: cuando una tabla tiene una clave simple (es decir formada por un solo atributo) y el tipo de datos es numrico, puede numerarse automticamente utilizando la funcionalidad que brindan los manejadores de base de datos para esto. La forma de indicarlo en GeneXus es configurando la propiedad Autonumber del atributo clave:

Si en la propiedad Autonumber de un atributo numrico clave, se selecciona el valor True, significa que se realizar la numeracin automtica del mismo. Se agregarn las siguientes propiedades en el dilogo: Start: Mediante esta propiedad se configura a partir de qu nmero comienza la numeracin automtica. Step: Mediante esta propiedad es posible configurar el incremento del campo (entre dos registros). For replication: Esta propiedad es slo vlida para el motor de base de datos SQL Server; el valor Yes le indica a ste que no debe aplicar la propiedad en caso de que la tabla sea receptora de replicacin (sino que debe mantener los nmeros que le vienen por replicacin). Para profundizar en el manejo de esta propiedad, recomendamos acceder al Help de GeneXus.

101

Update
OBJETIVO: Posibilita actualizar en el form de una transaccin (win/web) atributos de la tabla extendida (inferidos). SINTAXIS: Update( att1[, atti ]); DONDE: atti: es un atributo perteneciente a la tabla extendida de alguna de las tablas bases asociadas a la transaccin. FUNCIONALIDAD: En una transaccin, todos los atributos que pertenecen a las tablas base asociadas a la transaccin, por defecto son aceptados y los que perteneciendo a la tabla extendida, no pertenecen a la base, son inferidos, y por tanto no aceptados. Pero si queremos que algunos de estos atributos inferidos sean aceptados, para que el usuario pueda modificar desde el form su valor, entonces contamos con la regla Update. EJEMPLO:

InvoiceId* InvoiceDate CustomerId CustomerName

CustomerId* CustomerName

update(CustomerName);

102

Conceptos importantes sobre reglas de transacciones


En qu nivel de una transaccin se ejecutarn las reglas definidas en la misma? Cmo condicionar reglas para que se ejecuten en determinados modos?

En qu nivel de una transaccin se ejecutarn las reglas definidas en la misma? La mayor parte de las veces no es necesario agregar explcitamente en la definicin de las reglas el nivel de la transaccin en el cual se desea que se disparen, ya que los atributos involucrados en las reglas le dan la pauta a GeneXus del nivel en el cual corresponde ejecutarlas. Por ejemplo, si una regla referencia nicamente a atributos del primer nivel de la transaccin en la cual se encuentra definida (ya sea en la propia regla o en la condicin de disparo), GeneXus entender que la misma estar asociada al primer nivel de la transaccin. Anlogamente, si una regla referencia solamente a atributos del segundo nivel de la transaccin en la cual se encuentra definida (ya sea en la propia regla o en la condicin de disparo), GeneXus entender que la misma estar asociada al segundo nivel de la transaccin. En el caso que una regla referencie atributos de varios niveles, GeneXus entender que la regla estar asociada al ltimo de los niveles de los atributos involucrados, ya que ser en el ltimo nivel en el que contar con los valores de todos los atributos implicados. A continuacin presentamos ejemplos concretos: 1) Si se define la siguiente regla en la transaccin Invoice: Default(InvoiceDate, &today); como el nico atributo que se menciona en la regla es InvoiceDate, y es un atributo del primer nivel de la transaccin, GeneXus determinar que se tratar de una regla asociada al primer nivel. 2) Si se define la siguiente regla en la transaccin Invoice: subtract( InvoiceLineQuantity, ProductStock ); como los dos atributos que se mencionan en la misma se encuentran en el segundo nivel de la transaccin, GeneXus determinar que se tratar de una regla asociada al segundo nivel.

103

3) Si se define la siguiente regla en la transaccin Invoice: InvoiceLineDiscount= InvoiceLineAmount * CustomerDiscountPercentage/100; siendo InvoiceLineDiscount (descuento correspondiente a una lnea) un atributo perteneciente al segundo nivel de la transaccin Invoice y CustomerDiscountPercentage (porcentaje de descuento otorgado a un cliente) un atributo declarado en el primer nivel de la transaccin Invoice, GeneXus determinar que se tratar de una regla asociada al segundo nivel de la transaccin. Cuando nos referimos a que una regla est asociada a determinado nivel, significa que la misma se ejecutar para cada instancia con la cual se trabaje a travs de ese nivel (si se cumple la condicin de disparo de la regla, claro est). En el caso del primer ejemplo visto, la regla Default(InvoiceDate, &today) es una regla asociada al primer nivel de la transaccin Invoice. Esto significa que se ejecutar para todo cabezal de factura que se inserte a travs del primer nivel de la transaccin Invoice (la regla Default tiene la particularidad de dispararse nicamente cuando el modo de ejecucin es Insert). En el caso del segundo ejemplo visto, la regla subtract(InvoiceLineQuantity, ProductStock) es una regla asociada al segundo nivel de la transaccin Invoice. Esto significa que se ejecutar para toda lnea de factura que se inserte, actualice o elimine a travs del segundo nivel de la transaccin Invoice. En el caso del tercer ejemplo, la regla: InvoiceLineDiscount = InvoiceLineAmount * CustomerDiscountPercentage/100 es una regla asociada al segundo nivel de la transaccin Invoice. De modo que esta regla se ejecutar para toda lnea de factura que se inserte, actualice o elimine a travs del segundo nivel de la transaccin Invoice. Concluyendo, tal como se desprende de todo lo explicado, para cada factura con la cual se trabaje a travs de la transaccin Invoice: - para el cabezal: se ejecutarn las reglas asociadas al primer nivel - para cada una de las lneas: se ejecutarn las reglas asociadas al segundo nivel Es importante saber que como norma general GeneXus siempre determina que una regla se dispare en el primer momento en que sea posible, es decir, en aquel momento en el que cuente con todos los datos necesarios. Y solamente en algunos casos que as lo requieran, una misma regla se volver a disparar ms adelante. Qu nivel de disparo por defecto se le asociar a una regla que no referencia atributos? Cuando no hay atributos involucrados en una regla, el nivel asociado por defecto a la regla ser el primero. Por ejemplo, la siguiente regla definida en la transaccin Invoice: Error(No se permite eliminar facturas) if Delete; no tiene atributos involucrados, por lo tanto, el nivel asociado por defecto a la regla ser el primero. Cundo hay que especificar explcitamente el nivel de disparo de una regla? Existe una clusula opcional de nombre Level que permite modificar el nivel por defecto de disparo de una regla, cambindolo por un nivel posterior. Es decir, si por ejemplo una regla se ejecuta por defecto para el primer nivel de una transaccin y se desea que se ejecute para el segundo, se deber agregar a la regla el componente Level seguido de un atributo o conjunto de atributos del segundo nivel. Esto har que la regla se ejecute para cada una de las instancias correspondientes a las lneas, y no para la instancia correspondiente al cabezal como era el comportamiento por defecto. Por ejemplo, si definimos la siguiente regla en la transaccin Invoice: msg(La fecha de la factura es mayor a la fecha actual) if InvoiceDate > &Today; por defecto esta regla estar asociada al primer nivel de la transaccin, ya que el nico atributo referenciado en la regla se encuentra en el primer nivel de la transaccin. Si por algn motivo deseamos que la regla se ejecute para cada una de las instancias correspondientes a las lneas en vez de ejecutarse para la instancia correspondiente al cabezal, tendremos que agregar en la definicin de la regla, la clusula Level seguida de uno o varios atributos del segundo nivel: msg(La fecha de la factura es mayor a la fecha actual) if InvoiceDate>&Today Level InvoiceLineAmount;

104

Agregar la clusula Level a una regla solamente tiene sentido si a continuacin de la misma se mencionan atributos que son de algn nivel posterior a los niveles de los atributos implicados en la definicin de la regla en s. En el ejemplo que sigue, el hecho de haber agregado la clusula Level a la regla no aporta ms informacin de la ya aportada por el atributo implicado en la definicin de la regla en s: msg(La fecha de la factura es mayor a la fecha actual) if InvoiceDate > &Today Level CustomerId; Es fcil comprender que el atributo InvoiceDate ya le da la pauta a GeneXus de que se trata de una regla asociada al primer nivel, as que lo especificado por la clusula Level en el ejemplo no aporta ms informacin y por lo tanto su agregado es innecesario. Por ltimo, en el ejemplo que sigue: InvoiceLineDiscount= InvoiceLineAmount * CustomerDiscountPercentage/100 Level InvoiceDate; si bien se incluy la clusula Level en la definicin de la regla, como el atributo que sigue a la clusula es de un nivel superior al nivel de los atributos referenciados en la regla, la clusula Level definida no aportar informacin til en este caso tampoco. Es decir, no es posible que habiendo involucrados atributos de un segundo nivel en una regla, la misma se ejecute en el primer nivel, ya que en el primer nivel no se tiene la informacin del o de los niveles inferiores (adems de que hay N instancias para el o los niveles inferiores). De modo que la regla seguir estando asociada al segundo nivel de la transaccin Invoice, no habiendo aportado informacin til la clusula Level en este ejemplo. Concluyendo, la clusula Level solamente tiene sentido que sea agregada para modificar el nivel por defecto de disparo de una regla, a un nivel posterior. Cmo condicionar reglas para que se ejecuten en determinados modos? GeneXus provee las siguientes funciones booleanas para poder incluirlas en la condicin de disparo de las reglas con el objetivo de limitarlas a que se ejecuten puntualmente en algunos de los modos posibles: Insert Update Delete

Ejemplos de uso (todas las reglas correspondern a la transaccin Invoice) 1) Noaccept( InvoiceDate ) if Update; Si se est modificando una factura (modo Update), no se permite que se modifique su fecha. Si se definiera la regla sin la condicin de disparo que hemos explicitado, el atributo InvoiceDate se deshabilitara en todos los modos de ejecucin. 2) Error( No se permite eliminar facturas ) if Delete; Si se intenta eliminar una factura, se disparar el error deteniendo la eliminacin. Como no hay atributos involucrados en la regla, por defecto el nivel asociado a la regla ser el primero. 3) Error( No se permite eliminar lneas de facturas ) if Delete Level InvoiceLineQuantity; Si se intenta eliminar una lnea de una factura, se disparar el error deteniendo la eliminacin. Observar que se ha explicitado en la regla la clusula Level seguida de un atributo del segundo nivel de la transaccin Invoice, para indicar que se desea que la misma est asociada al segundo nivel de la transaccin.

105

Tipos de dilogo
Dilogo campo a campo
Las validaciones, disparo de reglas y frmulas y grabaciones, se van efectuando en forma interactiva, en la medida que el usuario va trabajando en la pantalla (Ej: Vb, Vfp con interfaz Win)

Dilogo a pantalla completa (full screen)


Todas las validaciones, disparo de reglas y frmulas y grabaciones, se efectan cuando se confirma la pantalla completa (Ej: Java y .Net con interfaz Win)

Dilogo con Validacin a nivel del cliente (CSV)


Hbrido entre los dos anteriores
Disparo de algunas reglas y frmulas interactivas Grabaciones cuando se confirma la pantalla completa
(aqu se redisparan reglas y frmulas)

(Ej: Java y .Net, Win y Web)

GeneXus genera distintos tipos de dilogos para las transacciones. El dilogo utilizado para un modelo en particular, depender de su ambiente o plataforma (en particular de su interfaz, Win o Web). Los dos tipos de dilogo clsicos son: campo a campo a pantalla completa (full screen) Luego se ha creado un hbrido entre ambos, que funciona en algunos aspectos como el dilogo a pantalla completa y en otros como el campo a campo. Le llamaremos: dilogo con validacin a nivel del cliente (Client Side Validation).

Dilogo campo a campo En este tipo de dilogo, cada vez que se digita un valor en un campo y se abandona, se controla inmediatamente su validez. Las reglas y frmulas1 se van disparando a medida que se va pasando por los campos, y los datos de la tabla extendida se van infiriendo ni bien se van ingresando los valores de las claves forneas. Generalmente la grabacin de los datos en este tipo de dilogo es por registro, vale decir: Ni bien se terminan de ingresar los datos del cabezal y se pasa a las lneas, el registro correspondiente al cabezal es grabado. Ni bien se terminan de ingresar los datos de una lnea y se pasa a la siguiente, el registro correspondiente a la lnea de la cual se sali, es grabado. La grabaciones se van realizando interactivamente, y si se realiza explcitamente una confirmacin de datos, se grabar puntualmente el registro con el cual se est trabajando (el correspondiente al cabezal o el correspondiente a cierta lnea en la cual el cursor se encuentre). Los generadores Visual Basic y Visual FoxPro trabajan con este tipo de dilogo.

-----------------------------------------------------------------------------------------------------------------Estudiaremos las frmulas un poco ms adelante.

106

Tipos de dilogo
Client Server Client Server

Ingreso de datos Confirmacin

Validaciones Controles IR inferencias Reglas Frmulas Grabaciones

Ingreso de datos Validaciones Controles IR Inferencias Algunas reglas Frmulas Confirmacin

Validaciones Controles IR inferencias Reglas Frmulas Grabaciones

Dilogo a pantalla completa

Dilogo con CSV

Dilogo a pantalla completa (full screen) En este tipo de dilogo no se realizan validaciones de los datos, controles de integridad referencial (IR), inferencias de la tabla extendida, ni disparos de reglas y frmulas a medida que los datos van siendo ingresados por el usuario en la pantalla. Las validaciones, reglas y frmulas se disparan solamente en dos momentos: 1. Al ingresar a la transaccin (reglas que no dependen de nada, no tienen condiciones de disparo). 2. Al confirmar los datos. La confirmacin de los datos determina la grabacin de la pantalla completa, disparando previamente todas las reglas, validaciones y haciendo la carga de los atributos de la tabla extendida. Est en la naturaleza de los generadores Java y .Net trabajar con este tipo de dilogo. Sin embargo existe la posibilidad de modificar este comportamiento, para que el usuario final pueda tener mayor interaccin con la aplicacin de manera tal que no deba esperar a confirmar la transaccin para ver los atributos inferidos, as como las validaciones y disparo de reglas y frmulas. En lo que sigue explicaremos el dilogo a pantalla completa con Validacin a nivel del Cliente. Dilogo a pantalla completa con Validacin a nivel del Cliente (Client Side Validation) La base de este dilogo es a pantalla completa, pero el usuario tendr mayor interaccin con la aplicacin. Tanto las validaciones de datos, como los controles de IR y disparo de algunas reglas y frmulas, adems de realizarse cuando se confirma la transaccin (como en el dilogo full screen clsico), tambin se realizarn antes, en forma interactiva a medida que el usuario vaya ingresando y abandonando los campos de la pantalla. Las grabaciones de los registros s se realizarn a pantalla completa, tras la confirmacin. De modo que se trata de un hbrido entre los dilogos campo a campo y a pantalla completa. Nota: en el caso de tratarse de ambiente Web, la pantalla que se ejecuta en el cliente es la ejecutada en el browser, y el servidor en este caso es el Servidor Web que ejecuta la aplicacin. Si bien la naturaleza de internet no posibilitaba la validacin a nivel del cliente (es decir, enviar partes de la lgica de las transacciones al browser), con el advenimiento de Ajax1, un conjunto de tecnologas existentes operando juntas, esto ahora es posible.
1

-----------------------------------------------------------------------------------------------------------------Puede encontrar un artculo interesante Ajax: A New Approach to Web Applications en http://www.adaptivepath.com/publications/essays/archives/000385.php

107

Dilogo con Validacin a nivel del cliente (Client Side Validation)


En su base es full screen, con algunas validaciones en el cliente que le permiten incrementar la interaccin con el usuario final Generadores .Net y Java interfaz Win: es configurable (propiedad CSV) interfaz Web: no es configurable, siempre se realizar. Valores de la propiedad CSV (solo para Win)
Yes: Activa las validaciones, inferencias y disparo de reglas y frmulas en la medida que el usuario va ingresando datos en la pantalla. Estas acciones se repiten cuando se confirma. (valor predeterminado) No: Todas las validaciones y disparo de reglas y frmulas se realizan cuando se confirma.

Propiedad a nivel de modelo y de objeto

Mientras que para aplicaciones .Net y Java con interfaz Web siempre se trabajar con dilogo con validacin a nivel del cliente (WCSV: Web Client Side Validation) posible solo gracias a la irrupcin del conjunto de tecnologas conocido como Ajax en el mundo de Internet, para el caso de las mismas aplicaciones para interfaz Win existe la posibilidad de configurar una propiedad de nombre Client Side Validation, para poder, si as se desea, trabajar con el dilogo base, exclusivamente a pantalla completa. Interfaz Win Cuando se trabaja con generadores .Net o Java y ambiente Windows, la validacin a nivel del cliente ofrece una alternativa al dilogo a pantalla completa para proveer mayor interaccin con el usuario final. La propiedad Client Side Validation admite los siguientes valores: - Yes: Si se selecciona este valor, en la medida que el usuario final vaya pasando por los campos de la pantalla y/o ingresando informacin en ellos, se irn validando los datos, infiriendo los atributos de la tabla extendida, y disparndose las reglas y frmulas definidas. Todas estas operaciones se ejecutarn en forma interactiva para que el usuario final pueda ir viendo resultados. De todas formas, las caractersticas del dilogo a pantalla completa se mantendrn, en el sentido de que cuando el usuario final confirme los datos, se grabarn los de la pantalla completa (disparndose previamente todas las validaciones y acciones, esta vez en el servidor). Este es el valor por defecto. -No: Indica que el dilogo a pantalla completa ser puro, es decir, sin el agregado de las validaciones en forma interactiva. La propiedad Client Side Validation se encuentra disponible tanto a nivel de modelo como a nivel de objeto. Esto significa que el valor que se configure en la propiedad a nivel del modelo determinar el comportamiento de todas las transacciones, a excepcin de aquellas que tengan configurado el valor contrario en su propiedad a nivel del objeto. Cuando se crea un modelo de prototipo con interfaz Win y generador Java o .NET, uno de los pasos del Wizard de creacin de dicho modelo contiene un combo titulado Client Side Validation que ofrece los dos valores posibles: Yes o No. De esta manera el analista ya puede determinar si desea que su aplicacin tenga un dilogo a pantalla completa (propiedad CSV = No) o si por el contrario, desea incrementar la interactividad de las transacciones, con validacin a nivel del cliente (propiedad CSV = Yes). Tambin se puede configurar esta propiedad a nivel del modelo ms tarde (editando las propiedades del modelo), as como a nivel de objeto si se desea que ciertas transacciones tengan el comportamiento contrario al configurado para el modelo.

108

Dilogo con Validacin a nivel del cliente


(Client Side Validation)

En la medida que el usuario final va ingresando informacin en la pantalla, se van validando los datos, realizando las inferencias, y disparndose las reglas y frmulas definidas. Procesamiento de datos (grabaciones) a pantalla completa Inferencia de modo:

WIN:

CSV=No CSV=Yes

Hay botn get / no se infiere el modo No hay botn get / se infiere el modo

WEB:

Hay botn get / no se infiere el modo

Resumen sobre dilogo a pantalla completa con validacin a nivel del cliente: Mientras el usuario va trabajando con la pantalla, ingresando datos en los distintos campos y abandonndolos, se irn realizando validaciones de los mismos, controles de IR e inferencias de la tabla extendida, as como disparo de reglas y frmulas que involucren a esos atributos que se abandonan. Esto le brindar al usuario la idea de una alta interaccin. Luego, cuando el usuario termina de trabajar con la instancia de cabezal y lneas, confirma presionando el botn de confirmacin, y all se realiza el procesamiento de datos a pantalla completa. Aqu vuelven a validarse los datos, a dispararse los controles de IR e inferencias, junto con las reglas y frmulas, adems de realizarse las grabaciones de todos los registros correspondientes (cabezal y lneas). Todo esto se realiza en el servidor, como si nada hubiese ocurrido en el cliente (tiene que ver con aspectos de seguridad, dado que si no vuelven a realizarse las validaciones luego en el servidor, podra haberse colado algo en el camino al servidor que burle la seguridad).

109

Dilogo a pantalla completa


Propiedad: Confirmation
Se cuenta tambin con la propiedad Confirmation, til fundamentalmente en dilogo a pantalla completa. Posibilita trabajar con o sin confirmacin explcita del usuario:
Con confirmacin: validacin en 2 pasos (grabacin en el ltimo). WIN: cambia texto del botn, confirm en el 2do. paso WEB: no cambia texto, confirm se muestra
en el 2do. paso en el Error Viewer

Sin confirmacin: se valida y graba en 1 solo paso


En Win: no hay botn Confirm, solo Insert o Update, dependiendo del modo. En Web: no hay mensaje de confirmacin en el Error Viewer

La propiedad Confirmation se encuentra disponible tanto a nivel de modelo como a nivel de objeto. Esto significa que el valor configurado en la propiedad a nivel de modelo determinar el comportamiento de todos los objetos del modelo, a excepcin de aquellos que tengan configurado otro valor en forma particular en su propiedad a nivel de objeto. Esta propiedad permite configurar: para transacciones: si se desea o no, que antes de que se graben directamente los datos, se le solicite confirmacin al usuario para hacerlo. para reportes y procedimientos: si se desea o no, que antes de que se comience a ejecutar el proceso, se le solicite al usuario confirmacin para hacerlo. Los valores que admite esta propiedad son: Always prompt: Si se selecciona este valor, se le solicitar confirmacin al usuario. Never prompt: Si se selecciona este valor, no se le solicitar confirmacin al usuario. Do not prompt on first level: Este valor se ofrece nicamente para los generadores Visual Basic y Visual Fox Pro, y aplica solamente a transacciones. Si se selecciona el mismo, se le solicitar confirmacin al usuario antes de que se graben los datos en cada nivel de la transaccin, a excepcin del primero. El trabajo con confirmacin reviste relevancia fundamentalmente en el caso en que se trabaje con dilogo a pantalla completa (sin validaciones del lado del cliente), pues como dijimos, es en ese tipo de dilogo en el que el usuario no tiene una respuesta interactiva por parte del sistema respecto a los datos que acaba de ingresar y requiere de una primera confirmacin para obtener alguna respuesta. Por ejemplo, puede haber ingresado un valor que no era el que deseaba para una clave fornea que corresponde al pas del cliente (suponiendo que no disfraza los valores del atributo y trabaja directamente con los cdigos1), y en ese caso como las inferencias no se realizarn interactivamente, puede querer realizar una confirmacin en dos pasos, de modo tal que en el primero se le muestren los datos inferidos y as ya sabr que el pas que digit era el deseado. En caso que no lo fuera, podr modificarlo antes de que la informacin sea efectivamente grabada en la base de datos (cosa que se lograr recin en el 2do. paso). Para interfaz Web (que trabaja con CSV) as como para Win con validacin a nivel del cliente, no resulta necesario este tipo de comportamiento, ya que las inferencias y validaciones se van disparando interactivamente a medida que el usuario va trabajando con la interfaz. Si igualmente se utiliza Confirmacin, las validaciones, controles de IR e inferencias, las reglas que no dependen de las grabaciones de los registros, y disparo de frmulas se ejecutarn tres veces (una en el primer paso de la confirmacin (en el cliente), segunda vez en el 2do. paso de la confirmacin (en el cliente) y una ltima vez en el servidor, junto con el resto de las reglas, cuando los registros pasan a grabarse en la base de datos. -----------------------------------------------------------------------------------------------------------1 Descripciones en vez de cdigos dentro del tema Integridad Referencial en este manual.

110

Transacciones en tiempo de ejecucin


WIN

eliminacin de lneas (tecla Supr)

Cmo trabaja el usuario final en ejecucin con las transacciones? En el ejemplo de arriba la transaccin Invoice se est ejecutando en un ambiente GUI-Windows, y .Net con validacin a nivel del cliente. Por tanto, ni bien el usuario ingresa un valor para el atributo que es PK y abandona el campo, se infiere el modo (ser Insert en caso en que no exista factura con ese identificador en la tabla, u Update en caso contrario). Update En caso de existir registro con ese identificador, se edita en los campos del form, as como se recuperan tambin las lneas de la tabla INVOICELINE asociadas y se editan en el grid. En este caso el usuario podr tanto modificar los valores editados (tanto de cabezal como de lneas), para los atributos para los que esto est permitido (los que no sean read only), insertar nuevas lneas en el grid, as como eliminar alguna lnea existente (posicionndose en la lnea y presionando la tecla DEL-Suprimir del teclado). Luego de efectuadas todas las modificaciones (de datos preexistentes, insercin de nuevas lneas o marcado para la eliminacin de lneas mediante la tecla DEL), se presiona el botn de Confirm1 para aplicar los cambios. En cambio, si lo que se desea es eliminar la factura entera, en ese y solo ese caso se presiona el botn Delete. Insert En caso de no existir registro en la tabla INVOICE con el valor ingresado por el usuario en la PK, entonces los campos del form estarn vacos esperando ser ingresados por el usuario. El botn de confirmacin dir Insert. El grid no contendr lneas ingresadas. El usuario ingresar por tanto los datos para el cabezal y las lneas, pudiendo arrepentirse de una lnea que ingres previamente y borrarla utilizando el mismo procedimiento indicado antes (tecla DEL-Suprimir del teclado sobre la lnea). Obsrvese que en este caso no tendr sentido presionar el botn Delete, dado que los registros aun no existen en la base de datos, por lo que no hay nada que borrar. Simplemente cerrando la transaccin, o pasando a editar otro registro, lo digitado por el usuario en la pantalla se perder sin grabarse. Luego de ingresados sus datos, el usuario confirmar la pantalla mediante el botn Insert (teniendo luego que reconfirmar si se trabaja con confirmacin; botn Confirm). --------------------------------------------------------------------------------------------------------1 Si se trabaja con confirmacin el botn dir Update en primera instancia y luego Confirm. Si se trabaja sin confirmacin, solo dir Update.

111

Transacciones en tiempo de ejecucin


WEB

eliminacin de lneas (&GxRemove)

Para la misma transaccin, generada en ambiente Web la historia es muy similar. Existen algunas pequeas diferencias, no obstante. Mientras que en ambiente Win contamos con el control Grid que muestra la cantidad de lneas por pantalla que determine el analista cuando disea el form de la transaccin, permite sin embargo el desplazamiento vertical (barra de scroll), permitiendo entonces ingresar tantas lneas como se desee, con tan solo hacer scroll cuando se han ingresado todas las lneas de la pantalla. En Web, sin embargo, al no contar con esta facilidad, siempre se mostrar un nmero de lneas vacas fijas para ser ingresadas por el usuario (valor configurable por el analista a nivel del grid, en su propiedad Rows). Por defecto se muestran 5 lneas vacas. Si el usuario ingres las 5 lneas y necesita ingresar ms, le bastar con presionar Apply Changes y 5 lneas vacas ms se adicionarn al formulario (si se trabaja con confirmacin, esto dar la oportunidad de agregar las lneas sin ingresar todo lo anterior en la base de datos). Otra diferencia respecto al tratamiento de las lneas con respecto a Win es que en el grid del form Web se incorpora automticamente una primera columna conformada una variable del sistema de nombre &GxRemove, en la forma de check box. Como lo indica su nombre, se utiliza para permitir al usuario en ejecucin marcar varias lneas para ser eliminadas. Lo que en Win se realizaba mediante la tecla DEL, aqu se realiza marcando el check box de la lnea que quiere eliminarse. Cuando se ingresa en la transaccin en modo Insert, el check box no aparecer en el grid, dado que no existe ninguna lnea an ingresada, que pueda ser por tanto eliminada. Al aplicar los cambios (Apply Changes) esta primera columna aparecer para las lneas ingresadas en el form. Por lo dems, el modo de operacin (cmo insertar, modificar, o eliminar registros) es anlogo al de Win.

112

Algunos elementos ms de las transacciones


Propiedades Documentacin Ayuda
Ayuda Documentacin Propiedades

Propiedades Las propiedades asociadas a un objeto en este caso nos referimos a una transaccin, pero vale en general, independientemente de cul objeto se trate- permiten definir ciertos detalles referentes al comportamiento general del objeto. Para ingresar al dilogo de propiedades de un objeto, teniendo el objeto abierto, se deber seleccionar el tem Object / Properties de la barra de men de GeneXus, o el botn de la barra de herramientas Fast Access que sealizamos en la transparencia. Sin tener el objeto abierto, es posible editar sus propiedades haciendo botn derecho sobre el nombre del objeto, y seleccionando el tem Properties del men contextual. Mediante cualquiera de los caminos anteriores, se abre un dilogo que ofrece las propiedades asociadas al objeto activo, y donde el analista podr especificar sus valores, definiendo as detalles referentes al comportamiento del objeto. Por ejemplo, la propiedad Confirmation de la que hablamos antes, as como la propiedad Client Side Validation aparecen en este dilogo en caso de estar trabajando en un modelo .Net o Java Win, dado que como dijimos oportunamente, pueden configurarse a nivel de objeto. La propiedad Confirmation tambin aparecer en este dilogo si el modelo es .Net o Java Web; no as la otra. Asimismo dentro de la seccin Web Transaction properties del dilogo de configuracin de propiedades, se encontrar la propiedad Theme para asociarle un objeto tema a la transaccin. Cada modelo, dependiendo de su configuracin (lenguaje, interfaz, etc.), tendr algunas propiedades u otras para configurar. A lo largo del curso iremos viendo algunas de estas propiedades. Para profundizar en el manejo de alguna propiedad en particular, recomendamos acceder al Help de GeneXus.

113

Documentacin Los objetos GeneXus ofrecen una seccin para que el analista pueda incluir documentacin tcnica acerca del objeto. Para ingresar a la seccin de documentacin de un objeto, teniendo al objeto abierto, se deber seleccionar la solapa Documentation, o el tem Object / Documentation de la barra de men de GeneXus. Tambin el botn de la barra de herramientas Fast Access que sealizamos en la transparencia, conducir a la seccin de documentacin del objeto activo. Se abrir un editor html para que el analista ingrese la documentacin tcnica correspondiente. Ayuda Los objetos GeneXus tienen una seccin especfica para poder escribir la Ayuda para el usuario final en el uso del objeto. Para ingresar a la seccin de ayuda de un objeto, teniendo al objeto abierto, se deber seleccionar la solapa Help, o el tem Object / Help de la barra de men de GeneXus. Tambin el botn de la barra de herramientas Fast Access que sealizamos en la transparencia. Se abrir un editor Html para que el programador ingrese el texto de ayuda que se le desplegar al usuario cuando ejecutando el objeto, solicite ayuda. Algunas consideraciones importantes Si se ingresa texto de ayuda para objetos y/o atributos y/o variables de la base de conocimiento, luego de especificar y generar las aplicaciones, se deber generar el Help. Para ello se deber seleccionar el tem Build / Generate Help. Al seleccionar el tem Build / Generate Help, se desplegar una pantalla para elegir entre dos formatos: CHM y WEB. Tambin se deber seleccionar el lenguaje en el que se generar el Help1. CHM: Es el formato que se deber elegir para aplicaciones GUI-Windows. Permite empaquetar toda la ayuda generada en un nico archivo de formato CHM, brindando la posibilidad de buscar en la ayuda generada, se definir un ndice, etc. WEB: Es el formato que se deber elegir para aplicaciones Web. En tiempo de ejecucin se abrir un browser con el texto de la ayuda en formato HTML. En el caso de elegir el formato CHM, se solicitar el path del compilador de Help (este compilador viene con Visual Studio, pero no se instala automticamente, sino que hay que instalarlo por separado). Cualquiera sea el formato de ayuda elegido, se generar un directorio HELP bajo el directorio del modelo, en el que se crear un archivo con extensin HTML por cada objeto/atributo/variable que tenga ayuda. Si el formato elegido es CHM, se crear adems un archivo de nombre APPHLP.CHM en el directorio del modelo, y un archivo de definicin de proyecto (de extensin HHP) que ser utilizado por el compilador de Help, para la generacin del CHM. El funcionamiento en ejecucin ser el siguiente: Cuando el usuario final seleccione el botn de Ayuda de la transaccin: se desplegar la ayuda del objeto. Cuando el usuario final presione F1: se desplegar la ayuda del atributo en el cual se encuentre el cursor; y si ese atributo no tiene definido texto de ayuda, se desplegar la ayuda del objeto. ------------------------------------------------------------------------------------------------------------------------Esto est directamente vinculado a la posibilidad de tener un texto de help por cada uno de los objetos Language, utilizados para poder traducir la aplicacin. Es decir, la posibilidad de tener un texto de Help para cada idioma posible. As deber seleccionarse aqu cul de esos textos de help (el correspondiente a qu lenguaje) deber tomarse para generar el help.
1

114

ATRIBUTOS FRMULA

115

Caractersticas
Relacin entre atributos, constantes y/o funciones. Definicin Global: definidas a nivel de la base de conocimiento. Atributo Virtual: no se almacena en la tabla.
Llamaremos tabla base del atributo frmula a la tabla asociada al mismo

Son calculadas siempre que se hace referencia al atributo

Cuando el valor de un atributo puede calcularse a partir del valor de otros atributos, constantes y/o funciones, el mismo puede ser definido como frmula. Para definir que un atributo es una frmula y especificar cmo calcularla, existen tres posibilidades, todas ellas disponibles nicamente en el modelo de Diseo: 1) En la estructura de una transaccin, as como se define para cada atributo su nombre, tipo de datos y descripcin, es posible definir que el atributo es una frmula e indicar cul es el clculo que debe hacerse. Esta va directa en la estructura de una transaccin que permite definir que un atributo es una frmula, se habilita tanto para un atributo ya definido y salvado previamente, como para un atributo que se est definiendo en el momento. 2) En la estructura de una transaccin, es posible pulsar el botn derecho del mouse sobre un atributo que haya sido definido y salvado previamente; se abrir el men pop up correspondiente, se deber seleccionar el tem Formula del mismo, y a continuacin se presentar una pantalla de edicin de frmula para que se indique cmo calcularla. 3) Seleccionando el tem Advanced / Formula de la barra de men de GeneXus, se abrir un dilogo ofreciendo todos los atributos definidos en la base de conocimiento, para que se seleccione uno, y se edite la forma de calcularlo. La definicin de un atributo como frmula -indicando cul es el clculo que debe hacerse para obtener su valor- es una definicin global. Dicho de otro modo, se trata de una definicin a nivel de la base de conocimiento y no a nivel de un objeto especfico, independientemente de por cual de las vas se realice su definicin. Siempre que se referencie/utilice un atributo frmula en cualquier objeto de la base de conocimiento en el cual sea vlido, GeneXus tendr el conocimiento de qu clculo habr que hacer para obtener su valor; as, en los programas generados asociados a los objetos que utilicen frmulas, incluir el cdigo necesario para que en tiempo de ejecucin se dispare el clculo y se muestre el valor resultante.

116

Los atributos definidos como frmula, a menos que se especifique lo contrario, no estarn almacenados en la base de datos. Dado que sus valores se pueden calcular a partir de los valores de otros atributos, constantes y/o funciones, resulta innecesario y sera redundante almacenarlos (motivo por el cual decimos que son atributos virtuales). A pesar de que los atributos definidos como frmula no se crearn como campos fsicos en ninguna tabla de la base de datos, cada uno de ellos estar asociado a una tabla (siguiendo los mismos criterios de normalizacin que se utilizan para determinar en qu tabla corresponde almacenar un atributo comn). Expresiones del estilo: la tabla donde est el atributo frmula x no son correctas; nos referimos en cambio a la tabla asociada o tabla base de un atributo frmula.

117

Frmulas vs. Asignaciones


atributo = expresin Puede especificarse de dos maneras:
mediante una frmula mediante una regla de asignacin

Diferencias:
frmula regla frmula regla atributo virtual atributo almacenado global local

Cuando el valor de un atributo puede obtenerse mediante un clculo, existen dos opciones para reflejar este conocimiento: Definir al atributo como frmula con el clculo correspondiente Reflejar el clculo mediante una regla de asignacin, dentro de la transaccin. La sintaxis de definicin en ambos casos es similar, sin embargo, existen diferencias importantes entre ambas alternativas: 1. Un atributo definido como frmula no se crear como campo fsico en una tabla de la base de datos (a no ser que se especifique lo contrario, definindolo como redundante, como se ver ms adelante). En cambio, si se especifica su clculo por medio de una regla de asignacin dentro de la transaccin, el atributo no presentar ninguna diferencia con respecto al resto de los atributos que no son frmula y al igual que los otros, se almacenar en la tabla que corresponda. 2. La asignacin de un clculo a un atributo mediante la definicin del atributo como frmula es una definicin global. Esto significa que el valor del atributo en tiempo de ejecucin siempre se mostrar actualizado al ejecutar todo programa que lo utilice, ya que su valor se calcular en el momento. Por el contrario, la asignacin de un clculo a un atributo mediante la definicin de una regla de asignacin en una transaccin, es una definicin local. Esto significa que solamente si se ejecuta la transaccin que tiene definida esa regla1, el clculo se efectuar y se almacenar el valor resultante en el campo fsico correspondiente. De existir otro objeto definido en la base de conocimiento que actualice la tabla que contiene al atributo cuyo valor se debe calcular, habr que definir explcitamente en el mismo la asignacin del clculo al atributo.

-------------------------------------------------------------------------------------------------------------1 La transaccin podr ejecutarse como tal o como business components, como veremos ms adelante. En cualquiera de estos casos, las reglas de la transaccin se ejecutarn.

118

Clasificacin
Frmulas Horizontales o Expresin
Permiten definir una o varias expresiones aritmticas condicionales

Frmulas Verticales
SUM COUNT

Son incondicionales

Frmulas Aggregate/Select
Aggregate: Sum, Count Select: Max, Min, Find Son condicionales

Frmulas Compuestas
Varias expresiones Horizontales y/o Aggregate/Select condicionales

Podemos dividirlas conceptualmente en cuatro categoras: Frmulas Horizontales o Expresin: Una frmula de este tipo, permite definir una o varias expresiones condicionales. Los atributos involucrados en la frmula debern pertenecer a la tabla extendida de la tabla asociada al atributo frmula (tabla base de la frmula). Son condicionales, en el sentido que pueden incluir condicin de disparo. Frmulas Verticales: Las frmulas verticales son dos: SUM y COUNT. SUM permite sumar y COUNT permite contar todas las ocurrencias del atributo referenciado, en la tabla en la que se encuentre. El atributo referenciado en la frmula deber pertenecer a una tabla directamente subordinada a la tabla asociada (tabla base) del atributo frmula, y no podr ser un atributo primario. Son incondicionales, significando esto que no permiten que se les incluya condicin de disparo ni condiciones sobre los registros a ser sumados/contados. Frmulas Aggregate / Select: Una frmula de este tipo permite buscar, sumar, contar atributos que cumplan determinadas condiciones, en cualquier tabla del modelo. Son condicionales, en el sentido que pueden incluir condicin de disparo y tambin condiciones sobre los registros a ser buscados/sumados/contados. Frmulas Compuestas: Una frmula de este tipo est compuesta por varias frmulas Aggregate/Select condicionales, pudiendo tambin contener expresiones horizontales. Como se puede percibir, dependiendo de la clase de frmula que se defina, se podrn involucrar en la misma atributos de tablas que tengan determinada relacin en particular con respecto a la tabla asociada al atributo frmula. En el presente curso no ahondaremos en las ltimas dos clases de frmulas. Para un estudio de las mismas recomendamos dirigirse al curso no presencial de GeneXus, donde encontrar un tratamiento profundo de estos temas.

119

Frmulas Horizontales
atributo = exp1 [if cond1] [; exp2 [if cond2]] ........................ [; expn [ otherwise | if condn]]

Donde: expi : cualquier expresin vlida (atributos, constantes, funciones, operadores). Los atributos involucrados deben ser de la tabla extendida. condi : condicin de disparo, es cualquier expresin lgica vlida. Los atributos involucrados deben ser de la tabla extendida.

expi : puede ser cualquier expresin vlida, pudiendo contener atributos pertenecientes a la tabla extendida de la tabla asociada al atributo que se est definiendo como frmula y/o constantes y/o funciones y/o operadores aritmticos (+,-,*,/,^) y/o operadores de strings (+) y/o operadores de fechas (+,). Otra posibilidad es que contenga una invocacin con udp (comando que veremos en breve) a un procedimiento GeneXus o a un programa externo que retorne un valor. El resultado -ya sea de las expresiones o el retornado por el programa invocado- deber ser del mismo tipo de datos que el del atributo que se est definiendo como frmula. condi : es cualquier expresin lgica vlida, pudiendo contener atributos pertenecientes a la tabla extendida de la tabla asociada al atributo que se est definiendo como frmula y/o constantes y/o funciones y/o operadores lgicos (and, or, not) y/o operadores de comparacin (>, >=, <, <=, =, like). La primera condicin que al ser evaluada d True, provocar que el resultado de la frmula sea el de la expresin de la izquierda de esa condicin (las dems no se seguirn evaluando). otherwise: cuando ninguna de las condiciones evaluadas dan True, si existe una expi con clusula otherwise, el resultado de la frmula ser el de la expresin expi que anteceda a esta clusula.

120

Frmulas Horizontales: Ejemplos

Transaccin Customer CusteromerId* CustomerName CustomerTotalPurchases CustomerTotalPayments CustomerBalance

TABLA CUSTOMER

CustomerId* CustomerName CustomerTotalPurchases CustomerTotalPayments

CustomerBalance = CustomerTotalPurchases - CustomerTotalPayments

En la transaccin "Customer" del ejemplo, como se puede observar, adems de los atributos correspondientes a los datos personales del cliente, existen los atributos CustomerTotalPurchases (total de compras del cliente) y CustomerTotalPayments (total de pagos del cliente), y se necesita saber en todo momento cul es el saldo del cliente, por lo qu tambin aparece el atributo CustomerBalance. Este saldo del cliente se calcula siempre igual: como la diferencia entre su total de compras CustomerTotalPurchases y su total de pagos CustomerTotalPayments. Como el clculo que debe realizarse es siempre ese, tenemos dos alternativas para definirlo: 1. Definir las siguientes reglas en la transaccin Customer: CustomerBalance = CustomerTotalPurchases CustomerTotalPayments; Noaccept(CustomerBalance); /*para que el usuario no pueda modificar el valor calculado de CustomerBalance*/ 2. Definir a CustomerBalance como un atributo frmula horizontal. Analizando las diferencias entre ambas alternativas decidimos optar por la segunda. Para ello, lo nico que tendremos que hacer estando en el modelo de Diseo, es abrir la transaccin "Customer" y agregar en su estructura al atributo CustomerBalance. Se deber ingresar el nombre, descripcin y tipo de datos del atributo, y en el campo frmula lo siguiente: CustomerTotalPurchases CustomerTotalPayments. Con esta definicin GeneXus tendr el conocimiento de que el atributo CustomerBalance ser un atributo virtual y sabr de qu forma calcular su valor. Cuando el analista pase a un modelo de Prototipo o Produccin y haya un anlisis de impacto, la definicin del atributo CustomerBalance no causar la creacin del campo fsico en la tabla CUSTOMER. Este es un ejemplo de frmula horizontal, debido a que se trata de un clculo aritmtico que involucra atributos de la tabla extendida de la tabla asociada al atributo definido como frmula (en particular, en este caso los atributos involucrados pertenecen a la propia tabla base del atributo frmula).

121

Frmulas Horizontales: Ejemplos


InvoiceId* CustomerId InvoiceDate InvoiceTotal INVOICE CustomerId* CustomerName CountryId CUSTOMER CountryId* CountryName COUNTRY

INVOICELINE InvoiceId* ProductId* InvoiceLineQuantity InvoiceLineAmount

PRODUCT

ProductId* ProductName ProductPrice ProductStock

InvoiceLineAmount = ProductPrice*InvoiceLineQuantity if InvoiceLineQuantity<=100; ProductPrice*InvoiceLineQuantity*0.9 otherwise;

Supongamos que queremos definir al atributo InvoiceLineAmount (importe de lnea de factura) como la siguiente frmula: InvoiceLineQuantity * ProductPrice (incondicional). Al hacerlo, si bien el atributo estar asociado a la tabla INVOICELINE, no se almacenar en ella (diremos que INVOICELINE ser su tabla base). La definicin de esta frmula se compondr de una expresin aritmtica sin condiciones de disparo, porque su valor siempre se calcula de la misma forma. En la expresin aritmtica intervienen los atributos InvoiceLineQuantity y ProductPrice, ambos pertenecientes a las tablas base y extendida del atributo frmula respectivamente. Si, en cambio, se necesita definir que cuando la cantidad de producto llevada por el cliente supere las 100 unidades, se haga un 10% de descuento al importe de lnea correspondiente, la frmula se transformar en la que aparece arriba en la transparencia, en la que hay dos expresiones condicionales. Si bien elegimos condicionar la segunda expresin con la clusula otherwise, hubiese sido equivalente definir: ProductPrice * InvoiceLineQuantity ProductPrice * InvoiceLineQuantity * 0,9 if InvoiceLineQuantity <=100; if InvoiceLineQuantity > 100;

ya que las dos condiciones de disparo son disjuntas y no dejan fuera ninguna posibilidad.

122

Frmulas Verticales
atributo =
Caractersticas: Suman o cuentan todas las ocurrencias del atributo att en una tabla. La tabla asociada a att debe ser directamente subordinada de la tabla base del atributo frmula. att no puede formar parte de ninguna clave del modelo (no puede ser atributo primario). Son incondicionales.

SUM(att) | COUNT(att)

Las frmulas verticales son dos: SUM y COUNT. SUM permite sumar los valores contenidos en el atributo att para todos los registros de la tabla asociada a l, que necesariamente deber ser directamente subordinada a la del atributo que estamos definiendo como frmula. COUNT permite contar todas las ocurrencias del atributo referenciado en la frmula, que tambin debe pertenecer a una tabla directamente subordinada a la tabla base del atributo que se est definiendo como frmula. Las frmulas verticales son incondicionales, es decir, no permiten que se les incluya condiciones sobre los registros de la tabla subordinada a ser sumados/contados.

Sintaxis: SUM(att) | COUNT(att) donde: att: Puede ser un atributo almacenado en una tabla directamente subordinada a la tabla base del atributo que se est definiendo como frmula, o un atributo frmula horizontal o vertical asociado tambin a una tabla directamente subordinada a la tabla base del atributo frmula. En cambio, no podr ser un atributo frmula Aggregate/Select, ni involucrar directa o indirectamente a un atributo frmula Aggregate/Select. No puede formar parte de ninguna clave del modelo. Para el caso de frmula SUM, debe ser de tipo numrico. El tipo de datos del atributo frmula debe ser numrico.

123

Frmulas Verticales
Caractersticas (continuacin): Se consideran los registros relacionados:
Relacin de subordinacin directa:

Tabla Base

Tabla Navegada

los registros estn relacionados

Para cada registro de la tabla base para el que se est evaluando la frmula, se suman/cuentan los registros de la tabla navegada relacionados.

Registros sumados/contados: Si bien no pueden establecerse condiciones sobre los registros de la tabla subordinada para que stos sean utilizados en la suma/cuenta (incondicionalidad de las frmulas verticales), en la resolucin de la frmula GeneXus no considera todos los registros de la tabla subordinada. Por el contrario, solo se suman/cuentan aquellos que estn relacionados con el registro de la tabla base para el cul la frmula se est evaluando. Quedar ms claro este punto con los ejemplos que veremos a continuacin.

124

Frmulas Verticales: Ejemplos


Transaccin "Invoice"
InvoiceId* INVOICE InvoiceId* CustomerId CustomerId 1 CustomerName InvoiceDate InvoiceDate InvoiceTotal = SUM(InvoiceLineAmount) N (ProductId* ProductDescription INVOICELINE ProductPrice InvoiceId* InvoiceLineQuantity ProductId* InvoiceLineAmount = ProductPrice*InvoiceLineQuantity InvoiceLineQuantity )

InvoiceTotal e InvoiceLineAmount son frmulas

no estn almacenados

En el clculo de InvoiceTotal solo intervienen los registros que cumplan: INVOICELINE.InvoiceId = INVOICE.InvoiceId

Queremos definir en la transaccin "Invoice" que el importe total (InvoiceTotal) se calcule automticamente como la suma de los importes de las lneas (InvoiceLineAmount). El atributo InvoiceTotal se encuentra en el primer nivel de la transaccin "Invoice" (siendo su tabla asociada: INVOICE) y el atributo InvoiceLineAmount se encuentra en el segundo nivel de la transaccin "Invoice" (siendo su tabla asociada: INVOICELINE). Es posible definir al atributo InvoiceTotal como la frmula vertical: SUM(InvoiceLineAmount) ya que el atributo que necesitamos referenciar en la frmula para ser sumado (InvoiceLineAmount) pertenece a una tabla directamente subordinada (INVOICELINE) a la tabla base (INVOICE) del atributo que queremos definir como frmula (InvoiceTotal). Las frmulas verticales no permiten que se les incluya condiciones de filtro. Por ejemplo, no podremos definir con una frmula vertical contar las lneas de la factura que cumplan que la cantidad de producto llevada supere las 100 unidades. Solamente podremos contar las lneas de la factura (todas). Sin embargo, como resulta evidente en el ejemplo que venimos viendo, los registros de INVOICELINE que intervendrn en el clculo sern slo los relacionados con el registro de INVOICE para el que se est calculando InvoiceTotal. Es decir, se contemplarn todos aquellos registros de INVOICELINE que cumplan, para el registro actual de INVOICE: INVOICELINE.InvoiceId = INVOICE.InvoiceId. De modo que si bien las frmulas verticales no permiten que se les incluya condiciones sobre los registros de la tabla directamente subordinada a ser sumados/contados, en la resolucin de la frmula GeneXus no considera todos los registros de la tabla subordinada, sino solamente aquellos que estn relacionados con el registro de la tabla base para el cul se est evaluando la frmula. En este ejemplo, el atributo sumado (InvoiceLineAmount) es un atributo frmula horizontal asociado a la tabla INVOICELINE que es directamente subordinada a la tabla INVOICE.

125

Frmulas Verticales: Ejemplos


Transaccin "Invoice"
InvoiceId* INVOICE InvoiceId* CustomerId CustomerId 1 CustomerName InvoiceDate InvoiceDate InvoiceLines = COUNT(InvoiceLineQuantity) N (ProductId* ProductDescription INVOICELINE ProductPrice InvoiceId* InvoiceLineQuantity ProductId* InvoiceLineAmount = ProductPrice*InvoiceLineQuantity InvoiceLineQuantity )

InvoiceLines e InvoiceLineAmount son frmulas

no estn almacenados

En el clculo de InvoiceLines solo intervienen los registros que cumplan: INVOICELINE.InvoiceId = INVOICE.InvoiceId

Si necesitamos contar la cantidad de lneas que tiene una factura, podemos agregar un atributo en el primer nivel de la estructura de la transaccin "Invoice" (de nombre InvoiceLines), y definirlo como la frmula: COUNT(InvoiceLineQuantity) o: COUNT(InvoiceLineAmount) Es exactamente lo mismo optar por referenciar a cualquiera de los atributos anteriores en la frmula COUNT, ya que el primero es un atributo almacenado en la tabla INVOICELINE y el segundo es un atributo frmula asociado a la tabla INVOICELINE, la cual es directamente subordinada a la tabla INVOICE (asociada al atributo InvoiceLines que se est definiendo como frmula). En cambio a los atributos InvoiceLineId y ProductId no es posible referenciarlos en la definicin de la frmula COUNT porque si bien se encuentran en la tabla INVOICELINE, forman parte de alguna clave.

126

Frmulas Verticales: Ejemplos


Transaccin Customer"
CustomerId* CustomerName CustomerTotalPurchases= SUM(InvoiceTotal) CustomerTotalPayments CustomerBalance InvoiceId* CustomerId InvoiceDate

CUSTOMER
1

CustomerId* CustomerName CustomerTotalPayments

INVOICE

1 N

InvoiceTotal = SUM( InvoiceLineAmount)

INVOICELINE

CUSTOMER e INVOICE: Relacin 1-N hay subordinacin directa vale la frmula

InvoiceId* ProductId* InvoiceLineQuantity

InvoiceLineAmount = ProductPrice*InvoiceLineAmount

En este otro ejemplo, el atributo CustomerTotalPurchases de la transaccin "Customer" representa el total de compras efectuadas por el cliente. Este total de compras se puede calcular como la suma de los totales de las facturas realizadas para ese cliente. Por tanto podemos definirlo como la frmula: CustomerTotalPurchases = SUM( InvoiceTotal ) GeneXus la interpretar como una frmula vertical, ya que la tabla base es CUSTOMER e InvoiceTotal est asociado a INVOICE, tabla directamente subordinada a CUSTOMER. Observar que en este caso, InvoiceTotal tambin es una frmula vertical. Como restriccin, no se pueden utilizar ms de dos frmulas SUM anidadas. Es decir, es posible definir una frmula SUM que involucre otra frmula SUM, pero sta ltima no puede involucrar otra frmula SUM. Lo mismo ocurre con la anidacin de frmulas COUNT.

127

Frmulas Verticales
Caractersticas (continuacin): Navegacin vertical: Performance y Redundancia Equivalencia entre SUM redundante y regla add
CustomerTotalPurchases = SUM(InvoiceTotal) Y redundante

CustomerTotalPurchases atributo secundario (no frmula) y calculado mediante la siguiente regla (en "Invoice"): add(InvoiceTotal, CustomerTotalPurchases)

Navegacin vertical: Performance y Redundancia El hecho de que una frmula no est almacenada puede ocasionar en algunos casos problemas de performance debido al tiempo que puede demorar el clculo. Esto depender de la cantidad de registros que se sumen o cuenten. Supongamos, por ejemplo, que tenemos miles de facturas, cada una de las cuales puede tener miles de lneas. Si frecuentemente se requiere sacar listados de las facturas mostrando sus totales, y los totales se calculan mediante la definicin de un atributo frmula SUM, por cada una de las miles de facturas, se debern navegar miles de registros correspondientes a sus lneas para realizar el clculo del total. Esto representa un costo elevado de performance. Para evitar este inconveniente, GeneXus provee la posibilidad de definir a un atributo frmula como redundante. Al hacerlo, el atributo deja de ser virtual y pasa a estar almacenado en la tabla asociada. En tiempo de ejecucin, al utilizar una transaccin que contiene un atributo frmula redundante, el comportamiento es el siguiente: la frmula se dispara efectundose el clculo y el resultado se almacena en el campo fsico de la base de datos. En los programas generados correspondientes a transacciones que tienen involucrados atributos frmulas redundantes, GeneXus incorpora rutinas que se encargan de almacenar los datos redundantes, siempre que se recalculen. Al consultar un atributo frmula redundante, no se dispara la frmula para obtener el clculo sino que se toma el valor almacenado del campo de la base de datos. Un atributo frmula redundante: A diferencia de un atributo frmula simple: estar almacenado en la base de datos. A diferencia de un atributo comn: GeneXus tendr el conocimiento de cmo calcular su valor y en los programas generados correspondientes a transacciones, incluir rutinas para mantener actualizado el valor almacenado.

128

Equivalencia entre definir un atributo frmula SUM redundante y utilizar regla add Definir un atributo como frmula SUM redundante es equivalente a que el atributo sea comn (no frmula) y definir una regla add en las transacciones en las cuales se encuentre, para efectuar el mismo clculo. Ambas cosas son equivalentes, con la salvedad de que la definicin de la frmula es global (est asociada al atributo), mientras que la definicin de la regla es local (es decir, la regla add se va a ejecutar solamente cuando se hagan ABM1 a travs de la transaccin en la cual est definida la regla). Por ejemplo, definir al atributo InvoiceTotal como la frmula: SUM(InvoiceLineAmount) redundante, es equivalente a que el atributo InvoiceTotal no sea definido como frmula, e incluir la regla: add(InvoiceLineAmount, InvoiceTotal) en la transaccin "Invoice". Si optamos por lo ltimo: Cada vez que se inserte una lnea, la regla add sumar el valor de InvoiceLineAmount al valor de InvoiceTotal. Cada vez que se elimine una lnea, la regla add restar el valor de InvoiceLineAmount al valor de InvoiceTotal. Cada vez que cambie el valor de InvoiceLineAmount de una lnea (porque se haya modificado el valor de alguno de los atributos que participan en la definicin de su frmula), la regla add sumar a InvoiceTotal, la diferencia entre el valor nuevo y el viejo de InvoiceLineAmount. Como sabemos, de definir al atributo InvoiceTotal como la frmula: SUM(InvoiceLineAmount), el comportamiento sera el mismo. Una de las diferencias a tener en cuenta a la hora de decidir si calcular el valor de un atributo mediante la definicin de una frmula o regla, es que con la primera alternativa, el atributo no se almacenar y con la segunda, si. Sin embargo, como nos estamos refiriendo a definir al atributo InvoiceTotal como la frmula: SUM(InvoiceLineAmount) redundante, el atributo InvoiceTotal se almacenar en su tabla asociada (INVOICE), de igual forma que si se define al atributo InvoiceTotal comn (no frmula) y se incluye la regla: add(InvoiceLineAmount, InvoiceTotal) en la transaccin "Invoice" para efectuar el clculo. Concluyendo, estas dos alternativas son equivalentes, ya que en tiempo de ejecucin en la medida que se vayan insertando, modificando o eliminando lneas por medio de la transaccin "Invoice", el valor del atributo InvoiceTotal se ir calculando y su valor quedar almacenado en un atributo fsico de la tabla INVOICE.

-------------------------------------------------------------------------------------------------------------------1 ABM = Altas, Bajas y Modificaciones.

129

COMUNICACIN ENTRE OBJETOS

130

Comunicacin entre objetos Procedimiento

Web Panel

Transaccin

Reporte PDF

Los objetos GeneXus pueden comunicarse entre ellos o con otros programas externos. Un objeto GeneXus puede llamar o ser llamado por otro objeto, intercambiando informacin a travs de parmetros1. Veremos a continuacin cmo invocar desde un objeto a otro, y cmo especificar los parmetros (en el objeto llamador y en el llamado) para el intercambio de la informacin. El esquema presentado arriba ilustra las posibles interacciones entre objetos GeneXus para una aplicacin Web. Obsrvese que la flecha simple entre Web Panel y Reporte PDF (as como entre Transaccin y Reporte PDF) indica que un Web Panel podr invocar a un Reporte2 pero un Reporte no podr invocar a un Web Panel (o transaccin Web). El esquema de interaccin entre los objetos GeneXus Win es ms flexible pues todos los objetos pueden interactuar con todos. En ese caso habr que sustituir al objeto Web Panel por el objeto Work Panel, y los reportes tendrn tambin ms flexibilidad, pues podrn invocarse en cualquier circunstancia, y podrn emitirse en formatos varios (y no solo PDF).

---------------------------------------------------------------------------------------------------------1 Para aplicaciones Web tambin se utilizan cookies para el intercambio de informacin. 2 En Web solamente podr invocarse a reportes PDF, como mencionaremos en el captulo que estudia el objeto Reporte.

131

Comunicacin entre objetos Win - Web


2 posibilidades: 1)
PgmName.Call(par1, , parN) Parm(par1, , parN); /*Invocacin a PgmName*/ /*Declaracin de parmetros en el objeto invocado*/

2)

att|&var = PgmName.Udp(par1, , parN) Parm(par1, , parN , parsalida);

/*Invocacin a PgmName*/ /*Declaracin de parmetros en el objeto invocado*/

CALL - Permite invocar a un objeto GeneXus o a un programa externo, tanto sin pasarle parmetros, como pasndole. UDP (User Defined Procedure) - Permite invocar a un objeto GeneXus o programa externo tanto sin pasarle parmetros como pasndole, y con la particularidad de que el programa llamado retornar necesariamente al menos un valor al programa que lo invoc. En Win la utilizacin de UDP es ms amplia que en Web, pues en Win todo objeto al finalizar su ejecucin devuelve el control al objeto llamador; sin embargo en Web esto no sucede en todos los objetos, por lo que UDP se utiliza nicamente para invocar a procedimientos (debido a que estos cumplen la condicin de ejecutar y devolver el control al llamador). Una invocacin (ya sea con CALL o UDP) podr escribirse en distintas partes del objeto llamador, dependiendo de si el mismo es una transaccin, web panel, procedimiento, etc.:

A su vez UDP puede utilizarse tambin en la definicin de un atributo frmula. Es decir, se define que cierto atributo es una frmula y que la definicin de la misma consiste en la invocacin a un procedimiento utilizando UDP.

PARM Cuando un objeto es invocado desde otro con parmetros, debe tener declarada la lista de parmetros que recibe. Esta declaracin se realiza mediante la regla: PARM.

A continuacin daremos ms detalles acerca del uso de CALL, UDP y PARM.

132

Comunicacin entre objetos Win - Web


2 posibilidades Ejemplos: 1)
Ej: RListInvoice.Call(InvoiceId) NOTAR PREFIJO

En el reporte ListInvoice

Parm(InvoiceId)

2)

Ej: &discount = PCalcDiscount.udp(ProductId,CustomerId)

En el proc CalcDiscount

Parm(ProductId,CustomerId , &discount);

Aqu mostramos un ejemplo de uso de CALL para realizar una invocacin y otro ejemplo de uso de UDP. Dependiendo de qu objeto llamador se trate, estas invocaciones podrn escribirse en una seccin u otra del mismo, pero independientemente de eso, aqu apuntamos a mostrar que CALL permite invocar a un objeto con estilo de invocacin a un programa, mientras que UDP invoca a un objeto con estilo de invocacin a una funcin. En el primer ejemplo se est utilizando CALL para invocar a un reporte (objeto ListInvoice) pasndole 1 parmetro (InvoiceId). En el reporte invocado se ha declarado el parmetro que recibe (en su seccin de reglas, mediante la regla parm). En el segundo ejemplo se est utilizando UDP para invocar a un procedimiento (objeto CalcDiscount) pasndole 2 parmetros (ProductId, CustomerId). Ahora, observemos en la sintaxis de la invocacin al procedimiento, que el mismo retorna un valor (en la variable &discount). Por este motivo, en el procedimiento invocado se han declarado 3 parmetros utilizando la regla parm: los 2 parmetros recibidos + el parmetro de retorno en ltimo lugar. Podemos ver entonces que cuando se utiliza CALL para invocar a un objeto envindole N parmetros, se deben declarar los N parmetros (posicionales y del mismo tipo de datos que los enviados) en el objeto invocado mediante la regla parm. En cambio cuando se utiliza UDP para invocar a un objeto envindole N parmetros: en la regla parm del objeto invocado se deben declarar N + 1. El ltimo parmetro declarado en la regla parm del objeto invocado, corresponde al que se encuentra al principio de todo en la invocacin, es decir, al que recibe el valor retornado. En algn lugar del objeto invocado se le deber asignar valor al parmetro de retorno.

133

Convencin de nombrado de los objetos GeneXus invocados


En la invocacin a un objeto GeneXus, el nombre del objeto que se invoca debe estar formado por: : Prefijo + nombre del objeto

Tanto si se utiliza, CALL como UDP para invocar a un objeto GeneXus, el nombre del objeto que se invoca debe estar formado por: un prefijo (que identifica al tipo de objeto) + el nombre del objeto. La tabla de la transparencia muestra algunos prefijos segn el tipo de objeto. Por ejemplo, si se desea invocar desde algn objeto GeneXus a la transaccin Invoice el nombre que se deber escribir en la invocacin es TInvoice. A su vez, si se desea invocar desde algn objeto GeneXus a un reporte de nombre CustomersReport, el nombre que se deber escribir en la invocacin es RCustomersReport. Recomendamos utilizar el tem: Insert/Object de la barra de men de GeneXus para seleccionar los objetos que se deseen invocar, ya que automticamente se insertarn con el prefijo que corresponda y el analista no tendr que recordarlo de memoria. Nota: Si el objeto invocado es un programa externo, el nombre del mismo deber incluirse entre comillas en la invocacin.

134

Qu declarar en la regla parm: variable o atributo?


Variable: Se podr utilizar libremente, en la lgica del objeto invocado:
como condicin de filtro por =, >, >=, <, <=, LIKE, etc. para alguna operacin aritmtica como bandera etc.

Atributo: Automticamente el mismo actuar como filtro por igualdad en el objeto, no siendo posible modificar el valor recibido.

Al definir una invocacin a un objeto (ya sea utilizando CALL o UDP), si se tienen que enviar datos por parmetro al objeto invocado, resulta evidente determinar si enviar atributos y/o variables: si un dato a ser enviado por parmetro, se encuentra en el objeto invocador, en un atributo, habr que enviar al mismo; y si se encuentra en una variable, habr que enviar a la variable. Sin embargo, al declarar la lista de parmetros en el objeto invocado, el programador GeneXus deber decidir para cada parmetro, si declararlo mediante un atributo o una variable, independientemente de cmo haya sido enviado. Cul es la diferencia entre declarar un parmetro como variable o como atributo en la regla parm del objeto invocado? Si se declara una variable, se la podr utilizar libremente en la lgica del objeto invocado: se la podr utilizar como condicin de filtro por igualdad, por mayor, mayor o igual, menor, menor o igual, LIKE, etc.; se la podr utilizar para alguna operacin aritmtica, como bandera, o lo que se necesite. Si en cambio se declara un atributo, automticamente el mismo actuar como filtro por igualdad en el objeto, no siendo posible modificar el valor recibido. Cuando lleguemos a la etapa del curso en la cual podamos invocar a reportes pasndoles parmetros as como a otros objetos, podremos terminar de comprender esto ya que la prctica nos permitir ver este tema.

135

Definicin de parmetros de entrada (in), salida (out),entrada-salida (inout) en Parm


Para cada parmetro que se declara en la regla parm, es posible definir si se desea que el mismo opere: de entrada (in) de salida (out) de entrada-salida (inout) Ejemplo: parm(out:&par1, in:&par2, &par3, inout:&par4); Ventajas: Mejor especificacin de la semntica de las interfaces. Independencia del lenguaje de generacin. Optimizar el pasaje de parmetros de las aplicaciones de acuerdo a la arquitectura en la que stas se implementan (ventaja contrapuesta a la anterior).

Para cada parmetro que se declara en la regla parm, es posible definir si se desea que el mismo opere: de entrada (in), de salida (out), o de entrada-salida (inout). Ejemplo: parm(out:&par1, in:&par2, &par3, inout:&par4); Como se puede percibir claramente en la sintaxis del ejemplo, el primer parmetro definido es de salida, el segundo parmetro es de entrada, y el cuarto parmetro es de entrada-salida. Cuando no se especifica nada, como es el caso del tercer parmetro de la sintaxis, depender de lo siguiente: si el objeto fue invocado con CALL, el parmetro, ser de entrada-salida. si el objeto fue invocado con UDP, y se trata del ltimo parmetro, ser de salida; y si se trata de otro parmetro distinto del ltimo, depender del lenguaje de generacin. Declarar explcitamente cmo se desea que cada parmetro opere, tiene las siguientes ventajas: 1. Mejor especificacin de la semntica de las interfaces; es decir, tanto para GeneXus como para el programador cuando trabaje con un objeto, ser claro tener definido en la regla parm el objetivo de cada parmetro, es decir: - si el mismo vendr con valor y luego de la ejecucin del objeto invocado, se devolver al objeto invocador el valor con que haya quedado (inout). - si el mismo vendr con valor y luego de la ejecucin del objeto invocado, no se devolver al objeto invocador el valor con que haya quedado (in). - si el mismo no vendr con valor y luego de la ejecucin del objeto invocado, se devolver al objeto invocador el valor que tenga (out). 2. Independencia del lenguaje de generacin; es decir, si se define explcitamente cmo se desea que cada parmetro opere, al generar las aplicaciones utilizando diferentes lenguajes de generacin no estar cambiando el comportamiento de los parmetros en base al comportamiento por defecto del lenguaje de generacin correspondiente. 3. Optimizar el pasaje de parmetros de acuerdo a la arquitectura en la que stas se generen (siendo una ventaja contrapuesta a la anterior); esto se refiere a lo siguiente: para la mayora de los lenguajes es ms eficiente pasar los parmetros por referencia (inout) que por valor (in / out); pero en Java, por ejemplo, los parmetros solo se pueden pasar por valor, por lo que para lograr la funcionalidad de pasarlos por referencia es necesario hacer conversiones de parmetros, lo cual puede redundar en un overhead importante; por otro lado, cuando se trata de aplicaciones distribuidas (por ejemplo Java con RMI o HTTP), la utilizacin de parmetros de tipo out tiene la ventaja de que no es necesario enviar al parmetro en la invocacin, a diferencia de si los parmetros se definen de inout (que implica que haya que pasar todos los parmetros); esto tiene como consecuencia que se enven ms bytes de los necesarios, lo cual es inconveniente especialmente en entornos tales como Internet.

136

Comunicacin entre objetos Web


Ms posibilidades para definir invocaciones Funcin Link

1)

control.Link = PgmName.Link([,par1 , parN]) Ej: imagen.Link = TCustomer.Link()


Los parmetros son opcionales, y en caso de haber, se declaran con regla parm

2)

control.Link = Link(URL) Ej: imagen.Link = Link(http://www.artech.com.uy)

La funcin Link se asocia a la propiedad link de un control dentro de cualquier evento de una transaccin o web panel1, teniendo como resultado que al hacer clic sobre dicho control se realizar la llamada al objeto o URL referenciada en el link. PgmName (el objeto invocado) podr ser un web panel, transaccin, o reporte PDF 2.

1 2

-------------------------------------------------------------------------------------------------------a excepcin del evento Load de los web panels (que veremos ms adelante) tambin un procedimiento HTTP, pero no profundizaremos sobre este concepto en este curso

137

Comunicacin entre objetos Web


Ms posibilidades para definir invocaciones Comando Link

1)

PgmName.Link([,par1 , parN]) Ej: TCustomer.Link(CustomerId)

2)

Link(URL) Ej: Link(http://www.google.com)

El comando Link puede ser utilizado dentro de cualquier evento de una transaccin o web panel1. Cuando se ejecute el evento, al llegar a la sentencia con el comando Link, se redireccionar en forma automtica a la URL especificada. En caso de utilizarse el comando Link como en el ejemplo 1, invocando a un PgmName (siendo PgmName un web panel, transaccin o reporte PDF), ser equivalente a la utilizacin de Call. Opcionalmente se podrn pasar parmetros al objeto invocado, debiendo declararse los mismos en el objeto llamado, con la regla parm.

1 2

-------------------------------------------------------------------------------------------------------a excepcin del evento Load de los web panels (que veremos ms adelante) tambin un procedimiento HTTP, pero no profundizaremos sobre este concepto en este curso

138

ORDEN DE EJECUCIN DE REGLAS Y FRMULAS

139

Orden de ejecucin de reglas y frmulas


Transaccin "Invoice"
InvoiceId* InvoiceDate CustomerId CustomerTotalPurchases CategoryDiscount InvoiceDiscount = InvoiceSubTotal *CategoryDiscount InvoiceShippingCharge = Max( ShippingDate, ShippingDate <=InvoiceDate,,ShippingCharge) InvoiceSubTotal = SUM( InvoiceLineAmount ) InvoiceTotal = InvoiceSubTotal InvoiceDiscount + InvoiceShippingCharge (ProductId* ProductPrice ProductStock InvoiceLineQuantity InvoiceLineAmount) = InvoiceLineQuantity * ProductPrice

Customer

CustomerId* CustomerName CategoryId CustomerTotalPurchases

Category

CategoryId* CategoryDiscount

Shipping

ShippingDate* ShippingCharge

Product

ProductId* ProductPrice ProducStock

Reglas:

Add( InvoiceTotal, CustomerTotalPurchases); Error( Insufficient Stock ) if ProductStock<0; Subtract( InvoiceLineQuantity, ProductStock);

La forma de programar el comportamiento de las transacciones es definiendo reglas, las cuales se escriben de forma declarativa. A su vez si hay clculos para efectuar, se puede optar por la alternativa de definir atributos frmula. El programador GeneXus en ningn momento especifica la secuencia de ejecucin de las reglas y frmulas definidas en una transaccin, sin embargo al momento de generar, GeneXus determina las dependencias existentes entre las reglas y frmulas definidas. Supongamos que estamos definiendo una aplicacin para una empresa que vende determinados productos, y que cuenta con un servicio de entrega a domicilio que lleva la mercadera a sus clientes. Y definimos entre otras, las siguientes 5 transacciones: "Customer" (para registrar los clientes de la empresa) Category (a las que pertenece cada cliente) Shipping (envos: guarda un histrico de costos de envo) "Invoice" (facturas que se emiten a los clientes) "Product" (productos vendidos por la empresa) Se resalta la estructura de la transaccin "Invoice", con sus atributos frmulas (algunas horizontales, otras verticales, otras aggregate/select) y sus reglas declaradas. En qu orden se dispararn las reglas y frmulas de la transaccin "Invoice"?

140

rbol de evaluacin
R. Add(InvoiceTotal, CustomerTotalPurchases); F. InvoiceTotal = InvoiceSubTotal - InvoiceDiscount + InvoiceShippingCharge F. InvoiceDiscount = InvoiceSubTotal*CategoryDiscount F. InvoiceShippingCharge = MAX( ShippingDate, ShippingDate <= InvoiceDate,,ShippingCharge) F. InvoiceSubTotal = SUM( InvoiceLineAmount ) F. InvoiceLineAmount = InvoiceLineQuantity *ProductPrice R. Subtract(InvoiceLineQuantity, ProductStock) ; R. Error( Insuffcient Stock) if ProductStock < 0 ;

CustomerTotalPurchases

InvoiceTotal

InvoiceDiscount InvoiceShippingCharge
error (Insufficient Stock )

InvoiceSubTotal

ShippingDate

InvoiceDate

ProductStock

InvoiceLineAmount

CategoryDiscount

ShippingCharge

InvoiceLineQuantity

ProductPrice

Al momento de generar el programa asociado a la transaccin "Invoice", GeneXus extraer las dependencias existentes entre las reglas y frmulas definidas; construir lgicamente un rbol de dependencias (o rbol de evaluacin) que determinar la secuencia de evaluacin. Podemos imaginar que el rbol se ejecuta de abajo hacia arriba, es decir que cada vez que cambia el valor de un atributo, se ejecutan todas las reglas y frmulas que dependen de ese atributo (y que en el rbol se encuentran hacia arriba). Por ejemplo, si cambia la cantidad de una lnea de una factura (InvoiceLineQuantity), como este atributo interviene en la frmula que calcula el importe de la lnea (InvoiceLineAmount), dicha frmula se redisparar. Por cambiar el importe de una lnea, deber redispararse la frmula correspondiente al subtotal de la factura (InvoiceSubTotal) y en consecuencia, tambin deber recalcularse la frmula correspondiente al descuento (InvoiceDiscount), ya que depende del subtotal. Deber redispararse tambin la frmula correspondiente al total de la factura (InvoiceTotal) ya que depende tanto del valor de InvoiceSubTotal como del valor de InvoiceDiscount. Por ltimo, por cambiar el total tambin se tendr que disparar la regla Add(InvoiceTotal, CustomerTotalPurchases);. Adems de dispararse todas las frmulas y reglas involucradas en la rama derecha del rbol desde el atributo InvoiceLineQuantity, tambin se dispararn las frmulas y reglas involucradas en la rama izquierda. Es decir, que al cambiar el valor del atributo InvoiceLineQuantity, se redisparar tambin la regla Subtract(InvoiceLineQuantity, ProductStock); y en consecuencia, por modificar esta regla el valor del atributo ProductStock, se evaluar si habr que disparar la regla Error(Stock Insuficiente) if ProductStock < 0; Concluyendo, las reglas y frmulas que se definen en una transaccin suelen estar interrelacionadas y GeneXus determina las dependencias entre ellas as como su orden de evaluacin. Observemos las 2 ltimas reglas definidas: Subtract(InvoiceLineQuantity, ProductStock); Error(Insufficient Stock) if ProductStock < 0;

141

Estas reglas estn interrelacionadas porque las dos involucran al atributo ProductStock. Ahora, mientras la segunda solamente consulta su valor, la primera lo actualiza. Entonces, la regla que actualiza al atributo ser la que se disparar primero, y luego se disparar la que lo consulta. Toda regla que actualice el valor de un atributo se disparar antes que una regla que lo consulte (esto se puede observar claramente en el rbol). Por este motivo es que la regla Error consulta si el atributo ProductStock qued con valor negativo; porque como dijimos la sustraccin se realizar primero. En la programacin clsica se suele consultar primero si alcanza el stock, y en caso de que sea suficiente recin se hace la sustraccin. Por eso quienes estn aprendiendo GeneXus pueden intuitivamente escribir la regla: Error(Insufficient Stock') if InvoiceLineQuantity > ProductStock. Esta sintaxis es correcta, sin embargo no es correcta su lgica ya que como venimos explicando, en el rbol de evaluacin determinado por GeneXus primero se disparar la regla Subtract y luego la regla Error; por lo tanto tendremos que especificar que se dispare el mensaje de error si es que qued el stock con valor negativo, dado que ya se habr ejecutado la sustraccin al momento de consultar el valor de ProductStock. As que la regla que se debe definir es: Error(Insufficient Stock) if ProductStock < 0; Y no: Error('Insufficient Stock') if InvoiceLineQuantity > ProductStock; Cuando se dispara una regla Error, se detiene cualquier actualizacin a la base de datos y se desarma el rbol de evaluacin, quedando todo en el estado anterior a producirse el error. Siguiendo el ejemplo que venamos viendo, si al dispararse la regla Subtract el stock quedara negativo, se disparara la regla Error. Como consecuencia de dispararse la regla Error, se deshara el Subtract que se haba ejecutado, as como todas las dems reglas y frmulas que se hayan ejecutado (reclculo de los atributos InvoiceLineAmount, InvoiceSubTotal, ...., CustomerTotalPurchases). Cmo podemos ver el orden de evaluacin determinado por GeneXus? Al especificar una o varias transacciones, seleccionando la opcin Detailed Navigation, se detallar en el listado de navegacin resultante el orden de ejecucin de todas las reglas y frmulas definidas en la transaccin.

142

Alteraciones del orden de disparo de las reglas


Total

Error Total

SupplierId* Calculado Ingresado InvoiceId* ... InvoiceEntTotal Entered Total InvoiceLineAmount ( ProductId* InvoiceLineQuantity InvoiceLinePrice InvoiceLineAmount = InvoiceLinePrice * InvoiceLineQuantity) ... InvoiceCalcTotal = SUM(InvoiceLineAmount) Calculated Total

Error(The calculated total doesnt match with the entered total') if (InvoiceEntTotal<>InvoiceCalcTotal) On AfterLevel Level ProductId;

En la mayora de los casos el orden de ejecucin de las reglas definido por GeneXus a partir de nuestras especificaciones es el deseado. Pero en algunos casos podemos querer cambiar el momento de disparo de una regla. Ejemplo: Definimos una transaccin para registrar las facturas que nos entregan nuestros proveedores. El identificador del primer nivel es compuesto por el identificador de proveedor y el identificador de factura, ya que el nmero de factura no nos sirve como identificador nico, porque proveedores distintos pueden repetir el mismo nmero de factura. Para cada factura de un proveedor que se ingrese, nos interesa controlar que el total que venga escrito en la factura (y que se ingresar en el atributo InvoiceEntTotal) sea correcto. Para hacer este control, definimos al atributo InvoiceCalcTotal como frmula vertical SUM(InvoiceLineAmount), y agregamos una regla Error que se disparar si no coinciden los valores de los atributos InvoiceEntTotal y InvoiceCalcTotal: Error('El total ingresado no coincide con el total calculado') if InvoiceCalcTotal <> InvoiceEntTotal; Si construimos el rbol de evaluacin correspondiente a las frmulas y regla que hemos definido en esta transaccin:

143

vemos que las dependencias indican que cada vez que se agreguen, modifiquen o eliminen valores de los atributos InvoiceLinePrice e InvoiceLineQuantity en las lneas, se recalcular el valor del atributo InvoiceLineAmount correspondiente; en consecuencia, se recalcular el valor del atributo frmula InvoiceCalcTotal que hemos definido para tener el total calculado de la factura; y como este atributo est involucrado en la condicin de disparo de la regla Error, si se cumple dicha condicin de disparo, se disparar la regla Error(El total ingresado no coincide con el total calculado) if InvoiceCalcTotal <> InvoiceEntTotal. Ahora, prestemos atencin a que la condicin de disparo InvoiceCalcTotal <> InvoiceEntTotal se va a cumplir repetidamente en la medida que el operador vaya ingresando lneas, porque para cada lnea que se ingrese se calcular el valor del atributo frmula InvoiceLineAmount de la lnea, y en consecuencia se recalcular el valor del atributo frmula InvoiceCalcTotal. Pero el valor calculado de este atributo no coincidir con el valor ingresado en el atributo InvoiceEntTotal hasta que no se hayan ingresado todas las lneas de la factura; entonces, se disparar la regla Error(The calculated total doesnt match with the entered total) if InvoiceCalcTotal <> InvoiceEntTotal;. Concluimos entonces que en este caso no nos sirve lo que determina el rbol de evaluacin, ya que no queremos que se evale la condicin de disparo de la regla Error cada vez que el operador ingrese, modifique o elimine lneas, sino que recin necesitamos que se evale cuando el usuario haya terminado de trabajar con todas las lneas de la factura. GeneXus ofrece eventos o momentos de disparo en las transacciones, que ocurren antes o despus de determinada accin, como la grabacin del cabezal, o de una lnea. Las reglas de las transacciones pueden condicionarse de manera tal de dispararse en el preciso instante en que ocurre alguno de esos eventos de disparo. Siguiendo el ejemplo que venamos viendo, existe un evento de disparo que ocurre luego de iterar en un nivel y salir del mismo. La sintaxis de este evento de disparo es: AfterLevel Level Atributo, debiendo ser Atributo un atributo perteneciente al nivel que se ha iterado y se abandona. De modo que a la regla Error de nuestro ejemplo, le agregaramos este evento de disparo, y quedara definida de la siguiente forma: Error(The calculated total doesnt match with the entered total) if InvoiceCalcTotal<>InvoiceEntTotal On AfterLevel Level InvoiceLinePrice; Con este evento de disparo que hemos agregado a la regla logramos controlar lo que desebamos en el momento adecuado. Adems de este evento de disparo, existen otros que veremos a continuacin.

144

Eventos de disparo
La mayora de las reglas de transacciones permiten que se les agregue de ser necesario un evento o momento de disparo. Al agregar un evento o momento de disparo a una regla, estaremos especificando que la regla se deber ejecutar en ese determinado momento. Eventos de disparo:
BeforeValidate AfterValidate BeforeInsert, BeforeUpdate, BeforeDelete AfterInsert, AfterUpdate, AfterDelete AfterLevel BeforeComplete AfterComplete

Al momento de la confirmacin de la transaccin, ocurre una serie de acciones que es necesario conocer para poder programar correctamente el comportamiento de las reglas. Para una transaccin de dos niveles, podramos enumerarlas como sigue: validacin de los datos del cabezal grabacin fsica del cabezal (ya sea insercin, modificacin o eliminacin) validacin de los datos de la primera lnea grabacin fsica de los datos de la primera lnea validacin de los datos de la segunda lnea grabacin fsica de los datos de la segunda lnea validacin de los datos de la n-sima lnea grabacin fsica de los datos de la n-sima lnea commit La accin de validacin de los datos del cabezal ocurre cuando se han validado todos y cada uno de los campos ingresados en el cabezal. Observar que en este punto ya se han disparado todas las reglas que correspondan a atributos del cabezal y que no tenan evento de disparo asociado (ejemplo: Default(InvoiceDate, &today)). Inmediatamente despus se grabar el registro correspondiente al cabezal. Anlogo es el caso de las lneas: la validacin de los datos de una lnea ocurre cuando ya se han validado todos y cada uno de los datos de la lnea, y tambin se han disparado todas las reglas correspondientes segn el rbol de evaluacin (ejemplo: subtract( InvoiceLineQuantity, ProductStock)). Inmediatamente despus de esta accin de validacin, se grabar fsicamente el registro correspondiente a la lnea. Cada transaccin, al terminar de trabajar con un cabezal y sus lneas, realiza un commit (es automtico; ser colocado en el cdigo generado por GeneXus, a menos que el analista especifique lo contrario, como veremos ms adelante). Es decir, si se van a ingresar los datos de dos facturas distintas utilizando la transaccin Invoice, luego de ingresados los datos de la primera, se commitearn sus registros, y luego se ingresar la segunda, al cabo de lo cul se commitearn sus registros. Los eventos de disparo de reglas permiten definir que se ejecuten antes o despus de alguna de las acciones que acabamos de enumerar. Veremos cundo ocurre cada evento de disparo.

145

Evento de disparo: BeforeValidate Este evento de disparo ocurre un instante de tiempo antes de que la informacin de la instancia con la que se est trabajando (cabezal o lnea x) sea validada (o confirmada). Es decir, ocurrir un instante de tiempo antes de la accin de validacin del cabezal o validacin de la lnea, segn corresponda. Observar que aqu tambin se habrn disparado todas las reglas segn el rbol de evaluacin que no estn condicionadas a evento de disparo alguno. Eventos de disparo: AfterValidate, BeforeInsert, BeforeUdate, BeforeDelete El evento de disparo AfterValidate permite especificar que una regla se ejecute inmediatamente antes de que se grabe fsicamente cada instancia del nivel al cual est asociada la regla, en la tabla fsica correspondiente, y despus de que se hayan validado los datos de esa instancia. En otras palabras, si se le agrega el evento de disparo AfterValidate a una regla, la misma se ejecutar para cada instancia del nivel al cual est asociada, inmediatamente antes de que la instancia se grabe fsicamente (ya sea que se inserte, modifique o elimine) como registro en la tabla fsica asociada al nivel. EJEMPLOS 1. Hay veces en las que no contamos con la posibilidad de utilizar la propiedad Autonumber para numerar de forma automtica y correlativa los atributos que son clave primaria simple. Tal funcionalidad es provista por los manejadores de base de datos (DBMSs) y GeneXus la aprovecha y permite usarla; sin embargo en los casos en los que no se trabaja con un manejador de base de datos, no contamos con la posibilidad de utilizar esta facilidad. En esos casos en los que necesitamos numerar de forma automtica y correlativa ciertos atributos, y no podemos utilizar la propiedad Autonumber, debemos resolverlo programndolo. Para ello solemos definir una transaccin conteniendo dos atributos, uno para almacenar un literal y otro para almacenar el ltimo nmero asignado automticamente al atributo descripto por el literal1; la transaccin conlleva la creacin de una tabla, y definimos un procedimiento que consulta esa tabla, obtiene el ltimo nmero asignado para el atributo a ser numerado, le suma uno y devuelve el prximo nmero, adems de actualizarlo en la tabla. Para invocar al procedimiento de numeracin automtica se debe definir en las transacciones que lo requieran una regla del siguiente estilo: CustomerId = PGetNumber.udp( CUSTOMER ) if Insert on AfterValidate; En este caso se est queriendo autonumerar el atributo CustomerId de la transaccin Customer Del mismo modo, si queremos autonumerar el identificador de facturas, escribiramos en la transaccin Inovice la siguiente regla: InvoiceId = PGetNumber.udp( INVOICE ) if Insert on AfterValidate; De esta forma definimos que se efecten numeraciones automticas en las transacciones nicamente cuando se realicen inserciones (por la condicin de disparo: if Insert) e inmediatamente antes de que se grabe fsicamente cada instancia a ser insertada (por el evento de disparo: on AfterValidate) a travs del primer nivel de la transaccin (porque en las dos reglas de invocacin mostradas, hay solamente un atributo involucrado que pertenece al primer nivel de las transacciones "Customer" e "Invoice" respectivamente). El motivo por el cual agregamos el evento de disparo on AfterValidate a estas reglas es para invocar al procedimiento de numeracin automtica inmediatamente antes de que se inserte el registro en la base de datos y luego de la validacin, intentando de esta forma tener el mayor grado de seguridad posible de que el nmero asignado ser utilizado (y no perder nmeros). Piense unos instantes el lector cundo se disparara la regla anterior de no estar condicionada a evento de disparo alguno, y qu podra pasar en el caso de que fallara la validacin de alguno de los datos del cabezal. La respuesta es simple: se perdera un nmero. Es decir, si el nmero de factura anterior fuera 5 y el usuario quisiera ingresar la siguiente factura, la regla de asignacin con udp que invoca la procedimiento de numeracin se disparara ni bien se ingresara a la transaccin estando en modo insert, ya que involucra al primer atributo del cabezal. El procedimiento devolvera el nmero 6, y si validando los datos del cabezal se encuentra algn error que no permite continuar con el proceso, y se abandonara la transaccin, por ejemplo, ese nmero 6 se habr perdido y la prxima factura, que correlativamente debera tener el nmero 6 no lo tendr, tendr el 7.

---------------------------------------------------------------------------------------------------------------------------Cuando vimos la regla serial introdujimos este tema de numeracin de cabezales, con la transaccin Number que era la que tena el literal: NumberCode y el ltimo nmero asignado a la transaccin correspondiente a ese literal: NumberLast

146

Existen tres eventos de disparo que ocurren en el mismo momento que el AfterValidate, pero que ya contienen intrnseco el modo. Ellos son: BeforeInsert, BeforeUpdate y BeforeValidate. Es equivalente escribir la regla presentada antes como lo hicimos, a escribirla: InvoiceId = PGetNumber.udp( INVOICE ) on BeforeInsert; Observar que aqu es redundante condicionar la regla a If Insert. Por tanto, valen las siguientes equivalencias: on BeforeInsert on BeforeUpdate on BeforeDelete If Insert on AfterValidate If Update on AfterValidate If Delete on AfterValidate

Si hacemos un esquema de las acciones que rodean al evento de disparo, quedarn claros los dos sinnimos elegidos para este evento (AfterValidate y BeforeInsert para modo insert) VALIDACIN DE LOS DATOS AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRABACIN DEL REGISTRO (insert, update, delete segn corresponda)

2) Si definimos una regla a la cual le incluimos tambin el evento de disparo on AfterValidate, u on BeforeInsert, BeforeDelete, BeforeUdate pero a diferencia de los ejemplos recin vistos, se referencia en la regla al menos un atributo del segundo nivel de la transaccin en la cual se est definiendo la regla, la misma estar asociada al segundo nivel1. Por lo tanto, la regla se ejecutar inmediatamente antes de que se grabe fsicamente cada instancia correspondiente al segundo nivel de la transaccin.

Eventos de disparo: AfterInsert, AfterUpdate, AfterDelete As como existe un evento de disparo que permite definir que determinadas reglas se ejecuten inmediatamente antes de que se produzca la grabacin fsica de cada instancia de un nivel (AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete), tambin existen eventos de disparo para definir que ciertas reglas se ejecuten inmediantamente despus de que se inserten, modifiquen o eliminen fsicamente instancias de un nivel. Estos eventos son AfterInsert, AfterUpdate y AfterDelete. El evento de disparo AfterInsert permite definir que una regla se ejecute inmediatamente despus de que se inserte fsicamente cada instancia del nivel al cual est asociada la regla; el AfterUdate luego de que se actualice fsicamente la instancia, y el AfterDelete luego de que se elimine. EJEMPLOS Supongamos que en la transaccin "Customer" queremos invocar a un reporte que realice la impresin de los datos de cada cliente con el cual se trabaje por medio de la transaccin. En qu momento debemos realizar la invocacin al reporte desde la transaccin? Caso 1: RPrintCustomer.call( CustomerId ) on AfterValidate; No es adecuado agregarle este evento de disparo a la regla de invocacin al reporte, porque ste se invocara inmediatamente antes de la grabacin fsica de cada cliente. En consecuencia, el reporte no encontrara al cliente con sus datos en la tabla CUSTOMER (si se estaba insertando un cliente por medio de la transaccin), o lo encontrara con sus datos desactualizados (si se estaba modificando un cliente por medio de la transaccin). Si en cambio se estaba eliminando un cliente por medio de la transaccin, el reporte encontrara los datos del cliente en la tabla CUSTOMER y los listara justamente antes de la actualizacin fsica (eliminacin). Si se desea esto, es decir, emitir un listado con los datos de cada cliente que se elimine, sera adecuado definir la siguiente regla: RPrintCustomer.call( CustomerId ) on BeforeDelete; o su equivalente: RPrintCustomer.call( CustomerId ) if delete on AfterValidate;

-------------------------------------------------------------------------------------------------------------------------Existe otra forma de provocar que una regla que contiene atributos de un nivel determinado, se dispare en el nivel siguiente, mediante la clusula Level que mencionamos cuando vimos conceptos importantes sobre reglas de transacciones.
1

tiempo

147

para restringir el disparo de la regla nicamente a cuando se est eliminando un cliente, porque es el nico caso en el sera correcto utilizar el evento de disparo AfterValidate (ya que justamente necesitamos emitir el reporte antes de la eliminacin). Caso 2: RPrintCustomer.Call( CustomerId ) on AfterInsert; El evento de disparo AfterInsert ocurre inmediatamente despus de que se inserte fsicamente cada instancia asociada a cierto nivel de la transaccin (en este caso, como el nico atributo involucrado en la regla es CustomerId, se trata de una regla asociada al primer y nico nivel de la transaccin "Customer"). Como lo indica claramente su nombre, el evento de disparo AfterInsert slo ocurre al insertar una nueva instancia (precisamente luego de ser insertada como registro fsico). Es por ello que cuando se agrega el evento de disparo on AfterInsert a una regla, no es necesario agregarle la condicin de disparo if insert. Es correcto agregarle este evento de disparo a la regla de invocacin al reporte, ya que el reporte se invocara inmediatamente despus de que se inserte fsicamente cada cliente. As que el reporte encontrara al cliente con sus datos en la tabla CUSTOMER y los imprimira. Lo que debe quedar claro es que con esta definicin el reporte se invocar nicamente luego de realizar inserciones. Caso 3: RPrintCustomer.Call( CustomerId ) on AfterUpdate; El evento de disparo AfterUpdate ocurre inmediatamente despus de que se actualice fsicamente cada instancia asociada a cierto nivel de la transaccin (en este caso, como el nico atributo involucrado en la regla es CustomerId, se trata de una regla asociada al primer y nico nivel de la transaccin "Customer"). Es adecuado agregarle este evento de disparo a la regla de invocacin al reporte, ya que el reporte se invocara inmediatamente despus de que se actualice fsicamente un cliente. As que el reporte encontrara al cliente con sus datos actualizados en la tabla CLIENTES y los imprimira. El reporte se invocar nicamente luego de realizar actualizaciones. Caso 4: RPrintCustomer.Call( CustomerId ) on AfterDelete; El evento de disparo AfterDelete ocurre inmediatamente despus de que se elimine fsicamente cada instancia asociada a cierto nivel de la transaccin (en este caso, como el nico atributo involucrado en la regla es CustomerId, se trata de una regla asociada al primer y nico nivel de la transaccin "Customer"). No es adecuado agregarle este evento de disparo a la regla de invocacin al reporte, porque el reporte se invocara inmediatamente despus de la eliminacin fsica de cada cliente. En consecuencia, el reporte no encontrara al cliente con sus datos en la tabla CUSTOMER. Caso 5: RPrintCustomer.Call( CustomerId ) on AfterInsert, AfterUpdate; RPrintCustomer.Call( CustomerId ) if delete on AfterValidate; Para finalizar, estas dos reglas son las adecuadas para invocar a un reporte en la transaccin "Customer", con el objetivo de imprimir los datos de cada cliente con el cual se trabaje, abarcando los tres modos de trabajo. Como se puede observar en la primera regla es posible incluir varios eventos de disparo separados por coma, cuando los mismos aplican a una misma regla. Es decir, es lo mismo definir estas dos reglas independientes: RPrintCustomer.Call( CustomerId ) on AfterInsert; RPrintCustomer.Call( CustomerId ) on AfterUpdate; que esta regla: RPrintCustomer.Call( CustomerId ) on AfterInsert, AfterUpdate;

148

Caso 6: Si definimos una regla a la cual le incluimos el evento de disparo on AfterInsert, pero a diferencia de los ejemplos recin vistos, se referencia en la regla al menos un atributo del segundo nivel de la transaccin en la cual se est definiendo la regla, la misma estar asociada al segundo nivel. Por lo tanto, la regla se ejecutar inmediatamente despus de que se inserte fsicamente cada instancia correspondiente al segundo nivel de la transaccin. Anlogo es el caso de on AfterUpdate y on AfterDelete. Ampliamos el esquema que habamos efectuado antes, de las acciones que rodean a los eventos de disparo vistos hasta ahora: VALIDACIN DE LOS DATOS tiempo tiempo AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRABACIN DEL REGISTRO (insert, update, delete segn corresponda) AfterInsert AfterUpdate AfterDelete

Este esquema se repite para cada instancia del nivel. Por ejemplo, pensemos en el ingreso de las lneas de una factura. Para cada lnea ocurrir este esquema, por lo que podemos pensar en un loop que se repite hasta que se termina de grabar la ltima lnea. La accin que sucede a la grabacin de la ltima lnea sera el abandonar ese nivel (en este caso el de las lneas de factura). Y luego de esa accin, a menos que venga otro nivel con el que se volvera a ingresar en el esquema anterior, ocurrir la ltima accin en la ejecucin, que es el commit. Entre la accin de abandonar el nivel, y el commit tendremos un evento (que admite dos nombres distintos) y otro para luego del commit. Son los que veremos a continuacin pero que ya mostramos en esquema: VALIDACIN DE LOS DATOS CABEZAL AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRABACIN DEL REGISTRO (insert, update, delete segn corresponda) AfterInsert AfterUpdate AfterDelete VALIDACIN DE LOS DATOS LNEA AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRABACIN DEL REGISTRO (insert, update, delete segn corresponda) AfterInsert AfterUpdate AfterDelete ABANDONAR NIVEL 2 AfterLevel - BeforeComplete COMMIT AfterComplete

loop

149

Eventos de disparo: AfterLevel, BeforeComplete El evento de disparo AfterLevel permite definir que una regla se ejecute inmediatamente despus de terminar de iterar determinado nivel. SINTAXIS: regla [if condicin de disparo] [on AfterLevel Level atributo]; DONDE: regla: es una regla de las permitidas en transacciones condicin de disparo: es una expresin booleana que permite involucrar atributos, variables, constantes y funciones, as como los operadores Or, And, Not. atributo: es un atributo perteneciente al nivel para el cual se desea que luego de ser iterado, se ejecute la regla. FUNCIONALIDAD: Si el atributo que se especifica a continuacin del evento de disparo AfterLevel pertenece al segundo nivel de la transaccin, la regla se ejecutar cuando se hayan terminado de iterar todas las lneas del segundo nivel. Y si el atributo que se especifica a continuacin del evento de disparo AfterLevel pertenece al primer nivel -siguiendo el mismo concepto- la regla se ejecutar cuando se haya terminado de iterar por todos los cabezales. Observar que esto se da al final de todo, es decir, una vez que se hayan ingresado todos los cabezales y sus lneas y se cierre la transaccin (en ese momento se habrn iterado todos los cabezales). Por lo tanto, si el atributo especificado pertenece al primer nivel, la regla se disparar una vez sola antes del Evento Exit (es un evento que se ejecuta una sla vez cuando se cierra una transaccin en tiempo de ejecucin, como veremos). Ejemplo: Rever el ejemplo presentado antes, donde tenamos una transaccin para representar las facturas que nos entregan nuestros proveedores, y donde queramos controlar que el total calculado de cada factura coincidiera con el total ingresado. All tenamos la regla: Error('El total ingresado no coincide con el total calculado') if InvoiceCalcTotal<>InvoiceEntTotal; que necesitramos se disparara luego de ingresadas todas las lneas de la factura. Por tanto, el evento de disparo apropiado ser AfterLevel Level att, donde att sea cualquier atributo de las lneas. El evento de nombre BeforeComplete, en este caso, coincide con el AfterLevel. Si observamos el esquema presentado en la pgina anterior, podemos ver que el instante de tiempo que hay entre que se abandona el ltimo nivel y se realiza el commit es el instante en que ocurren estos eventos. Son dos nombres para referirnos a lo mismo. Cuidado que esto es as siempre y cuando el nivel abandonado sea el ltimo. Supngase por ejemplo una transaccin con dos niveles paralelos. Por ejemplo, si agregamos al cliente sus direcciones de mail y sus nmeros telefnicos (puede tener varios): CustomerId* CustomerName (CustomerPhone* ) (CustomerEMail* ) El momento en que deber dispararse una regla condicionada a: On AfterLevel Level CustomerPhone NO COINCIDIRA con el de una regla condicionada a on BeforeComplete. Mientras que la primera se disparar cuando se abandona el nivel de los telfonos, y antes de entrar a validar todos los emails, la segunda se disparar despus de abandonar este ltimo nivel. En este caso el evento BeforeComplete coincidir con el AfterLevel Level CustomerEMail. Evento de disparo: AfterComplete Este evento corresponde al instante de tiempo que sucede al commit. Hablaremos ms de este evento unas pginas adelante, cuando estudiemos la integridad transaccional. Si se abre la transaccin de facturas, se ingresan 3 facturas (cabezal y sus respectivas lneas) y se cierra la transaccin, ocurrirn 3 commits (uno al final de cada ingreso de cabezal + lneas) y 3 eventos AfterComplete.

150

Ejemplo en transaccin de 2 niveles


Interactivamente (Web o Win con Client Side Validation) y antes de confirmar:
REGLAS STAND-ALONE

EVALUACION DE REGLAS Y FORMULAS SEGN ARBOL

EVALUACION DE REGLAS Y FORMULAS SEGN ARBOL

PARA CADA LINEA

El siguiente ejemplo pretende mostrar visualmente en qu momentos se irn disparando las reglas y frmulas definidas en una transaccin1. Esto depender en parte del tipo de dilogo, aunque el orden ser el mismo para cualquiera de ellos. La diferencia radicar en el momento en que se realizar la grabacin de los registros y el disparo de reglas que estn condicionadas a eventos. Si tenemos un dilogo con validacin a nivel del cliente (.Net o Java, ya sea interfaz Win con la propiedad Client Side Validation en Yes, o interfaz Web) entonces las reglas que no posean evento de disparo, as como las frmulas, se ejecutarn en forma interactiva a medida que el usuario vaya pasando por los campos (ejecucin en el cliente). El disparo de reglas y frmulas se ir haciendo de acuerdo al rbol de evaluacin, siguiendo el orden que ste determina. Una vez que el usuario confirme la pantalla (esto es, en Win: presione el botn Confirm, cuyo ttulo ser: Add, Update, Delete, Confirm, segn el caso; en Web: presione el botn Apply Changes), los datos se enviarn al servidor y all se realizarn las validaciones y disparo de reglas y frmulas mencionadas antes, nuevamente, adems de dispararse las reglas que estn condicionadas a eventos de disparo, por primera vez, junto con las grabaciones de los registros correspondientes, en el orden que se muestra en la siguiente hoja. Esto se realizar en el servidor. Si el dilogo es a pantalla completa, en el cliente no se disparar nada, y todo se har en el servidor, como se muestra en la siguiente hoja. Con respecto al dilogo campo a campo, si bien el orden ser el mismo que el de la siguiente hoja, la diferencia se encuentra en el momento en que esto se realiza: en este tipo de aplicaciones, ser absolutamente interactivo, dado que cuando el usuario pase en la pantalla del cabezal a las lneas, o de una lnea a la siguiente, ya en ese momento se realizar la grabacin.

151

Ejemplo en transaccin de 2 niveles


Al confirmar los datos, se ejecutan en el siguiente orden:

REGLAS STAND-ALONE EVALUACION REGLAS Y FRMULAS SEGN ARBOL BeforeValidate VALIDACIN AfterValidate / BeforeInsert / Update / Delete GRABACION DEL CABEZAL AfterInsert / Update / Delete EVALUACION DE REGLAS Y FORMULAS SEGN ARBOL PARA CADA LINEA

BeforeValidate VALIDACIN AfterValidate / BeforeInsert / Udpate / Delete GRABACION DE LA LINEA AfterInsert/Update/Delete ABANDONAR NIVEL 2 AfterLevel Level attNivel2 - BeforeComplete COMMIT AfterComplete

Reglas stand alone Las reglas stand alone son aquellas que: 1. Pueden ejecutarse con la informacin provista por los parmetros recibidos. 2. No dependen de nada para ejecutarse. Ejemplos de reglas stand alone (por poder ejecutarse con la informacin provista por los parmetros): &A = parmetro2; Msg( ... ) if parmetro1 = 7; Ejemplos de reglas stand alone (por no depender de nada para ejecutarse): msg( You are in the invoice transaction); &A = 7; Por lo tanto, son las primeras reglas que pueden ejecutarse. Luego de la ejecucin de las reglas stand alone, se ejecutan las reglas asociadas al primer nivel de la transaccin, que no tengan evento de disparo definido, siguiendo el orden de dependencias determinado por GeneXus (as como las frmulas asociadas al primer nivel). A modo de ejemplo, se disparar la regla: Default( InvoiceDate, &Today); Despus de ejecutadas las reglas mencionadas para el cabezal, se ejecutarn todas las reglas que tengan como evento de disparo BeforeValidate, ya que inmediatamente despus ocurrir la accin de validacin (o confirmacin) de la informacin de ese primer nivel. Inmediatamente despus de la validacin del primer nivel se ejecutan las reglas asociadas al primer nivel de la transaccin que incluyan en su definicin el evento de disparo AfterValidate, o los BeforeInsert, BeforeUpdate, BeforeDelete, dependiendo del modo en el que se est. Por ejemplo: Si no podemos autonumerar las facturas con la propiedad Autonumber por no ser soportada por el DBMS elegido: InvoiceId = PGetNumber.udp(INVOICE) on BeforeInsert;

152

Seguidamente a la ejecucin de las reglas asociadas al primer nivel con alguno de estos eventos de disparo se ejecuta la accin de grabacin; es decir, se grabar fsicamente la instancia correspondiente al primer nivel de la transaccin como registro fsico en la tabla correspondiente (en este ejemplo, en la tabla: INVOICE). Inmediatamente despus de haberse grabado esa instancia: si la grabacin correspondi a una insercin: se ejecutarn las reglas asociadas al primer nivel de la transaccin con evento de disparo AfterInsert. si la grabacin correspondi a una actualizacin: se ejecutarn las reglas asociadas al primer nivel de la transaccin con evento de disparo AfterUpdate. si la grabacin correspondi a una eliminacin: se ejecutarn las reglas asociadas al primer nivel de la transaccin con evento de disparo AfterDelete.

Si se trata de una transaccin de dos niveles, como en este caso, a continuacin se ejecutar para cada una de las lneas: En primer lugar, las reglas asociadas al segundo nivel de la transaccin que no tengan evento de disparo definido, siguiendo el orden de dependencias determinado por GeneXus (as como las frmulas asociadas al segundo nivel). Ejemplos de ello son la regla Subtract( InvoiceLineQuantity, ProductStock ); la frmula InvoiceLineAmount = InvoiceLineQuantity*ProductPrice. Despus de ejecutadas las reglas mencionadas para una lnea, se ejecutarn todas las reglas que tengan como evento de disparo BeforeValidate, dado que inmediatamente despus ocurre la validacin de la lnea; esto es una accin que ocurre a continuacin de haber terminado de trabajar con la lnea. Inmediatamente despus de la validacin de la lnea, se ejecutarn las reglas asociadas al segundo nivel de la transaccin que incluyan en su definicin alguno de los eventos de disparo: AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete. Seguidamente a la ejecucin de las reglas asociadas al segundo nivel con alguno de estos eventos de disparo se ejecutar la accin de grabacin; es decir, se grabar fsicamente la instancia correspondiente a la lnea como registro fsico en la tabla correspondiente (en este ejemplo, en la tabla: INVOICELINE). Inmediatamente despus de haberse grabado la instancia correspondiente a la lnea como registro fsico en la tabla correspondiente: si la grabacin correspondi a una insercin: se ejecutarn las reglas asociadas al segundo nivel de la transaccin con evento de disparo AfterInsert. si la grabacin correspondi a una actualizacin: se ejecutarn las reglas asociadas al segundo nivel de la transaccin con evento de disparo AfterUpdate. si la grabacin correspondi a una eliminacin: se ejecutarn las reglas asociadas al segundo nivel de la transaccin con evento de disparo AfterDelete. Todas estas operaciones sombreadas de gris claro, se ejecutarn en el orden descrito, para cada una de las lneas.

Luego de la iteracin de todas las lneas, podemos suponer la existencia de una accin que podramos llamar abandono del segundo nivel. Luego de la misma se ejecutarn las reglas definidas con evento de disparo AfterLevel Level Atributo del 2do nivel. Si no existe otro nivel, como es el caso del ejemplo, Aclaracin importante: evento las disparo BeforeComplete. tanto en gris claro como en gris oscuro, se entonces coincidir con el Todas de operaciones sombreadas, ejecutan nicamente si se trata de una transaccin de dos niveles; de modo que cuando se trata de una transaccin de un nivel, tales operaciones no se ejecutarn. El motivo de los dos sombreados distintos, es para diferenciar el conjunto de operaciones que se ejecuta para cada una de las lneas (sombreado gris claro) de las operaciones que se ejecutan solamente una vez finalizada la iteracin en las lneas (sombreado gris ms oscuro). A continuacin seguimos explicando en orden, el resto de las operaciones que se ejecutan, as sea que se trate de una transaccin de un nivel o dos. Luego de haberse ejecutado todas las operaciones explicadas hasta el momento, se efectuar un commit, siempre y cuando el ambiente o plataforma de trabajo sea Cliente/Servidor.

153

A continuacin se ejecutarn las reglas con evento de disparo AfterComplete. Es de fundamental importancia que quede claro que todas las operaciones explicadas se ejecutarn en el orden en el que se han descrito, para cada factura con la cual se trabaje por medio de la transaccin "Invoice" (ya sea que se ingrese, modifique o elimine). Puede ser til tener en cuenta que se han resaltado en negrita las acciones cada vez que se las ha mencionado. Las mismas son: validacin, grabacin , abandono del segundo nivel y commit. Es indispensable asimilar el orden en el que se ejecutan las reglas en una transaccin, cules son los eventos de disparo disponibles para asignarles, cundo se disparan exactamente, y qu acciones ocurren antes y despus de cada evento de disparo, ya que solamente conocindolos bien se podr programar el comportamiento de las transacciones adecuadamente. Es sencillo comprender que si necesitamos programar determinados controles o acciones en las transacciones, tendremos que saber bien si hacerlo antes de que se grabe el cabezal, despus de que se haya grabado el mismo, para cada una de las lneas despus de que se hayan grabado, o antes, despus del commit o antes, por lo tanto es fundamental tener claro todo este tema. Nos ha faltado mencionar cundo ocurrir una regla condicionada al evento de disparo: AfterLevel Level Atributo 1er nivel. Diferencia entre aplicacin 3 capas Win y aplicacin Web Aqu aparece una diferencia importante entre Win y Web, que cada una. Mientras que en Win la capa de la aplicacin que se servidor de manera continua (el servidor mantiene estado) , deben intercambiar informacin y luego se desconectan; no diferencias en el comportamiento de las transacciones. tiene que ver con las caractersticas inherentes a encuentra en el cliente se mantiene conectada al en Web la conexin es discreta: se logra cuando se mantiene un estado. Esto establece algunas

Mientras que una aplicacin Win mantiene la conexin con el servidor de manera tal que ste pueda mantener el estado de una transaccin que se est ejecutando: controlar cundo se abri, cuntas instancias se han ingresado y cundo se ha cerrado la misma, en Web esto no es posible (no mantiene estado). Por tanto una regla condicionada al evento de disparo AfterLevel Level atributo del 1er. nivel solo se disparar en una transaccin Win (para una Web no tiene sentido) y lo har una sola vez, cuando se cierra la transaccin. Recordemos que una regla con evento de disparo AfterLevel Level Atributo 1er nivel se ejecuta luego de que se haya iterado por todos los cabezales, y esto se da al final de todo, es decir, una vez que se haya trabajado con todos los cabezales y sus lneas y se cierre la transaccin (en ese momento se habr iterado por todos los cabezales). No podemos dejar de mencionar algo que tambin para Win se ejecutar una nica vez en la ejecucin de una transaccin: el Evento Start y el Evento Exit. Como mencionaremos luego, en una transaccin Web estos eventos se ejecutarn una vez por cada instancia de transaccin con la que se trabaje.

154

Ejemplos
Cundo se dispararn las siguientes reglas?
PSomething.call( InvoiceId ) if Insert; Luego de validado el campo InvoiceId e inferido que se est en modo Insert PSomething.call( InvoiceId ) on BeforeInsert; Luego de disparadas todas las reglas y frmulas segn rbol, y validados todos los datos del cabezal. Un instante antes de insertar el registro. PSomething.call( InvoiceId, ProductId ) on BeforeInsert; Luego de disparadas todas las reglas y frmulas segn rbol, y validados todos los datos de la lnea. Un instante antes de insertar el registro. PSomething.call( InvoiceId ) on BeforeInsert Level ProductId; dem que el anterior. Observar que Level ProductId especifica que se est hablando del BeforeInsert de las lneas y no del cabezal.

155

Ejemplos
Algunas reglas estn mal programadas. Cules? InvoiceDate = &today on AfterInsert;
Incorrecto: El ltimo momento para asignar valor a un atributo del cabezal es inmediatamente antes de su grabacin (BeforeInsert)

PSomething.call( InvoiceDate ) on AfterInsert;


Correcto: aqu se est pasando el valor de un atributo del cabezal; mientras se est en la instancia de la factura se tiene ese valor en memoria. ltimo momento posible para utilizarlo AfterComplete.

PSomething.call( InvoiceId, ProductId ) on AfterLevel Level ProductId;


Incorrecto: la regla, sin el evento de disparo est asociada al 2do. Nivel, es decir, se disparara por cada lnea. Pero el evento de disparo la condiciona a ejecutarse al salir de las lneas. Qu valor tendra ProductId?

156

Reglas con el mismo evento de disparo


Son disparadas en el orden en que fueron definidas Ejemplo 1 xxx.call() On AfterComplete; yyy.call() On AfterComplete; Ejemplo 2 pgmname.call( CustomerId, &flag) On AfterComplete; error(' ') if &flag = 'N On AfterComplete;

Reglas con el mismo evento de disparo Cuando en una transaccin se definen dos o ms reglas con el mismo evento de disparo, y no existe ninguna dependencia entre ellas, las mismas se ejecutarn respetando el orden de definicin. Ejemplos: 1) Se definen las siguientes reglas en una transaccin: xxx.Call() on AfterComplete; yyy.Call() on AfterComplete; Como las dos reglas definidas estn condicionadas con el mismo evento de disparo, y no existe ninguna dependencia entre ellas, las mismas se ejecutarn en el mismo orden en el cual se han escrito. 2) En una transaccin se necesita invocar a un procedimiento que realiza determinada validacin y retorna un valor S o N; si el valor devuelto es N, se debe dar un mensaje de error. Para resolver esto, evaluaremos dos posibilidades: 2.1) Definir las reglas: PXXX.call(&flag) on AfterValidate; error() if &flag=N on AfterValidate; 2.2) O definir las reglas: &flag = PXXX.udp() on AfterValidate; error() if &flag=N on AfterValidate;

157

En la primera alternativa, se ha definido una regla call y una regla error. Ambas reglas tienen el mismo evento de disparo, y aparentemente existira dependencia entre ellas, ya que la regla de error est condicionada al valor de la variable &flag, y la variable &flag se pasa por parmetro en la regla call. Sin embargo, si bien la dependencia nos puede parecer evidente porque en el procedimiento programaremos a la variable &flag, de salida, en la seccin de reglas de la transaccin -que es donde se encuentran las reglas que estamos viendo-, el especificador de GeneXus no puede saber si los parmetros pasados en un call son de entrada, de salida, o de entrada-salida; en consecuencia el especificador no encontrar interdependencia entre las reglas call y error, ya que la variable &flag podra ser pasada como variable de entrada al procedimiento, y en ese caso por ejemplo, no habra una dependencia por la cual primero se deba ejecutar la regla call y luego la regla error. As que concluyendo, no se detectan dependencias entre las reglas call y error de la alternativa 2.1), por lo que las mismas se dispararn entonces en el orden en el que estn escritas. Es importante ver que si las reglas call y error estuvieran escritas en orden inverso (es decir, primero la regla error y despus la regla call), el comportamiento no ser el esperado en muchos casos. Con respecto a la segunda alternativa, observemos que la misma consiste en una regla con udp y una regla error. Ambas reglas tienen el mismo evento de disparo, y en este caso s existe dependencia entre ellas, ya que la regla error est condicionada al valor de la variable &flag, y como la invocacin al procedimiento se realiza con udp, para el especificador de GeneXus queda claro que la variable &flag vuelve modificada del procedimiento; por lo tanto el especificador de GeneXus entiende que primero se debe disparar la invocacin al procedimiento con udp y luego la regla error, porque la variable &flag se carga mediante la invocacin al procedimiento con udp, y luego de que dicha variable tenga valor, es que habr que evaluar si disparar la regla error, o no. En el caso 2.2) entonces, independientemente del orden de definicin de ambas reglas, la invocacin al procedimiento con udp se disparar primero, y luego de ello, se disparar la regla error (en caso de que se cumpla la condicin de disparo, claro est). Por esta razn se recomienda que siempre que se quieran definir validaciones de este tipo, se utilice udp en lugar de call.

158

Consideracin importante acerca del disparo de reglas


Reglas que no tienen evento de disparo asociado, se ejecutarn una vez o dos o tres, dependiendo de si se trabaja con Confirmation (y en Win con Client Side Validation) Ejemplo: Client Side Validation Confirmation
Reglas que no tienen evento de disparo asociado, se dispararn 3 veces

Cuidado si la regla es una invocacin a un procedimiento que actualiza la BD!


Para que no se dispare ms de una vez, habr que asignarle evento de disparo especfico a la regla, (o bien, para Win, dejar el dilogo a pantalla completa para esta transaccin), o estudiar bien la lgica del procedimiento y tener en cuenta la doble o triple ejecucin del mismo.

Esto no suceder con reglas de GeneXus (como subtract, add) que actualizan la BD porque GX tiene la inteligencia para realizar el update solo al confirmar (lo mostrado en forma interactiva se calcula en memoria).

Es importante tener en cuenta que las reglas que no tienen evento de disparo asociado, se ejecutarn una vez o dos o tres, dependiendo de lo que se haya configurado en la propiedad del modelo Confirmation y de tratarse de una aplicacin .Net o Java Win, de la propiedad Client Side Validation (recordemos que en Web siempre se trabaja con este tipo de dilogo) Por ejemplo, si se trabaja en Web o en Win (con la propiedad: Client Side Validation=Yes) y propiedad Confirmation=No, valor por defecto, las reglas que no tengan evento de disparo asociado se dispararn: primero en forma interactiva en la medida que el usuario final vaya trabajando en el form, y luego nuevamente cuando el usuario final efecte la confirmacin. Es especialmente importante considerar esto en aquellos casos de reglas que consistan en invocaciones a procedimientos que actualicen la base de datos. Si se tiene una invocacin a un procedimiento que actualiza la base de datos, habr que optar por alguna de las siguientes alternativas para evitar que se dispare ms de una vez: asignarle evento de disparo especfico a la regla o bien decidir si configurar o no la propiedad CSV del modelo con Yes (solo Win) y la confimation o estudiar bien la lgica del procedimiento y tener en cuenta la doble o triple ejecucin del mismo Si trabajando en Win, en lugar de configurar la propiedad: Client Side Validation= Yes, se la dejara con valor No y se configurara la propiedad Confirmation= Yes, estaramos en la misma situacin de doble disparo de las reglas que no tienen evento de disparo. En este caso no se dispararan en forma interactiva las reglas (ya que la propiedad Client Side Validation=No) pero se dispararan en la primera confirmacin del usuario (en la cual se efectan las validaciones pero no se graba) y en la reconfirmacin del usuario (en la cual se efectan las validaciones y se graba). Por ltimo, si se configurara Confirmation= Yes (y en Win Client Side Validation= Yes), las reglas sin evento de disparo asociado tendran un triple disparo.

159

EVENTOS EN TRANSACCIONES

En las transacciones se permite la programacin dirigida por eventos, que es un estilo de programacin en el cul se define cdigo que permanece ocioso, hasta que suceden eventos provocados por el usuario o por el sistema, que provocan que el cdigo definido se ejecute. Los eventos son acciones reconocidas por un objeto que pueden suceder o no. A cada evento se le puede asociar cdigo, que se ejecutar solamente si el evento se produce. El cdigo que se le puede asociar a un evento se escribe siguiendo el estilo procedural; y cuando el evento se produce, el cdigo asociado al mismo se ejecutar secuencialmente.

160

Eventos en Transacciones

Evento Start Evento User Event Evento After Trn Evento Exit

Los eventos Start y Exit difieren de acuerdo a la interfaz que se utilice. Como en Web no se mantiene un estado en el servidor que permita saber qu es lo que se ejecut en el cliente, no es posible saber si se est ingresando la primera instancia de una factura, o si es la n-sima. Por esta razn, mientras que el evento Start se ejecutar en una aplicacin Win una sola vez cuando se abre la transaccin, y luego con cada iteracin no vuelve a ocurrir, en Web esto no es posible, por lo que se disparar el evento cada vez que se enve al servidor la informacin de la instancia con la que se est trabajando. Anlogas consideraciones podemos hacer para el caso del evento Exit: en una aplicacin Win es posible saber que se est abandonando la transaccin, por lo que puede capturarse ese evento. En cambio en una aplicacin Web esto no ser posible, razn por la cul el evento se ejecutar por cada iteracin, al final de la misma.

161

Evento Start
Se ejecuta:
Win: una sola vez, cuando se abre una transaccin en tiempo de ejecucin. Web: cada vez que se somete el form de la transaccin al servidor.

SINTAXIS:

Event Start cdigo EndEvent

EJEMPLO: Event Start &entrada=Now() EndEvent

El evento Start es un evento del sistema, por lo tanto ocurre automticamente. En qu momento se ejecuta? La respuesta depender de si se trata de una transaccin Win o Web. Win: Cuando comienza la ejecucin del programa asociado a una transaccin, es decir, ni bien se abre una transaccin en tiempo de ejecucin. Entonces, en el evento Start de una transaccin se puede incluir cdigo que se desee se ejecute una nica vez, cuando comience la ejecucin de la transaccin. Generalmente el cdigo que se incluye en este evento, es para inicializacin (ejemplo, asignar valores a variables para inicializarlas una nica vez en la ejecucin del programa). EJEMPLO: En una transaccin nos interesa capturar la fecha y hora de entrada a la misma. Para ello en el evento Start le asignamos a una variable de nombre &entrada y tipo de datos DateTime, el resultado de la funcin Now() que devuelve la fecha y hora actual: Event Start &entrada = Now() EndEvent Web: Se ejecutar cada vez que se someta el form de la transaccin, es decir cuando se presione cualquier botn del form (Get, Apply Changes, botones de navegacin, botn Select o cualquier botn con un evento de usuario asociado). Notas generales: En el evento Start fundamentalmente se trabaja con variables. En cuanto a utilizar atributos en este evento, ya sea para evaluarlos y/o usarlos de algn modo menos para actualizarlos, se debe tener en cuenta que los nicos atributos que se tienen disponibles son los que se reciben por parmetro en la regla parm. Ningn otro atributo tendr valor en este evento, pues todava no se ha editado ninguna instancia de la transaccin.

162

Evento Exit
Se ejecuta:
Win: una sola vez, cuando se cierra la transaccin en tiempo de ejecucin. Web: se ejecuta cada vez que se somete el form de la transaccin al servidor. Por ello no suele utilizarse.

SINTAXIS:

Event Exit cdigo Endevent

Ejemplo: En Win, llamar a un procedimiento que graba la fecha/hora de entrada y la fecha/hora de salida del programa, para cada usuario en una tabla de control.

El evento Exit es un evento del sistema (por lo tanto ocurre automticamente) y es lo ltimo en ejecutarse. En qu momento se ejecuta? Otra vez, esto depender de la interfaz: En Win se ejecuta una sola vez cuando se cierra una transaccin en tiempo de ejecucin. En Web, ocurre una nica vez, al final de c/iteracin (es lo ltimo que se ejecuta). Al igual que en el evento Start, en el evento Exit fundamentalmente se trabaja con variables. En cuanto a utilizar atributos en este evento, ya sea para evaluarlos y/o usarlos de algn modo salvo actualizarlos, se debe tener en cuenta que los nicos atributos que se tienen disponibles son los que se reciben por parmetro en la regla parm. Ningn otro atributo tendr valor en este evento. WIN EJEMPLO: Cada vez que se cierre cierta transaccin en tiempo de ejecucin, invocaremos a un procedimiento que grabe la fecha y hora de entrada a la transaccin (que se captur en el evento Start, en una variable &in) y la fecha y hora de salida de la misma, para cada usuario en una tabla de control: Event Exit &user = userid() &out = now() PControlStore.call(&in, &out, &user) Endevent Cul es la diferencia en Win entre definir cdigo en el evento Exit o en cambio definir una regla con evento de disparo on AfterLevel Level atributo 1er nivel, siendo que ambas cosas se dispararan una nica vez al cerrar la transaccin, una a continuacin de la otra? Si se define una regla con el evento de disparo AfterLevel Level atributo 1er nivel, la misma se disparar una sola vez cuando el usuario cierre la transaccin, existiendo la posibilidad de retorno. Es decir, si fuera necesario, se podra definir una regla Error para mantener la pantalla abierta. El Evento Exit en cambio, si bien ocurre tambin una vez sola al cerrar la transaccin, ya no brinda la posibilidad de retorno. Cuando ocurre el Evento Exit, la pantalla ya se cerr. WEB Como se dispara cada vez que se dibuja la pantalla, al final, no hace las veces de un verdadero exit, por lo que no suele utilizarse en este ambiente.

163

Eventos de Usuario
Adems de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por l, llamados eventos de usuario. Cada evento de usuario luego se asocia a algn control del form de los que aceptan evento de usuario (depende de la interfaz):
En Win: botn y/o tecla de funcin. En Web: botn, imagen o text block tecla de funcin
(solo para Win)

SINTAXIS:

Event nombre de evento de usuario <Key> cdigo Endevent 1. 2. 3. 4. Evento Start Lectura de atributos y variables del form Evento de usuario seleccionado Evento Exit

Web:

Orden de ejecucin

Como se puede observar en la sintaxis, se le debe dar un nombre a un evento de usuario, debindose declarar a continuacin de la palabra Event, encerrado entre comillas simples. EJEMPLO: Se desea que en la transaccin "Invoice", el usuario tenga la posibilidad de imprimir la factura con la cual est trabajando, presionando F7 (esto solo es vlido para Win): Event Print Invoice 7 //evento definido en la transaccin "Invoice" RPrintInvoice.Call( InvoiceId ) EndEvent Win: Cmo asociar un evento de usuario a una tecla de funcin o a un botn? Como tambin se puede observar en la sintaxis, opcionalmente se puede especificar a continuacin del nombre del evento, el nmero correspondiente a una tecla de funcin. Por ejemplo, si se quiere que el evento se ejecute cuando el usuario presione la tecla de funcin F6, habr que poner a continuacin del nombre del evento, el nmero: 6. Para asociar el evento a un botn, se debe insertar un control botn en el form GUI-Windows, y a continuacin se abrir automticamente un dilogo con las propiedades del botn; all se deber seleccionar el evento de usuario definido. Si se trata de un botn ya insertado en el form, slo habr que abrir el dilogo con las propiedades del botn, y seleccionar all, el evento de usuario definido. Web: Cmo asociar un evento de usuario a un control? En el caso de interfaz web, adems de los botones, tambin las imgenes y los text blocks admiten la asociacin de evento de usuario. Para realizar la asociacin se debe insertar el control correspondiente en el form Web y luego en las propiedades del control, se deber seleccionar donde dice OnClickEvent uno de los eventos existentes, o se puede crear uno nuevo. Nota: se pueden ejecutar eventos asociados a botones con Alt+<letra>. Se logra colocando un & en el Caption del botn, antes de la letra con la que se desea acceder al evento. (Tanto Win como Web) Ejemplo: si se desea que el cdigo del evento de usuario asociado a un botn de caption MyEvent se pueda ejecutar tambin con Alt+E, entonces en el Caption del botn, tendremos que escribir My&Event y se ver en el form web (en diseo) con un infraguin antes de la letra correspondiente, mientras que en ejecucin no se percibir nada:

164

Evento After Trn


Ocurre inmediatamente despus de la ejecucin de las reglas con evento de disparo AfterComplete. Sintaxis: Event After Trn cdigo Endevent

Ejemplo: Event After trn Return EndEvent

El evento After Trn de las transacciones ocurre inmediatamente despus de la ejecucin de las reglas con evento de disparo AfterComplete. Por consiguiente, el cdigo que se incluya en este evento se ejecutar luego de culminada cada iteracin completa por medio de la transaccin (es decir, luego de haberse grabado cada cabezal con sus correspondientes lneas como registros fsicos en las tablas que corresponda y de haberse efectuado COMMIT). Existen las siguientes alternativas para programar comportamientos que se deseen ejecutar luego de cada iteracin completa por medio de una transaccin: 1. Definir reglas individuales con evento de disparo AfterComplete y dejar el evento After Trn sin cdigo 2. Definir todas las sentencias en el evento After Trn con estilo procedural, y no definir reglas con evento de disparo AfterComplete 3. Definir ambas cosas: algunas reglas con evento de disparo AfterComplete y cdigo en el evento After Trn Como venimos explicando, primero se ejecutan las reglas definidas con evento de disparo AfterComplete, e inmediatamente despus de las mismas se ejecuta el cdigo definido en el evento After Trn. Un concepto que es muy importante tener claro es que tanto en reglas con evento de disparo AfterComplete como en el evento After Trn, se conocen los valores de los atributos del primer nivel de la transaccin. Es decir, si bien ya se grabaron fsicamente los registros correspondientes al cabezal y las lneas de cierta iteracin completa, e incluso se efectu COMMIT, an se tienen disponibles los valores de los atributos del primer nivel, pudiendo estos utilizarse para pasarlos por parmetro en una invocacin, o evaluar su valor, o usarlos de algn modo salvo actualizarlos 1.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------1

Hay dos motivos por los cuales no es posible actualizar atributos en reglas AfterComplete ni en el evento After Trn. El primer motivo es que ya se han correspondientes e incluso se ha efectuado COMMIT, de modo que ya es tarde atributos. Y adems, en lo que respecta al evento After Trn, en los eventos asignaciones a atributos.

con evento de disparo hecho las grabaciones para asignar valores a no se permite realizar

165

Un detalle a tener en cuenta es que en el evento After Trn -como en todo evento- es posible incluir comandos, a diferencia de en la seccin de reglas de una transaccin, en la que no es posible. EJEMPLOS: 1. Event After Trn return EndEvent Si en el evento After Trn de una transaccin se incluye el comando return, al terminar de ejecutarse la primera iteracin completa, se ejecutar el evento After Trn y se cerrar el programa correspondiente a la transaccin, volviendo al objeto llamador. 2. Event After Trn // Evento After Trn en la transaccin "Invoice" /*el comando return hace que se abandone el programa y se vuelva al objeto llamador*/

RPrintInvoice.Call( InvoiceId ) Msg(Recurdele al cliente nuestra promocin XXX) Endevent 3. Se necesita controlar la cantidad de iteraciones completas realizadas por medio de una transaccin Win durante una sesin. Para ello definiremos cdigo en varios eventos, no slo en el evento After Trn. Event Start &veces = 0 EndEvent Event After Trn &veces += 1 EndEvent Event Exit Msg( Se han realizado la siguiente cantidad de iteraciones completas: + str( &veces ) ) EndEvent Con este ejemplo logramos dejar bien en claro que el evento Start se ejecuta una sola vez en ambiente Win, ni bien se abre una transaccin en tiempo de ejecucin, el evento Exit se ejecuta una sola vez cuando se cierra una transaccin en tiempo de ejecucin (lo veremos a continuacin), y el evento After Trn por su parte, se ejecuta una vez por cada iteracin completa culminada. Si la misma transaccin se generara en ambiente Web, el resultado sera absolutamente distinto: el mensaje siempre mostrara 1, ya que el start y el exit se ejecutan en este caso por cada iteracin.

166

Ejemplo en transaccin de 2 niveles


Resumiendo, al confirmar los datos, se ejecutan en orden todo lo siguiente: START (lo primero en ejecutarse)
REGLAS STAND-ALONE EVALUACION REGLAS Y FRMULAS SEGN ARBOL BeforeValidate VALIDACIN AfterValidate / BeforeInsert / Update / Delete GRABACION DEL CABEZAL AfterInsert / Update / Delete EVALUACION DE REGLAS Y FORMULAS SEGN ARBOL PARA CADA LINEA

BeforeValidate VALIDACIN AfterValidate / BeforeInsert / Udpate / Delete GRABACION DE LA LINEA AfterInsert/Update/Delete ABANDONAR NIVEL 2 AfterLevel Level attNivel2 - BeforeComplete COMMIT AfterComplete After TRN

EXIT (lo ltimo en ejecutarse)

Para completar el diagrama visto anteriormente, agregamos al comienzo la ejecucin automtica del cdigo asociado al evento START y al final la ejecucin automtica del cdigo asociado al evento EXIT. Adems, incluimos la ejecucin del evento After TRN en el lugar que corresponde a su ejecucin.

167

Consideraciones
En los Eventos no se permite asignar valores a los atributos. Eventos Start y Exit: son sin tabla base.

Eventos de usuario y After Trn: son con tabla base.

No se permite asignar valores a atributos en los eventos. Los valores de los atributos pueden modificarse en las transacciones: hacindolo el usuario final, en tiempo de ejecucin, a travs del form (slo atributos de las tablas bases asociadas a la transaccin, o aquellos de la extendida permitidos por regla update) mediante reglas definidas por el programador (atributos de las tablas bases asociadas a la transaccin y sus extendidas) Solemos decir que los eventos Start y Exit son sin tabla base. Con esta expresin nos referimos a que en los eventos Start y Exit no hay consulta activa a la base de datos (ya que en el evento Start an no se ha hecho la consulta y en el evento Exit en Win ya se est cerrando el programa asociado a la transaccin y en Web se est cerrando la instancia y ya no disponemos de la consulta). Por este motivo es que no se conocen valores de atributos en los eventos Start y Exit, salvo los recibidos por parmetro. Por el contrario solemos decir que los eventos After Trn y de usuario son con tabla base, ya que cuando los mismos se ejecutan, s hay una consulta en edicin. Entonces, en particular en el evento After Trn, se conocen los valores de los atributos del primer nivel (el segundo nivel ya se ha iterado a esa altura y no hay posibilidad de posicionamiento en alguna lnea en particular); y en lo que respecta a los eventos de usuario se disponen los atributos de todos los niveles 1. Es fundamental comprender que as se disponga de los valores de ciertos atributos u otros dependiendo del evento, los mismos podrn utilizarse para ser evaluados y/o pasados por parmetro a objetos que se invoquen, y/o para alguna otra operacin cualquiera que no sea asignarles valor. Concluyendo, en ningn evento (no slo de transacciones, sino de ningn objeto GeneXus) se permite realizar asignaciones a atributos.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------1

Si en un evento de usuario se referencian atributos de un segundo nivel u otro nivel subordinado, cuando el evento de usuario se ejecute se tendrn en cuenta los atributos de aquella lnea en la que se est posicionado; al momento de ejecutarse el evento de usuario se considerarn los valores de los atributos de dicha lnea. Y si el usuario no se haba posicionado explcitamente en determinada lnea, por defecto la lnea que estar seleccionada ser la primera, as que se considerarn los valores de los atributos de la misma.

168

INTEGRIDAD TRANSACCIONAL

169

Qu es el concepto: integridad transaccional?


Un conjunto de actualizaciones a la base de datos tiene integridad transaccional cuando en caso de una finalizacin anormal, la base de datos permanece en estado consistente.

Muchos manejadores de bases de datos (DBMSs) cuentan con sistemas de recuperacin ante fallos, que permiten dejar la base de datos en estado consistente cuando ocurren imprevistos tales como apagones o cadas del sistema.

170

Qu es el concepto: unidad de trabajo lgica (UTL)?


Una unidad de trabajo lgica (UTL) es un conjunto de operaciones a la base de datos, que deben ejecutarse o bien todas o bien ninguna de ellas.

Los manejadores de bases de datos (DBMSs) que ofrecen integridad transaccional permiten establecer unidades de trabajo lgicas (UTLs), que corresponden ni ms ni menos que al concepto de transacciones de base de datos.

171

Qu es efectuar COMMIT?
El comando COMMIT permite especificar que cierto conjunto de operaciones realizadas sobre una base de datos, ha culminado de efectuarse correctamente:
........... Operacin sobre Operacin sobre Finaliza UTL Comienza UTL Operacin sobre Operacin sobre Operacin sobre Operacin sobre Finaliza UTL Base de Datos Base de Datos Base Base Base Base de de de de Datos Datos Datos Datos

COMMIT

COMMIT

De modo que efectuar COMMIT en una base de datos, significa que se da por finalizada una unidad de trabajo lgica (UTL).

Podemos ver que una unidad de trabajo lgica (UTL) queda definida por el conjunto de operaciones entre un par de Commits.

172

Qu es efectuar ROLLBACK?
Hacer ROLLBACK (vuelta a atrs) provoca que se deshagan todas las operaciones efectuadas en la base de datos que no hayan quedado con COMMIT. Esto se resuelve deshaciendo todas las operaciones posteriores al ltimo COMMIT.

173

Unidades de trabajo lgicas (UTLs) por defecto en GeneXus


Todo objeto GeneXus transaccin y todo objeto GeneXus procedimiento, determina unidades de trabajo lgicas (UTL). Es decir, las transacciones y procedimientos son los nicos objetos GeneXus (*) que permiten actualizar la base de datos, y por defecto GeneXus incluye en los programas generados asociados a los mismos, la sentencia COMMIT. En el objeto procedimiento automtico al final del Source. GeneXus incluye un COMMIT

En el objeto transaccin GeneXus incluye un COMMIT automtico al final de cada instancia, inmediatamente antes de las reglas con evento de disparo AfterComplete
(*) una excepcin la brindan los Business Components, pero no realizan commit automticamente.

Es importante aclarar que GeneXus incluye la sentencia COMMIT en los programas generados asociados a transacciones y procedimientos, slo en ambientes de trabajo Cliente/Servidor (incluyendo, por tanto, los ambientes Web). El motivo de esto es que en ambientes Cliente/Servidor existe un DBMS que asegura la integridad transaccional, por lo tanto GeneXus efecta la tarea de definir las unidades de trabajo lgicas (UTLs). En cambio, en ambientes de trabajo que no son Cliente/Servidor, GeneXus no incluye sentencias COMMIT pues no hay un DBMS por detrs que maneje la integridad transaccional. Dnde incluye GeneXus COMMIT exactamente? En cada procedimiento: al final del programa fuente. En cada transaccin: inmediatamente antes de las reglas con evento de disparo AfterComplete. Es decir, que por cada iteracin completa que se efecte en tiempo de ejecucin por medio de la transaccin, habr un COMMIT, justo antes de las reglas con evento de disparo AfterComplete. Nota: El nuevo tipo de datos Business Component que veremos ms adelante permite actualizar la base de datos desde cualquier objeto GeneXus, pero tambin como veremos, no realiza automticamente un COMMIT.

174

Personalizacin de unidades de trabajo lgicas (UTLs) por defecto en GeneXus


Propiedad Commit on Exit de transacciones y procedimientos:
Valores: Yes (Default): Se ejecuta COMMIT No: No se ejecuta COMMIT

GeneXus ofrece una propiedad a nivel de cada objeto transaccin y procedimiento, para definir si se desea que su programa generado efecte COMMIT, o no. El nombre de la propiedad es Commit on Exit y su valor por defecto es Yes (por eso, toda transaccin y procedimiento por defecto efecta COMMIT). Si se desea que cierta transaccin o procedimiento no tenga en su programa generado COMMIT, bastar con cambiar el valor de la propiedad Commit on Exit a No.

175

Personalizacin de unidades de trabajo lgicas (UTLs) por defecto en GeneXus


Ejemplo de uso de Commit on Exit = No

Trn. X

call

Proc. Y

Commit on Exit = Yes

Commit on Exit = No

Es muy importante invocar desde la Trn. X al Proc. Y utilizando un evento de disparo que consideremos adecuado y que ocurra antes de la ejecucin del COMMIT de la Trn X.

Por qu motivo se puede necesitar no efectuar COMMIT en una transaccin o procedimiento? Para personalizar una unidad de trabajo lgica (UTL). Es decir, podemos necesitar ampliar una unidad de trabajo lgica (UTL) para que varias transacciones1 y/o procedimientos, conformen una nica unidad de trabajo lgica (UTL). Ejemplo (mostrado arriba): La transaccin X invoca al procedimiento Y, y se desea que ambos objetos conformen una nica UTL. La transaccin actualiza ciertos registros, y el procedimiento otros, y se desea que ese conjunto total de operaciones conforme una nica UTL (para asegurarnos de que si ocurre una falla, quede efectuado el conjunto completo de actualizaciones a la base de datos, o nada). Para lograrlo podemos eliminar el COMMIT del procedimiento y dejar que se realice en la transaccin (al retornar del procedimiento a la transaccin, para que se ejecute al final de todas las operaciones); de modo que configuraramos la propiedad Commit on Exit del procedimiento con valor: No y dejaramos la propiedad Commit on Exit de la transaccin con el valor por defecto: Yes. Pero adems de esto, es fundamental que la invocacin al procedimiento se realice antes de que se ejecute el COMMIT en la transaccin (ya que la idea es que ambos objetos conformen una nica UTL, y para ello el COMMIT debe efectuarse en la transaccin al retornar del procedimiento); as que la invocacin al procedimiento deber definirse en la transaccin, con un evento de disparo que ocurra antes de la ejecucin del COMMIT (dependiendo de si la transaccin es de un nivel o ms, y de los requerimientos, podra servir AfterInsert por ejemplo, AfterUpdate, o AfterLevel Level Atributo del 2do nivel, o BeforeComplete, pero no AfterComplete). No existe una nica solucin para personalizar una UTL. Lo fundamental es analizar cul objeto puede hacer COMMIT (pudiendo haber ms de una posibilidad) y una vez que se decida cul objeto efectuar COMMIT, las invocaciones que se requieran hacer, debern efectuarse en momentos adecuados, considerando si ya se efectu el COMMIT o no. ----------------------------------------------------------------------------------------------------------1 En ambiente Web existe una importante restriccin a este respecto: si desde una transaccin se invoca a otra, el Commit que realice una no aplica sobre los registros ingresados/modificados/eliminados por la otra. Es decir, el Commit de cada transaccin solo tiene visibilidad sobre los registros operados por esa transaccin, y no por la otra, por lo que dos transacciones distintas no pueden quedar incluidas en una misma UTL. No puede realizarse personalizacin en este caso, al contrario de lo que sucede con los procedimientos, donde el comportamiento es idntico al de ambiente Win.

176

Por ejemplo, para que la transaccin y procedimiento vistos conformen una nica UTL, podramos haber optado tambin por la alternativa de que no efecte COMMIT la transaccin (Commit on Exit = No), sino que lo haga el procedimiento al final de todo; y de hacerlo as, no sera un error como s lo sera en la solucin anteriorinvocar al procedimiento utilizando el evento de disparo AfterCompete, porque la transaccin no har COMMIT, sino que lo har el procedimiento. Concluyendo, es cuestin de decidir cul objeto har COMMIT y que las invocaciones que se deban hacer, se hagan en momentos adecuados, para que la UTL personalizada quede bien definida. Otro ejemplo: Sea la transaccin Invoice estudiada hasta el momento, en un modelo de Prototipo cliente/servidor. Supongamos que no modificamos el valor predeterminado de la propiedad Commit on Exit. Supongamos ahora que el usuario ejecuta la transaccin, ingresando la factura 1 con todas sus lneas. Luego pasa a ingresar la factura 2 y cuando est ingresando la 3era. lnea de la misma, ocurre un apagn. Al recuperarse la energa y reiniciarse la ejecucin, qu registros habrn quedado grabados en las tablas y cules se habrn perdido? La factura 1 ntegra estar grabada (cabezal y sus lneas). Por qu? Pues porque al terminar de ingresarla y pasar a ingresar la factura 2, se efectu un Commit. La factura 2 con los registros que se haban grabado hasta el momento de la falla de energa, se habr perdido. Por qu? Pues porque la transaccin realiza el rollback de todo lo que se hubiere efectuado luego del ltimo Commit. El cabezal de la factura 2 y las 2 lneas que se haban ingresado no estaban commiteadas an. Observar entonces que el Commit no es por transaccin entera (es decir, todas las iteraciones del cabezal y sus lneas) sino por cada instancia de cabezal + lneas. Si el Commit se realizara una nica vez antes de cerrar la transaccin, entonces si se hubieran ingresado 29 facturas y a la trigsima se cayera el sistema, se perderan las 29 facturas anteriores (se deshara todo, ya que an no se habra alcanzado el Commit). Esto no es as, y si ocurriera una cada del sistema a la trigsima factura ingresada, las 29 anteriores quedarn grabadas (no as la trigsima).

177

Personalizacin de UTLs en ambiente Web


No puede definirse una UTL compuesta por varias transacciones Web.

call

Trn.X
UTL 1

Trn.Y
UTL 2

Una transaccin Web solo puede Commitear los registros insertados por ella misma, o por procedimientos en una cadena de invocaciones, pero no puede Commitear los registros insertados por otra transaccin.

call

Trn.X
No pueden quedar dentro de una misma UTL

(luego del Commit)

Trn.Y

call
(antes del Commit)

Proc.Z

UTL

En ambiente Web los registros visibles para ser commiteados por una transaccin son los actualizados por la propia transaccin, y por los procedimientos que sta invoque antes de su Commit, pero no los de otra transaccin. Cada transaccin trabaja, as, sobre UTLs distintas. Es por ello que en el primer ejemplo presentado arriba, donde la transaccin X llama a la transaccin Y luego de haber insertado un registro, aunque la transaccin Y realice un Commit al final de que cabezal y lneas sean ingresados, este Commit no valdr sobre el registro que haba sido ingresado previamente por la transaccin X. Este registro quedar perdido, sin Commit. Por la forma de trabajo en Internet, las transacciones Web viven solamente el tiempo entre que el usuario de un navegador selecciona el link o presiona un botn y la nueva pgina es mostrada. Toda modificacin a la base de datos que se haga durante la vida de la transaccin debe ser confirmada o eliminada antes de que la Transaccin Web termine su ejecucin y retorne la pgina resultante. Como consecuencia, una Transaccin Web inicia una UTL (unidad de trabajo lgica) al comenzar a ejecutar y la cierra (ya sea por COMMIT o ROLLBACK) antes de terminar. No puede formar parte de otra UTL. Si un programa llama a una Transaccin Web, sta iniciar otra (nueva) UTL. En cambio no sucede lo mismo con los procedimientos. En el segundo ejemplo mostrado arriba, vemos que podemos formar una UTL que engloba a la transaccin Y y al procedimiento Z sin embargo no podemos incluir a la transaccin X en la misma UTL.

178

Personalizacin de (UTLs)
Si deseamos que las inserciones mediante dos transacciones distintas conformen una nica UTL:

Trn.X

Trn.Y

Tenemos una solucin: utilizar Business Components y el comando Commit al terminar de insertar mediante las variables Business Components los registros asociados a ambas transacciones (se ver ms adelante).

Si se necesita que las operaciones de dos o ms transacciones (con o sin procedimientos incluidos) conformen una misma UTL, se pueden emular las transacciones con Web panels y Business Components y utilizar el comando Commit. Dejamos aqu anotado simplemente el tema, para volver a l luego de estudiados los Business Components, donde nos ser posible comprender esta solucin.

179

Comandos COMMIT y ROLLBACK de GeneXus


GeneXus ofrece los comandos: COMMIT y ROLLBACK Se pueden incluir en Procedimientos, Work y Web Panels, as como en combinacin con Business Components. Ejemplo (usuario final decide si ejecutar Commit o Rollback): Se invoca desde una transaccin a varios procedimientos consecutivos, se les configura a todos ellos la propiedad Commit on exit = No y en el ltimo procedimiento se le pregunta al usuario si confirma; dependiendo de la respuesta del usuario, habr que ejecutar el comando COMMIT o ROLLBACK

180

OBJETOS REPORTE y PROCEDIMIENTO

181

Reportes y Procedimientos
Reportes Procesos no interactivos de consulta de la base de datos. Procedimientos Procesos no interactivos de consulta y actualizacin de la base de datos.

Reportes: Definen procesos no interactivos de consulta a la base de datos. Los reportes son listados que pueden (dependiendo de la interfaz win o web) emitirse por impresora, visualizarse por pantalla, o grabarse en un archivo. Procedimientos: Definen procesos no interactivos de actualizacin de la base de datos. Los procedimientos pueden hacer todo lo que los reportes hacen y adems actualizar la base de datos1. Por este motivo, todo lo que se trate en la presente exposicin referido al objeto reporte, ser tambin vlido para el objeto procedimiento.

---------------------------------------------------------------------------------------------------------1 Como veremos ms adelante, existe un tipo de datos especial, que no es estrictamente un tipo de datos, sino algo un poco ms complejo, el business component, por medio del cul se podrn realizar actualizaciones a la base de datos en cualquier objeto GeneXus. Por tanto, utilizando variables de tipo de datos business component, podrn realizarse actualizaciones incluso en los objetos que por naturaleza no ofrecen esta posibilidad, como los reportes.

182

Caractersticas Definicin procedural Definicin sobre la base de conocimiento Independencia de la base de datos: definicin a nivel de atributos

Definicin procedural A diferencia de las reglas de las transacciones donde las especificaciones se realizan en forma declarativa y GeneXus determina en el momento de generar el programa la secuencia de ejecucin, en los reportes y procedimientos las especificaciones se realizan en forma procedural. De esta forma, la secuencia de ejecucin es determinada por el analista, utilizando para ello un lenguaje bastante simple que contiene comandos de control, de impresin, de acceso a la base de datos, etc. Definicin sobre la base de conocimiento La gran potencia del lenguaje de reportes y procedimientos radica en que las definiciones se hacen sobre la base de conocimiento y no directamente sobre el modelo fsico (tablas, ndices, etc.). Esto nos permite utilizar automticamente todo el conocimiento ya incorporado o generado por GeneXus a partir de las especificaciones realizadas. Por ejemplo, si deseamos desplegar el resultado de una frmula alcanza con nombrar al atributo frmula en el lugar adecuado y GeneXus disparar su clculo desplegando el resultado, sin necesidad de que el analista tenga que brindar ninguna otra informacin. La informacin de cmo se calcula un atributo frmula est contenida en la base de conocimiento. Tambin podremos utilizar el concepto de tabla extendida, ya que GeneXus conoce las relaciones entre las tablas de la base de datos, por lo que el analista no necesita explicitar estas relaciones a la hora de recuperar datos. Independencia de la base de datos: definicin a nivel de atributos La definicin de reportes y procedimientos se hace a nivel de atributos: no es necesario indicar explcitamente cules tablas sern recorridas ni mediante qu ndices. Con solo mencionar los atributos a los que se desea acceder es suficiente para que GeneXus determine esta informacin. Esto es posible porque GeneXus tiene un completo conocimiento de la estructura de la base de datos. De esta manera logramos una real independencia de la base de datos, ya que cualquier cambio en las tablas ser manejado automticamente por GeneXus y de esta forma, para actualizar los programas alcanzar, gran parte de las veces, con regenerar los objetos sin tener que modificar nada de lo programado en ellos.

183

Elementos
Layout Source Reglas y Propiedades Condiciones Ayuda Documentacin

Como en las transacciones, pueden definirse variables que sern locales al objeto.

Para cada reporte (procedimiento) se puede definir: Layout: As como las transacciones tienen una pantalla (form), los reportes tienen un layout de la salida. En esta seccin se define la presentacin del reporte: los datos que se quieren listar y el formato de la salida. Source: Aqu se escribe el cdigo correspondiente a la lgica del reporte. Tambin pueden definirse al final del cdigo subrutinas1 que podrn ser invocadas desde el propio cdigo mediante el comando adecuado. Reglas-Propiedades: Definen aspectos generales del reporte, como su nombre, descripcin, tipo de salida (impresora, archivo, pantalla), parmetros que recibe el objeto, etc. Condiciones: Condiciones que deben cumplir los datos para ser recuperados (filtros). Ayuda: Permite la inclusin de texto de ayuda, para ser consultado por los usuarios en tiempo de ejecucin, para el uso del reporte. Se puede redactar una ayuda para cada lenguaje. Documentacin: Permite la inclusin de texto tcnico, para ser utilizado como documentacin del sistema.

--------------------------------------------------------------------------------------------------No se tratarn en el presente curso. Vase Curso No Presencial de GeneXus.

184

Ejemplo
Queremos implementar un listado como el que sigue:
rea con datos fijos rea con datos fijos

rea con datos variables (acceso a la base de datos)

Por ejemplo, supongamos que queremos implementar un reporte para imprimir el identificador, nombre y pas de todos nuestros clientes y queremos que el listado luzca como se muestra en la figura. Para ello, debemos identificar en la salida del listado las distintas reas que lo componen. A cada una de ellas la representaremos con un print block. Los primeros dos print blocks lucirn en GeneXus tal cul las primeras dos reas sealadas pues stas contienen nicamente textos, lneas, recuadros. Tambin podramos haber fusionado estas dos reas convirtindolas en una y utilizando por tanto un nico print block. El tercer print block ser el correspondiente al rea de datos variables de la figura anterior, que representa informacin que debe ser extrada de la base de datos. Lo que queremos mostrar en este caso es el identificador y nombre de cada cliente, junto con el nombre del pas al que pertenece. Esta informacin es la representada por los atributos CustomerId, CustomerName y CountryName de la base de conocimiento de la aplicacin, por lo que el tercer print block contendr los tres controles atributo CustomerId, CustomerName y CountryName. Transformando las reas en print blocks, el Layout del reporte nos quedar como el que figura en la pgina siguiente.

185

Layout: ejemplo
Nombre de cada print block print block

Layout: Sucesin de print blocks No importa el orden de definicin Cada print block debe tener un nombre nico Solo se declaran, son invocados desde el Source con el comando print (Ej.: print header)

El Layout de un reporte ser una sucesin de print blocks que no tienen por qu seguir el orden en el que se desea que aparezcan en la salida. En el ejemplo anterior, el mismo reporte habra sido impreso si se hubieran especificado los print blocks en el orden inverso (o en cualquier orden). Aqu simplemente se declaran. El orden en el que se ejecutan queda determinado en la seccin Source que es la que contiene la lgica del reporte. Desde all sern invocados mediante un comando especfico para tal fin (el comando print). Por esta razn, cada print block deber tener un nombre nico para poder ser referenciado luego desde el Source. En el ejemplo, para listar todos los clientes, el print block de nombre customer deber ser invocado dentro de una estructura repetitiva en el Source. Esta estructura repetitiva es el comando For each que estudiaremos luego.

186

Layout: print block


Para definir los print blocks tenemos los siguientes controles disponibles:
Texto Lnea Recuadro Atributo/Variable Bitmap

y para insertar un print block en el Layout aparece el control print block

El print block es un tipo de control vlido solamente en reportes y procedimientos, que es insertado y eliminado del Layout por el analista, y que contendr otros controles -atributos, textos, recuadros, lneas, etc.-, siendo estos ltimos los que efectivamente especifican qu es lo que se quiere desplegar en la salida. Para insertar los controles en el Form de una transaccin contbamos con una toolbar. La misma toolbar se utiliza para insertar los controles en el Layout. De hecho esta toolbar est disponible para todos los objetos GeneXus que se creen, y en cada caso tendr habilitados los controles disponibles segn el tipo de objeto y la interfaz (Win o Web). Para los reportes (y procedimientos) se habilita el cono correspondiente al print block para poder insertar este tipo de control en el Layout. Como todo control, el print block tiene propiedades que pueden ser configuradas por el usuario. En particular, tiene la propiedad Name, muy importante dado que es el identificador del print block. Con este identificador es que el print block puede ser invocado desde el Source para ser impreso.

187

Source
Define la lgica del reporte Programacin procedural Lenguaje muy simple
Comandos usuales de control
If, Do-case, Do-while, For

Comandos de impresin
Print, Header, Footer, etc.

Comando de acceso a la base de datos y de actualizacin


For each new - delete

Comandos para salir de un bucle, abandonar el programa, invocar a otro objeto, invocar a una subrutina, etc.
Exit, Return, Call, Do, etc.

En esta seccin se define la lgica del reporte (o procedimiento). El lenguaje que se utiliza para programar el cdigo fuente de los reportes y procedimientos es muy simple, y consta de algunos comandos que iremos viendo. El estilo de programacin es procedural imperativo por lo que el Source ser una sucesin de comandos para los que el orden es fundamental: el orden en el que estn especificados corresponder, salvo excepciones, al orden en el que sern ejecutados. Existen, como en todo lenguaje imperativo, comandos de control para la ejecucin condicional (if, do case), la repetitiva (do while, for), para invocar a otro objeto (call), para cortar las iteraciones dentro de un bucle (exit) o abandonar el programa (return), as como tambin comandos especficos de este lenguaje: para imprimir un print block del Layout (print), para acceder a la base de datos (for each), para insertar nuevos registros en una tabla (new: solo en procedimientos), para invocar a una subrutina (do), etc. Al final de la sucesin de comandos que constituye el cdigo general o principal del reporte, pueden definirse subrutinas que podrn ser invocadas (mediante el comando do) desde el cdigo general. No pueden ser invocadas desde otro objeto (son locales). Por su importancia, empezaremos estudiando en profundidad el comando de acceso a la base de datos, fundamental a la hora de recuperar la informacin almacenada. Luego se tratarn brevemente los comandos de control, que son comunes a todos los lenguajes de programacin imperativa, los comandos de asignacin y los de impresin.

188

Comando for each


Se utiliza para acceder a la informacin de la base de datos. Con un for each se recorre una tabla de la base de datos: la tabla base del for each. Para cada registro de esa tabla, se quiere hacer algo con la informacin asociada. (Ejemplo: imprimirla)

La definicin del acceso a la base de datos para recuperacin de informacin se realiza con un nico comando: el comando for each1. Usando el for each se define la informacin a la que se va a acceder. La forma de hacerlo se basa en nombrar los atributos a utilizar. As, con este comando se definen qu atributos se necesitan y en qu orden se van a recuperar, y GeneXus se encarga de encontrar cmo hacerlo. No se especifica de qu tablas se deben obtener, ni qu ndices se deben utilizar para acceder a esas tablas: eso lo inferir GeneXus. Evidentemente esto no siempre es posible, y en tales casos GeneXus da una serie de mensajes de error indicando por qu no se pueden relacionar los atributos involucrados. La razn por la cul no se hace referencia al modelo fsico de datos es porque de esta manera la especificacin del reporte es del ms alto nivel posible, de tal forma que ante cambios en la estructura de la base de datos la especificacin del mismo se mantenga vlida la mayor parte de las veces. Cuando aparece un for each se est indicando que se quiere recuperar informacin de la base de datos. Concretamente GeneXus sabe que con un for each se quiere recorrer (o navegar) una tabla. Para cada registro de esa tabla, se quiere hacer algo con la informacin asociada (ej: imprimirla). Por lo tanto, todo comando for each tendr una tabla fsica asociada: la tabla que ser recorrida o navegada. A esta tabla la llamaremos tabla base del for each.

-----------------------------------------------------------------------------------------------------------1 Cuando estudiemos los business components veremos que utilizando su mtodo Load tambin se consigue consultar la base de datos.

189

Comando for each Ejemplo: Listado de clientes


CUSTOMER Layout: COUNTRY

Source:

for each print customer endfor

Intuitivamente resulta claro que con este comando estamos queriendo listar identificador, nombre y pas de cada uno de los clientes de la base de datos. Es decir, queremos que se recorra la tabla CUSTOMER, y para cada cliente se recupere de la tabla COUNTRY el nombre del pas al que pertenece, imprimiendo esta informacin, junto con el identificador y nombre del cliente. (Observar que la tabla COUNTRY pertenece a la extendida de CUSTOMER) Cmo infiere esto GeneXus si todo lo que hicimos en el for each del ejemplo fue nombrar los atributos que nos interesaba mostrar?

190

Comando for each


Tabla que se recorre: CUSTOMER Tabla que se accede para cada cliente: COUNTRY CUSTOMER INTERPRETACIN
For each record in table CUSTOMER Find the corresponding CountryName in table COUNTRY print customer endfor

COUNTRY

Dentro de todo for each se navega -recorre o itera- la tabla base, pero puede accederse a las tablas que constituyen su tabla extendida para recuperar informacin, que por pertenecer a la extendida estar unvocamente relacionada con cada registro de la tabla base con el que se est trabajando en cada iteracin (el concepto de tabla extendida es muy importante en este comando y sugerimos repasar su definicin). Es por ello que en el for each del ejemplo, la tabla base ser CUSTOMER, y adems se acceder para cada cliente, no solo a los datos de su registro, sino a los del registro asociado en la tabla COUNTRY (que est en la extendida de CUSTOMER). Decimos entonces que se recorre CUSTOMER y se accede adems a COUNTRY para buscar el resto de la informacin requerida. Como podemos ver claramente en el ejemplo presentado, no le damos explcitamente a GeneXus esta informacin. No es necesario, ya que GeneXus conoce las relaciones entre las tablas, y en base a los atributos mencionados dentro del for each, puede encontrar sin necesidad de ms informacin una tabla extendida que los contenga. La tabla base de esa extendida es la que elige como tabla base del for each.

191

Comando for each: determinacin tabla base


El acceso a la base de datos queda determinado por los atributos que son utilizados dentro del comando for each. Para ese conjunto de atributos, GeneXus buscar la mnima tabla extendida que los contenga. Su tabla base ser la tabla base del for each.

A la tabla base correspondiente a esa tabla extendida la llamaremos tabla base del for each y ser recorrida en forma secuencial, ejecutando para cada registro lo que se indique en los comandos internos al for each.

192

Comando for each: determinacin tabla base


{CustomerId, CustomerName, CountryName} ext(CUSTOMER) {CustomerId, CustomerName, CountryName} ext(INVOICE)

Pero: ext(CUSTOMER) < ext(INVOICE) ext(CUSTOMER) es la mnima tabla extendida que contiene a los atributos del for each.

Tabla base: CUSTOMER

Para el ejemplo presentado en el que se quieren listar de cada uno de los clientes su identificador, nombre y nombre de pas, si observamos los atributos utilizados dentro del for each, vemos que ellos son los contenidos en el print block de nombre customer: CustomerId, CustomerName y CountryName. En qu tablas estn estos atributos? CustomerId est en 2 tablas: - CUSTOMER como clave primaria (PK). - INVOICE como clave fornea (FK). CustomerName est solo en CUSTOMER (es un atributo secundario). CountryName est solo en COUNTRY (es un atributo secundario). GeneXus conoce las relaciones entre las tablas. Podemos ver el diagrama de Bachman correspondiente a las tablas en las cuales aparecen los atributos del for each (Tools/Diagrams). Aqu puede verse claramente el por qu del requerimiento de que la tabla extendida sea la mnima (entendiendo por mnima aquella que involucra menor cantidad de tablas). La tabla extendida de INVOICE tambin contiene a todos los atributos del for each, pero no es mnima, pues la de CUSTOMER tambin los contiene. Por lo tanto, se va a recorrer secuencialmente la tabla CUSTOMER, y para cada registro de esa tabla, se va a acceder a la tabla COUNTRY, para recuperar el registro de la misma que cumpla: COUNTRY.CountryId = CUSTOMER.CountryId y para el mismo se va a recuperar el valor del atributo CountryName, para poder imprimirlo, junto con el cdigo y nombre del cliente.

193

Listado de navegacin

tabla base Se resuelve la consulta ordenada por la PK de la tabla base

tabla base: la que se navega Se accede para recuperar info relacionada (CountryName)

Listado de navegacin GeneXus ofrece para todos sus objetos un listado conocido como listado de navegacin, que es el resultado de la especificacin del objeto. Este listado es muy til para los reportes, ya que indica cules son las tablas que se estn accediendo en cada for each del Source, si existe un ndice para recuperar los datos de la tabla base, y en caso de que as sea cul es ese ndice (su nombre), si se aplican filtros sobre los datos o se van a listar todos, etc. De esta manera, el analista no tiene que ejecutar el objeto para verificar que la lgica sea la esperada. Con estudiar el listado de navegacin ya tiene la informacin necesaria para saber si se est recorriendo la tabla esperada, si se estn aplicando correctamente los filtros deseados, etc. Como puede verse en el listado correspondiente al reporte del ejemplo, muestra para el comando for each del Source, cul es su tabla base, por qu orden se va a resolver esa consulta (ser el orden en el que se imprimirn los resultados), si existe un ndice que satisfaga ese orden cul es su nombre, y adems aparecen dos elementos ms: los filtros de navegacin y el diagrama de tablas. Los filtros de la navegacin indican qu rango de la tabla base se va a a recorrer. En el ejemplo se va a recorrer toda la tabla base del for each: empezando por el primer registro de CUSTOMER, y hasta que se alcance el fin de tabla (utilizando el ndice ICUSTOMER). El diagramita de tablas muestra la tabla base del for each con su clave primaria, e indentadas todas las tablas de la extendida que deban accederse para recuperar informacin asociada al registro de la tabla base con el que se est trabajando en cada iteracin del for each. En el comando for each del ejemplo no aparece explcitamente ninguna informacin respecto al orden en el que queremos que se imprima la informacin. En este caso GeneXus elige como orden la clave primaria de la tabla base del for each. Es por esta razn que para el for each del ejemplo GeneXus determin que el orden ser el correspondiente al atributo CustomerId, clave primaria de la tabla CUSTOMER.

194

For each: clusulas Where


Permiten establecer filtros sobre los datos a recuperar Ejemplo: for each where CustomerName >= &Start when not &Start.IsEmpty() where CustomerName <= &End when not &End.IsEmpty() print customer endfor
Solo para los registros que cumplan las condiciones booleanas de las clusulas where deben ejecutarse los comandos internos al for each. Las clusulas where aplican siempre y cuando se satisfagan las condiciones de sus clusulas when (solo vlidas para arquitectura cliente/servidor).

Para restringir los datos que se quieren listar en un for each se utilizan las clusulas where del comando. Si en el listado de clientes no queremos listar todos los clientes, sino solo aquellos cuyo nombre est dentro de un rango ingresado por el usuario, entonces debemos agregar al for each que habamos visto una cllusula where, para especificar los filtros deseados sobre los datos: for each where (CustomerName >= &Start) and (CustomerName <= &End) print customer endfor donde las variables &Start y &End deben definirse en el reporte con el mismo tipo de datos que CustomerName, y cargarse con valores fijos recibidos por parmetro1. Con la clusula where definida le estamos diciendo a GeneXus que no queremos quedarnos con todos los registros de la tabla base, sino solo con aquellos para los que se satisfaga la condicin booleana de la clusula. En el ejemplo escribimos una sola clusula where con una condicin compuesta, pero podramos haber programado lo mismo con dos clusulas where, como se muestra arriba en la transparencia. Es decir, cuando aparecen varios where la condicin de filtro que se va a aplicar sobre los datos es la conjuncin booleana de todas las condiciones de los where que aparezcan. Observemos que en la transparencia las clusulas where estn a su vez condicionadas con clasulas when. Esto se lee de la siguiente forma: se aplicar el filtro establecido por el where solo cuando se satisfaga la condicin del when. En el ejemplo, solo se aplicar el primer filtro: CustomerName >= &Start si la variable &Start no est vaca. Si est vaca, este filtro no se aplicar. Anlogo es el caso de la segunda clusula when. Observar que si &Start y &End estn vacos, no aplicar ninguna de las clusulas where, y por tanto se listarn todos los clientes (como si las clusulas where no hubiesen sido escritas). ---------------------------------------------------------------------------------------------------------1 A travs de un objeto que los pide al usuario, como un Work Panel para ambiente Win y un Web Panel para ambiente Web. En el caso de ambiente Win, tambin podr utilizarse la funcin Ask para pedir datos al usuario en ejecucin.

195

Cada condicin booleana de un where puede estar compuesta de varias expresiones booleanas concatenadas con los operadores lgicos and, or y not. La clusula when para condicionar la aplicacin de una clusula where solo puede utilizarse en arquitecturas cliente/servidor. Si no es el caso, y deseamos que si el usuario no ingresa valores en las variables (las deja vacas), no se realicen los filtros sobre los datos, podemos hacer: For each where CustomerName >= &Start or &Start.IsEmpty() where CustomerName <= &End or &End.IsEmpty()) print customer Endfor Un cliente ser impreso si cumple con las condiciones de ambos where. Si la variable &Start es vaca entonces todo registro cumplir la condicin del primer where, ya que es una condicin compuesta por or, donde una de las subexpresiones da True, por lo que la expresin completa tambin dar True. Lo mismo ocurre si la variable &End est vaca. Por lo tanto, si ambas variables estn vacas, todos los registros cumplirn con las condiciones de los where, y por lo tanto no se aplicar filtro alguno sobre los datos. Se listarn todos los clientes. Pedido de datos al usuario del reporte Interfaz Win: GeneXus cuenta con la funcin estndar Ask, que se ejecuta antes de entrar al objeto y pide al usuario el ingreso de un valor. Utilizaremos esta funcin para pedir al usuario los valores que cargaremos en las variables &Start y &End por medio del comando de asignacin. En el Source del reporte escribimos: &Start = Ask( Ingrese nombre de cliente inicial: ) &End = Ask( Ingrese nombre de cliente final: ) Notas No importa el lugar del Source donde se especifiquen estos comandos, dado que la funcin Ask se ejecutar siempre al principio. Lo mismo puede programarse utilizando la regla de asignacin, en lugar del comando de asignacin, en las Rules del reporte, en lugar de hacerlo en el Source. Interfaz Web: El reporte no tendr ningn tipo de interaccin con el usuario, por lo que la funcin Ask no tendr efecto alguno. Por tanto si el reporte va a ejecutarse en el marco de una aplicacin Web, debern pedirse estos valores al usuario en uno de los objetos diseados especficamente para tal fin: esto es, el Web Panel y luego invocar al reporte envindole estos datos por parmetro. Tambin podr utilizar esta solucin en un ambiente Win, utilizando el objeto anlogo: el Work Panel1.

----------------------------------------------------------------------------------------------------------Para ver cmo realizar esto, puede dirigirse al captulo del objeto correspondiente (Web Panel o Work Panel segn corresponda), y estudiar el primer panel presentado, clasificado como panel de entrada.
1

196

Listado de navegacin

Listado de navegacin Aparece un nuevo elemento en este listado que no estaba presente antes, cuando no tenamos clusulas where: las constraints (restricciones). Qu informacin nos brinda este listado de navegacin? que la tabla base del for each seguir siendo CUSTOMER que se seguir ordenando la consulta por CustomerId, utilizando el ndice ICUSTOMER correspondiente que seguir recorriendo toda la tabla CUSTOMER en busca de la informacin pero que para cada cliente evaluar si cumple con las restricciones que aparecen enumeradas (CustomerName>= &Start si &Start no est vaca y CustomerName<=&End si &End no est vaca) y solo en caso de que las cumpla, ejecutar para ese cliente los comandos que aparecen dentro del for each. En este caso, imprimir los valores de los atributos del print block customer: CustomerId, CustomerName, CountryName. que debe acceder a la tabla COUNTRY cuya clave primaria es CountryId para obtener algn dato (CountryName)

197

For each: clusulas Where

Atributos permitidos: los de la tabla extendida de la tabla base del for each Ejemplo: for each where CountryName = Uruguay print customer endfor

Los atributos utilizados en las condiciones de filtro pueden ser cualesquiera de la tabla extendida del for each. En el ejemplo, si bien la tabla base del for each es CUSTOMER, estamos filtrando los datos a recuperar utilizando el atributo CountryName, que es de la tabla COUNTRY, perteneciente a la extendida de CUSTOMER. En este ejemplo tampoco se explicita nada con respecto al orden, por lo cul los datos aparecern ordenados por la clave primaria de la tabla base, es decir, por identificador de cliente, CustomerId.

198

For each: clusula Order


Permite establecer el orden en el que se quieren recuperar los datos.
Ejemplos: for each order CustomerName print customer endfor for each order CustomerName when not (&Start.IsEmpty() and &End.IsEmpty()) print customer endfor Para determinar orden descendente se deben colocar parntesis rodeando a los atributos del orden. Ejemplo: order (CustomerName)

Si queremos realizar un listado de todos los clientes pero ordenado por nombre del cliente en lugar de por cdigo, lo nico que tenemos que hacer es modificar el comando for each agregando esta informacin del orden. Esto se logra utilizando la clusula order del for each, como se muestra en el primer ejemplo. Como no existe un ndice definido en la tabla CUSTOMER por el atributo CustomerName, GeneXus indicar en el listado de navegacin mediante una advertencia (warning) que no existe un ndice para satisfacer el orden, lo que podra ocasionar problemas de performance, dependiendo de la plataforma de implementacin elegida, de la cantidad de registros que deben ser ledos de la tabla, etc. En algunas plataformas, como VFP o iSeries (AS/400), si no existe ndice para satisfacer el orden especificado se crea uno temporal cada vez que se ejecuta el reporte y se elimina al finalizar la ejecucin. Este tipo de ndice es el que llamamos ndice temporal. En otras plataformas, como VB con Access o en ambientes cliente/servidor, si no existe ndice para satisfacer el orden, el for each se traduce en una consulta SQL (select) que es resuelta por el motor del DBMS de la plataforma. Al igual que en el caso de las clusulas where, en plataformas cliente/servidor la clusula order puede condicionarse, como se muestra en el segundo ejemplo. En caso de no cumplirse la condicin del when, no aplicar ese orden y de no existir orden incondicional (sin clusula when) como en el ejemplo, el orden a utilizar ser indefinido, significando esto que el orden resultante podr variar de DBMS a DBMS e incluso entre ejecuciones sucesivas. Pueden especificarse varias clusulas order condicionadas (con clusula when) consecutivas en casos de arquitecturas cliente/servidor y una sin condicin (la ltima de la lista). La primera clusula order cuya condicin del when se satisfaga, ser la elegida y su orden el utilizado. Clusula Order None: clusula que evita que GeneXus elija por defecto el orden de los atributos de la clave primaria de la tabla base y utilice un orden de navegacin indefinido. La clusula order none admite condicin para aplicarse (when).

199

Listado de navegacin
for each order CustomerName print customer endfor

Listado de navegacin Cuando no existe ndice que satisfaga el orden de un for each, como es el caso del ejemplo, el analista GeneXus puede resolver crearlo (ndice de usuario). En la mayora de los casos el reporte ser bastante ms eficiente de esta manera, pero se debe mantener un ndice ms (lo que implica mayor almacenamiento y mayor procesamiento para mantener actualizado el ndice) No es posible recomendar a priori cul de las dos soluciones es la mejor (no ndice vs ndice de usuario), por lo tanto se debe estudiar, caso por caso, la solucin particular teniendo en cuenta la plataforma de implementacin y siendo fundamental la frecuencia con que se ejecutar el reporte. De cualquier manera, si al comienzo no se defini el ndice de usuario y posteriormente se decide definirlo, alcanza con regenerar el reporte (sin modificar nada de lo programado en el mismo) y ste pasar a utilizarlo. El listado de navegacin anterior nos informa que: la tabla base del for each es CUSTOMER y se recorrer ordenada por CustomerName no existe un ndice definido para ese atributo se recorrer toda la tabla CUSTOMER con el orden especificado no hay condiciones de filtro, por lo que para todos los registros de la tabla se ejecutarn los comandos dentro del for each (en nuestro caso, el comando print).

200

For each: clusula Order


Atributos permitidos: los de la tabla extendida del for each, salvo que se trate de una plataforma centralizada. en plataforma centralizada solo pueden utilizarse atributos de la tabla base.

De tratarse de una plataforma centralizada (Visual Basic / Access o Visual Fox Pro / DBFs), al especificar un reporte que contenga: For each order CountryName Print customer endfor se desplegar en el listado de navegacin un mensaje de error indicando que no es posible ordenar por CountryName. El motivo es que la tabla base del for each es CUSTOMER, y CountryName no pertenece a la misma. En cambio, si se est generando en una plataforma cliente/servidor, no habr ningn problema con un reporte que contenga el comando anterior.

201

OPTIMIZACIN: Orden compatible con los filtros


for each where CustomerName >= &Start where CustomerName <= &End print customer endfor for each order CustomerName where CustomerName >= &Start where CustomerName <= &End print customer endfor Se recorre toda la tabla base

No se recorre toda la tabla base: optimizado!

Hay que evaluar asiduidad de esta consulta, creacin del ndice, y su mantenimiento.

Si nos interesa filtrar los clientes de forma tal que sus nombres pertenezcan a un rango, en el primer ejemplo, como no especificamos clusula order GeneXus ordena por clave primaria, es decir, por CustomerId. En este caso, el listado de navegacin nos va a informar que se debe recorrer toda la tabla CUSTOMER, y para cada registro de la misma se debe evaluar si el registro cumple o no con las condiciones (restricciones o constraints). En caso afirmativo, se imprimen para el mismo los datos correspondientes. Si en lugar de ordenar los datos por CustomerId pedimos que se ordenen por CustomerName, como se presenta en el segundo ejemplo, la tabla base se recorre ordenada por CustomerName y como en los filtros establecemos que queremos quedarnos solo con aquellos clientes cuyo nombre, CustomerName, est en el rango determinado, entonces ya no ser necesario recorrer toda la tabla base para obtener los datos que cumplen con las condiciones! Diremos que esta segunda consulta est optimizada en ese sentido. Tener en cuenta, sin embargo, que GeneXus no tiene creado un ndice en forma automtica por CustomerName, y aqu habr que evaluar si conviene crear un ndice de usuario (que debe ser mantenido por Genexus luego) o no crear ndice y que se cree un ndice temporal en ejecucin para resolver la consulta si el DBMS no puede resolverlo de otra forma. El listado de navegacin nos informar si una consulta est o no optimizada, de acuerdo a si recorrer toda la tabla (desde First Record hasta End of table) o si recorrer por el contrario un rango ms reducido.

202

Definicin de la estrategia de acceso a las tablas


Begin of table
READ READ READ READ READ READ READ READ

Begin of table
READ READ READ READ READ READ READ READ

Start point End point

End of table

End of table

1. 2. 3. 4.

Se define el orden en que se recorrer la tabla. Se elige el punto de comienzo (Starting Point) Se elige la posicin final (End Point). Se leen secuencialmente los registros entre el punto inicial y el punto final, seleccionando los registros que cumplen las condiciones y descartando los restantes.

Normalmente los programas procesan registros agrupando aquellos que tengan ciertas caractersticas comunes, por ejemplo, todas las facturas de un determinado cliente, o las ventas de una clase de artculos. Estas caractersticas comunes se establecen a travs de condiciones que determinan un filtro sobre los registros. Tales condiciones se especifican en GeneXus de diversas formas, una de las cuales es el caso de las clusulas where en un For each. En el ejemplo que estamos viendo: de todos los clientes, quiero imprimir los datos de aquellos cuyo nombre est en un rango determinado. El tiempo necesario para realizar el proceso con los registros que cumplen las condiciones determina el grado de "optimizacin" que tiene la estrategia de acceso elegida. Decimos que una estrategia de acceso est ms "optimizada" que otra cuando es necesario un menor tiempo para leer todos los registros que cumplen las condiciones establecidas. La optimizacin consiste en posicionarse lo ms cerca posible del primer registro del grupo que cumple las condiciones y desde all leer secuencialmente hasta el ltimo que las cumpla. Lo que se establece, en definitiva, es un intervalo que cubre todos los registros que cumplen las condiciones, de manera tal que los que estn fuera de ese intervalo ni se consideran, pues ya se sabe que no podrn cumplir las condiciones. En este intervalo no necesariamente todos los registros cumplen la condicin. En estos casos, la mejor estrategia consiste en tener el menor intervalo tal que cubra a todos los registros que cumplirn la condicin. Igualmente las lecturas se realizarn para todos los registros de este intervalo, pero solamente se considerarn aquellos que cumplan con las condiciones. Para definir una buena estrategia de acceso, GeneXus cuenta con una inteligencia razonable. Se determinar, estableciendo (de acuerdo al orden en que deban considerarse los registros y a las condiciones), una posicin inicial y una posicin final en el archivo, leyendo en forma secuencial en este intervalo.

203

For each: clusula Defined by


No ofrece funcionalidad alguna en lo que respecta a los datos a recuperar. Se utiliza exclusivamente para dar un elemento ms para la determinacin de la tabla base del for each deseada. Ejemplo:

for each defined by InvoiceDate print customer endfor

Mn. extendida que contiene a InvoiceDate, CustomerId, CustomerName, CountryName: ext(INVOICE) tabla base INVOICE

Puede darse el caso de que para un For each haya ms de una tabla base cuya extendida contenga a los atributos del for each, siendo mnima. Ante esta ambigedad, GeneXus escoge la primera de estas tablas extendidas mnimas. Para resolver este tipo de ambigedad surge la clusula defined by, que permite nombrar atributos de la tabla base deseada, que no se utilizarn para devolver la consulta ordenada por esos atributos, ni para filtrar la informacin a recuperar, ni para ser desplegados en el listado (es decir, no tienen funcionalidad alguna con respecto a los datos a recuperar), sino solo para aportar ms informacin que permita determinar la tabla base del for each. En la clusula Defined by se debe hacer referencia a por lo menos un atributo de la tabla base deseada. De la misma manera, se puede (y se suele) utilizar para modificar la que sera la tabla base en caso de no nombrarse ningn atributo ms dentro del For each. Este es el caso del ejemplo presentado, en el que no queremos listar todos los clientes de la tabla CUSTOMER, sino por el contrario, queremos listar todos los clientes de las facturas. De no nombrarse dentro del For each algn atributo de INVOICE, la tabla base sera CUSTOMER. En la mayora de los casos no es necesario utilizar esta clusula. Sin embargo, para reportes ms o menos complejos, an cuando no exista problema de ambigedad, se recomienda el uso del Defined by porque mejora bastante el tiempo de especificacin del reporte. Sin embargo, no puede aconsejarse un uso indiscriminado. La contra de utilizar esta clusula cuando no es necesaria es que ata un poco ms el cdigo al diseo de las tablas. Supngase por ejemplo que no se tiene creada una tabla COUNTRY, y se tiene de cada cliente el pas al que pertenece, como atributo secundario. Si lo que queremos es listar los clientes y su pas, seran equivalentes: For each print customer endfor For each Defined by CountryName print customer endfor

donde customer es un print block con los atributos CustomerId, CustomerName y CountryName. Si ahora decide crearse la tabla COUNTRY y tener en la transaccin Customer a CountryId como FK, si bien el primer for each continuar siendo vlido y haciendo lo que queremos, el segundo dejar de funcionar, ya que en el Defined By no hay ningn atributo de la tabla base.

204

For each: clusula Defined by


Atributos permitidos: pueden aparecer varios atributos de la tabla extendida, pero al menos uno debe corresponder a la tabla base que se desea (en caso contrario dar un error)

Pueden aparecer varios atributos, para el posible caso en el que no alcance uno solo para determinar completamente la tabla base deseada, donde al menos uno de ellos deber estar asociado a la tabla base deseada. Se recomienda el uso en el Defined by de atributos secundarios de la tabla base que se desea navegar, ya que como sabemos, los atributos secundarios solo pueden estar en una tabla del modelo y de esta forma eliminamos por completo toda posible ambigedad. Esto sin embargo, no es obligatorio, es decir, pueden nombrarse en el Defined by atributos primarios cuando se sepa que no habr ambigedad en la eleccin de la tabla base. Un error comn es creer que cuando un for each tiene esta clusula, la tabla base del mismo queda determinada exclusivamente a partir de los atributos mencionados en el defined by. La realidad es que los atributos del defined by arrojan una o ms tablas base candidatas a ser la tabla base del for each, pero luego hay que ver si tomando cada tabla base candidata, su extendida contiene a todos los dems atributos del for each, adems de los del defined by. Si ninguna de las posibles tablas base candidatas cumplen esta condicin, entonces el reporte dar un error al ser especificado, y no podr ser generado (recordemos que debe cumplirse que todos los atributos del for each estn contenidos en una misma tabla extendida).

205

For each: clusula When none


Permite ejecutar determinado cdigo cuando en un for each no se encuentra ningn registro que cumpla las condiciones. Ejemplo:

for each where CustomerName >= &Start where CustomerName <= &End when none endfor
print customer print message

El print block message (que podr contener un texto advirtiendo al usuario de que no existen clientes que cumplan los filtros) se ejecuta slo cuando no se entra en el For each, es decir, cuando no hay ningn registro correspondiente a la tabla base del for each para el que se cumplan las condiciones de filtro. Tambin se aplica a for each [selected] line, XFor Each y XFor First, comandos que veremos ms adelante. La clusula when none debe ser la ltima dentro del For each. Las acciones a realizar cuando no existe ningn registro para el que se cumplan las condiciones, quedan determinadas por el bloque de cdigo que hay entre la clusula when none del for each y el endfor. Cuando un for each no tiene condiciones de filtro, los comandos del when none se ejecutarn solo en el caso en que se cumpla que la tabla base del For each est vaca, porque solo en ese caso no habr ningn registro que cumpla las condiciones de filtro. Importante: Si aparecen atributos en el bloque de cdigo correspondiente al when none, stos no son tenidos en cuenta para determinar la tabla base del for each. Si se incluyen for eachs dentro del when none no se infieren Joins ni filtros de ningn tipo con respecto al for each que contiene el when none, ya que son considerados for eachs paralelos.

206

Comando For each - Sintaxis


for each [{[order] order_attributes [when condo] }| [order none] [when condon]] [{where condition when condw }] [defined by defined_attributes] code1 [when duplicate code2] [when none code3] endfor

La sintaxis presentada generaliza el ejemplo con el que vinimos trabajando. Es la sintaxis general que aplica a plataformas Cliente/Servidor. Para plataformas centralizadas existen algunas limitaciones (clusulas when y order none no aplican a este caso). Order order_attributes::= att1, , attn Es una lista de atributos, que indican el orden en el que ser devuelta la consulta, siendo atti un atributo de la base de conocimiento escrito simple, o entre parntesis curvos. Cuando un atributo del order aparece rodeado de parntesis curvos se est indicando orden descendente para el mismo. Aqu pueden mencionarse atributos de la tabla extendida, a menos que se est trabajando en una plataforma centralizada, en cuyo caso solo podrn utilizarse atributos almacenados en la tabla base. Para plataforma centralizada, podr especificarse a lo sumo una clusula order, sin condicin (when). Sin embargo puede no especificarse clusula order. En tal caso se asume como orden el de la clave primaria de la tabla base, salvo excepciones que estudiaremos oportunamente. Para plataforma cliente/servidor es posible definir varias clusulas order condicionales, y una incondicional, que debera ser la ltima listada. El por qu responde al hecho de que como solamente una de esas clusulas order tomar efecto, se van evaluando sus condiciones (las del when) hasta la primera que de True, y con esa se queda. Si ninguna da true y existe una clusula incondicional (es decir, sin when), se tomar ese orden. Si no existe tal clusula, el orden ser indefinido, queriendo esto significar que depender de la plataforma, e incluso podr variar entre ejecuciones sucesivas. La justificacin para escribir clusulas order condicionales, deriva de si queremos aplicar clusulas where condicionales. Es decir, por motivos de optimizacin de las consultas. Por ejemplo, si queremos filtrar por CustomerName > &Name when not &Name.IsEmpty(), entonces para optimizar la consulta deberamos ordenar por CustomerName, pero si no se va a aplicar el filtro, dado que &Name est vaca, entonces ser mejor dejar un orden indefinido. Para ello especificamos la clusula order condicional: order CustomerName when not &Name.IsEmpty() En lugar de todo lo anterior, tambin puede especificarse una clusula order none que se agrega para cuando no nos interesa un orden en particular y queremos que ste quede indefinido.

207

Eleccin del ndice: GeneXus elige automticamente el ndice a utilizar para satisfacer el orden. En caso de que no exista, informa de esta situacin en el listado de navegacin y dependiendo de la plataforma, crea un ndice temporal o deja en manos del DBMS la eleccin de la estrategia para procesar la consulta. Los atributos del order son tenidos en cuenta a la hora de determinar la tabla base del for each. Pero ellos por s solos no la determinan. Deben examinarse tambin otras partes del for each. Where Condition Condicin booleana que debern cumplir los datos para ser procesados dentro del for each, pudiendo ser una condicin compuesta, utilizando los operadores lgicos and, or y not. Los atributos que aparezcan en la condicin booleana pueden ser tanto de la tabla base del for each como de la extendida. Como se desprende de la sintaxis, para un mismo for each pueden especificarse n clusulas where sucesivas, cada una con una condicin: where cond1 where cond2 ... where condn La ocurrencia de n clusulas where es equivalente a la ocurrencia de una sola clusula, con la conjuncin booleana de las condiciones: where cond1 and cond2 and and condn Los datos de la tabla extendida del for each que cumplan con todas las condiciones de los where sern los procesados en los comandos internos al for each (los del bloque de cdigo code1). Para el caso de plataformas cliente/servidor, al igual que ocurre con la clusula order, podrn condicionarse los filtros (con clusulas when). De esta manera, primero se evala la clusula when de cada clusula where, y de cumplirse su condicin, aplicarn el filtro especificado en el where. Para que una restriccin condicional pueda ser generada como tal, se debe estar en una arquitectura Cliente/Servidor y la condicin del when tiene que ser "evaluable" por el DBMS que se est utilizando, es decir, GeneXus tiene que saber cmo escribir la condicin en el lenguaje propio del DBMS utilizado. Si no se puede generar como tal (porque el generador no lo soporta o porque la condicin no puede ser escrita en el lenguaje del DBMS) se transformar en un filtro "comn" sustituyendo el WHEN por un OR. Adems, se generar el mensaje de cdigo spc0053 Unsupported conditional constraint%1 changed to standard constraint %2. - en el Diagrama de Navegacin. Nota: Existe tambin la clusula Option Distinct del For Each que permite retornar los registros que cumplan unicidad de valores de los atributos referenciados. No veremos esta clusula. El lector interesado puede recurrir a las distintas fuentes de documentacin para estudiarla (Help, GXDL, Wiki, Release Notes, etc.) Defined by defined_attributes::= att1, att2,,attp Es un conjunto de atributos que sern utilizados a los solos efectos de determinar la tabla base del for each. Al mencionar aqu algunos atributos de la tabla que se desea recorrer, stos participarn en la determinacin de la tabla base del for each. La clusula defined by aparece para solucionar algunos problemas de ambigedad en la determinacin de la tabla base (cuando existen varias tablas extendidas mnimas que contienen a los atributos del for each) o cuando se desea que la tabla base sea otra, distinta de la que sera determinada por los atributos que aparecen en el resto del for each (este caso cobrar sentido cuando se estudie corte de control). Tambin se utiliza para mejorar el tiempo de especificacin en reportes complejos. Los atributos de esta clusula no determinan por s solos la tabla base del for each. Podra darse el caso de que de estos atributos surja determinada tabla como la candidata a tabla base, pero si luego el resto de los atributos del for each no estn contenidos en la extendida de esa tabla, el for each dar un error y el objeto que lo contiene no podr ser generado. code1 Es una sucesin de comandos en los que pueden utilizarse atributos de la tabla extendida del for each. A este bloque de cdigo le llamaremos cuerpo del for each. Los atributos que figuren en este bloque de cdigo participarn en la determinacin de la tabla base del for each.

208

Los comandos especificados se ejecutarn secuencialmente para los datos de la tabla extendida que cumplan las condiciones de filtro, considerndose los datos en el orden especificado. When Duplicate Esta clusula solo tiene sentido en procedimientos (dado que tiene que ver con la actualizacin) y se ver ms adelante. Se ejecutar esta clusula si dentro del cuerpo del For each code1, se intenta actualizar un atributo que es clave candidata (tiene ndice unique) y ya existe un registro con ese valor. GeneXus utiliza el ndice unique para asegurar la unicidad de esa clave candidata y en caso de encontrar duplicados, si el for each tiene programada esta clusula, ejecutar su cdigo: code2 . De no existir la clusula no se ejecutar cdigo alguno. When none En caso de que no existan datos que cumplan las condiciones de filtro no se ejecutarn los comandos del code1 sino que se ejecutarn los del bloque de cdigo code3. Tanto para When Duplicate como para When none: Si se incluye dentro de alguno de los dos un comando for each, no se infieren joins ni filtros con respecto al for each que los contiene (el del when none | when duplicate). Son consideradas navegaciones independientes (la del code1, code2 y code3).

209

For eachs paralelos


Llamamos de esta forma al caso de for eachs que estn escritos en forma secuencial (no anidada) Ejemplo:

for each print invoice endfor for each print bill endfor
Tambin aplica al caso en el que un for each aparece dentro de la clusula when none o when duplicate de otro. Las navegaciones son totalmente independientes

El For each es un comando como otros, y por tanto puede aparecer varias veces dentro del Source, tanto en forma paralela (independiente), como anidado a otro for each. Cuando dentro del cuerpo del for each (code1) aparece otro for each, decimos que se trata de for eachs anidados. GeneXus soporta varios niveles de anidamiento para los for eachs. El caso en el que un for each aparece en el bloque de cdigo code3, si bien puede verse como un anidamiento de for eachs porque uno aparece dentro de otro, el comportamiento en cambio, es como el del caso de for eachs paralelos. Un for each anidado en el when none de otro, solo se ejecutar si no existe ningn registro de la tabla base del for each que lo contiene que cumpla las condiciones de filtro. En el ejemplo, invoice y bill son dos print blocks del Layout que continen atributos de las tablas INVOICE y BILL (recibo) respectivamente. Hemos definido dos for eachs paralelos. El primero recorrer todas las facturas y el segundo todos los recibos.

210

For eachs anidados


Se busca recuperar por cada registro del for each principal, muchos registros del anidado

for each ... for each ... endfor ... when none ... endfor

Cuerpo del for each principal

El for each es una estructura repetitiva que permite recuperar muchos registros de una tabla. Cuando uno piensa en for eachs anidados, es evidente que lo que se busca recuperar es, por cada registro del principal, muchos registros del anidado. Qu cosas podra GeneXus detectar que se quiere hacer con este tipo de estructuras, de forma tal de poder inferir el comportamiento automticamente con la menor codificacin posible? para cada registro de para cada registro de procesar informacin atributo o conjunto de al grupo. una tabla recuperar algunos de otra: los relacionados. una tabla recuperar todos los de otra. por grupos, esto es, agrupar los registros de una tabla segn el valor de un atributos y para cada grupo, recuperar algunos registros: los correspondientes

Siempre la relacin es uno a muchos: por cada registro de una tabla recuperar muchos de la otra (pudindose tratar de la misma tabla). Utilizando esta lgica es que GeneXus infiere las tablas base y el comportamiento de los for eachs anidados, sabiendo que lo que se desea es implementar alguna de las tres opciones anteriores. Por ejemplo si queremos realizar un listado de todas las facturas del sistema, donde para cada una queremos imprimir tambin el detalle de la misma, debemos recorrer dos tablas: INVOICE (que almacena los cabezales) e INVOICELINE (que almacena las lneas), y lo haremos de una forma bien simple, sin nombrar las tablas, y sin tener que explicitar todo, como veremos. Otro ejemplo es el de un listado de todos los clientes, donde para cada uno se quieren imprimir, adems de sus datos personales, los datos de todas sus facturas. Este comportamiento se logra con un par de for eachs anidados, donde el primero recorrer la tabla CUSTOMER y el segundo recorrer la tabla INVOICE, recuperando solo las facturas de ese cliente, como veremos en breve.

211

For eachs anidados


Ejemplo: imprimir todas las facturas con sus respectivas lneas

for each print invoice_header for each print invoice_lines endfor print invoice_total endfor

{InvoiceId, InvoiceDate, CustomerName} {ProductDescription, ProductPrice, InvoiceLineQuantity, InvoiceLineAmount} {InvoiceTotal}

Queremos realizar un listado de todas las facturas del sistema, donde para cada una se muestre tanto informacin de su cabezal como de sus lneas. En el Source programado, claramente recorremos la tabla INVOICE, imprimiendo los atributos que nos interesan del cabezal y para cada registro de esa tabla, recorremos la tabla INVOICELINE, para imprimir los atributos que nos interesan de sus lneas. Tan simple como eso! Otra vez, nos alcanza con nombrar los atributos que queremos utilizar y del resto se encarga GeneXus. Observemos que ni siquiera tuvimos que especificar condicin de filtro sobre los registros de INVOICELINE a recuperar. GeneXus se da cuenta de la relacin existente entre las tablas, y aplica automticamente la condicin de filtro sobre los datos, de manera tal de solo imprimir las lneas de esa factura (recordar que algo idntico ocurra con las frmulas verticales, como InvoiceTotal, donde la condicin de filtro sobre los registros a ser sumados o contados quedaba implcita, y no haba que especificarla).

212

For eachs anidados


Ejemplo: imprimir todas las facturas con sus respectivas lneas

INVOICE

INVOICELINE

Para cada registro de INVOICE imprimir algunos de sus datos (InvoiceId, InvoiceDate) y de su extendida (CustomerName). Luego navegar INVOICELINE y recuperar los registros que correspondan a la factura que se est imprimiendo. Los que cumplan la condicin implcita: INVOICELINE.InvoiceId = INVOICE.InvoiceId

Como para un for each simple, GeneXus debe determinar para cada for each (principal y anidado) cul es su tabla base. Y luego, a partir de esa determinacin, inferir la lgica correspondiente. Ms adelante veremos con exactitud cmo es que GeneXus determina cada tabla base. Aqu nos quedaremos con la idea intuitiva de que lo hace en forma similar a como lo haca para el caso de un for each simple. Encuentra, pues, que debe recorrer las tablas INVOICE e INVOICELINE. Como esas tablas estn relacionadas de acuerdo a una relacin 1-N infiere ms que eso: infiere adems que debe aplicar la condicin sobre los datos de INVOICELINE que se indica arriba.

213

For eachs anidados


GeneXus debe: 1. Determinar la tabla base de cada for each. 2. A partir de eso definir las navegaciones que realizar para cada for each (existen 3 casos posibles). La lgica de los for eachs depender de las relaciones que encuentre entre las tablas determinadas.

Cuando tenemos for eachs anidados, GeneXus debe determinar la tabla base de cada uno, y esas sern las tablas que se navegarn. Para cada registro de la tabla base del for each principal, se ejecutarn los comandos del cuerpo del mismo. Entre esos comandos, se encuentra el for each interno, que se ejecutar, como cualquier otro comando, en el lugar donde se encuentre, realizando una navegacin sobre su tabla base. Pero para la determinacin de la tabla base del for each anidado, podr influir la tabla base del for each principal, por lo que las determinaciones no son por completo independientes, como podra pensarse. A partir de la determinacin de las tablas base de cada for each primero y de las relaciones que encuentre GeneXus entre las tablas involucradas luego, surgen tres posibles casos de for eachs anidados: join, producto cartesiano y corte de control, respectivamente. Estudiaremos en lo que sigue cada uno de estos casos con ejemplos, para luego generalizar todo lo visto.

214

For eachs anidados: determinacin tablas base


Se procede en forma ordenada, determinando for each cada vez la tabla base de un nivel de anidacin, ... yendo de afuera hacia adentro: primero se for each determina la tabla base del for each ms ... externo, luego del que est anidado endfor a ste y as sucesivamente. ... when none ... endfor Para cada for each, intervienen nicamente los atributos propios de ese for each: del order, where, defined by y todos los del cuerpo que no pertenezcan a un for each anidado (tampoco intervienen los de la clusula when none).

Consideremos el caso ms simple, de un par de for eachs anidados. La determinacin de la tabla base del for each principal, es anloga al caso de for each simple (sin anidamientos). En este caso se consideran todos los atributos del for each principal, descartando los for eachs anidados que ste contenga (y todos sus atributos). GeneXus encuentra la mnima tabla extendida que contenga a los atributos referidos y define as la tabla base a travs de la cual llega a todas las dems. Para determinar la tabla base del for each anidado, GeneXus se fija si los atributos utilizados dentro del cuerpo del mismo estn incluidos o no dentro de la tabla extendida previamente determinada (la del for each principal). En caso afirmativo, GeneXus determina que la tabla base del for each anidado ser la misma que la del for each principal. En caso contrario, se busca la mnima tabla extendida que cumpla que contiene a todos los atributos del for each anidado. Su tabla base ser la del for each. (Observar que solo en este caso se procede a determinar la tabla base como si se tratase de for eachs independientes). Veremos un esquema resumiendo lo anterior ms adelante.

215

For eachs anidados: determinacin tablas base


for each print invoice_header for each print invoice_lines endfor print invoice_total endfor for each print invoice_header for each print invoice_lines endfor print invoice_total endfor Tabla base for each externo
{InvoiceId, InvoiceDate, CustomerName} {InvoiceTotal}

INVOICE

Tabla base for each interno


{ProductDescription, ProductPrice, InvoiceLineQuantity, InvoiceLineAmount}

INVOICELINE

Para el ejemplo que presentamos antes, mostramos arriba cmo se determina cada tabla base. Para la del anidado, como los atributos que figuran no estn contenidos en la tabla extendida de INVOICE (que es la tabla base del principal), entonces se pasa a determinar su tabla base como si se tratase de un for each independiente. Este es el caso general, pero en algunas circunstancias particulares GeneXus toma un criterio ms exhaustivo intentando encontrar relacin 1-N entre los for each y en esos casos, la determinacin de la tabla base del for each anidado (cuando los atributos del mismo no estn incluidos en la extendida del principal) no es independiente. GeneXus busca otra relacin, pero no entraremos en estos casos particulares en el presente curso. De sucederle al estudiante, lo notar claramente en el listado de navegacin.

216

For eachs anidados: lgica asociada


Tablas base distintas Fe externo
1 N

Existe relacin implcita que lo vincule con un nmero N de registros del for each anidado? S No
Join: se recuperan algunos registros del anidado, los relacionados. (Caso 1) Producto cartesiano: se recuperan todos los registros del anidado. (Caso 2)

Fe anidado ?

Tablas base iguales


Corte de Control: Corresponde al caso en el que queremos recuperar informacin por grupos. (Caso 3)

De la determinacin de las tablas base, surgen los tres casos de for eachs anidados que se mencionan y que estudiaremos uno a uno en lo sucesivo. Este tema es de vital importancia, ya que la mayora de las aplicaciones requieren navegaciones complejas sobre las tablas, donde se requiere una mixtura de todos estos casos.

217

Caso 1: Join
Distintas tablas base pero existe una relacin 1-N directa o indirecta entre ellas
Ejemplo: Listado de todos los clientes y sus facturas

for each print customer for each print invoice endfor endfor

CUSTOMER
{CustomerId, CustomerName} {InvoiceId, InvoiceDate, InvoiceTotal}

CustomerId

INVOICE

ext(principal) base(anidado) = {CustomerId} En el for each anidado se ordena por atributo relacin: CustomerId

Este es el caso en el que GeneXus determina que las tablas base de cada for each son distintas y hay una especie de relacin 1-N (pudiendo ser sta indirecta, como veremos luego) entre las tablas que se recorren. Es decir, por cada registro de la tabla base del for each principal, GeneXus encuentra que hay N relacionados con l, directa o indirectamente, en la tabla base del for each anidado. Al encontrar esta relacin, aplicar condiciones de filtro automticas en el for each anidado, de forma tal de solo quedarse con esos registros relacionados. El ejemplo del reporte en el que se imprimen todas las facturas del sistema, con sus detalles, cae dentro de esta categora. En ese caso hay una relacin 1-N directa entre las tablas que se recorren: para cada cabezal de factura, se lista el mismo, junto con todas sus lneas de factura, es decir, todos los registros de INVOICELINE que estn relacionados con el registro de INVOICE en el que se est posicionado en cada iteracin. Este es uno de los casos ms comunes de for eachs anidados, donde se quiere recorrer una tabla, y para cada registro de la misma, recorrer otra tabla, relacionada con la primera por una relacin N-1. GeneXus encuentra esta relacin, y en la navegacin interna solo recupera los registros asociados, y de ah el nombre de join para este caso. En el ejemplo presentado arriba ocurre lo mismo. La tabla base del primer for each es CUSTOMER, y la del segundo, INVOICE. Como encuentra atributo en comn entre la tabla extendida del for each principal y la tabla base del anidado1, CustomerId, determina que ese atributo actuar como condicin de filtro en la recorrida de la tabla del for each anidado.

-----------------------------------------------------------------------------------------------------------Esta es una forma de expresar formalmente lo que habamos dicho en trminos informales: relacin directa o indirecta 1-N entre las tablas base. La relacin ser directa cuando la tabla base del principal tenga relacin 1-N con la tabla base del anidado, es decir, sea superordinada de esta ltima. La relacin ser indirecta cuando esto no exista una relacin directa entre las tablas base, pero s entre la tabla extendida del primero y la tabla base del segundo. Tambin ser indirecta cuando la tabla extendida del anidado incluya a la tabla base del principal. De esto veremos ejemplos luego.
1

218

Caso 1: Join

Veamos, por ahora intuitivamente, cmo hace GeneXus para determinar las tablas base. Los atributos utilizados en el for each externo son CustomerId y CustomerName, por lo que la tabla base de este for each ser claramente CUSTOMER. Observemos que solo participan en la determinacin de esta tabla base los atributos del for each principal, no los del anidado. Luego GeneXus debe encontrar la tabla base del for each anidado. Los atributos que participan son InvoiceId, InvoiceDate y InvoiceTotal, es decir, los atributos internos a este for each. Observemos que estos atributos no pertenecen a la tabla extendida del principal, que era CUSTOMER. Por tanto se pasa a determinar su tabla base como la de cualquier for each simple: la tabla extendida de INVOICE contiene a todos los atributos del for each anidado, y es la mnima tabla extendida que los contiene. Por lo tanto, INVOICE ser elegida como tabla base del segundo for each. Observemos, nuevamente, que no explicitamos clusula where en el for each anidado para filtrar las facturas del cliente del for each principal. Justamente, por tratarse de tablas relacionadas por una relacin 1-N directa, esta condicin es aplicada implcitamente por GeneXus y puede verse claramente en el listado de navegacin que se muestra arriba. Hay otro hecho interesante que podemos observar en este listado: si bien en el for each anidado no especificamos clusula order, GeneXus no eligi el orden por clave primaria de la tabla base sino por el atributo relacin, CustomerId. De esta manera, est optimizando automticamente la consulta. Ac se presenta, pues, una excepcin a la regla que enunciaba que cuando no se especifica clusula order en un for each, GeneXus determina como orden el de la clave primaria de la tabla base de dicho for each.

219

Caso 1: Join
Ejemplo: Listado de todas las facturas por pas
{CountryId, CountryName} CountryId

for each print country for each print invoice endfor endfor
base(principal) ext(anidado)

CUSTOMER
CustomerId

COUNTRY

INVOICE

{InvoiceId, InvoiceDate, InvoiceTotal}

COUNTRY ext(INVOICE) por lo que hay una relacin 1-N indirecta condicin implcita: se listan las facturas del pas

Si queremos realizar un listado de las facturas emitidas por pas, tenemos otro caso de for eachs anidados con distintas tablas base, donde la informacin que se quiere listar est relacionada. Aqu queremos recorrer las tablas COUNTRY e INVOICE. Observemos que si bien no estn relacionadas directamente, s lo estn en forma indirecta. De hecho, COUNTRY pertenece a la tabla extendida de INVOICE. Por lo tanto, por cada factura se puede encontrar un solo pas relacionado con la misma. Hilando fino, este es un caso un poco ms complejo que el anterior, porque si bien la tabla extendida del for each principal no tiene interseccin con la tabla base del anidado (ext(COUNTRY) INVOICE = ), sin embargo s existe una relacin 1-N indirecta, y GeneXus la encuentra. En este caso, la tabla base del for each principal est incluida en la extendida del anidado (COUNTRY ext(INVOICE)), por lo que hay una relacin 1-N indirecta. Por este motivo, no necesitamos especificar clusula where en el for each interno para filtrar las facturas del pas del for each principal. Esto puede verse claramente en el listado de navegacin, que mostrar el filtro: CountryId = CountryId para el segundo for each, pero esta vez como Constraint dado que no puede optimizar la recorrida. Puede probar el lector este caso en GeneXus y estudiar detenidamente el listado de navegacin resultante.

220

Caso 2: Producto Cartesiano


Distintas tablas base, pero no existe relacin 1N directa ni indirecta entre las mismas. El resultado que obtenemos es el producto cartesiano de dichas tablas: para cada registro de la tabla base del for each principal, se recuperan todos los registros de la tabla base del anidado.
ext(principal) base(anidado) = y base(principal) ext(anidado)

En este caso GeneXus no logra encontrar una relacin 1-N directa o indirecta entre las tablas y por lo tanto no aplica filtros implcitos a los registros del for each anidado, vale decir, realiza un producto cartesiano entre las tablas. El caso se da cuando: ext(for each principal) base(for each anidado) = base(for each principal) ext(for each anidado) y

Para cada registro de la tabla base del for each principal se recorre toda la tabla base del for each anidado. Por ejemplo, si la tabla base de un for each fuera COUNTRY y la del anidado PRODUCT, evidentemente no existir relacin y se har un producto cartesiano y se recorrer para cada pas, todos los productos. Por supuesto que el programador podr establecer filtros sobre los datos a recuperar, pero stos ya no sern condiciones implcitas inferidas por GeneXus, sino especificadas explcitamente por el programador.

221

Caso 3: Corte de Control


Ejemplo: Para cada cliente que tiene facturas, listar sus facturas.

En el ejemplo que habamos visto antes, del listado de clientes y sus facturas, qu ocurre si un cliente no tiene facturas? Como la tabla base del for each principal es CUSTOMER, el cliente sale impreso antes de saberse si tiene o no facturas. Si no deseamos que esto ocurra, es decir, que salgan listados clientes que no tengan facturas, entonces la solucin es acceder nicamente a las facturas, pues si un cliente est en esta tabla, es porque est en una factura!. Pero para poder agrupar las facturas por cliente, de forma tal de poder desplegarlas de ese modo, debemos recorrer la tabla INVOICE ordenada por CustomerId. De esta forma procesaremos la informacin de un cliente, y luego pasaremos al siguiente, para procesar su informacin, y as sucesivamente. Si imaginamos un puntero que se va desplazando secuencialmente por la tabla INVOICE, podemos escribir el pseudocdigo de nuestro reporte como sigue: 1. Para el registro apuntado, retener el valor del atributo de corte o agrupamiento, CustomerId. 2. Acceder a la tabla CUSTOMER (que est en la extendida de INVOICE) para recuperar el CustomerName e imprimirlo junto con el CustomerId (print customer) 3. Mientras el valor de CustomerId del registro apuntado coincida con el valor retenido en el paso 1 (aqu se procesan todas las facturas del cliente) a. Imprimir InvoiceId, InvoiceDate e InvoiceTotal del registro apuntado. (print invoice) b. Avanzar el puntero al siguiente registro y volver al paso 3. 4. Volver al paso 1. (cuando se lleg a este punto, es o bien porque se lleg al fin de tabla o bien se cambi de cliente).

222

Caso 3: Corte de Control


Ejemplo: Para cada cliente que tiene facturas, listar sus facturas. Source

for each order CustomerId defined by InvoiceDate print customer for each print invoices endfor endfor

orden determina el criterio de corte


Cada vez que cambia el cliente se define un nuevo grupo

Se utiliz defined by para que la tabla base fuera INVOICE y no CUSTOMER y as implementar corte de control y no join. Layout

GeneXus brinda una forma de implementar lo anterior de una forma absolutamente sencilla. El pseudocdigo visto en la pgina anterior se implementa en GeneXus con el par de for eachs anidados que se muestran arriba. Si se compara este cdigo con el que vimos unas pginas atrs para el caso de join, vemos que existen solamente dos diferencias: la clusula order que aparece en este cdigo, en conjuncin con el defined by. Con solo esos dos cambios al listado original, cambiamos radicalmente el comportamiento, puesto que en este caso solamente se listarn los clientes si tienen facturas. En este caso, ambas clusulas (order y defined by) son indispensables para que este reporte funcione del modo que queremos. Si agregamos solo una de ellas, pero no la otra, el resultado ser otro. No en toda implementacin de un corte de control deber especificarse una clusula defined by en el for each principal, mas s una clusula order. La clusula order es indispensable, porque es la que especifica por qu atributo o conjunto de atributos se realizar el corte (o agrupamiento). Es decir, especifica esa informacin comn al grupo, que se procesar una sola vez (dentro el cdigo del for each externo). La clusula defined by no es indispensable en todos lo casos. En este s lo fue, porque de no especificarla, GeneXus determinara como tabla base del for each principal CUSTOMER, que no es lo que queremos (pues no queremos implementar un join, cosa que ya hicimos antes, sino un corte de control, para solo recorrer la tabla INVOICE). Pero tambin podramos haber utilizado otra solucin para modificar la tabla base del for each principal: utilizar en vez del defined by el comando print if detail dentro del cuerpo del primer for each (este comando le dice a GeneXus que tome como tabla base del for each, la que determine para el anidado).

223

Caso 3: Corte de Control


Condiciones que deben cumplirse para implementar Cortes de Control: 1. for each anidados 2. Tienen la misma tabla base 3. Cuntos for each? Uno ms que la cantidad de cortes 4. Debemos establecer en la clusula order de cada for each externo, el atributo o conjunto de atributos por los que queremos cortar.

Un corte de control es bien simple de implementar y puede hacerse siguiendo las consideraciones anteriores. En el order del for each ms externo, debemos mencionar el primer atributo de corte, en el order del segundo for each debemos mencionar el segundo atributo de corte, y as sucesivamente. No es obligacin mencionar atributo/s en el order del for each ms interno (en todos los dems for each s lo es). Corresponde al caso en el que nos interesa trabajar con la informacin de una tabla, pero agrupada por algn atributo o conjunto de atributos. Los cortes de control pueden ser simples, dobles, triples, etc. A continuacin veremos un ejemplo de un corte de control doble.

224

Ejemplo: Corte de control doble Supongamos que queremos como antes listar los clientes y sus facturas, pero queremos agrupar las facturas de cada cliente por fecha. Es decir, queremos mostrar, para cada cliente, para cada fecha, las facturas existentes. Ejemplo: Customer: 1 Juan Prez Date: 12/05/05 Invoice Total 1 15 Date: 01/01/06 Invoice Total 9 35 3 30 Customer: 3 Mara Donoso Date: 06/06/05 Invoice Total 2 20 Date: 12/08/05 Invoice Total 4 40 8 15 Date: 02/02/06 Invoice Total 7 20 Como ahora queremos agrupar por cliente, y dentro de ese grupo por fecha de factura, necesitamos tres for eachs anidados: For each order CustomerId defined by InvoiceDate print customer for each order InvoiceDate print date for each print invoice endfor endfor endfor Como ejercicio, sigamos todos los pasos que realiza GeneXus para inferir el comportamiento del reporte. 1. Determinacin de la tabla base de cada for each Como siempre, para determinar las tablas base de for eachs anidados, se empieza de afuera hacia adentro, determinando la de cada for each, sin tomar en cuenta los atributos de los for eachs internos al que se est considerando.

for each order CustomerId defined by InvoiceDate print customer for each order InvoiceDate print date for each print invoice endfor endfor endfor

Tabla base 1er. for each Solo intervienen los atributos de los lugares sealados en negrita. Mnima tabla extendida que los contiene: ext(INVOICE)

225

for each order CustomerId defined by InvoiceDate print customer for each order InvoiceDate print date for each print invoice endfor endfor endfor

Tabla base 2do. for each Intervienen los atributos de los lugares sealados en negrita y como todos ellos estn incluidos en la extendida del 1er. for each, entonces se determina la misma tabla base: INVOICE

for each order CustomerId defined by InvoiceDate print customer for each order InvoiceDate print date for each print invoice endfor endfor endfor

Tabla base 3er. for each Intervienen los atributos de los lugares sealados en negrita y como todos ellos estn incluidos en la extendida del 2do. for each, entonces se determina la misma tabla base: INVOICE

2. Determinacin de la navegacin Luego de determinadas las tablas base, GeneXus determina la navegacin. Como en este caso son tres for eachs sobre la misma tabla base, se trata de un doble corte de control. Podemos pensar que cuando hablamos de corte de control, ya sea simple, doble, triple, cudruple, etc., tenemos un solo puntero, que se utiliza para avanzar en los registros de la tabla base. Recordemos que la clusula order es fundamental para establecer el criterio de corte en cada par de for eachs. Como en nuestro caso queremos agrupar por CustomerId y luego, para todas las facturas con ese cliente, agrupar por InvoiceDate, entonces tendremos que ordenar el primer for each por CustomerId y el inmediatamente anidado por InvoiceDate. En el ejemplo estamos diciendo que: Mientras no se alcance el fin de tabla Imprimir los datos del cliente de la factura actual Mientras no cambie el cliente Imprimir la fecha de la factura actual Mientras no cambie la fecha Imprimir los datos de la factura actual (nro y total) Avanzar el puntero al siguiente registro Recomendamos al lector implementar en GeneXus este reporte y observar detenidamente el listado de navegacin. Ver que GeneXus elige un nico orden, para el que no tiene un ndice creado: el compuesto por la concatenacin de los rdenes de cada for each con clusula order. Esto resulta evidente si pensamos en trminos de un nico puntero que se va desplazando por la tabla base.

226

Resumen: Determinacin general de las tablas base


Se procede en forma ordenada, determinando cada vez la tabla base de un nivel de anidacin, yendo de afuera hacia adentro: primero se determina la tabla base del for each ms externo, luego del que est anidado a ste y as sucesivamente. Determinacin tabla base del for each externo Se determina a partir de los atributos que aparecen dentro de ese for each: clusulas order, where, defined by y cuerpo del for each, exceptuando los atributos que estn dentro del for each anidado. No participan los atributos que estn dentro del when none, en caso de que el for each principal tenga esta clusula. Al igual que en el caso de un for each simple, se encuentra la mnima tabla extendida que contenga los atributos mencionados. Determinacin tabla base del for each anidado Podemos vernos tentados a pensar que por analoga lo que se debera hacer es extraer los atributos del for each anidado, y hacer lo mismo que antes, es decir, encontrar la mnima tabla extendida que contenga a esos atributos, como si se tratase de un for each independiente. Pero no son for eachs independientes! Para el for each anidado, GeneXus se fija primeramente si los atributos utilizados dentro del cuerpo del mismo estn incluidos o no dentro de la tabla extendida previamente determinada. En caso afirmativo, GeneXus determina que la tabla base del for each anidado ser la misma que la del for each principal (y ser un caso de corte de control). En caso contrario, s se determina como si fueran independientes: busca la mnima tabla extendida que contenga a todos los atributos del for each anidado1.

Esquema general de determinacin de la tabla base de un for each anidado. Presentamos a continuacin un esquema con notacin matemtica, que pretende mostrar grficamente lo que hemos dicho por escrito en los prrafos anteriores acerca de cmo se determina la tabla base del for each anidado.

En la siguiente pgina mostramos otro esquema, pero esta vez con los casos de for eachs anidados de acuerdo a las tablas base encontradas.

---------------------------------------------------------------------------------------------------------1 Existe alguna excepcin, pero no entraremos aqu en este tema.

227

Esquema de casos Luego de determinadas las tablas base de los for eachs anidados, el siguiente paso que realiza GeneXus es determinar la lgica que se asociar a los mismos. Esa lgica viene determinada de acuerdo al caso (join, producto cartesiano o corte de control) en el que caigan los for eachs anidados bajo anlisis. Un esquema de los casos puede verse ms claramente con el diagrama de flujo que se muestra a continuacin:

228

Comandos de control
if cond bloque1 [else bloque2] endif do while cond bloque enddo do case case cond1 bloque1 [case cond2 bloque2] ...... [case condn bloquen] otherwise bloquen+1 endcase

for &var=inicio to fin [step salto] bloque endfor for &var in &array bloque endfor

Los comandos introducidos son similares a los existentes en los lenguajes de programacin imperativa conocidos, por lo que no incluimos documentacin de este tema. Puede encontrarla en el curso no presencial o en el Help de GeneXus. Los dos ltimos, no obstante, incorporan algunos elementos interesantes sobre el manejo de arrays y de colecciones1 en GeneXus, por lo que mostraremos algunos ejemplos. For to step: inicio, fin son expresiones numricas salto es una constante numrica var es alguna variable numrica bloque es una sucesin de comandos vlidos del lenguaje Permite iterar una cierta cantidad de veces: desde el valor inicio que toma la variable &var cuando se ingresa al bucle, hasta el valor fin que tomar la misma luego de cierta cantidad de iteraciones. De iteracin en iteracin la variable &var se va incrementando automticamente en una cantidad igual a salto. El valor por defecto de salto es 1, por lo que si no se especifica la clusula step el incremento de la variable ser de uno en uno. El valor de salto puede ser negativo y en ese caso se ir decrementando la variable de iteracin en iteracin. Ejemplo For &i = 1 to 5 &ok = PInvoicing.udp( &month ) endfor

---------------------------------------------------------------------------------------------------------1 Las colecciones representan listas de largo variable. Se vern cuando estudiemos el tipo de datos estructurado (SDT).

229

For in array: array es un vector o matriz (variable de una o ms dimensiones). Tambin puede ser una variable SDT collection (este tema se estudiar ms adelante) var es una variable que debe tener el mismo tipo de datos que array o compatible (en caso de tratarse de un SDT, deber ser un SDT correspondiente a los tems) Esta estructura de programacin permite recorrer con menos cdigo una variable array de una o ms dimensiones. Se almacena en la variable &var los valores de cada posicin del array. Para el caso de arrays de una dimensin, es equivalente a: &x = 1 do while &x <= rows(&array()) &var = &Array(&x) bloque &x += 1 enddo En el caso de dos dimensiones el comando es equivalente a: &x = 1 do while &x <= rows( &array() ) &y = 1 do while &y <= cols( &array() ) &var = &array( &x, &y ) bloque &y += 1 enddo &x += 1 enddo Consideraciones: No es posible modificar los valores del array en la recorrida. Esto significa que cambios en el valor de &var en el alcance de la estructura, no afectan al correspondiente valor del &array(&x) (o de &array(&x, &y)) No es posible obtener la posicin del array durante la recorrida, para esto es necesario definir una variable que acte como contador Ejemplo For &i= 1 to 4 For &j=1 to 3 &array(&i,&j) = &i + &j endfor endfor

230

Comandos de impresin
Print
Se utiliza para imprimir en la salida un print block definido en el Layout Sintaxis: Print nombrePrintBlock

Header
Se utiliza para definir lo que se quiere imprimir como encabezado de cada pgina del listado Sintaxis: Header bloque end

Footer
Define las lneas de pie de pgina a ser impresas al final de cada pgina del reporte. Sintaxis: Footer bloque end

Aqu veremos algunos comandos de impresin, que permiten disear la salida del reporte. Print donde nombrePrintBlock es el identificador de un print block del Layout. Si no existe en el Layout un print block con ese nombre, al intentar salvar el objeto se desplegar un mensaje de error informando sobre esta situacin. De esta forma se implementa la impresin en la salida de los print blocks del Layout. Cuando el print block que se quiere imprimir no contiene atributos, entonces este comando se puede utilizar en cualquier lugar del Source. Los atributos indican acceso a la base de datos y este acceso no puede realizarse en cualquier lado, sino nicamente dentro del comando especfico para ello, esto es, el comando for each. Por tanto no es correcto escribir el comando print fuera de un for each si el print block que se est queriendo imprimir contiene atributos. La nica excepcin a esta regla se produce cuando los atributos del print block estn incluidos entre los parmetros recibidos por el reporte, pues en este caso no es necesario acceder a la base de datos para recuperar sus valores, dado que ya vienen instanciados. Header Aqu se define lo que se quiere imprimir como encabezado de cada pgina del listado. Este encabezado es opcional. Si no se especifica, entonces las pginas del listado no tendrn encabezado. Ejemplo: En el reporte en el que queramos imprimir un listado con el cdigo, nombre y pas de cada uno de los clientes de nuestro sistema, si queremos que en cada pgina del listado aparezca el encabezado: CUSTOMERS REPORT, entonces alcanza con escribir en el Source: Header Print title End Donde title es el nombre de un print block del Layout que contiene este texto.

231

Tambin podramos haber escrito directamente: Print title al comienzo del Source, pero en este caso, si el listado tiene varias pginas, solo saldr impreso este texto en la primera. En el otro caso, saldr en cada una de las pginas, como encabezado. Footer Define las lneas de pie de pgina a ser impresas al final de cada pgina del reporte. Los comandos del bloque de cdigo son ejecutados cuando se llega al final de una pgina. Ejemplo: Footer print endOfPageText end

donde endOfPageText es el nombre de un print block del Layout

232

Diseo de la salida
Existen algunos comandos para disear la salida del reporte. Presentamos aqu algunos a los efectos de la documentacin.

MT nline: nline es el nmero de lnea en el que se quiere empezar a imprimir el listado. En caso de no especificarse un valor se asume el valor por defecto que es 0. MB nline: nlneas es el nmero de lneas que se desea dejar como margen inferior. En caso de no especificarse un valor se asume el valor por defecto que es 6. PL nline: Setea el largo de pgina. El nmero de lneas que ser impreso es el nmero especificado menos el margen de abajo (valor por defecto es 6). Ej: PL 66 Setea el largo de pgina a 66 lneas, aunque slo 60 lneas sern impresas en el form, con un margen inferior de 6 lneas. CP nlines: Si queda en la pgina actual un nmero de lneas mayor o igual al nmero especificado, contina imprimiendo en la misma pgina. De lo contrario, pasa a imprimir en la prxima pgina (fuerza a un salto de pgina). Lineno nline: Define el nmero de lnea donde va a ser impresa la siguiente lnea. Si el nmero de lnea actual es mayor al nmero especificado, entonces, la lnea ser impresa en la prxima pgina. El conteo de lneas comienza en la lnea 0. Eject: Fuerza a un salto de pgina. Noskip: Tiene que estar inmediatamente despus de un print block. Si el comando se encuentra entre dos lneas, este comando las imprimir en la misma lnea.

233

Reportes PDF
Configurar las propiedades:
Main Program = True Call Protocol = HTTP Report Output = Only to file

Regla
output_file( xx.pdf, PDF)

En Web los reportes solamente pueden ser PDF y se deben configurar las propiedades y regla anteriores para que funcionen. Definicin de un objeto como main Al definir que un objeto es main (en este caso un reporte, pero podra ser una transaccin, web panel, etc.), GeneXus genera un programa ejecutable con la lgica del objeto mismo y la de todos los objetos invocados directa o indirectamente por l. El programa ejecutable generado se podr compilar y ejecutar de forma independiente, es decir, al seleccionar Build / Run se ver como programa independiente del Developer Menu y podr compilarse y ejecutarse. La definicin de un objeto como main se realiza editando las propiedades del objeto, y configurando la propiedad Main program del mismo con valor True.

234

Condiciones
Permiten especificar condiciones globales que debern cumplir los datos a ser recuperados.
Ejemplo:

En esta seccin se permiten establecer condiciones que deben cumplir los datos para ser recuperados. Una condicin es equivalente a la clusula where del comando for each (incluso tiene la misma sintaxis) con una salvedad: mientras que la clusula where est ligada a un for each especfico: aquel al que pertenece, las condiciones estn ligadas a todos los for eachs del Source en los que tenga sentido aplicarlas. Y para qu for eachs tiene sentido aplicarlas? Las condiciones generalmente involucran atributos. Si en la tabla extendida de un for each se encuentran los atributos que intervienen en una condicin, entonces la misma se aplicar a este for each para filtrar los datos quedndose nicamente con aquellos que satisfagan tal condicin. En el listado de navegacin del reporte se indican los for eachs a los que se aplica cada condicin de las especificadas en la seccin Conditions. Si en el Source del reporte PrintCustomers tenemos: For each Print customer endfor Entonces al especificar las condiciones que se muestran en la transparencia, estaremos filtrando los clientes, de acuerdo a las condiciones (es equivalente a tener las condiciones como where).

235

Condiciones
Si el Source del reporte es:

For each Print customer Endfor For each Print invoice Endfor For each Print product Endfor

For each where CustomerName>=&start Print customer Endfor For each where CustomerName>=&start where InvoiceId < 100 Print invoice Endfor For each Print product Endfor
Conditions: CustomerName >= &Start;

InvoiceId < 100;

donde: customer es un print block que contiene los atributos CustomerId, CustomerName, CountryName invoice es un print block que contiene los atributos InvoiceId, CustomerId, CustomerName, InvoiceDate, InvoiceTotal product es un print block que contiene los atributos ProductId, ProductDescription, ProductStock Si el reporte anterior tiene definidas las condiciones mostradas arriba, el reporte ser equivalente a uno sin condiciones y con el Source que se muestra a la derecha. Observemos que en este caso las condiciones se traducen en clusulas where pero que se aplican solo a los for eachs para los que tiene sentido aplicarlas. En la tabla extendida del ltimo for each no se trabaja con nombre de cliente, ni con identificador de factura. No tiene sentido aplicar las condiciones en este for each ya que no existe ninguna relacin. En el primero, solo tiene sentido aplicar la que involucra a CustomerName y no la otra. Observacin Los atributos involucrados en las condiciones no participarn en la determinacin de las tablas base de los for eachs del Source (a diferencia de los filtros que se especifican mediante clusulas where). Es decir, las tablas base de los for eachs que aparezcan en el Source se determinan sin mirar las condiciones. Una vez determinadas, recin en ese momento las condiciones son examinadas para determinar a cules for eachs se aplicarn y a cules no. Lo mismo ocurre con los atributos que se reciban como parmetro. Aplicarn como filtro global por igualdad para los for eachs en los que tenga sentido, pero no participarn en la determinacin de las tablas base.

236

Filtros en la navegacin
Formas de filtrar los datos: Clusulas Where Condiciones
Participan en determinacin de tabla base

NO participan en determinacin de tabla base

Regla Parm (Atributos recibidos como parmetros) Parm(Att1 ... Attn)

Resumimos aqu las distintas formas de filtrar en un reporte o procedimiento la informacin a recuperar de la base de datos: a. clusulas where b. Condiciones c. parm( att, ..., att ) Estudiemos las diferencias y similitudes entre ellas. 1. Las clusulas where aplican exclusivamente al for each en el que se encuentran, mientras que los filtros especificados como condiciones o los que quedan determinados por los atributos en la regla parm son globales, es decir, aplicarn a todos los for eachs del Source en los que tenga sentido aplicarlos. 2. Los filtros que quedan determinados al recibir en atributos en la regla parm son filtros por igualdad, es decir, para los for eachs en los que tenga sentido aplicarlos, se instanciarn nicamente los registros que tengan el mismo valor que el recibido por parmetro. En cambio, los filtros especificados en las clusulas where de un for each o en las condiciones pueden ser expresiones booleanas cualesquiera, incluso compuestas. 3. Mientras que los atributos que aparecen en las clusulas where participan en la determinacin de la tabla base del for each donde se encuentran, los que aparecen en las condiciones o en la regla parm no lo hacen. Recin entran en juego LUEGO de determinadas las tablas base de los for eachs del Source.

237

PROCEDIMIENTOS

Actualizacin de la base de datos

Los procedimientos definen procesos no interactivos (batch) de consulta y/o actualizacin de la informacin de la base de datos. En lo anterior estudiamos los reportes y mencionamos que la mayora de las caractersticas y conceptos introducidos eran comunes a los procedimientos. Aqu nos abocaremos a profundizar en los comandos que son especficos para este tipo de objetos, es decir, aquellos que tienen que ver con la actualizacin de la base de datos. Dijimos que los procedimientos eran un superset de los reportes, en el entendido de que todo lo que se realiza con un reporte puede realizarse con un procedimiento, pero en cambio no se cumple el recproco, es decir, no todo lo que se realiza con un procedimiento puede realizarse con un reporte1. En este captulo estudiaremos ese plus que es lo que diferencia a ambos tipos de objetos y que viene dado por la posibilidad que tienen los procedimientos de actualizar la base de datos. Estudiaremos entonces cmo se dan las altas, bajas y modificaciones en la base de datos utilizando procedimientos. La pantalla de edicin de procedimientos es idntica a la de reportes.

---------------------------------------------------------------------------------------------------------1 A menos que se utilicen business components para hacer actualizaciones a la base de datos, como veremos cuando estudiemos este tema.

238

Actualizacin
No hay un comando especfico de actualizacin: se realiza en forma implcita dentro del comando for each. Ejemplo: Transaccin Product ProductId* ProductDescription ProductStock (ProductDate* ProductPrice) Procedimiento PriceIncrease Reglas: Parm( &Inf ); Source: for each where ProductDate = &Today ProductPrice = ProductPrice* (1+&inf/100) endfor

La modificacin de datos de la base de datos se realiza en forma implcita, ya que no hay un comando especfico de actualizacin. Para actualizar uno o varios atributos de una tabla se utiliza el comando for each, y dentro del mismo el comando de asignacin. Supongamos que queremos tener un proceso batch que actualice para todos los productos almacenados que tengan el precio fijado para el da de hoy, el atributo ProductPrice para adecuarlo segn el porcentaje de inflacin. La tabla base del for each ser PRODUCTLINE y estamos asignando valor a un atributo de la misma, para todos los registros. Se pueden actualizar varios atributos dentro del mismo for each, pudiendo stos pertenecer tanto a la propia tabla base como a la tabla extendida.

239

Actualizacin
Atributos actualizables: los pertenecientes a la tabla extendida del for each. Salvo:
los que forman parte de la clave primaria de la tabla base del for each. los que forman parte del ndice por el que se est accediendo a dicha tabla.

La actualizacin se realiza en el endfor.

Supongamos que tenemos el siguiente diagrama de Bachman genrico:

A* B C D
for each C = &C E = &E D = &D endfor

B* E F

Y en el Source de un procedimiento hacemos:

Aqu la tabla base del for each ser claramente la de clave primaria A y dentro del for each estamos actualizando tanto atributos de la propia tabla base como de la extendida. En qu momento ocurre efectivamente la actualizacin de los registros involucrados? Al final de cada iteracin del for each se actualiza el registro de la tabla base y el/los registro/s de la extendida que deban ser actualizados. Es decir, la actualizacin no ocurre ni bien se encuentra un comando de asignacin dentro del for each, sino luego de que se encuentran todos, para cada instancia de la tabla base, es decir, cuando se llega al endfor para cada iteracin.

240

Actualizacin
Claves candidatas: ndices unique Se utiliza clusula when duplicate en el for each for each ... bloque1 [when duplicate ...] endfor

Como vimos antes, no podemos actualizar dentro del comando for each atributos de la clave primaria. Sin embargo podramos querer actualizar un atributo que sin ser clave primaria, est definido como clave candidata (mediante un ndice unique). Si el atributo es clave candidata, debe controlarse que no se dupliquen sus valores, por lo que de encontrarse duplicado el registro en este sentido, no se permitir hacer la actualizacin. Si se desea tomar una accin en caso de que esto ocurra, el comando for each agrega la clusula when duplicate. Solo tiene sentido si existe alguna clave candidata para ese for each.

241

Eliminacin
Comando Delete Debe ir dentro de un for each Elimina el registro de la tabla base en el que se est posicionado Se ejecuta ni bien se encuentra el comando (y no en el endfor) Ejemplo: for each defined by InvoiceDate Delete endfor
Borra todos los registros de la tabla base: INVOICE

Para eliminar datos se utiliza el comando Delete dentro del comando for each. El comando Delete elimina el registro en el que se est posicionado en un momento dado. Es por ello que no puede aparecer suelto dentro del Source. Debe colocarse dentro de un comando for each, cuya tabla base sea la tabla de la que se quieren eliminar registros. Solo se eliminan los registros de la tabla base, no de la extendida. Si deseamos eliminar todas las facturas anteriores a una fecha dada, podemos programar un procedimiento: for each where InvoiceDate <=&date for each defined by InvoiceLineQuantity DELETE //se eliminan las lneas endfor DELETE //luego de eliminar las lneas se elimina el cabezal endfor

242

Insercin de registros
Comando New: permite insertar un registro en una tabla Ejemplo:
Transaccin Product ProductId* ProductDescription ProductStock (ProductDate* ProductPrice) Procedimiento NewPrice Rules: Parm( &ProductId, &price ); Source: New ProductId = &ProductId ProductDate = &Today ProductPrice = &price endnew

Supongamos que queremos implementar un procedimiento que haga lo siguiente: para el producto cuyo cdigo es recibido por parmetro, d de alta un nuevo precio (tambin recibido por parmetro) en su lista de precios, para la fecha correspondiente al da en que se ejecuta el procedimiento. El procedimiento debe crear un nuevo registro en la tabla PRODUCTLINE, que est compuesta por los atributos ProductId, ProductDate y ProductPrice, siendo su clave primaria una compuesta, conformada por ProductId y ProductDate. Para ello se utiliza el comando new que escribimos arriba. Observemos que dentro del mismo aparecen comandos de asignacin, donde se le da valor a los atributos de la tabla en la que se quiere insertar el registro. En este caso queremos insertar un registro en la tabla PRODUCTLINE y le especificamos mediante asignaciones el valor que queremos que tomen los atributos de dicha tabla para ese registro. Cmo entiende GeneXus que la tabla en la que queremos insertar el registro es PRODUCTLINE, si no la mencionamos? Cada vez que GeneXus encuentra un new, debe determinar la tabla en la que se realizar la insercin (tabla base del new). Esta tabla es determinada a partir de los atributos que aparecen dentro del comando new, del lado izquierdo en una asignacin. En el ejemplo, son tres los atributos que aparecen dentro del new del lado izquierdo de un comando de asignacin.

243

Insercin de registros
El comando new realiza el control de duplicados (clave primaria y claves candidatas)
Ejemplo (cont.) En caso de que exista un precio para ese producto y esa fecha, queremos cambiar ese precio New ProductId = &ProductId ProductDate = &Today ProductPrice = &price When duplicate for each ProductPrice = &price endfor endnew

Solo se insertar uno, pues el comando new realiza el control de duplicados. Es decir, al intentar insertar un nuevo registro, se controla previamente que ya no exista uno en la tabla con el mismo valor en la clave primaria que el que se est intentando insertar. De existir claves candidatas (definidas mediante ndices unique) tambin se controlarn. El comando new cuenta con una clusula opcional: la clusula when duplicate. Con ella se programa la accin a realizar en caso de encontrarse duplicado el registro. Por ejemplo, supongamos que en caso de que el producto ya tenga en su lista de precios una entrada correspondiente a la fecha de hoy, entonces en tal caso queremos cambiar ese precio. Para ello agregamos al comando new la clusula when duplicate. Aqu estamos actualizando el valor del atributo ProductPrice en caso que el registro se encuentre duplicado. Es decir, si ya existe un registro en la tabla con los valores de &ProductId y &Today en su clave primaria, entonces para ese registro se actualiza el precio. Observemos que para realizar la actualizacin del atributo, la asignacin debe estar dentro de un comando for each. Si no colocamos el for each no se realizar la actualizacin del precio para ese registro, es decir, es como si no se hubiera incluido clusula when duplicate. Como hemos visto, para actualizar la base de datos se emplea el comando for each, y por tanto aqu simplemente se uniformiza el comportamiento, de manera tal que siempre que se pretenda actualizar la base de datos va comando, se har con un for each (a excepcin del uso de business components, que veremos ms adelante en el curso).

244

Insercin de registros
Sintaxis del new: new [Defined by att1,, attN] bloque_asignaciones1 [when duplicate for each bloque_asignaciones2 endfor] endnew

La insercin de datos en la base de datos utilizando procedimientos se realiza exclusivamente con el comando new, que permite dar de alta un registro en una tabla de la base de datos. En la sintaxis presentada, bloque_asignaciones1 es un bloque de cdigo compuesto mayormente por sucesivos comandos de asignacin (aqu se asigna valor a los atributos de la tabla en la que se insertar el registro, aunque tambin pueden asignarse valores a variables). La clusula Defined By opcional, se incorpora a los mismos efectos que lo haca para el comando for each: ayudar a determinar la tabla base. El comando new realiza un control de duplicados, de manera tal que no se permitir insertar un registro que ya exista en la tabla. La clusula when duplicate del comando permite programar la accin en caso de que el registro ya exista en la tabla base (tanto por clave primaria como por clave candidata). Normalmente, de ocurrir lo anterior, se quiere actualizar algunos de los atributos de dicho registro. Para ello, en bloque_asignaciones2 se realizan tales asignaciones, pero como lo que se hace es actualizar un registro (y no insertar uno nuevo), estas asignaciones aparecen rodeadas de for each endfor, pues como hemos visto, las actualizaciones solo pueden realizarse dentro de un for each. De no especificarse clusula when duplicate para un new, si el registro que quiere insertarse se encuentra duplicado no se realizar accin alguna y la ejecucin continuar en el comando siguiente. Es decir, como no puede insertar el registro porque ya existe uno, no hace nada y sigue adelante, con el prximo comando.

245

Insercin de registros
Determinacin tabla base del new: De existir, se consideran los atributos que se especifiquen en la clusula Defined by. Se consideran todos los atributos que aparezcan en bloque_asingaciones1 a la izquierda en comando de asignacin. Estos atributos deben pertenecer a una misma tabla fsica tabla base

La tabla fsica en la que se insertar el registro del new (tabla base del new) se determina a partir de los atributos que aparecen en bloque_asignaciones1 del lado izquierdo del comando de asignacin. Al igual que en el comando for each, se incluye la clusula Defined by para agregar ms elementos que permitan determinar la tabla base. Es decir, la tabla base del new ser aquella en la que se encuentren fsicamente almacenados los atributos att1,, attN que figuran en la clusula Defined by, junto con los que aparezcan en el bloque de asignaciones, del lado izquierdo. Observar que marcamos en negrita fsicamente almacenados y esto introduce una diferencia importante con respecto al comando for each: aqu, tanto los atributos del Defined by como los que se encuentren en asignaciones del lado izquierdo, debern pertenecer a la tabla base (no a la extendida). Es ms restrictivo, puesto que con el comando new estamos insertando un nico registro en una sola tabla de la base de datos. GeneXus buscar una tabla fsica que contenga a todos estos atributos. De no existir tal tabla, al especificar el procedimiento se desplegar un error en el listado de navegacin informando de esta situacin y el objeto no ser generado.

246

Insercin de registros
Determinacin tabla base del new:

A* B F

B* C

Es correcto? Cul ser el comportamiento?

New A = &A B = &B C = &C endnew

No!: no existe una tabla fsica que incluya los atributos A, B y C. El New solo permite insertar UN REGISTRO en UNA TABLA.

El ejemplo pretende dejar claro a qu nos referimos con tabla fsica, en contraposicin a tabla extendida. Mientras que en el caso de la determinacin de la tabla base del for each los atributos deban pertenecer a una misma tabla extendida, en el New es ms restrictivo: deben pertenecer a una misma tabla fsica.

247

Insercin de registros
Atributos asignados en el new
No es necesario asignar valor a todos y cada uno de los atributos de dicha tabla. Algunos atributos vienen instanciados por el contexto del new y no es necesario asignarles valor para el registro a insertar. Contexto:
parmetros atributo new anidado a un for each new anidado a un new

New siempre se ejecuta por la clave primaria.

Una vez que GeneXus determin la tabla del new, los atributos pertenecientes a la misma y no asignados explcitamente dentro de este comando tomarn como valor: Para aquellos que estn instanciados en el contexto donde se encuentra el new, tomarn los valores correspondientes al contexto. Para los que no estn instanciados en el contexto, tomarn el valor nulo (o empty, dependiendo de la propiedad Empty As Null en conjuncin con la Nulls). Atributos instanciados en el contexto: Atributos recibidos por parmetro Si los atributos no asignados explcitamente en el new son recibidos en la regla parm, entonces para el registro a ser insertado toman el valor que viene en el parmetro. New anidado a un for each El new es un comando como otros, por lo que puede aparecer anidado a un for each (es el caso en el que se quiere navegar determinada tabla, y para cada registro que cumpla determinadas condiciones dar de alta un registro en otra tabla que puede tambin ser la misma. Veremos un ejemplo a continuacin). En este caso, todos los atributos de la tabla del new que no estn asignados explcitamente y que estn instanciados en el for each que contiene al new, tomarn el valor que tienen en la instancia del for each para el registro a ser insertado. New anidado a otro new Dentro del comando new puede aparecer otro new sobre la misma o distinta tabla. Los atributos del new anidado que no estn asignados explcitamente y que estn en el principal tomarn sus valores del mismo.

248

Insercin de registros
New anidado a un For each, con igual tabla base.
MedicalDoctor MDoctorId* MDoctorName MDoctorAddress MDoctorPhone ConsultationHour MDoctorId* ConsultationDate* ConsultationShift* ConsultationOfficeNbr
Date Shift M.Doctors office

Procedimiento que sustituya al mdico &SourceMD (recibido por parmetro) en todas sus consultas, por el mdico &replacementMD

Parm(&SourceMD, &replacementMD);

For each Where MDoctorId = &SourceMD Defined by ConsultationDate new MDoctorId = &replacementMD endnew Delete endfor

Queremos escribir el Source de un procedimiento que sustituya a un mdico por otro para las consultas que el primero tena asignadas. Es decir, debemos recorrer la tabla CONSULTATIONHOUR que es la que representa las consultas asignadas a cada mdico en una fecha y turno determinado, filtrando por el mdico que debemos sustituir, y luego reemplazar a ese mdico por el sustituto para esos registros. Haramos una simple actualizacin de registro, a no ser por el hecho de que el atributo a sustituir es parte de la clave primaria, por lo que no podemos modificarlo. Deberemos, por tanto, crear un nuevo registro con el mdico sustituto, y el resto de los atributos tomarn los valores del registro original. Luego borraremos el registro original, as queda el nuevo registro, con el mdico sustituto. Observemos que dado que el new est anidado al for each, en el contexto del new existirn todos los atributos de la tabla extendida del for each. En este caso, estarn instanciados los atributos de CONSULTATIONHOUR y los de MEDICALDOCTOR, para un registro en particular. Es por ello que en el new solamente asignamos valor al atributo MDoctorId, pues los dems: ConsultationDate, ConsultationShift, ConsultationOfficeNbr estn instanciados y queremos que conserven esos valores. Sin embargo, aqu tenemos un problema. Cul elegir GeneXus como tabla base del new?

249

Insercin de registros
New anidado a un For each, con igual tabla base.
For each Where MDoctorId = &SourceMD Defined by ConsultationDate new MDoctorId = &replacementMD endnew Delete endfor For each Where MDoctorId = &SourceMD Defined by ConsultationDate new defined by ConsultationDate MDoctorId = &replacementMD endnew Delete endfor

Tabla base del new? MEDICALDOCTOR

CONSULTATIONHOUR

En este ejemplo lo que pretendemos mostrar es el cuidado que hay que tener cuando queremos que ciertos atributos de la tabla base del new tomen sus valores del contexto. Es decir, primero tenemos que asegurarnos que por los atributos que figuren dentro del new, quede determinada la tabla base que deseamos, para que a partir de all, s puedan quedar implcitos los atributos del contexto.

250

Restricciones
No se realiza control de integridad referencial. El nico control que se realiza es el de duplicados.

No actualiza atributos definidos como redundantes.

En los procedimientos el nico control de integridad que se realiza automticamente es el control de duplicados. El control de integridad referencial queda a cargo del programador, lo que no ocurre en las transacciones. Por lo tanto, en el ejemplo anterior podramos haber eliminado primero el cabezal, y luego las lneas, sin ningn problema. Incluso podramos haber eliminado solo el cabezal, y estaramos dejando referencias colgadas (las lneas). Por ejemplo, al dar de alta por procedimiento una nueva factura, cuando se da de alta el cabezal no se controla que el valor de CustomerId ingresado exista en la tabla CUSTOMER. Los atributos definidos como redundantes no se actualizan. Un caso particular de ello son las frmulas redundantes. Como en procedimientos no se actualizan, hay que calcularlas y actualizarlas en forma manual. Las frmulas redundantes deben ser mantenidas explcitamente con los comandos de asignacin. Por ejemplo, si en la transaccin "Invoice" tenemos definido el atributo InvoiceTotal como una frmula vertical redundante, siendo: InvoiceTotal = SUM( InvoiceLineAmount ) y por procedimiento damos de alta una o varias lneas, debemos tener en cuenta que no se actualizar el valor almacenado de InvoiceTotal. Habr que actualizarlo explcitamente en el procedimiento, por cada lnea dada de alta.

251

OBJETO WEB PANEL

252

Caractersticas

Permiten definir consultas interactivas a la base de datos. Son flexibles por lo que se prestan para mltiples usos.

Los web panels son objetos GeneXus que permiten al usuario en tiempo de ejecucin, realizar interactivamente consultas a la base de datos a travs de una pantalla. El trmino interactivamente se refiere a que el usuario podr ingresar en la pantalla de un web panel una y otra vez distintos valores de filtros, y consultar a continuacin los datos que concuerden con los mismos. Adems, sobre los datos consultados, el usuario podr realizar distintas acciones, como veremos. Los web panels no permiten la actualizacin de la base de datos, sino slo su consulta1. El objetivo primordial de este objeto GeneXus es la definicin de consultas interactivas a la base de datos, sin embargo se trata de un objeto muy flexible por lo que se presta para diversos usos. En este captulo estudiaremos algunos detalles de este tipo de objeto.

-------------------------------------------------------------------------------------------------------------------A menos que se utilicen en combinacin con los business components (estudiados ms adelante) 253

Elementos
Algunos de ellos son:
Web Form Reglas Condiciones Subrutinas Eventos Propiedades Ayuda Documentacin

Los elementos de los web panels son: Web Form: Cada web panel contiene un form Web, el cual debe ser diseado por el analista agregndole variables, atributos, as como otros controles, para que el usuario pueda interactuar con el mismo. Reglas: Las reglas de un web panel permiten definir ciertos comportamientos puntuales de dicho objeto. Por ejemplo, declarar qu parmetros recibe, definir qu variables no queremos que sean aceptadas en el form sino utilizadas para desplegar informacin, etc. Condiciones: Es para definir las condiciones que deben cumplir los datos a ser recuperados (filtros). Subrutinas: Son rutinas locales al web panel. Eventos: Los web panels emplean la programacin orientada a eventos. Este tipo de programacin permite definir cdigo ocioso, que se activa en respuesta a ciertas acciones provocadas por el usuario o por el sistema. En esta seccin de un web panel es donde se define el cdigo ocioso asociado a los eventos que pueden ocurrir durante la ejecucin del web panel. Propiedades: Son caractersticas a ser configuradas para definir ciertos detalles referentes al comportamiento general del web panel. Ayuda: Permite la inclusin de texto de ayuda, que los usuarios podrn consultar en tiempo de ejecucin del web panel. Documentacin: Permite la inclusin de texto tcnico como documentacin para los desarrolladores.

254

Clasificacin de web panels


Web panels de Entrada Web panels de Salida Web panels Mixtos

Todo web panel tiene un form asociado, y en el mismo, contrariamente al comportamiento del form de una transaccin, los atributos que se incluyan sern de salida, y las variables que se incluyan sern de entrada. Es fcil de comprender que el objetivo del form de un web panel es exactamente el contrario al objetivo del form de una transaccin, ya que: a travs del form de una transaccin se ingresan los valores de los atributos en la base de datos. a travs del form de un web panel, se consultan / recuperan los valores de los atributos de la base de datos. Es por esto que los atributos son de entrada en las transacciones y de salida en los web panels. Y en lo que respecta a las variables, las mismas son de salida en las transacciones y de entrada en los web panels. La siguiente clasificacin describe los distintos usos posibles de los web panels: Web panel de entrada: le damos este nombre a un web panel que tiene la nica funcin de aceptar valores digitados por el usuario (esto significa que su form contendr nicamente variables). Web panel de salida: le damos este nombre a un web panel que tiene la nica funcin de mostrar informacin (esto significa que su form contendr nicamente atributos, pudiendo tambin contener variables a las cuales se les haya cambiado el comportamiento por defecto de ser de entrada, definindolas de salida y cargndoles valores explcitamente). Web panel mixto: le damos este nombre a un web panel que permite tanto ingresar valores como mostrar informacin (en este caso su form contendr tanto variables como atributos, o bien slo variables, algunas con el comportamiento por defecto de ser de entrada y otras definidas explcitamente de salida y cargndoles valores). Vale aclarar que esta clasificacin es independiente de la herramienta; es decir, GeneXus internamente no clasifica a los web panels.

255

Web panel de Entrada

Event Enter

Las variables adquieren el valor digitado luego de presionar algn botn. Event Enter RList.call( &InitialCustomerName, &FinalCustomerName ) endevent

Denominamos web panels de entrada a aquellos web panels cuya nica funcin es que el usuario realice ingresos de valores por medio de los mismos. Por lo tanto, sus forms contendrn solamente variables. Por ejemplo, un web panel de entrada puede contener dos variables &InitialCustomerName y &FinalCustomerName como se muestra arriba. En tiempo de ejecucin, el usuario podr ingresar valores en las variables &InitialCustomerName y &FinalCustomerName dado que en los web panels las variables son por defecto de entrada. En el evento Enter del web panel (asociado al botn Confirm), se invocar a un reporte, al cual se le pasarn por parmetro las variables &InitialCustomerName y &FinalCustomerName para que el reporte liste todos los clientes cuyos nombres se encuentren en el rango solicitado: Event Enter RListCustomerRange.call( &InitialCustomerName, &FinalCustomerName ) EndEvent // Enter De modo que la definicin de este web panel de entrada es para que el usuario ingrese el rango de clientes a listar, y al seleccionar el botn Confirm, se ejecute el reporte correspondiente.

256

Web panel de Salida

tabla base: CUSTOMER

Regla:

parm(in:CustomerId);

Denominamos web panels de salida a aquellos web panels cuya nica funcin es exhibir datos. Para que un web panel nicamente muestre datos, su form debe contener solamente atributos, ya que los atributos en los forms de web panels son indefectiblemente de salida1. Otra posibilidad es incluir en el form variables, pero habr que cambiarles su comportamiento por defecto de ser de entrada, a ser de salida, y cargarles valores explcitamente2. El web panel mostrado arriba ha sido creado para exhibir los datos de un cliente. Se necesita invocarlo desde otro objeto, pasndole por parmetro el cdigo del cliente del cual se quiere mostrar la informacin. Para resolver esto, una vez creado el web panel View Customer Data: se han agregado los atributos que se desean visualizar en su form se ha definido la regla: Parm(in: CustomerId); en la seccin de reglas del objeto Tan slo definiendo esto obtendremos el comportamiento deseado. Qu concluir GeneXus acerca de este web panel, cuando lo especifiquemos? Primeramente GeneXus observar que los atributos incluidos en el form pertenecen a las tablas CUSTOMER y COUNTRY respectivamente. El siguiente diagrama de Bachman explicita la relacin entre ambas tablas:

CUSTOMER

COUNTRY

-------------------------------------------------------------------------------------------------------------------1 Al contrario de lo que sucede con los atributos en las transacciones (salvo los inferidos o los que tienen regla noaccept o propiedad Enabled deshabilitada). 2 El comportamiento por defecto de las variables tambin es opuesto entre Web Panels y Transacciones.

257

Teniendo en cuenta la relacin entre las tablas involucradas, GeneXus descubrir que deber recorrer la tabla CUSTOMER y acceder a la tabla COUNTRY por el concepto de tabla extendida. La tabla COUNTRY no podr ser elegida para ser recorrida porque su tabla extendida no incluye a la tabla CUSTOMER. As es que GeneXus determinar un for each asociado al web panel, en este caso con tabla base CUSTOMER; nosotros no escribimos el for each, pero GeneXus lo infiere automticamente. A su vez, como en la regla parm definida en el web panel se recibe un atributo, el mismo actuar como filtro por condicin de igualdad. Es decir, que al ejecutarse la recorrida de la tabla CUSTOMER (accediendo a la tabla COUNTRY para traer el nombre de pas), se filtrar por el cdigo de cliente recibido por parmetro. Concluyendo, se recorrer la tabla CUSTOMER, con condicin de filtro por el cliente recibido en la regla parm y se mostrarn los datos en la pantalla. El nombre del pas del cliente (CountryName) se inferir por el concepto de tabla extendida y se mostrar tambin en la pantalla. Decimos que este web panel tiene tabla base, y la misma es CUSTOMER. Esto significa que el web panel tiene un for each implcito / automtico asociado, cuya tabla base es CUSTOMER.

258

Web panel de Salida

grid: Se cargan los registros de la base de datos correspondientes en archivo temporal

Regla:

parm(in:CustomerId);

tabla base: INVOICE

Este web panel ha sido creado para mostrar las facturas de determinado cliente. Se necesita desde otro objeto, invocar a ste, pasndole por parmetro el cdigo del cliente del cual se quieren mostrar sus facturas. Para resolver esto, una vez creado el web panel View Customer Invoices: se han agregado los atributos que deseamos visualizar en su form (utilizando el control grid para mostrar las N facturas del cliente en cuestin) se ha definido la regla: Parm(in: CustomerId); en la seccin de reglas del objeto Este web panel, a diferencia del anterior no es plano, pero contina siendo un web panel de salida, ya que lo nico que hace es mostrar datos de la base de datos, sin permitir que el usuario ingrese nada. Cuando se incluye un grid en un form, se est indicando que se va a mostrar una cantidad indefinida de datos (en este caso, facturas). Dado que en este web panel hay involucrados atributos de las tablas CUSTOMER e INVOICE y que la relacin entre ambas tablas es:

INVOICE

CUSTOMER

GeneXus determinar que recorrer la tabla INVOICE y acceder a la tabla CUSTOMER por el concepto de tabla extendida. La tabla CUSTOMER no podr ser elegida para ser recorrida porque en su tabla extendida no se encuentra la tabla INVOICE. De modo que GeneXus determinar un for each implcito asociado al web panel, con tabla base INVOICE, accediendo a la tabla CUSTOMER por el concepto de tabla extendida. Como en la regla parm definida en el web panel, se recibe un atributo, el mismo actuar como filtro por igualdad. Es decir, que al ejecutarse la recorrida a la tabla INVOICE accediendo a la tabla CUSTOMER, se filtrar por el cdigo de cliente recibido por parmetro. Decimos que este web panel tiene tabla base, y la misma es INVOICE. Esto significa que el web panel tiene un for each implcito/automtico asociado, cuya tabla base es INVOICE.

259

Web panel Mixto: Work With


Las variables adquieren el valor digitado luego de presionar algn botn

Event Enter Evento Usuario

Tabla Base: CUSTOMER

generales versus particulares

Los web panels no tienen por qu ser slo de entrada o slo de salida. El web panel que se muestra arriba es de entrada/salida (mixto), su form contiene tanto variables como atributos. La funcionalidad de este web panel es cargar en el grid los datos de todos los clientes cuyos nombres cumplan con la condicin de filtro especificada. La idea es digitar sobre la variable &CustomerName el valor de filtro deseado, y a continuacin presionar el botn Search para que se ejecute la consulta en el servidor y el resultado de la misma sea cargado en la pgina. El evento asociado al botn Search puede ser el Evento Enter (evento del sistema) cualquier evento definido por el usuario (volveremos sobre esto ms adelante). Las condiciones de filtro pueden definirse de dos maneras posibles: A nivel de un grid en particular (botn derecho sobre el grid/Conditions): de hacerlo as, se tratar de condiciones particulares para ese grid (las que se muestran arriba). A nivel de todo el web panel (en la seccin Conditions del objeto): de hacerlo as, se tratar de condiciones globales, es decir que aplicarn a todos los grids del web panel en los que tenga sentido aplicarlas (ms adelante veremos web panels con mltiples grids). En el web panel del ejemplo tenemos un slo grid, por lo cual ambas opciones seran equivalentes desde el punto de vista lgico. Sin embargo es recomendable escribir las condiciones a nivel del grid ya que en un futuro podrn agregarse ms grids al web panel. Adems teniendo las condiciones a nivel del grid se optimiza al momento de la especificacin (ya que en caso contrario, GeneXus deber estudiar para cada grid si aplicar las condiciones generales a ese grid particular o no). Qu lgica inferir GeneXus al momento de la especificacin del Web Panel? Como los atributos involucrados en el web panel pertenecen algunos a la tabla CUSTOMER y otros a la tabla COUNTRY, y en la tabla extendida de CUSTOMER est la tabla COUNTRY, GeneXus determinar que la tabla a recorrer es CUSTOMER y que acceder por su extendida a la tabla COUNTRY para cargar el valor del atributo CountryName. Es decir, GeneXus determinar un for each implcito asociado al web panel, con tabla base CUSTOMER. Las condiciones definidas antes (a nivel de grid) se incluirn en el for each implcito (como clusulas where), de modo tal que al ejecutarse la consulta, se recorrer la tabla CUSTOMER, filtrando por dichas condiciones. Es importante considerar que tanto en las condiciones globales del web panel, como en las condiciones locales a un grid de un web panel, es posible utilizar la clusula when al igual que cuando se definen filtros en los objetos reportes y procedimientos.

260

Web panel con tabla base?


Decimos que un web panel es con tabla base cuando GeneXus puede determinar un for each implcito asociado a l. Es decir, si bien el analista no escribe un for each explcitamente en el web panel para efectuar la consulta, GeneXus lo determina automticamente (por eso lo llamamos: for each implcito). Tabla base del for each implcito = Tabla base del web panel. Un Web Panel es sin tabla base cuando GeneXus no puede determinar una tabla de la base de datos a recorrer para mostrar la informacin que se presenta en el form. En este caso en el form solamente aparecen variables (y no atributos).

Un web panel es con tabla base cuando de los atributos que aparecen, GeneXus puede determinar una tabla de la base de datos a recorrer para, recuperando sus registros, mostrar la informacin que aparece en los atributos del web panel. De este modo, es como si hubiramos escrito un for each para navegar esa tabla base y trabajar con algunos atributos de la misma, y de la extendida. Si en el Web Panel no aparecieran atributos, sino solo variables, evidentemente GeneXus no podr determinar una tabla a ser navegada. En este caso el web panel ser sin tabla base.

261

Orden de los datos a recuperar


Botn derecho sobre el grid:

Para definir que una consulta se efecte ordenando por ciertos atributos, y por ende que los datos extrados de la consulta se muestren ordenados con dicho criterio, se debe hacer clic con el botn derecho del mouse sobre el grid, y seleccionar el tem Order del men pop up que se muestra arriba. A continuacin, se presentar el dilogo para que se ingresen los atributos por los que se desea ordenar. Definir esto es equivalente a definir la clusula order en el comando for each, y se aplica todo lo visto en dicho tema: desde que para ordenar en forma descendente por un atributo se debe encerrar el atributo entre parntesis (), la creacin de ndices temporales cuando no exista un ndice fsico correspondiente a los atributos de ordenamiento, as como la posibilidad de utilizar la clusula when para condicionar la aplicacin de ese order. En nuestro web panel Work With Customers ordenamos los clientes que se listan en el grid por CustomerName. El poder definir order para un grid permite entre otras cosas optimizar la consulta, cuando se establecen condiciones de filtro. As, si en las conditions generales y/o las del grid particular, siendo la tabla base CUSTOMER establecemos los filtros, teniendo dos variables ingresadas por el usuario: CustomerName >= &customerStartName; CustomerName <= &customerEndName; Entonces, de no especificar un orden por CustomerName, se deber recorrer toda la tabla, de principio a fin, para cargar los registros que cumplan con las condiciones. Especificando un order optimizamos la consulta. Nota: Solamente si el form del web panel no tiene ningn grid (atributos sueltos), y se necesita definir un orden especfico para la consulta, se contar con la posibilidad de definir en la seccin de reglas del web panel, la regla de sintaxis: order(att1, att2, attN); siendo att1, att2, attN: la lista de atributos que define el orden de la consulta.

262

Eventos en web panels


En los web panels se utiliza la programacin dirigida por eventos. Eventos disponibles en web panels: Evento Start Evento Refresh Evento Load Evento Enter Eventos de Usuario Evento Click asociado a control

Dado que la programacin de los Web Panels est dirigida por eventos, para poder programar adecuadamente un objeto de este tipo es necesario conocer los eventos existentes y el momento y orden en que stos se disparan.

263

Evento Start
Es un evento del sistema, que ocurre automticamente siempre que se hace Get o Post y es el primer evento que se ejecuta. No se conocen valores de atributos, salvo los recibidos por parmetro. Esto se debe a que an no se ha efectuado la consulta. Ejemplo: se puede utilizar para que un control del form no aparezca visible, para cargar un bitmap, para asociarle un Link a otro control, etc.: Event Start &var.Visible = 0 &Update = LoadBitmap("images/edit.gif") newControl.Link = Link(TCustomer) endevent

En el ejemplo, tendremos 3 controles en el form: la variable de nombre var, la de nombre Update de tipo Bitmap y un control de nombre newControl que puede ser, por ejemplo, un control imagen. En el evento Start se le asigna a la propiedad Visible del control variable &var el valor 0, indicando que no deber verse en el form. A su vez, a la variable de tipo bitmap, &Update, se le carga la imagen que contendr, y al control que suponemos imagen, newControl, se le define la propiedad Link, de manera tal que cuando el usuario haga clic sobre el control, se invocar a la transaccin Customer.

264

Evento Refresh
El evento Refresh es un evento del sistema Se ejecuta cada vez que se realiza un Get o Post. Provoca que se ejecute la consulta a la base de datos. Es decir, al ocurrir el evento Refresh, se ejecuta lo codificado en dicho evento, y a continuacin se ejecuta la consulta a la base de datos. Viene seguido siempre del evento Load.

265

Evento Load
Cada vez que se ejecute el evento Refresh en un web panel, seguidamente se ejecutar el evento Load. La cantidad de veces que el evento Load ser ejecutado, depender de si el web panel tiene tabla base o no la tiene: Tiene tabla base:
Cuando aparecen atributos que le permiten automticamente determinar que se desea navegar una tabla determinada de la base de datos El evento Load se ejecutar N veces

No tiene tabla base:


Cuando no ocurre lo anterior (en el form solo hay variables) El evento Load se ejecutar solamente una vez.

Cuando el web panel es con tabla base, al producirse el evento Refresh se accede a la base de datos, a esa tabla base (la asociada al web panel), y se la recorre cargando los registros que cumplan las condiciones (conditions del grid y generales). Ocurrir en ese proceso un evento Load por cada registro en el que se est posicionado, inmediatamente antes de cargarlo. Esto nos permite realizar alguna operacin que requiera de ese registro (y de su extendida), antes de efectivamente cargarlo en el grid. Inmediatamente luego de ejecutado el cdigo asociado al evento Load, se cargar la lnea del grid y se pasar el puntero al siguiente registro de la tabla base, para realizar lo mismo (evento Load, carga de la lnea). Este proceso se repetir hasta cargar todas las lneas del grid. Si un web panel es sin tabla base, GeneXus no puede determinar automticamente una tabla de la base de datos a recorrer para mostrar la informacin que se presenta en el form. En este caso en el form solamente aparecen variables (y no atributos) y tambin ocurrirn los eventos Refresh y Load, slo que el evento Load se ejecutar una nica vez, dado que no se estar posicionado en ningn registro de ninguna tabla.

266

Evento Load en web panel con tabla base

Luego del evento Refresh se ejecuta el evento Load N veces: una vez por cada registro de la tabla base ledo para ser cargado en la lnea del grid

Por cada registro ledo en la consulta efectuada a la base de datos, se disparar el evento Load (ejecutndose el cdigo incluido en el mismo, y cargndose a continuacin una lnea en el grid con los datos asociados al registro).

267

Evento Load en web panel con tabla base: ejemplo

Si en el grid que muestra los clientes que cumplen con las condiciones de filtro, quisiramos agregar una columna al final, que marque que el cliente es moroso (deudor) si su saldo es mayor a $10.000, es decir, que en ejecucin sobresalga su condicin de moroso apareciendo un literal DEBTOR en ese caso, alcanza con agregar una variable &type al grid, de tipo Character(10) y cargarla en el evento Load del web panel como se muestra arriba. Para cada registro de la tabla base CUSTOMER que se vaya a cargar como lnea en el grid, se ejecutar el cdigo del evento Load, cargndose en la columna &type el valor DEBTOR nicamente si el saldo de ese cliente que va a listarse supera los $10.000. Luego, si para cada cliente del grid adems de mostrar su nombre, pas, sexo, saldo y tipo, queremos mostrar la cantidad de facturas que se le han emitido, alcanza con agregar una variable &quantity al grid, e incluir en el cdigo del evento Load, el for each para contar esas facturas. Observar que el for each definido en el evento Load estar anidado al for each implcito (el de la tabla base), por lo que se efectuar un join, recorrindose solamente las facturas de ese cliente, el que se est cargando.

268

Evento Load en web panel sin tabla base


En un web panel sin tabla base, el evento Load se ejecutar solamente una vez.

Evento Refresh Evento Load

Que el web panel no tenga tabla base, significa que no tiene un for each implcito asociado; por lo tanto, cuando se ejecute el evento Refresh, no comenzar a ejecutarse ninguna consulta; se ejecutar el cdigo asociado al evento Refresh, y a continuacin se ejecutar el cdigo asociado al evento Load, una nica vez. Aqu es donde tendremos que cargar el grid, consultando la base de datos con un for each explcito. A continuacin vemos el cdigo de este evento.

269

Evento Load en web panel sin tabla base: ejemplo

Comando (que solo puede ir dentro de evento Load) para efectivamente cargar una lnea con el valor que tengan las variables en ese momento.

El objetivo del comando LOAD dentro del evento Load es cargar efectivamente una lnea en el grid. Una vez que se hayan asignado valores a todas las variables que sean necesarias, y se desee agregar la lnea al grid, deber ejecutarse el comando LOAD. Solamente se puede especificar el comando LOAD dentro del evento Load del grid de un web panel y en ningn otro lado. Event Load for each &CustomerId = CustomerId &CustomerName = CustomerName &CustomerGender = CustomerGender &CustomerBalance = CustomerBalance if CustomerBalance > 10000 &type = DEBTOR else &type = endif &quantity = 0 for each defined by InvoiceDate &quantity += 1 endfor Load /* LUEGO DE HABER CARGADO TODAS LAS VARIABLES CON LOS VALORES CORRESPONDIENTES A LA LNEA A SER CARGADA EN EL GRID, DEBEMOS INCLUIR EL COMANDO LOAD, EL CUAL AGREGAR EFECTIVAMENTE LA LNEA AL GRID. */ endfor Endevent Si en la codificacin del evento Load definimos comandos For each y asignamos valores a las variables en las iteraciones pero no incluimos el comando LOAD, en tiempo de ejecucin estaremos asignando una y otra vez valores a las variables, pero no se estarn agregado lneas en el grid (solamente quedar una lnea en el grid con los ltimos valores cargados en las variables). Por esta razn es muy importante no olvidar escribir este comando en el lugar apropiado. 270

Evento Enter
Cuando se inserta un nuevo botn en el form de un Web Panel, por defecto aparece con el Caption Confirm y aparece asociado al evento del sistema Enter. El evento Enter puede asociarse a cualquier botn, atributo, imagen, text block, en la propiedad de los controles: OnClickEvent. De modo que si se necesita ejecutar acciones cuando el usuario final haga clic en el control asociado, en este evento debern codificarse.

271

Eventos de usuario
Adems de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por l, llamados eventos de usuario. Cada evento de usuario debe asociarse a un control insertado en el form del web panel de los que soportan el OnClickEvent (botones, text blocks, imgenes, atributos) En tiempo de ejecucin, el evento de usuario ocurrir luego de que el usuario haga clic sobre el control asociado al mismo.

Casi todos los controles que aparecen en el form brindan la posibilidad de disparar un evento cuando el usuario hace clic con el mouse sobre ellos (aparecen como hipervnculos en ejecucin); se consigue de dos maneras distintas: 1. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad OnClickEvent 2. Dndole un nombre al control y en la seccin de Eventos programando: Event nombreControl.click Endevent Con esta ltima alternativa no tendremos que definir un evento de usuario, sino que estaremos programando el evento click del control.

272

Web panel "Work With Customer

Acciones sobre el cliente seleccionado

Para que el web panel con el que venimos trabajando sea un verdadero trabajar con se le deben agregar acciones a ser efectuadas sobre los clientes: la posibilidad de insertar un nuevo registro (nuevo cliente), el modificar uno existente, o el eliminarlo (as como tambin poder simplemente visualizarlo). Una forma de implementar esto es agregar los cuatro botones que aparecen arriba, en el form: . . . . un un un un botn botn botn botn que que que que ofrezca ofrezca ofrezca ofrezca insertar un cliente (Insert) modificar un cliente (Update) eliminar un cliente (Delete) visualizar los datos de un cliente (View)

Adems debemos permitir la seleccin de una lnea de la grilla para aplicarle alguna de las acciones definidas en los botones del form. Para ello, accedemos a las propiedades de la grilla con botn derecho sobre el control grid y configuramos la propiedad AllowSelection con el valor True como muestra la figura. Al hacerlo se nos habilitan tres propiedades ms, que permiten especificar SelectionColor: el color que tendr la lnea cuando el usuario la seleccione (haciendo clic con el mouse sobre la misma); AllowHovering: la posibilidad de que cambie el color de las lneas cuando el usuario se desplaza con el mouse sobre ellas, y HoveringColor: el color que tendr una lnea cuando el mouse pasa sobre ella. Estas funcionalidades se implementan con cdigo javaScript que se enva al Browser al ejecutar el Web Panel. En la seccin de eventos del web panel, definiremos el cdigo asociado a estos botones. Lo veremos en la pgina siguiente.

273

Eventos de usuario en el web panel Work With Customer


Event Insert Tcustomer.call(INS, 0) Endevent Event Update Tcustomer.call(UPD, CustomerId) Endevent Event Delete Tcustomer.call(DLT, CustomerId) Endevent Event View Tcustomer.call(DSP, CustomerId) Endevent

En las reglas de la transaccin Customer:


Parm(&Mode, &CustomerId ); Variable del sistema Variable de usuario

CustomerId = &CustomerId if not &CustomerId.IsEmpty();

La variable &Mode es del sistema y su tipo es Character(3). Tiene la particularidad de entender 4 valores: INS: este valor indica ejecutar la transaccin en modo Insert UPD: este valor indica ejecutar la transaccin en modo Update DLT: este valor indica ejecutar la transaccin en modo Delete DSP: este valor indica ejecutar la transaccin en modo Display

Cul es el resultado de recibir por parmetros en una transaccin el modo de ejecucin y la clave primaria? El permitir insertar, modificar o eliminar puntualmente una instancia y luego retornar al objeto llamador. Es por ello que en todos los eventos definidos en el Web Panel Work With Customer estamos invocando a la transaccin Customer, pasndole dos valores por parmetro: un literal de 3 letras, que es el modo y el cdigo de cliente correspondiente a la lnea del grid que fue seleccionada (por ello necesitamos habilitar la seleccin de lneas del grid, mediante la propiedad AllowSelection que vimos antes). En definitiva la regla parm a definirse en la transaccin "Customer", es: parm(&Mode, &CustomerId); Como se puede observar, no recibimos el cdigo de cliente directamente en el atributo CustomerId, sino en una variable. Por qu? Si declarramos el atributo CustomerId en vez de una variable, el valor que se recibiera en l actuara automticamente como filtro por igualdad. Sin embargo cuando invocamos a la transaccin "Customer" con los parmetros INS y 0, el modo INS indica que queremos que la transaccin se ejecute en modo insert; y como en dicho caso no tenemos que enviar el cdigo de cliente para instanciarlo, completamos el segundo parmetro con valor 0 (porque la cantidad y el tipo de datos- de los parmetros enviados, debe coincidir con la cantidad y el tipo de datos- de los parmetros recibidos). De modo que el valor 0 es para completar el parmetro simplemente, no para que se filtre por l tratando de instanciar un cliente de cdigo 0. En los otros 3 casos en que se invoca a la transaccin "Customer" (con los parmetros UPD y CustomerId ; DLT y CustomerId DSP y CustomerId respectivamente) s se quiere filtrar por el valor del cdigo de cliente recibido; pero basta que haya un caso en el cual se invoque a la transaccin y que no sirva filtrar por el valor recibido, para que no sirva recibir el parmetro en el atributo y esa es la razn por la cul se est recibiendo en una variable. Si la clave primaria, CustomerId es autonumerada, entonces en ese caso s podr recibirse en atributo. Recuerde que a partir de la inclusin de la regla parm en un objeto, ste desaparece del Developer Men, debido a que desde el mismo no es posible el envo de parmetros.

274

Web panels - Funcionamiento


Esquema de trabajo en Internet: el servidor no sabe lo que se est haciendo en el Browser, hasta que se someta la pgina. Es decir, hasta que se dispare un evento (enter, de usuario, click). Orden de disparo de eventos: es diferente si se trata de la primera carga del web panel (Get) o si ya estaba cargado cuando se dispara un evento de usuario, enter, click (Post)

Es importante entender que en Internet, cuando el usuario accede a una pgina del servidor Web para visualizarla, el Browser baja la pgina al cliente. Por lo tanto, no existe forma de detectar lo que realiza el usuario: el servidor Web volver a tener el control cuando se dispare el evento ENTER o algn evento de usuario o click. En ese momento se enva (se somete, se hace un post) el resultado al servidor para continuar con su procesamiento. Es decir, una vez que el objeto web finaliza la ejecucin en el servidor, no queda en memoria. Como consecuencia, la forma en que programamos este tipo de aplicaciones presenta algunas diferencias con respecto a lo acostumbrado en ambientes no web. Es por esta razn que es importante destacar el orden en que se disparan los eventos y el momento en que las variables adquieren el valor ingresado por el usuario. El orden de ejecucin de los eventos en web panels es diferente si se trata de la primera llamada al mismo (GET) o si se dispar algn evento de usuario, enter o click (POST).

275

GET: Orden de disparo de eventos

Al ejecutar un web panel por primera vez se disparan los siguientes eventos: Start Refresh Load

La primera vez que se ejecuta el web panel (se conoce tambin como el momento en que se hace el GET de la pgina) los eventos que se disparan son los siguientes y en el siguiente orden: 1. Start 2. Refresh 3. Load Luego de esto, cuando el usuario haga clic sobre un control que tenga asociado el evento Enter o uno de usuario o click se ejecutar nuevamente el web panel y el orden de disparo de los eventos ser diferente, como se indica en la siguiente pgina.

276

POST: Orden de disparo de eventos


Resto de las ejecuciones del web panel:

Start Lectura de variables en pantalla Evento Enter o de usuario (submit) Refresh Load

En el resto de las ejecuciones del web panel, que ocurren cuando se presiona un botn, o se fuerza la ejecucin del evento asociado a una imagen, text block, etc. (haciendo clic sobre el control que tiene asociado el evento de usuario o Enter o click) momento que se conoce tambin como el POST de la pgina, los eventos se dispararn en el siguiente orden: 1. Start (nuevamente se dispara el evento Start) 2. Lectura de las variables de la pantalla. Esto se realiza porque el usuario puede haberlas modificado (por ejemplo las variables de la parte fija del web panel que estn involucradas en las conditions, como en el ejemplo que se presenta arriba, donde se quieren cargar en el grid los clientes cuyo nombre contenga el string cargado por el usuario en la variable &CustomerName) 3. Evento Enter o click o evento de usuario (cdigo correspondiente al evento asociado al control que se presion y produjo el POST). 4. Refresh 5. Load En el ejemplo no necesitamos codificar nada en el evento asociado al botn Search. Solo lo pusimos para poder enviar al servidor la variable con el valor que ingres el usuario y que la pgina se refresque cargando en el grid los clientes que cumplan con el filtro que el usuario estableci mediante esa variable.

277

Web panels - Variables


Variables: adquieren valor ingresado por el usuario luego de sometido evento (POST) Si en un evento se usa una variable que se carga en otro evento la variable debe estar en el form, y adems debe estar despus del control en el que se carga su valor. Ejemplo: Event Load &cont+=1 endevent
Event Refresh &cont= 0 endevent Event Enter if &cont<5 endevent

Relacionado con el orden de disparo de los eventos, es importante destacar el momento en que las variables adquieren los valores ingresados por el usuario: solamente lo harn despus de presionar un botn1 (que es cuando el servidor Web tiene el control del procesamiento). Por ejemplo, cualquier Link especificado en el evento Start a otro web panel con una variable que se ingresa en el form no va a tener ningn valor cuando se haga clic sobre el Link. (Ej: control.Link = HWebPanelX.Link(&var). No se debe escribir esto en el start si la &var esta en el form, porque al momento de armarse el link no se tiene el valor de la variable) Si en un evento se usa una variable que se carga en otro evento, entonces esa variable debe estar presente en el form. Si no est en el form, la variable no tendr valor cuando se disparen los eventos que la consultan (esto es por el orden en que ocurren los eventos). Adems, deber estar en el form despus del control en el que se carga. Por ejemplo, si la variable se carga en el LOAD de un grid entonces la variable tiene que estar en pantalla despus del grid. Ejemplo: web panel con grid que lista las facturas existentes, y queremos contar la cantidad de facturas que se listan en el grid. Para ello definimos una variable &cont que debemos incrementar cada vez que se carga una nueva lnea, es decir, en el evento Load del grid. Para que la variable se cargue correctamente, deber incluirse luego del grid, puesto que de lo contrario ya se habr dibujado en la pgina, antes de que pueda ser cargada por el evento Load. Gracias a tenerla en el form, cuando el usuario presione el botn Confirm que consulta por el valor de la variable, la misma podr tener el valor cargado antes por el Load. Recordemos que al presionar el botn Confirm se realizar un POST al servidor, y en l se dispararn Start, lectura de variables de pantalla (aqu se leer el valor de &cont que haba sido cargado antes por el evento Load), luego se disparar el evento Enter asociado al Confirm y dentro del mismo se consulta por el valor de la variable, que gracias a que fue enviada al servidor por estar en el form, tiene el valor que se haba cargado antes. Luego se dispararn Refresh y Load. Observemos que aqu, cuando se dispare el Load, se incrementar la variable, por lo que deberemos resetearla antes de que se empiecen a cargar las lneas, porque de lo contrario mostrar el doble de las lneas que tena antes. Dnde resetearla? Event Refresh &cont = 0 endevent ----------------------------------------------------------------------------------------------------------------------1 O hacer clic sobre algn control del form que tenga un evento de usuario o click o Enter asociado (ya sea con la propiedad Link, o la propiedad OnClickEvent, o el evento click).

278

Ejemplo: Supongamos que tenemos un web panel donde en un sector del form se puede ingresar usuario y contrasea para loguearse al sistema. En el evento donde validamos el usuario y la contrasea (asociado a algn botn o text block), guardamos en una variable el cdigo de usuario para poder utilizarlo en otro evento. Esto nos permitira, por ejemplo, llamar a un objeto que permita visualizar los datos del usuario (por ejemplo un web panel de nombre CustomerData, que recibir por parmetro el identificador de cliente). En consecuencia, primero que nada, deberamos programar lo siguiente en el evento donde validamos el usuario: Event Login For each Where CustomerUser = &CustomerUser If CustomerPassword = &CustomerPassword &CustomerId = CustomerId Mensaje.Caption = Bienvenido/a +trim(CustomerName) Else Mensaje.Caption = La contrasea ingresada no es correcta Endif When none Mensaje.Caption = El usuario ingresado no existe Endfor Endevent donde Mensaje es el nombre de un text block que dinmicamente (con la propiedad Caption) cambia de texto. Obsrvese que tenemos una tabla CUSTOMER que contiene la info de usuario y password. Para realizar la llamada al web panel Datos del Cliente (CustomerData), existen varias alternativas, una de las cules sera agregar un botn o una imagen con un evento click asociado (o definir un evento de usuario y asocirselo al control mediante la propiedad OnClickEvent), entonces el cdigo seria el siguiente: Event Ver.clic // ver es el nombre de la imagen o botn. HCustomerData.Call(&CustomerId) Endevent Repasemos entonces lo que ocurre: 1. En la primera ejecucin se disparan los eventos: Start, Refresh y Load y podemos ingresar el usuario y password en las variables respectivas. 2. Cuando presionamos el botn o text block para validar el login, se dispara el evento Start, se leen las variables anteriores que estn en pantalla, se ejecuta el cdigo del evento Login, donde se asigna a la variable &CustomerId el cdigo de cliente del usuario correspondiente. Luego ocurren Refresh y Load y la pgina se despliega en el Browser. 3. Ahora, ya estando logueados, cuando presionamos la imagen o botn con el evento click asociado, se dispara el evento Start, se leen las variables que estn en pantalla, se ejecuta el evento click y ah cuando redireccionamos al Web Panel CustomerData, la variable &CustomerId no tiene valor alguno, ya que la misma se perdi luego de haber finalizado la ejecucin del Web Panel en el punto 2. Es por esta razn que si queremos disponer del valor de la misma, deberamos agregar la variable &CustomerId en el form y la ocultaramos usando la propiedad Visible (por ejemplo en el evento Start). Event Start &CustomerId.Visible = 0 Endevent Entonces en este caso, cuando el Web Panel ejecute por segunda vez, se dispararn los eventos: 1. Start 2. Se leen las variables del form (en este momento se obtiene el valor de &CustomerId) 3. Se ejecuta el evento click, y por consiguiente se llama al Web Panel con el cdigo de cliente correcto. Esto es porque no existe un concepto de memoria local para los web objects, por lo cual, si en un evento se usa una variable que se carga en otro evento, entonces esa variable debe estar presente en el form, de manera que, aprovechando el orden de disparo de los eventos en el POST, se obtenga el valor de la variable.

279

Definicin de columnas ocultas en el grid de un web panel


Al hacer botn derecho sobre el grid y seleccionar Columns:

Editar las propiedades de la columna que se quiere ocultar:

Hay veces que por motivos de presentacin, no se desea incluir ciertos atributos o variables como columnas visibles de un grid, pero se necesita tener sus valores cargados en columnas ocultas. Por qu motivo se puede necesitar definir una columna oculta en el grid de un web panel? Un grid siempre tiene un archivo temporal asociado. Cuando en un Web Panel se ejecuta el evento Refresh, se comienza a ejecutar la consulta a la base de datos; a continuacin por cada registro ledo que cumpla con las condiciones de filtro definidas, se ejecuta el evento Load y se cargan los datos de dicho registro, en el archivo temporal asociado al grid. Qu datos de los registros se cargan en el archivo temporal? Es decir, qu columnas contendr el archivo temporal? Una columna por cada atributo o variable mostrado en el grid, ms una columna por cada atributo o variable declarado en el grid como columna oculta. A modo de ejemplo, si en un grid hay 2 columnas visibles con los atributos CustomerName y CustomerBalance y ninguna columna oculta, el archivo temporal asociado al grid contendr 2 columnas correspondientes a los atributos CustomerName y CustomerBalance, respectivamente. Si adems de esas 2 columnas visibles, se declara el atributo CustomerId como columna no visible en el grid, el archivo temporal asociado contendr 3 columnas correspondientes a los atributos CustomerName, CustomerBalance y CustomerId, respectivamente. Si en el grid slo incluimos 2 columnas visibles con los atributos CustomerName y CustomerBalance, en el caso en que necesitemos en un evento de usuario conocer el valor del atributo CustomerId correspondiente al cliente de cierta lnea seleccionada (para escribir alguna sentencia utilizndolo), no lo tendremos. Para conocer en un evento de usuario el valor del atributo CustomerId correspondiente a cierta lnea seleccionada, tendremos que incluirlo en el grid ya sea visible o no visible, pero debe estar presente. Como ejemplo, pensemos en nuestro Web Panel Work With Customers: necesitbamos una vez que el usuario seleccionaba una lnea, y presionaba el botn Update llamar a la transaccin Customer envindole como parmetro el CustomerId seleccionado. En este caso necesitamos tener el CustomerId en el archivo temporal, ya sea que est visible en el grid o no lo est. Cmo ocultar una columna en un grid? Para ocultar una columna en un grid, debemos configurar la propiedad Visible del atributo o variable que se desea ocultar con valor False. Para ello, debemos hacer clic con el botn derecho del mouse sobre el grid y seleccionar las columnas (Columns) de la grilla; se abrir el dilogo mostrado. Luego, habr que posicionarse en el atributo o variable que se desee definir como columna oculta, y editar sus propiedades (Properties). Por ltimo, se debe configurar la propiedad Visible de la columna con valor False.

280

De modo que el motivo por el cual podemos necesitar incluir un atributo o variable como columna oculta de un grid, es porque necesitemos conocer el valor de ese atributo o variable en un evento de usuario, pero no deseemos mostrarlo. As como los eventos de usuario trabajan con los datos cargados en el archivo temporal asociado al grid, las condiciones de filtro en cambio, trabajan sobre la tabla fsica consultada y su tabla extendida; por lo tanto, al definir condiciones de filtro, se podrn referenciar atributos que pertenezcan a la tabla fsica que se consulta y su tabla extendida, sin la necesidad de que dichos atributos deban estar incluidos en el grid (ni visibles ni ocultos) ni en ninguna otra seccin del web panel. Por ejemplo, pinsese en el ejemplo que ya presentamos antes: Event Load if CustomerBalance > 10000 &type = 'DEBTOR' else &type = '' endif endevent Aqu surge la pregunta: como en este evento utilizamos el atributo CustomerBalance para poder cargar adecuadamente la variable, es necesario colocarlo oculto en el grid? La respuesta es no. En el evento Load estamos posicionados en un registro de la tabla base. Tenemos a disposicin todos los atributos de esta tabla base y de la extendida, sin necesidad de cargarlos luego en el grid.

281

Comando FOR EACH LINE


GeneXus nos provee el comando For each line para recorrer las lneas de un grid en un web panel:

for each line [in gridName] Sentencia 1 Sentencia N endfor


in NombreGrid: solamente es necesario explicitarlo cuando hay ms de un grid en el form del web panel. Sentencia 1, , Sentencia N: sentencias a ejecutarse para cada lnea recorrida del grid.

282

Comando FOR EACH LINE


Ejemplo

Event Delete for each line if &dlt = Y PDelCustomers.call(CustumerId) endif endfor Endevent

A continuacin, implementaremos un caso de seleccin mltiple, una operativa diferente a la presentada en el caso del web panel Work With Customer, que permita seleccionar una nica lnea por vez (seleccin simple). La operativa que pretendemos ofrecer en el web panel DelCustomers presentado arriba es la siguiente: luego de que el usuario haya ingresado un substring para filtrar los clientes y se haya cargado el grid con los clientes que cumplan dicho filtro, el usuario podr marcar (con un clic del mouse) qu lneas (clientes) desea eliminar. En el ejemplo, hemos incluido en el grid del web panel DelCustomers", una variable de nombre &dlt (definida como check box), adems de los atributos CustomerId, CustomerName, CountryId, CountryName y CustomerAddress. De esta forma, el usuario seleccionar el check box en los clientes que desea eliminar. A su vez, tendramos que tener un botn "Delete" y en el cdigo del evento asociado a dicho botn deberamos recorrer el grid y para cada lnea seleccionada invocar a un procedimiento que haga la eliminacin fsica de dicho cliente. A continuacin incluimos el cdigo del procedimiento DelCustomers que recibe en la regla parm el cdigo del cliente a eliminar (CustomerId). Reglas: Parm(CustomerId); Source: for each defined by CustomerName Delete Endfor //se elimina el cliente recibido como parmetro

283

Variables en un grid
Por defecto todas las variables de un grid son Read-Only For each line [in grid], evento click, OnClickEvent: modifica valor por defecto y todas las variables del grid pasan a ser de entrada. Propiedad: Read Only para que alguna sea de salida.

Cmo desplegar datos en un grid Por defecto todo atributo y variable que est dentro de un grid se despliega en ejecucin como texto, es decir que es nicamente de lectura y por consiguiente no puede ser modificado. Cmo aceptar datos en un grid Es posible aceptar datos en las variables de un grid dependiendo de la programacin de los eventos existentes en el objeto: 1. Si dentro de un evento del web panel se est utilizando el comando For each line, todas las variables que estn dentro del grid pasan a ser de entrada. Es posible indicar en este caso cules son las variables que no van a poder ser modificadas (Ver ms abajo). 2. Si dentro de la fila hay algn control con un evento click asociado ( evento de usuario especificado en la propiedad OnClickEvent). Cmo indicar que una variable no puede ser modificada 1. Para indicar que el valor de una variable en un grid no puede ser modificado, debemos configurar la propiedad Read Only de la variable con valor True. Para ello, debemos hacer clic con el botn derecho del mouse sobre el grid y seleccionar las columnas (Columns) de la grilla. Luego, habr que posicionarse en la variable que se desee definir como de slo lectura, y editar sus propiedades (Properties). Por ltimo, se debe configurar la propiedad Read Only de la columna con valor True. 2. Utilizando la regla Noaccept()

284

Diferentes tipos de grilla/grid


Grid estndar: datos repetitivos en formato fijo (lnea, columna)

Grid Freestyle: datos repetitivos en formato libre

Se dispone de dos tipos de grilla: Grilla estndar: la que vimos hasta ahora, en Transacciones y Web Panels Grilla Freestyle Estas grillas, agregan potencia al diseo de aplicaciones web, permitiendo al desarrollador mayor libertad a la hora del diseo.

285

Grid estndar
Propiedades:

Establece si el grid se cargar o no por pginas (paginado). Indica cantidad de filas por pgina. 0 todas (no habr paginado) Permite seleccin de lnea del grid

Los grids permiten trabajar con datos repetitivos en web panels y transacciones con form HTML. Las columnas de los grids pueden ser atributos, variables (incluyendo las de tipo bitmap), y siempre tendrn una primera fila que corresponder a los ttulos de las columnas. En ejecucin, el grid ser una tabla HTML. Para interiorizarse de cada una de las propiedades configurables de un grid, sugerimos acceder al Help de GeneXus. Aqu solo mencionaremos algunas como ejemplo: ControlName: Permite indicar el nombre del control. Siempre se le asigna un nombre por defecto. Class: Clase (del tema asociado al objeto) asociada al control. La propiedad Class solo se encuentra disponible si el control est en el form de un objeto que tiene un Tema asociado. BackColorStyle: Permite asignar un estilo al grid. Los estilos disponibles son: 1. None: el grid no tendr un estilo particular, sino que tendr el diseo del form o del control que lo contenga. 2. Header: permite especificar un color para el fondo de los ttulos del grid y otro para las lneas del mismo. Las propiedades son LinesBackColor y TitleBackColor. 3. Report: permite especificar un color para el fondo de los ttulos y alternar colores para las lneas pares e impares del grid. Las propiedades son LinesBackColor, LinesBackColorEven y TitleBackColor. 4. Uniform : permite especificar un nico color para el fondo del grid(tanto el ttulo como las lneas). Dependiendo del valor de la propiedad BackColorStyle, estarn disponibles otras propiedades adicionales relacionadas con la configuracin de las lneas del grid. Rows: Esta propiedad permite al usuario indicar la cantidad de registros que va a cargar en el grid. Aplica nicamente a los grids que tienen tabla base. Si el valor de esta propiedad es 0, se despliegan tantas lneas como registros resulten de la consulta asociada. El valor por defecto de esta propiedad es 0. Collapsing: AllowCollapsing :True: Permite colapsar el grid en ejecucin Collapsed :True: Arranca el grid colapsado. Selection: AllowSelection: True: Especifica que es posible seleccionar una lnea en la grilla. SelectionColor: Seleccionar el color deseado al marcar la fila AllowHovering: True: Marca la fila cuando el mouse se posiciona sobre la misma. HoveringColor: Seleccionar el color deseado

286

Grid Freestyle
Permite formato libre de los registros
Tabla con registros repetitivos No posee ttulos para las columnas Permite tener ms de un tipo de control en una misma celda Propiedades de diseo de tablas Propiedades del Grid

grid

El grid Freestyle permite al usuario definir el formato de los datos a desplegar de una forma menos estructurada que el grid estndar. El grid Freestyle es bsicamente una tabla a la que se le pueden insertar los atributos/variables, text blocks, imgenes, botones, web components, embedded pages, grids freestyle y/o grids que se van a mostrar posteriormente en la pantalla. Este tipo de grid no posee ttulos para las columnas y adems permite tener ms de un tipo de control, atributo/variable en una misma celda, proporcionando de esta forma mayor libertad de diseo. Cabe destacar que el grid Freestyle posee las mismas propiedades mencionadas anteriormente para el grid estndar. En este caso para poder visualizar las propiedades hay que seleccionar la tabla donde se encuentran los atributos/variables. En el ejemplo presentado arriba queremos mostrar alguna informacin de los clientes. El atributo CustomerPhoto se ha incluido en la transaccin Customer para almacenar la foto de cada cliente (es un atributo de tipo Blob). Pero no queremos mostrar la informacin como lo haramos en un grid estndar, con cada elemento de informacin en una columna distinta del grid. Aqu queremos mostrar la foto y debajo el nombre del cliente. El comportamiento de las variables dentro de un grid Freestyle es anlogo al que presentan dentro de un grid estndar, por lo tanto tambin quedan de ingreso si existe un For each line o For each line in <grid> dentro de algn evento, o si se asocia un evento a cualquier control de la fila. Nuevamente este comportamiento puede modificarse, agregando la regla noaccept o cambiando la propiedad Read Only.

287

Grid Freestyle
Propiedades

Para visualizar las propiedades de un grid Freestyle, hay que seleccionar la tabla del grid, presionar el botn derecho del mouse y seleccionar la opcin Properties. Nuevamente, para interiorizarse de cada una de las propiedades configurables de un grid freestyle, sugerimos acceder al Help de GeneXus. Aqu solo mencionaremos algunas como ejemplo: Class: Permite modificar la clase de un control, ya sea en tiempo de diseo como en ejecucin. La clase debe pertenecer al tema asociado al objeto que contiene el control. La propiedad Class solo se encuentra disponible si el control est en el form de un objeto que tiene un Tema asociado. BackColorStyle: Permite asignar un estilo al grid. estndar (ver grid estndar) Los estilos disponibles son los mismos que para un grid

Rows: Esta propiedad permite al usuario indicar la cantidad de registros que va a cargar en el grid. dem a grid estndar. Columns: Esta propiedad permite al usuario indicar cuntas columnas va a tener el Freestyle grid en ejecucin. Si se ingresa un valor distinto de 1, el Freestyle grid va a mostrar los registros en tantas columnas como se haya especificado en la propiedad. Si el valor de esta propiedad es 0, se despliegan tantas columnas como registros resulten de la consulta asociada. El valor por defecto de esta propiedad es 1. Esta es propia de este tipo de grids. Propiedades modificables en ejecucin: En tiempo de ejecucin se pueden modificar algunas propiedades, como: visible, backcolor, backColorEven, BackColorOdd, Columns, Rows y RecordCount: La propiedad RecordCount aplica nicamente a grids que tienen tabla base y retorna un nmero mayor o igual a cero representando la cantidad de registros de la tabla base del grid que cumplen las condiciones de seleccin. Puede retornar -1 si no existe navegacin para la tabla base del grid. PageCount: La propiedad PageCount devuelve la cantidad de pginas del grid en base a las propiedades Rows y Columns del mismo. Al igual que la propiedad RecordCount, devuelve 1 si el grid no tiene tabla base. Para el caso de un grid estndar, tambin existe esta propiedad dinmica, pero toma en cuenta solo la propiedad Rows.

288

Paginado de grids en Web panels


Asignarle valor a propiedad Rows para indicar cantidad de registros a cargar por pgina. Mtodos:
Firstpage Nextpage Previouspage Lastpage (tabla base) Gotopage (tabla base)

Propiedades:
RecordCount (tabla base) PageCount (tabla base)

Descripcin El paginado del grid aplica a grids comunes y freestyle cuya propiedad Rows tenga un valor diferente de cero. Existen algunas diferencias relacionadas con la paginacin cuando un grid tiene tabla base o no. Podemos agregar al web panel Work With Customer botones de navegacin para el grid (se muestran arriba) y eventos para realizar el paginado. Mtodos A continuacin se describen los mtodos disponibles: FirstPage: El mtodo FirstPage lleva al usuario al primer conjunto de registros devueltos. Los valores devueltos por este mtodo son los siguientes: 0: Operacin exitosa 1: No est habilitado el paginado en el grid NextPage El mtodo NextPage lleva al usuario al siguiente conjunto de registros. Los valores devueltos por este mtodo son los siguientes: 0: Operacin exitosa 1: No est habilitado el paginado en el grid 2: Ya se encuentra en la ltima pgina PreviousPage El mtodo PreviousPage lleva al usuario al conjunto anterior de registros. Los valores devueltos por este mtodo son los siguientes: 0: Operacin exitosa 1: No est habilitado el paginado en el grid 2: Ya se encuentra en la primera pgina Lastpage El mtodo LastPage lleva al usuario al ltimo conjunto de registros. Puede ser utilizado nicamente si el grid tiene tabla base. Los valores devueltos por este mtodo son los siguientes: 0: Operacin exitosa 1: No est habilitado el paginado en el grid 3: El grid no tiene tabla base 289

GoToPage El mtodo GotoPage(PageNumber) permite acceder en forma directa a un determinado conjunto de registros. Puede ser utilizado nicamente si el grid tiene tabla base. Los valores devueltos por este mtodo son los siguientes: 0: Operacin exitosa 1: No est habilitado el paginado en el grid Propiedades Cada grid dispone de las siguientes propiedades que son utilizadas en la paginacin: RecordCount La propiedad RecordCount aplica nicamente a grids que tienen tabla base y retorna un nmero mayor o igual a cero representando la cantidad de registros de la tabla base del grid que cumplen las condiciones de seleccin. Puede retornar -1 si no existe navegacin para la tabla base del grid. PageCount La propiedad PageCount devuelve la cantidad de pginas del grid en base a las propiedades Rows y Columns del mismo. Al igual que la propiedad RecordCount, devuelve 1 si el grid no tiene tabla base. Recomendamos estudiar las consideraciones de eficiencia relacionadas con el uso de estos mtodos. Se aconseja realizar un buen filtrado de datos del grid.

290

Reglas ms utilizadas en Web Panels A diferencia del objeto transaccin, en el cual se programa su comportamiento mediante la definicin de reglas, en el objeto web panel la programacin es dirigida por eventos. Son pocas las reglas para web panels, y las mismas permiten definir comportamientos puntuales (hay algunas reglas ms adems de las mencionadas, que se pueden consultar en el Help de GeneXus). Noaccept(&variable); En los web panels las variables que estn en el form fuera de un control grid, que estn dentro de un grid pero hay algn evento donde se utiliza el comando For each line, o se le ha asociado evento de usuario o click a algn atributo o variable del grid, son de entrada por defecto; es decir, el comportamiento por omisin es que en las mismas pueden ingresarse valores. Para definir que una variable se presente deshabilitada en un web panel, es decir, no permitiendo ingresos en la misma, una opcin es definir la regla: noaccept(&variable); siendo &variable una variable definida en el objeto. La otra opcin que tenemos en GeneXus para que una variable se presente deshabilitada en un web panel es configurando la propiedad Read Only de la variable con valor True. Ver seccin Propiedades de la grilla. Default(&variable, valor); Asigna un valor por defecto a una variable. &variable: es una variable definida en el objeto. valor: puede ser un literal entre comillas, un nmero o una de las funciones Today(), Date() o SysDate(), debiendo coincidir el tipo de datos del valor con el tipo de datos de la variable. El valor por defecto se asignar a la variable al principio de la ejecucin del programa.

291

Conceptos fundamentales
Web panel con a lo sumo un grid:
Con tabla base Sin tabla base

Web panel con N grids:


Grids paralelos Grids anidados

292

Web Panel con tabla base


Web panel es con tabla base cuando a lo sumo tiene un grid y GeneXus puede determinar un for each implcito asociado a l. Para determinar si un web panel tiene tabla base y en caso afirmativo cul ser, al momento de especificarlo GeneXus analiza los atributos incluidos en:
1. form: en la parte fija 2. form: en el grid (visibles o no visibles) 3. el order del grid 4. las condiciones del grid (no en las condiciones globales) 5. los eventos fuera de comandos for each

GeneXus busca la mnima tabla extendida que contenga a todos estos atributos, y la tabla base de dicha mnima tabla extendida, ser la tabla base del for each implcito (es decir, la tabla que navegar el for each), se llamar tabla base del web panel. Observar que GeneXus no toma en cuenta para determinar la tabla base de un web panel: 1) los atributos recibidos por parmetro 2) los atributos mencionados en las condiciones globales del web panel stos actan como filtros una vez determinada la tabla base.

293

Web panel sin tabla base

Un web panel sin tabla base es aquel que no tiene atributos en ninguno de los 5 lugares puntuados antes.

Por lo tanto GeneXus no determina un for each implcito asociado a l.

Los web panels de entrada generalmente son web panels sin tabla base por el hecho de que suelen contener solamente variables; entonces, por no contener atributos en ninguno de los 5 lugares tenidos en cuenta por GeneXus para determinar la tabla base, son web panels sin tabla base. Adems del caso de los web panels de entrada, existen otros casos que ameritan la definicin de web panels sin tabla base. En la prxima pgina vemos la resolucin de una consulta con un web panel sin tabla base.

294

Web panel sin tabla base


Ejemplo
Mostrar para cada cliente el total facturado, pero slo de los clientes que tienen facturas.

Event Load

EndEvent

For Each CustomerId defined by InvoiceDate &Customer = CustomerName &Total =0 for Each &Total +=InvoiceTotal endfor Load endfor

Dado que no mencionamos atributos en ninguno de los 5 lugares tenidos en cuenta por GeneXus para determinar la tabla base, se trata de un web panel sin tabla base. Por tratarse de un web panel sin tabla base, el evento Load se ejecuta una sla vez; y en el mismo codificamos explcitamente los accesos con comando for each: cargamos valores en variables y para cargar lneas en el grid utilizamos el comando LOAD. Nota: Observar en este caso que todas las columnas definidas en el grid (variables: &Customer y &Total) son exclusivamente de salida, manteniendo el comportamiento por defecto definido para las variables en un grid. Esto se debe a que no se est utilizando el comando For each line en ninguno de los eventos del web panel, ni tampoco hay definido un evento click asociado a un control del grid (ni OnClickEvent).

295

Comando LOAD
El objetivo del comando LOAD es incluir efectivamente una lnea en un grid. Una vez que se haya asignado valores a todas las variables que sean necesarias, y se desee agregar la lnea al grid, deber ejecutarse el comando LOAD. Solamente se puede especificar el comando LOAD dentro del evento Load del grid de un web panel.

Si en la codificacin del evento Load definimos comandos For each y asignamos valores a las variables en las iteraciones pero no incluimos el comando LOAD, en tiempo de ejecucin estaremos asignando una y otra vez valores a las variables, pero no se estarn agregado lneas en el grid (solamente quedar una lnea en el grid con los ltimos valores cargados en las variables).

296

Web panel con tabla base


Ejemplo
Mostrar para cada cliente el total facturado, pero slo de los clientes que tengan facturas.
Event Load &Total =0 For Each &Total +=InvoiceTotal endfor EndEvent

Atributo Oculto: InvoiceDate Atributo Order: CustomerId Corte de control!

Atributo en el form del web panel: CustomerName Atributo oculto (no visible) en el grid: InvoiceDate Atributo order en el grid: CustomerId Al especificarse este web panel, GeneXus determinar que la tabla base del mismo es INVOICE, significando esto que el web panel tiene un for each implcito asociado, con tabla base INVOICE. Recordemos que en los web panels con tabla base, el evento Load se ejecuta N veces y es muy importante el siguiente concepto: Si en un web panel con tabla base, se incluye un comando for each en el evento Load, dicho for each se anidar al for each implcito asociado al web panel. Es decir, el for each definido en el evento Load no ser un for each independiente. En el web panel del ejemplo, codificamos lo siguiente en su evento Load: - Inicializacin de la variable &Total con valor cero - For each cuya tabla base ser INVOICE (porque el nico atributo que contiene es InvoiceTotal) y dentro del mismo incrementamos la variable &Total con el total de cada factura (InvoiceTotal) recorrida. De modo que como el web panel tiene tabla base INVOICE, en su evento Load definimos un for each con tabla base INVOICE tambin, y definimos un order indicando un criterio de agrupacin, hemos implementado en el web panel con tabla base, un corte de control. En cambio, si no hubisemos puesto el atributo InvoiceDate en el grid, el web panel seguira teniendo tabla base, pero esta vez sera CUSTOMER. En el evento Load se defini un for each con tabla base INVOICE (ya que dentro del comando for each solamente se encuentra el atributo InvoiceTotal). El for each del evento Load no ser un for each independiente, sino que se anidar al for each implcito asociado al web panel y estaremos implementando un join. GeneXus analizar: existe algn atributo relacin entre las tablas CUSTOMER e INVOICE? S, CustomerId. Por lo tanto, GeneXus definir el siguiente filtro automtico en el for each con tabla base INVOICE: INVOICE.CustomerId = CUSTOMER.CustomerId. tabla base del web panel: INVOICE

297

En resumen, cuando se ejecute el evento Refresh del web panel, comenzar a ejecutarse el for each implcito asociado al web panel. Y por cada cliente recorrido, justo antes de cargarse una lnea en el grid con el mismo, se ejecutar el evento Load. Entonces, para ese cliente que se vena recorriendo, se ejecutar el cdigo definido en el evento Load (es decir, se recorrern sus facturas, sumando el total facturado del cliente). Al finalizar la ejecucin del evento Load, se cargar la lnea en el grid. Obsrvese que aqu no es necesario especificar comando Load para realizar la carga: se hace automticamente por el hecho de tener una tabla asociada a este grid. En los eventos de usuario sucede algo parecido: cuando se incluye un for each en un evento de usuario, el mismo no es un for each independiente tampoco, sino que tambin se anidar al for each implcito asociado al web panel. GeneXus considerar qu lnea del grid est seleccionada al momento de ejecutar el evento de usuario (recordar Allowselection = True), y para los datos de la misma ejecutar el evento. De modo que si estando seleccionada determinada lnea con un cliente, se ejecuta un evento de usuario, y el mismo tiene un for each con tabla base INVOICE, se recorrern las facturas del cliente de la lnea seleccionada. Teniendo los conceptos relacionados al objeto web panel bien claros, el analista GeneXus podr optar si definir un web panel con tabla base o sin tabla base.

298

Web panels con N grids


Grids paralelos
Cuando un web panel contiene ms de un grid en su form, GeneXus no determina una nica tabla base asociada al web panel, sino una tabla base asociada a cada grid. Atributos que participan en la determinacin de la tabla base de cada grid:
Los incluidos en el grid (se tienen en cuenta tanto los atributos visibles como los no visibles) Los referenciados en Order y Conditions locales al grid

A diferencia de lo que suceda para un web panel con un solo grid, en el caso de mltiples grids los atributos de la parte fija del web panel no participan en la determinacin de la tabla base de ninguno de ellos, pero debern pertenecer a la tabla extendida de alguno (para que sea posible inferir sus valores). De no respetarse esto, al especificar al web panel, se mostrar en el listado de navegacin resultante, un warning advirtiendo de esta situacin. Los atributos utilizados en los eventos del web panel tampoco participan en la determinacin de la tabla base de ninguno de los grids. Los atributos que se incluyan en los eventos fuera de comandos for each, debern pertenecer a la tabla extendida de alguno de los grids (al igual que los de la parte fija).

299

Web panels con N grids


Grids paralelos - Ejemplos

Una tabla base por grid

No busca ni establece relaciones entre ellas

Ejemplo: Dado que el web panel View Suppliers And Customers tiene ms de un grid en su form, GeneXus no determinar una tabla base asociada al web panel, sino que determinar una tabla base para cada grid. En este ejemplo, no hay definidos ni Order ni Conditions para ninguno de los grids, por lo tanto GeneXus slo tendr en cuenta los atributos incluidos en cada grid para determinar sus tablas bases. La tabla base del grid que se encuentra arriba en el form ser: SUPPLIER y la tabla base del grid que se encuentra abajo en el form ser: CUSTOMER. Es importante resaltar que GeneXus determina la tabla base de cada grid pero no busca ni establece relaciones entre las mismas. Al igual que en el web panel View Suppliers And Customers, en el web panel View Customers And Invoices, GeneXus determinar la tabla base del primer grid (que ser CUSTOMER) y la tabla base del segundo grid (que ser INVOICE), pero no analizar si hay atributos en comn entre ellas, y por ende no definir filtros automticos. Es decir que los grids tendrn asociadas navegaciones independientes o paralelas. Si bien GeneXus no establece relaciones entre las tablas bases de los grids, el analista podr definirlas explcitamente. Primero estudiaremos los eventos en web panels con ms de un grid, y a continuacin veremos cmo definir cargas relacionadas.

300

Grids paralelos Eventos y carga


Un Refresh global No se relacionan las cargas Refresh independiente de grids. Evento Load de cada grid Secuencia de Carga:
Refresh <Grid Control Name1>.Refresh
<Grid Control Name1>.Load <Grid Control Name1>.Load <Grid Control Name1>.Load

Web panels con N grids

N veces si GridControlName1 tiene tabla base. Sino 1. N veces si GridControlName2 tiene tabla base. Sino 1.

<Grid Control Name2>.Refresh


<Grid Control Name2>.Load <Grid Control Name2>.Load <Grid Control Name2>.Load

En web panels con ms de un grid, existe un evento Refresh global y un evento Refresh particular para cada grid. El evento Load, no existe global sino slo a nivel de cada grid. Los eventos Refresh y Load a nivel de grids, deben referenciar al grid usando la siguiente nomenclatura: Event <Grid Control Name>.<Refresh | Load> .... EndEvent Por ejemplo, si en el web panel View Suppliers And Customers, los nombres de los grids son SuppliersGrd y CustomersGrd respectivamente, para codificar los eventos Refresh y Load a nivel de los grids, la sintaxis deber ser: Event SuppliersGrd.Refresh .... EndEvent Event CustomersGrd.Refresh .... EndEvent Event SuppliersGrd.Load .... EndEvent Event CustomersGrd.Load .... EndEvent

Adems de estos eventos a nivel de los grids, estar el evento Refresh global: Event Refresh .... EndEvent La carga de los grids en un web panel se realiza para cada grid de forma independiente. Es decir, an si los datos que se muestran en ambos grids estn relacionados, el especificador no relaciona las cargas. La carga asociada a los grids de un web panel incluye el evento Refresh, o sea que la secuencia de carga de un objeto con 2 grids es como se muestra arriba. La ejecucin del mtodo Refresh de cualquier grid solo se dispara par refrescar dicho grid. El orden en que se cargan los grids es como aparecen en el form: de arriba hacia abajo y de izquierda a derecha. De esa manera, cada uno de los grids se cargar con los datos correspondientes.

301

Web panels con N grids


Grids paralelos - Comandos

Load: La sintaxis sigue siendo Load, pero debe estar incluido dentro del evento load asociado al grid que se est queriendo cargar. Su uso es anlogo al caso de un grid (sin tabla base).
Event Grid1.Load .... Load Endevent

For each line: Debe incluir una referencia al grid de la siguiente forma:
For each line IN <Grid Control Name>

El comando LOAD mantiene la misma sintaxis en Web Panels con ms de un grid. Se debe incluir al mismo para hacer cargas de grids sin tabla base, dentro del evento Load de un grid.

302

Grids paralelos - Cargas Relacionadas

Web panels con N grids

Se requiere la implementacin de un Web Panel que muestre en un grid todos los pases (GrdCountries), y cada vez que el usuario seleccione un pas, que se carguen sus clientes en un segundo grid (GrdCustomers).

SOLUCIN

303

Mltiples grids - Cargas Relacionadas

Web panels con N grids

AllowSelection = True

Event Enter &CountryId = CountryId EndEvent // Enter

AMBOS GRIDS CON TABLA BASE

En la solucin que se presenta, ambos grids han sido definidos con tabla base, as que cada uno de ellos tiene un for each mplicito asociado: GrdCountries tiene un for each implcito asociado que navega la tabla COUNTRY. GrdCustomers tiene un for each implcito asociado que navega la tabla CUSTOMER. Debemos habilitar la seleccin de lnea por parte del usuario para el grid de pases (propiedad AllowSelection del grid GrdCountries). Cuando el usuario la seleccione, presionar el botn View customers para que se desplieguen en el grid inferior todos los clientes del pas seleccionado. Para ello necesitamos guardar en una variable el pas seleccionado, para que luego, cuando se haga la carga del grid de los clientes, puedan stos filtrarse mostrando solo los que correspondan al valor almacenado en esa variable. Es decir, en el evento asociado al botn, asignaremos a la variable &CountryId el valor del pas actual, es decir, del de la lnea seleccionada por el usuario. Recordemos que cuando se presione este botn, se disparar el evento Start, luego se leern las variables del form (en este caso no hay), luego se disparar el evento asociado al botn (all se le dar valor a la variable) y luego se dispararn el evento refresh general y a continuacin los eventos refresh y load para cargar nuevamente el grid de pases, e inmediatamente el refresh y load para cargar los clientes (y aqu se aplicar el filtro asociado). Observar que no necesitamos colocar la variable &CustomerId en el form, puesto que es cargada y utilizada en la misma ejecucin en el servidor, por lo que no pierde su valor. Existen otras soluciones posibles para implementar la carga relacionada en web panels con mltiples grids que veremos a continuacin.

304

Solucin Nro. 2: Grid Grdcountries con tabla base y GrdCustomers sin tabla base

En esta segunda solucin, el grid GrdCountries ha sido definido con tabla base, as que tiene un for each mplicito asociado al mismo, que navega la tabla COUNTRY. Debemos habilitar la seleccin de lnea por parte del usuario sobre este grid, a travs de la propiedad AllowSelection. Una vez que el usuario se posiciona en una lnea y presiona el botn View customers se debe refrescar el grid GrdCustomers con los clientes que pertenezcan a ese pas. Al igual que antes, en el evento asociado al botn (en nuestro caso es el enter), debemos darle valor a la variable para que luego pueda ser utilizada para filtrar. Event Enter &CountryId = CountryId endevent El grid GrdCustomers fue definido sin tabla base asociada, por lo cual debemos programar a mano la carga del grid en el Evento Load. Event GrdCustomers.Load For each where CountryId=&CountryId &CustomerId=CustomerId &CustomerName = CustomerName Load endfor Endevent Como el grid de clientes (GrdCustomers) es sin tabla base; cada vez que se ejecute Refresh para el grid GrdCustomers, a continuacin se ejecutar su evento Load una sola vez. Por lo tanto, programamos en el evento GrdCustomers.Load un for each con tabla base CUSTOMER, filtrando los clientes del pas que habamos cargado en una variable, y agregamos explcitamente los clientes en el grid (asignando a las variables &CustomerId y &CustomerName los valores de los atributos CustomerId y &CustomerName respectivamente y ejecutando el comando Load a continuacin para efectuar la carga de cada lnea). Recordemos que cuando el usuario habiendo seleccionado un pas en el grid correspondiente, presione el botn View customers se realizar un post al servidor, donde se ejecutar el evento Start, luego se leern las variables de pantalla, se ejecutar el cdigo asociado al botn (evento Enter), donde la variable para filtrar es cargada, y a continuacin se dispara el evento Refresh general, y luego el Refresh seguido de N ocurrencias del evento Load del grid de pases (1 por cada pas a ser cargado) y finalmente el evento Refresh del grid de clientes, seguido de un evento Load para ese grid (dentro del cul se cargan las lneas con el comando Load).

305

Solucin Nro. 3: Ambos grids sin tabla base

En esta tercera solucin ambos grids han sido definidos sin tabla base, por lo cual el evento Load de cada grid se ejecutar una sla vez. Event GrdCountries.Load For each &CountryId=CountryId &CountryName=CountryName Load Endfor Endevent Event GrdCustomers.Load For each where CountryId=&CurrentCountryId &CustomerId=CustomerId &CustomerName = CustomerName Load endfor Endevent En el evento Load correspondiente al grid GrdCountries, programamos explcitamente con comando for each y comando Load, que se carguen todos los pases de la tabla COUNTRY. Luego codificamos el evento Enter asociado al botn View customers: Event Enter &currentCountryId = &CountryId Endevent En tiempo de ejecucin, estas 3 soluciones vistas se comportarn igual. Como se ha mencionado anteriormente, si se incorporan bien los conceptos tericos vistos, el analista GeneXus podr optar al definir un web panel, si trabajar con tabla base, sin tabla base o combinando ambas cosas.

306

Grids paralelos - Consideraciones

Web panels con N grids

Acerca de condiciones de filtro Es posible especificar condiciones de filtro tanto a nivel global como a nivel de cada grid. Para cada grid se tendrn en cuenta las condiciones globales y las condiciones locales (es decir: condiciones globales and condiciones locales). Las globales nunca participan de la determinacin de la tabla base No es posible nombrar a un atributo o variable de un grid Ejemplo: GrdCountries.CountryId / GrdCustomers.CountryId S es posible referirse a CountryId, codificar sus propiedades, eventos y mtodos Igualmente no se recomienda tener el mismo atributo / variable en ms de un grid, ya que las codificaciones afectaran a todos

Si por ejemplo el atributo CountryId se agregara en ms de un grid y se codificara: CountryId.Visible=0, atributo CountryId quedara invisible en todos los grids.

el

307

Web panels con N grids


Grids Anidados

Varios niveles de anidacin Anidaciones paralelas Ej: Countries y Customers


ejecucin

Para profundizar en este tema dirigirse al curso de Desarrollo de aplicaciones para Internet con GeneXus

Es posible definir grids anidados en un web panel. Los grids anidados consisten en un grid Freestyle al que se puede insertar dentro de una celda otro grid estndar u otro Freestyle. Por ejemplo, se quiere tener un web panel que muestre los clientes, pero indentados por pas, como se muestra en la imagen en ejecucin arriba a la derecha. Para ello se define un grid freestyle con el pas y dentro de ste se inserta otro grid, en este caso estndar, con los clientes. Puede haber grids anidados de varios niveles y puede haber tambin paralelos. Puede decirse que se est definiendo un rbol en donde cada nodo es un grid. Cada grid puede ser un freestyle o un grid estndar, aunque si es estndar no puede tener ninguno anidado. Los grids estndar slo pueden ser hojas del rbol de anidacin. No se ahondar en el tema en el presente curso. Podr hacerlo en el curso de Desarrollo de aplicaciones para Internet con GeneXus.

308

Web panels
Tipos de Web panels
Component Master Page Web Page

Propiedad Type

Los objetos web pueden ser definidos con tres tipos diferentes, configurable en la propiedad Type del objeto. Para un web panel podr tomar uno de los valores: Component: (transaccin web panel, que a partir de aqu podr ser incluido en otro web object) Master Page Web Page (es decir, el objeto ser una transaccin web panel tal como hemos trabajado hasta el momento) El tipo de web panel Component se analiza en detalle en el curso Desarrollo de Aplicaciones para Internet con GeneXus. A continuacin introduciremos el Web Panel tipo Master Page y su utilizacin.

309

Master Pages

HEADER

CONTENT

Tener un look&feel consistente es hoy en da un deber de toda aplicacin Web. Crear y mantener cada pgina de una aplicacin Web asegurando la consistencia con el resto del sitio gran tiempo de programacin. toma

En el ejemplo presentado arriba, hemos capturado una pantalla del sitio de Sony. Navegando entre las distintas pantallas, nos hemos encontrado que todas ellas tienen un header comn, as como un men a la izquierda de cada pgina. Ambas cosas pueden ser visualizadas en la pantalla capturada arriba. Lo que va variando a medida que uno va navegando por las distintas pginas es lo que aparece a la derecha, y que es el contenido especfico de cada pgina. Cmo implementar un sitio de estas caractersticas? Con el conocimiento que tenemos hasta el momento, tendramos que repetir la parte del Layout comn a todas las pginas del sitio, as como el comportamiento comn, en cada web panel que implementa cada una de esas pginas. Eso introduce dos problemas fundamentales: si hubiera que realizar alguna modificacin a esas partes comunes a todas las pginas, habr que ir pgina por pgina a realizarlo. Y relacionado con esto, la posibilidad de olvidarnos de hacerlo en alguna pgina, o introducir alguna variacin en la misma, degradar la consistencia del sitio. Las Master Pages proveen una forma de centralizar el layout y el comportamiento comn en un solo objeto y reutilizarlo en todo otro objeto sin tener que programar. Esto significa que la modificacin de alguna parte del layout o del comportamiento comn es tan fcil como modificarla en un nico objeto y listo!. Se crear un web panel categorizado como Master Page con todo lo que sea el Layout y comportamiento comn a todas las pginas del sitio, y en el mismo se dejar un espacio para cargar en cada oportunidad la pgina que corresponda (el contenido variable del sitio). Las pginas web que implementan el contenido variable, se implementan como Web Panels o Web Transactions comunes y corrientes (es decir de tipo Web Page, ver pgina anterior), y se asocian a la Master Page, de manera que cada vez que se ejecuten, se carguen con ese contexto.

M ENU

310

Master Pages
Propiedad Type = Master Page Permiten definir en un nico lugar el layout y comportamiento comn a todas las pginas del sitio (especifican el marco o contexto de toda pgina)
Header Men

Marco, contexto de todas las pginas del sitio Lugar donde las pginas individuales sern cargadas.

Master Pages Se crea entonces un objeto Web Panel y se le configura la propiedad Type con el valor Master Page. En una misma base de conocimiento se pueden definir tantas Master Pages como se desee. Una vez que exista al menos una Master Page en la base de conocimiento, puede ser referenciada desde cualquier web panel o web transaction, en la propiedad MasterPage de estos objetos (que por defecto tiene el valor (none)). El efecto de hacer esto ser que al ejecutar estos objetos, se ejecutarn con la master page asociada, es decir, se cargar la master page, y en el hueco es donde se cargar la pgina individual. Se profundiza en Master Pages, Web Components, Embedded Pages, en el curso Desarrollo de Aplicaciones para Internet con GeneXus.

311

PATTERNS

312

Patterns
Es una herramienta que:
es parte de GeneXus 9.0 (Tools / Patterns) puede ejecutarse tambin como aplicacin independiente

Bsicamente permite aplicar a una Base de Conocimiento cierto patrn (pattern), y que se generen todos los objetos GeneXus necesarios para implementar el patrn, para aquellas instancias que se hayan seleccionado. Existe un conjunto de patrones muy tiles ya definidos (al instalar la herramienta se instalan) para que el desarrollador pueda aplicarlos a sus Bases de Conocimiento rpidamente, obteniendo por resultado funcionalidades tiles generadas automticamente. A su vez la herramienta permite crear patrones nuevos, siendo esta una tarea un poco ms compleja.

Puede obtener los requerimientos de software para instalar la herramienta Patterns de la siguiente pgina del Wiki: http://wiki.gxtechnical.com/wiki/tiki-index.php?page=PatternsInstallation

313

Patterns
Algunos patrones (patterns) existentes: WorkWith Bill Of Materials OAV

Catlogo: http://wiki.gxtechnical.com/wiki/tiki-index.php?page=Business+Patterns+Catalog

Work With: Genera a partir de una transaccin (o para todas aquellas transacciones que se deseen), todos los objetos necesarios para tener una aplicacin web. Por ejemplo, si se aplica el pattern Work With a la transaccin Customer, se generar un objeto GeneXus Web Panel que permitir al usuario final consultar interactivamente los clientes de la base de datos (se presentar una pgina web vistosa conteniendo una lista con los clientes de la tabla CUSTOMER). Este Web Panel se llamar Work With Customers y ofrecer entre tantas cosas, un link asociado a cada cliente mostrado en la lista, para que mediante su seleccin se acceda a otro objeto Web Panel (de nombre View Customer) que mostrar todos los datos del cliente (y su informacin relacionada como podran ser facturas, recibos, etc.). El Web Panel Work With Customers adems ofrecer para cada cliente mostrado, la posibilidad de modificar sus datos (habindose agregado automticamente para ello una invocacin a la transaccin Customer) as como la posibilidad de eliminar un registro de cliente, o de insertar un cliente nuevo (invocando a la transaccin Customer para ello tambin). Se podrn configurar variadas propiedades para agregar opciones de filtrado en el Web Panel Work With Customers (por ejemplo para que el usuario final pueda consultar solamente los clientes de cierto pas, o aquellos cuyos nombres se encuentren incluidos en determinado rango); y tambin configurando una simple propiedad se podr incluir en el Web Panel Work With Customers un combo box que ofrezca distintos rdenes posibles, para que el usuario final elija si desea el resultado de la consulta ordenado por nombre de cliente, por cdigo u otro atributo. Si el patrn Work With se aplicara tambin a la transaccin Product obtendramos todas estas funcionalidades para dicha instancia tambin, as como para cada una de las transacciones que se deseen.

Bill of materials: Este patrn permite generar a partir de una transaccin, otra que representa la relacin compuesto componente. OAV: Objeto-Atributo-Valor; Este patrn genera a partir de una transaccin otras dos transacciones que permiten extender la original, con el objetivo de permitir definir atributos en runtime. Adems, seguimos trabajando en la definicin de nuevos patterns. Sugerimos ver catlogo con lista de patterns, algunos de los cuales ya estn implementados y otros sugeridos para una futura implementacin.

314

Patterns
Objetivos y beneficios de la herramienta Patterns: Gran incremento de productividad y calidad en las aplicaciones

Ejemplo de uso: Aplicar el pattern Work With a una KB para generar la mayora de los web objects necesarios para obtener una aplicacin web atractiva y amigable.

315

Patterns
Utilizacin de la herramienta
(mostramos ejemplo aplicando pattern WorkWith) Paso 1
- Contamos con una KB con algunas transacciones (se recomienda prototipo web creado) - Ejecutamos la herramienta Patterns - Desde GeneXus (Tools / Patterns, en el modelo de Diseo) la KB se cerrar automticamente, y se reabrir cuando se cierre la herramienta Patterns - En forma independiente (GeneXusPatterns.exe) ser necesario cerrar la KB desde GeneXus, ya que para utilizar una KB desde la herramienta Patterns debe haberse cerrado previamente desde GeneXus y viceversa tener

Si se ejecuta la herramienta Patterns en forma independiente de GeneXus, ser necesario seleccionar la KB con la cual se trabajar (para ello la herramienta Patterns ofrece el tem: File / Open Knowledge Base). Cuando se trabaja con la herramienta Patterns con una KB por primera vez, se presenta un dilogo cuyo ttulo es Workspace Configuration. Este dilogo permite configurar algunas opciones relacionadas a la KB, otras opciones relacionadas al pattern a ser aplicado, y otras opciones relacionadas a operaciones de GeneXus (impactar, especificar, etc.) que pueden ejecutarse utilizando la herramienta Patterns. En este punto inicial puede cerrarse este dilogo si se desea, y posteriormente es posible ingresar al mismo, mediante el tem Build / Configure GX Integration (ver paso 8).

316

Patterns
Paso 2

- Se despliega informacin de la KB
- Dado que muchos patterns usan TRNs, se muestra una lista de las TRNs disponibles en el tab KB Explorer:

317

Patterns
Paso 3

- Seleccionar en el combo box mostrado en la toolbar, el pattern que se desea aplicar:

Se ofrece por defecto la lista de patterns predefinidos.

318

Patterns
Paso 4
Debemos obtener un instance file por cada caso al cual queramos aplicar el pattern. Instance file = archivo XML con los datos propios de la instancia Si bien es posible crear cada instance file de cero, los patterns suelen proveer una funcionalidad para crear instance files por defecto, y luego poder modificarlos fcilmente. En el caso del pattern WorkWith, en el tab KB Explorer: - Teniendo una TRN (o varias) seleccionada(s) derecho / Generate Instance File - Doble clic en una TRN

botn

Llamamos proceso de instanciacin de un patrn al proceso de aplicar un patrn a una o varias situaciones (instancias). En el proceso de instanciacin de un patrn las entradas son: Instance files: por cada situacin o instancia a la cual se quiera aplicar el patrn, habr que crear un instance file con la informacin propia de esa instancia en particular (atributos a mostrar, etc.). Cada instance file es en definitiva un archivo XML con los datos propios de la instancia, y tal como se explica en la transparencia, los patterns suelen proveer una funcionalidad para crear instance files por defecto (que luego, de considerarse necesario, se pueden modificar fcilmente). Template files: contienen la implementacin del patrn y de su aplicacin a las instancias. El resultado que se obtiene del proceso de instanciacin de un patrn (procesando los instance files y template files) es: un conjunto de objetos GeneXus para ser consolidados en la KB.

319

Patterns
[Paso 5]
- Los instance files pueden editarse en el panel derecho - Dos opciones para hacerlo: Tree View / XML View:

Cada instance file es un archivo XML con estructura jerrquica, conteniendo cada uno de sus nodos un conjunto de propiedades. La herramienta patterns ofrece 2 editores para editar cada instance file en el panel derecho: el editor XML View y el editor Tree View. El editor XML View permite editar los instance file directamente en su formato XML. Por su parte el editor Tree View es mucho ms amigable, sencillo de usar, y con interfaz en alto nivel que provee mayor funcionalidad para ayudar en el proceso de edicin. Por todo esto el editor Tree View es el ms usado y es el recomendado para usuarios no avanzados.

320

Patterns
Paso 6
- Los instance files se deben grabar. Para ello, bajo el tem Instance se ofrecen las opciones Save y Save All.

- Los instance files que no se han salvado an se visualizan con nombre: <TRN Name.Pattern>*. - Una vez salvados se visualizan con el nombre: TRN Name.Pattern (ej: Country.WorkWith).

Save salva el instance file con el que se est trabajando. Los instance files que no se han salvado an se visualizan con nombre: <TRN Name.Pattern>*. Y una vez salvados se visualizan con el nombre: TRN Name.Pattern(por ejemplo: Country.WorkWith). Dnde se almacenan fsicamente los instance files? En el subdirectorio Templates bajo el directorio de la KB. Seleccionando el tab Folder Explorer se pueden visualizar estos archivos:

Save All Salva todos los instance files (si ya existen, pregunta si reemplazar). Es importante tener en cuenta que si se generan los instance files por defecto nuevamente a partir de las transacciones, sern sobrescritos.

321

Patterns
Paso 7
- Una vez creados y editados los instance files, el siguiente paso es que la herramienta genere los objetos GeneXus que implementan el pattern para las instancias. - Opciones:
- Build / Apply Pattern - Build / Apply and Consolidate Se genera en KBPath\Templates\Import, un archivo <TRNName>.xpz.xml por cada instance file

- Posibilidad de que continuacin o que lo desarrollador GeneXus.

se consoliden haga despus

automticamente (desde la KB)

a el

Mediante botn derecho tambin es posible ejecutar estas acciones: es decir, estando posicionado en el tab Folder Explorer, luego de haber seleccionado los instance files (.workwith files), se pueden ejecutar las opciones Apply Pattern o Apply and Consolidate. Nota: Tambin es posible seleccionar una TRN o grupo de TRNs estando posicionado en el tab KB Explorer, y mediante botn derecho ejecutar la opcin Generate, Apply and Consolidate. Pero es importante entender que seleccionando esta opcin, se generarn los instance files por defecto nuevamente para las TRNs seleccionadas, y luego de ello, se generarn los archivos <TRNName>.xpz.xml correspondientes y se consolidarn en la KB. Si se est seguro que los instance files por defecto no necesitan ser editados, es posible seleccionar esta opcin directamente. A su vez es importante saber que si se selecciona la opcin Apply and Consolidate se efectuarn tambin las siguientes acciones: Se configurar como default theme de la aplicacin al theme Fantastic. El directorio Images ser copiado automticamente bajo el directorio KBPath\Templates. La model property "Base image path" del modelo de diseo se configurar con el valor anterior.

322

Patterns
Paso 8
- Desde la herramienta Patterns, es posible ejecutar las acciones que se realizan tambin desde GeneXus: Impactar el modelo, Especificar, Generar, Compilar y Ejecutar.

- Dilogo donde se configura:

Para hacer ms fcil todo el proceso, desde la herramienta Patterns, es posible ejecutar las acciones que se realizan con GeneXus: Impactar el modelo, Especificar, Generar, Compilar y Ejecutar. Estas acciones se configuran en el dilogo Workspace Configuration que se abre en el momento de abrir la KB con la herramienta Patterns, o seleccionando luego la opcin Build / Configure GX Integration. Opciones disponibles en el dilogo Model Muestra los modelos definidos en la KB, y permite seleccionar uno de ellos (se requiere tener los modelos creados y la creacin de sus tablas hechas). Apply and Consolidate Al seleccionar la opcin Apply and Consolidate, es posible ejecutar ms acciones adems de la generacin de objetos y consolidacin. Este combo ofrece las siguientes posibilidades: Consolidate Only (Apply and Consolidate) Impact Model (Apply and Consolidate + Impact Model) Impact, Specify (Apply and Consolidate + Impact + Specify) Impact, Specify, Compile (Apply and Consolidate + Impact + Specify + Compile) Impact, Specify, Compile, Run (Apply and Consolidate + Impact + Specify + Compile + Run) GeneXus Version - La versin de GeneXus correspondiente a la KB se detecta automticamente (puede ser 8.0 o 9.0). El modelo se especificar / generar con dicha versin.

323

Build Actions- Permite seleccionar qu objetos deben especificarse y generarse al seleccionar Specify and Generate. Las opciones disponibles son: - Build All - Build Pending (updated since last specification) Specify Consolidated Objects

Specification Permite seleccionar el tipo de especificacin / generacin a ser ejecutado al seleccionar Specify and Generate. Las opciones disponibles son: Full Specification Check Specification Force Generation

Run Command En esta opcin se debe indicar la URL que se ejecutar si se seleccion la opcin Impact, Specify, Compile, Run. Se debe configurar: para aplicaciones .NET para aplicaciones Java Run Command = http://localhost/services/hhome.aspx o http://localhost:8080/servlet/hhome

Nota: Vale aclarar que home es el nombre de un web panel generado por el patrn WorkWith; el mismo ofrece links a todos los web panels WorkWith generados (y la letra h que antecede a su nombre en la invocacin, corresponde al prefijo que se agrega a todo objeto web panel main o ejecutable que se invoca).

324

Patterns
Resultado en ejecucin

325

Patterns
Cmo modificar los objetos generados? Mediante la herramienta Patterns 1. Modificando las propiedades de las instancias (en la medida que ofrezcan lo que se desea) 2. Modificando el pattern, personalizndolo para que ofrezca configurar propiedades que implementen las necesidades

Mediante GeneXus Modificando los objetos GeneXus generados (Desventaja: en caso de querer volver a generarlos con Patterns, se regeneran los objetos, perdiendo los cambios hechos a los mismos)

326

Patterns
Cmo modificar las propiedades de las instancias?
Archivo de instancia Editor Tree View

Propiedades configurables

Son muchas las propiedades que se ofrecen en los archivos de instancia correspondientes al pattern WorkWith para personalizar el comportamiento de los objetos que se generarn. A continuacin describimos algunas de ellas. El nodo Selection ofrece las propiedades relacionadas al web panel WorkWith que se generar para la instancia. Sus sub-nodos son: Modes Este nodo permite definir en cules modos se ofrecer invocar a la transaccin. Las posibilidades y sus valores por defecto son: Insert: True Update: True Delete: True Display: False Export: True (exportacin a planilla excel) Para casa modo podr especificarse una condicin. Se proveen las siguientes propiedades para ese propsito: Insert Condition Update Condition Delete Condition Display Condition Si se define una condicin asociada a un modo, la invocacin para ese modo solo se habilitar si la evaluacin de la condicin es verdadera (Ejemplo: CountryId=10).

327

Attributes Este nodo permite definir cules atributos se desean mostrar en el grid (y para cada atributo, se pueden personalizar varias propiedades).

Orders Es posible ofrecer al usuario final varios rdenes posibles para ver el resultado de la consulta (es decir, las lneas mostrando los datos en el grid). Utilizando el botn derecho del mouse se puede definir un nuevo orden (su nombre y composicin). Cada orden puede estar compuesto por varios atributos (pudiendo indicar para cada un de ellos si se desea orden ascendente o descendente). Se presentar un combobox en el web panel WorkWith ofreciendo todos los rdenes posibles de seleccionar, para que el usuario final elija uno y los datos se presenten en el grid ordenados por el mismo. Filters Permiten definir condiciones de filtro para que se muestren en el grid solo los registros que cumplan con las mismas.

El nodo View por su parte, ofrece las propiedades relacionadas al web panel View que se generar para la instancia. El web panel View muestra toda la informacin de un registro, que fue seleccionado en el grid del web panel WorkWith (la informacin del registro es mostrada en una solapa de un tab control, y adems hay una solapa con un grid por cada tabla directamente subordinada, para mostrar la informacin relacionada).

328

Observaciones Al crear cada instance file por default, podemos observar que las distintas propiedades del instance file se inicializan con valores por default. Dichos valores por default para las propiedades, se especifican en un archivo denominado NombrePattern.config (en nuestro caso WorkWith.config). El archivo NombrePattern.config se encuentra donde est instalada la herramienta Patterns, bajo el subdirectorio del Pattern particular que se est utilizando. Para el caso del pattern WorkWith estar bajo: Patterns\WorkWith (recordar que bajo el directorio de la herramienta Patterns, existe un subdirectorio por cada patrn predefinido (WorkWith, Bill of Materials, OAV) as como deber haber un subdirectorio por cada patrn definido por el usuario. Si deseamos tener un archivo de configuracin NombrePattern.config por cada KB, debemos copiar este archivo al directorio Templates que se crea bajo la KB al usar la herramienta Patterns; as la herramienta Patterns utilizar dicho archivo ubicado en la KB para inicializar las propiedades de los instance files que se creen. Si la herramienta Patterns no encuentra el directorio Templates con este archivo bajo la KB, utilizar el archivo NombrePattern.Config (en nuestro ejemplo WorkWith.config) ubicado en el directorio Patterns\WorkWith. El WorkWith.Config permite configurar algunos aspectos generales que aplicarn a todos los objetos. Por ejemplo, las master pages a ser utilizadas por los objetos web, los web components utilizados como header y footer, etc.. Para editar este archivo de configuracin, la herramienta Patterns ofrece el tem: Tools/Change Pattern Configuration. Ejemplo:

El pattern WorkWith adems de generar objetos nuevos, hace algunas modificaciones a las trns existentes (regla parm para recibir parmetros del WorkWith correspondiente, etc.). En el archivo WorkWith.config, el valor configurado por default para esta propiedad es Only rules and events.

Propiedad UpdateTransaction, ofrece los siguientes valores: Do not update: La trn no ser modificada (web form, reglas y eventos sern mantenidos) Only rules and events (default value): Solo las reglas y eventos son modificados, pero no el web form. Apply WW Style: la primera vez que el pattern sea aplicado, el comportamiento ser el mismo que si se hubiese seleccionado el valor Create Default. A partir de la segunda vez, el header, footer y botones del form web sern modificados, pero no la Data Area. Los eventos y reglas tambin sern modificados. Create default: el web form, reglas y eventos sern modificados.

329

Ejemplo: Work With desde GeneXus

En el captulo donde estudiamos el objeto web panel, implementamos manualmente un web panel Work With Customer donde agregamos variables al grid para dar un mensaje de cliente moroso si su saldo superaba los $10.000 y para contar la cantidad de facturas que se le realizaron, respectivamente. Habamos asimismo programado el evento Load para lograr lo anterior. Todo esto puede ser codificado automticamente por el Pattern Work With, si ud. agrega en la lista de atributos del archivo de instancia correspondiente, las dos variables anteriores, y asociadas a las mismas en el LoadCode el cdigo asociado, como puede ver en la siguiente pgina.

330

desde Patterns

Se definen las variables &type y &quantity haciendo botn derecho sobre el nodo Attributes y luego, posicionndose en &type, en la ventana de la derecha, en la opcin LoadCode, se ingresa el cdigo que se quiere ejecutar para esa variable, cuando se cargue la lnea.

331

Ejemplo: Work With desde Genexus

Acciones sobre el cliente seleccionado

Asimismo, en el web panel Work With Customer que habamos implementado manualmente antes, agregamos botones para poder realizar las acciones tpicas de un Work With (alta, baja, modificacin, y vista de registro). Asimismo, tuvimos que modificar la transaccin Customer para recibir como parmetro el modo y clave, como se puede recordar en la siguiente pgina.

332

Ejemplo: Work With Customer desde GeneXus


Event Insert Tcustomer.call(INS, 0) Endevent Event Update Tcustomer.call(UPD, CustomerId) Endevent Event Delete Tcustomer.call(DLT, CustomerId) Endevent Event View Tcustomer.call(DSP, CustomerId) Endevent
Pattern crea el enumerado:

En las reglas de la transaccin Customer:


Parm(&Mode, &CustomerId );

CustomerId = &CustomerId if not


&CustomerId.IsEmpty();

El Pattern Work With no implementa estas acciones de la misma manera. Esta herramienta crea un dominio enumerado para los valores que puede tomar la variable &Mode y la implementacin de las acciones en el web panel Work With Customer que realiza es como se muestra en las pginas siguientes. Pattern modificar la transaccin Customer para agregar exactamente las mismas reglas que nosotros escribimos en forma manual.

333

desde Patterns

Event Start NewControl.Link = Link(TCustomer, TrnMode.Insert, CustomerId.SetEmpty()) &Update = LoadBitmap(!"images/edit.gif") Endevent Event Load &Update.Link = Link(TCustomer, TrnMode.Update, CustomerId) Endevent UPD

Aqu podemos ver otra forma de seleccin de una lnea del grid. En el caso anterior utilizamos la propiedad AllowSelection del grid para habilitar la seleccin de una lnea en ejecucin por parte del usuario. Otra opcin es la que implementa el Pattern Work With mediante la utilizacin de variables (en este caso de tipo bitmap, &update y &delete, cargadas con la imagen correspondiente en el evento Start) a las que en el evento Load del grid se les asigna la propiedad Link para determinar el identificador de cliente que se le enva a la transaccin Customer en cada lnea cargada (en el cuadro de arriba solo se incluy el cdigo para cargar la variable &update, pues para la variable &delete es anlogo). Nota: Obsrvese que delante del path relativo a la imagen aparece el smbolo !. No le d importancia. Se utiliza para la herramienta de Traduccin (Application Localization), para evitar que el literal que le siga sea traducido. Como ya mencionamos la herramienta Patterns define el tipo enumerado TrnMode y es por ello que no aparece UPD directamente sino su descripcin TrnMode.Update.

334

USO Y RECOMENDACIONES EN EL USO DE SUBTIPOS

335

Definicin de subtipos
Las relaciones entre atributos GeneXus se establecen a travs de sus nombres. Mediante subtipos se puede establecer que dos atributos que se llaman diferente corresponden al mismo concepto. Se dice que el atributo A es subtipo del atributo B si se cumple una dependencia funcional, o sea para cada valor de A existe un solo valor de B y el valor de A es igual al valor de B.

336

Casos de uso de subtipos


Algunos casos:
Mltiples referencias Especializacin de un nivel (relacin 1-1) Subtipos recursivos Evitar controles de integridad referencial

337

A. Mltiples referencias
Atributos conceptualmente iguales que cumplen roles diferentes (ej.: reservas de pasajes).
Transaccin Reservation
PROBLEMA Atributos con el mismo nombre

Transaccin City CityId * CityName

ReservationId* CityId origen CityId destino


SOLUCION

Transaccin Reservation
Desaparece el problema

Transaccin City CityId* CityName

ReservationId* subtipo ReservationCityFromId subtipo ReservationCityToId

Realidad a representar/disear: en cada reserva hay dos ciudades involucradas, las cuales cumplen roles diferentes. El rol de una de las ciudades es el de ser la ciudad de partida (ciudad origen) y el rol de la otra es el de ciudad de arribo (ciudad destino). El dominio de ambas ciudades es el mismo, el de la tabla CITY. La forma de representar que tanto el origen como el destino son ciudades de la tabla CITY, es diseando la transaccin Reservation en la forma mencionada inicialmente en la transparencia. Sin embargo, no es posible que en la estructura de una transaccin figure el mismo atributo ms de una vez, pues no habra manera de identificarlos. SOLUCIN: llamar a las dos ciudades de la reserva con diferentes nombres de atributos. Cualquiera de las siguientes opciones es vlida. Elegimos la 3era por mayor claridad. Opcin 1) ReservationCityFromId CityId Opcin 2) CityId ciudad origen ciudad destino (mismo nombre que la PK de CITY) ciudad origen (mismo nombre que la PK de CITY) ciudad destino ciudad origen ciudad destino

ReservationCityToId Opcin 3) ReservationCityFromId ReservationCityToId

El problema es que al poner por ejemplo ReservationCityFromId en lugar de CityId, GeneXus deja de inferir que ReservationCityFromId corresponde al cdigo de una ciudad de la tabla de CITY. Cmo hacemos para relacionarlos, siendo que tienen diferente nombre de atributo? ver respuesta en prxima hoja

338

Para estos casos GeneXus provee los SUBTIPOS, que permiten definir que dos atributos que se llaman diferente corresponden al mismo concepto. En nuestro ejemplo, si definimos al atributo ReservationCityFromId como subtipo de CityId, estamos especificando que si bien ReservationCityFromId y CityId son diferentes atributos (de nombres diferentes), corresponden, no obstante, al mismo concepto (una ciudad de la tabla CITY). Al establecer que un atributo es subtipo de otro, estamos estableciendo una dependencia funcional entre ellos. Si ReservationCityFromId es subtipo de CityId, entonces decimos que CityId es el supertipo de ReservationCityFromId. Los atributos que se encuentran en una relacin subtipo-supertipo comparten la misma definicin (tipo de datos). Se realizan los controles de integridad referencial automticamente. La tabla extendida que se obtiene con la definicin del subtipo, es la misma que se obtendra si se utilizara directamente el supertipo.

339

A. Mltiples referencias
Con la definicin de subtipos:
se establece la siguiente relacin: ReservationCityFromId

RESERVATION
ReservationCityToId

CITY

Se hacen adems automticamente los controles de Integridad Referencial (IR) entre ambas tablas cuando se utilizan sus correspondientes transacciones.

Los atributos secundarios de CITY:

pertenecen a la tabla extendida de RESERVATION, pero al existir doble referencia no se pueden utilizar directamente desde RESERVATION (ambigedad de caminos y con valores de ciudades diferentes). Solucin definir tambin subtipos para los atributos secundarios de CITY, e incluirlos en c/u de los grupos de subtipos.

IMPORTANTE: Notar que este caso de mltiples referencias puede darse tanto: en la tabla base (*) como en la tabla extendida (*) es el caso del ejemplo, en el que en la propia tabla (RESERVATION) hay ms de una referencia a otra tabla (CITY) y con valores diferentes.

RESUMIENDO: siempre que desde una tabla se accede a otra que est en su tabla extendida por ms de un camino y con valores diferentes, es necesario definir SUBTIPOS, para poder llamarle diferente a los atributos y hacindose automticamente todos los controles de integridad referencial. Una vez definidos los grupos de subtipos que sean necesarios, la forma de indicarle a GeneXus cul de los caminos debe tomar para acceder a la tabla destino, es mencionando los nombres de atributos que correspondan. Ej.: mencionar ReservationCityFromName si lo que se necesita en ese momento es el nombre de la ciudad origen, o mencionar ReservationCityToName si lo que se necesita es el nombre de la ciudad destino.

340

A. Mltiples referencias
Nombre de c/grupo de subtipos.

Transaccin Reservation
ReservationId* ReservationCityFromId ReservationCityFromName Inferido ReservationCityToId ReservationCityToName Inferido

Tabla Reservation
ReservationId* ReservationCityFromId FK FK ReservationCityToId

Con el grupo estamos indicando que los atributos pertenecientes al mismo grupo de subtipos, estn relacionados. Por ej., en nuestro ejemplo, GeneXus sabr que el atributo ReservationCityToName ser inferido a travs del atributo ReservationCityToId (y no a travs del ReservationCityFromId). Esto es por pertenecer ambos al mismo grupo (al de nombre ReservationCityTo). Cuando el usuario digite un valor sobre ReservationCityToId, no solo se va a hacer automticamente el control de integridad referencial (que exista un ciudad con ese cdigo en la tabla CITY), sino que se va a inferir en ReservationCityToName el nombre correspondiente a ese cdigo de ciudad.

IMPORTANTE: Todo grupo de subtipos, debe contener un atributo o conjunto de atributos, cuyos supertipos, juntos, correspondan a la clave primaria de una tabla del modelo. Estos atributos aparecen en la ventana de edicin del grupo con la categora class: Primary. Los dems atributos del grupo debern ser de tipo Inferred, es decir, debern poder inferirse a travs de esa clave. En caso contrario estar mal definido el grupo.

En nuestro caso, por ej. en el grupo ReservationCityTo: - el atributo ReservationCityToId es el nico que aparece como Primary y podemos comprobar que existe una tabla (CITY) cuya clave primaria es el supertipo de ReservationCityToId (CityId). - adems, el resto de los atributos de ese grupo (ReservationCityToName) aparece como Inferred. con lo cual, comprobamos que este grupo est bien definido.

341

A. Mltiples referencias en la tabla extendida


COUNTRY pertenece a la tabla extendida de SALE por caminos diferentes y con cdigos de pas diferentes.
un camino desde SALE a COUNTRY: a travs del Pas del cliente (CountryId)

CUSTOMER SALE SELLER


Otro camino desde SALE a COUNTRY: a travs del Pas del vendedor (CountryId)
qu pas imprime? cul de los caminos toma? Hay una ambigedad en el modelo de datos!

COUNTRY

Layout

Si quisiramos por ejemplo listar las ventas (SALE), y de c/u de ellas mostrar los datos del cliente (nombre, pas, etc.) y del vendedor (nombre, pas, etc.): necesitamos un for each con tabla base SALE y acceder a travs de su extendida a las tablas CUSTOMER, SELLER y COUNTRY para listar los atributos secundarios del cliente, vendedor y pas respectivamente. Problema: Los atributos de nombre CountryId, CountryName y todos los de la tabla extendida de COUNTRY pertenecen a la tabla extendida de SALE por dos caminos diferentes: 1) a travs del pas del cliente y 2) a travs del pas del vendedor. Solucin: Debemos diferenciarlos, llamarlos con diferente nombre de atributo pero queriendo que se sigan representando todas las relaciones y hacindose automticamente todos los controles de integridad referencial.

342

A. Mltiples referencias en la tabla extendida - Solucin -

Cuando queremos el pas del cliente de la venta: SaleCustomerCountryName


erId om ust aleC S

CUSTOMER COUNTRY SELLER

SALE

Sal

eS e ller

Id

Cuando queremos el pas del vendedor de la venta: SaleSellerCustomerName

Una vez definidos los dos grupos de subtipos que se muestran en la figura, y haciendo el cambio correspondiente en la estructura de la transaccin Sale, queda resuelta la ambigedad en el modelo de datos!

Atributos almacenados en la tabla SALE

Atributos inferidos

343

A. Mltiples referencias en la tabla extendida - Solucin -

SaleCustomerCountryId

SaleSellerCountryId

Problema resuelto!

Una vez definidos los subtipos, tenemos que recordar usar el nombre de atributo que corresponda a lo que queremos acceder. Por ejemplo, en todos aquellos objetos GeneXus en los cuales queramos acceder al cdigo o al nombre del pas del cliente de la venta debemos usar los atributos SaleCustomerCountryId y SaleCustomerCountryName respectivamente.

344

B. Especializacin de atributos
Ej.: Sistema para una Universidad

PERSON datos comunes a profesores


y estudiantes

datos propios TEACHER de los profesores Sistema Teachers

STUDENT datos propios de


los estudiantes

Sistema Students

Caso de subtipos Especializacin de atributos: Cuando se esta modelando una categorizacin. Generalmente es utilizada, cuando un objeto del negocio comparte todas las caractersticas de otro objeto, pero agrega algunas ms. La diferencia puede estar tanto en las propiedades, como en el comportamiento que tendr. Ejemplo Sistema para una Universidad: En este ejemplo, el profesor y el alumno tienen roles y comportamientos claramente diferenciados. Por ejemplo, el profesor tendr cursos asignados, sueldo, etc. El alumno estar inscripto a un curso, tendr asignados pagos, asistencia, escolaridad, etc. Estamos frente a un caso en el que los roles y el tratamiento de las entidades de la categorizacin estn claramente diferenciados. Tanto los estudiantes como los docentes comparten informacin comn (ambos tienen un nombre, una direccin, etc) pero tambin tienen informacin que difiere, que es propia de c/u de ellos. Para representar esta realidad, se crean las tres transacciones: Person, Teacher y Student. En la transaccin Person figura la informacin comn. Para representar que tanto los estudiantes como los docentes son personas, se utilizan los subtipos. Al definir que el identificador de Teacher es subtipo del identificador de Person estamos estableciendo esta relacin. Cada vez que se inserte un registro en la tabla TEACHER a travs de su transaccin, se realizar el chequeo de integridad referencial contra Person. Asimismo, cada vez que se intente eliminar un registro de Person, se verificar primeramente que no exista ningn registro en la tabla TEACHER (ni en STUDENT) con el mismo valor en la clave primaria.

345

B. Especializacin de atributos
Transacciones: Person PersonId* PersonName PersonAddress Teacher TeacherId* TeacherName TeacherAddress TeacherSalary Student StudentId* StudentName StudentAddress StudentAverage

Se crean 3 tablas fsicas. Se realizan chequeos de IR contra la tabla PERSON.

La transaccin Teacher tiene asociada una tabla que contendr fsicamente slo dos atributos: TeacherId y TeacherSalary. Al ser TeacherId identificador de la transaccin, ser la clave primaria de la tabla asociada. Adems, al ser un subtipo de PersonId, ser una clave fornea a la tabla PERSON. Por lo tanto, se harn los chequeos de integridad referencial correspondientes. Los atributos TeacherName y TeacherAddress son subtipos de PersonName y de PersonAddress respectivamente y estn agrupados con TeacherId, por lo que sern inferidos de la tabla PERSON, a travs de la clave fornea TeacherId (no estn almacenados en la tabla TEACHER).

346

C. Subtipos recursivos
Ejemplo: Employee-Manager

Tabla EMPLOYEE
EmployeeId* EmployeeName EmployeeIsManagerFlag EmployeeManagerId FK

Error(Debe ingresar un gerente para el empleado) if EmployeeIsManagerFlag=N and EmployeeManagerId.isnull();

Es posible tener una tabla subordinada a s misma definiendo subtipos. Este tipo de subtipos se utiliza para modelar las relaciones recursivas. Por ejemplo, la relacin entre Empleado y Gerente: - cada empleado tiene un gerente. Un gerente, a su vez, es un empleado (aqu est la - un gerente puede tener varios empleados a su cargo Si adems la realidad a representar es que slo los empleados que no son gerentes tienen un gerente, entonces, cuando se ingresan los datos hay que realizar los siguientes controles: -cuando se ingresan los gerentes, hay que permitir dejar en nulo el atributo EmployeeManagerId. Para esto, cambiamos a Yes la columna Nulls del atributo EmployeeManagerId, el cual es FK en la tabla EMPLOYEE. que todo empleado que no es gerente, tenga un gerente. Este control lo hacemos con la regla error que se muestra en la figura. El atributo EmployeeManagerName no queda almacenado en la tabla EMPLOYEE, se infiere luego de ingresar un valor en EmployeeManagerId. Por ser EmployeeManagerId subtipo de EmployeeId, se realizan automticamente los controles de integridad referencial de la tabla consigo misma. Esto se puede ver en la navegacin de la transaccin, como se muestra en la siguiente pgina. recursin).

347

C. Subtipos recursivos
Listado de navegacin detallado:

348

D. Evitar controles de integridad referencial


Purchase Order History SupplierId* SupplierName ProductId* ProductDescription PurchaseOrderHistoryQuantity Purchase Order PurchaseOrderId* SupplierId ProductId PurchaseOrderQuantity Supplier SupplierId* SupplierName

Product ProductId* ProductDescription

En la figura indicamos automticamente.

con

flechas

los

controles

que

queremos

que

GeneXus

realice

349

D. Evitar controles de integridad referencial


Purchase Order History SupplierId* SupplierName ProductId* ProductDescription PurchaseOrderHistoryQuantity Purchase Order PurchaseOrderId* SupplierId ProductId PurchaseOrderQuantity Supplier SupplierId* SupplierName

Product ProductId* ProductDescription

Pero los controles que en realidad realiza GeneXus en forma automtica son los que se muestran en esta figura. En este ejemplo, no queremos que se realice el chequeo que va de la tabla PURCHASEORDER sobre la tabla PURCHASEORDERHISTORY, porque la orden de compra se realiza antes de que efectivamente se realice la compra, por lo cul, si es la primera compra que se realiza para ese proveedor de ese producto, lgicamente los datos de esa compra no estarn an dados de alta en el histrico. Observar adems que en la transaccin Purchase Order no se est haciendo automticamente un control que s queremos que se haga: el control de proveedor contra la tabla SUPPLIER y de producto contra PRODUCT. Estos controles no se estn haciendo porque al efectuarse el chequeo contra PURCHASEORDERHISTORY, se supone que ya en esa transaccin se cheque que el producto fuera vlido y que el proveedor fuera vlido.

350

D. Evitar controles de integridad referencial


Purchase Order History SupplierId* SupplierName PurchaseOrderHistoryProductId* PurchaseOrderHistoryProductDescription PurchaseOrderHistoryQuantity

Solucin

Cmo evitar que GeneXus controle que el proveedor y producto de una orden de compra existan en la tabla de histrico de compras? Alcanza con cambiarle el nombre de atributo al cdigo de producto (o al cdigo de proveedor) en el histrico de compras, pero conservando el concepto al que corresponde (es decir, definindolo como subtipo de producto o de proveedor segn corresponda). La solucin elegida fue la de cambiarle el nombre al atributo que corresponde al producto en el histrico de compras, le cambiamos a PurchaseOrderHistoryProductId. Adems, definimos a dicho atributo como subtipo de ProductId, para seguir manteniendo la relacin que hay entre Purchase Order History y Product.

351

D. Evitar controles de integridad referencial


Purchase Order History SupplierId* SupplierName PurchaseOrderHistoryProductId* PurchaseOrderHistoryProductDescription PurchaseOrderHistoryQuantity Purchase Order PurchaseOrderId* SupplierId ProductId PurchaseOrderQuantity Supplier SupplierId* SupplierName

Product ProductId* ProductDescription

Luego de haber definido el grupo de subtipos mencionado, y en l a PurchaseOrderHistoryProductId como subtipo de ProductId y a PurchaseOrderHistoryProductDescription como subtipo de ProductDescription y usarlos en la transaccin Purchase Order History, los controles que realiza GeneXus son los que se muestran en la figura (los controles deseados). Como ya no existe una tabla de clave primaria compuesta por los nombres de atributos SupplierId, ProductId, los controles de que el SupplierId y el ProductId digitados en la transaccin Purchase Order existan se hacen sobre las tablas SUPPLIER y PRODUCT respectivamente.

352

Consideraciones
El subtipo y supertipo sern definidos del mismo tipo, GeneXus lo determina as y cuando se define un subtipo ste "hereda" la definicin del supertipo. Al menos uno de los supertipos del grupo (o conjunto de supertipos del grupo) debe(n) corresponder a la PK de una tabla del modelo. Si al definir el grupo, algn atributo queda como Secondary (en lugar de Primary o Inferred), significa que hubo un error en la definicin del grupo.

353

Consideraciones
Es posible actualizar los subtipos inferidos. Ejemplo:
Primary

Inferred

Rules:

Es posible actualizar subtipos inferidos, tanto en las reglas de las transacciones como en procedimientos. Al ejecutar la regla de la transaccin Invoice que se muestra en la figura, el atributo que se actualiza fsicamente es el supertipo CompanyPurchases de la tabla COMPANY. Vale aclarar que CustomerPurchases (al igual que CustomerName) es subtipo inferido y por lo tanto no est almacenado en ninguna tabla.

Tabla extendida de INVOICE: INVOICE, CUSTOMER, COMPANY. Tabla extendida de CUSTOMER: CUSTOMER, COMPANY. Tabla extendida de COMPANY: COMPANY. Tabla INVOICE InvoiceId* InvoiceDate CustomerId InvoiceTotal Tabla CUSTOMER CustomerId* Tabla COMPANY CompanyId* CompanyName CompanyPurchases

354

Consideraciones
En ambientes que generan SQL es posible ordenar por subtipos inferidos.
Siguiendo con el ejemplo anterior: es posible recorrer las facturas ordenadas por nombre de cliente, CustomerName, subtipo inferido a travs de CustomerId: For each order CustomerName print Invoice endfor

Esta posibilidad no est disponible para los generadores que no usan SQL. Por ejemplo: Cobol, RPG y VFP.

355

Consideraciones
Frmulas verticales pueden involucrar subtipos. Ejemplo:

En el ejemplo, se desea modelar la relacin entre personas (Parejas) y sus Hijos. Para cada pareja se desea mantener la cantidad de hijos que tiene. Para esto se define la transaccin Person y luego Couple, siendo el esposo, esposa e hijos subtipos de personas. Los 3 grupos de subtipos definidos son:

356

La cantidad de hijos se calcula con el atributo CoupleChildrenQuantity definido en el primer nivel de la transaccin Couple, como frmula COUNT que involucra en su definicin a un subtipo inferido (CouplePersonChildAge).

357

Consideraciones
Los subtipos inferidos no se pueden definir como redundantes.
Ejemplo:

No se pueden definir como redundantes en la tabla COUPLE.

358

TIPOS DE DATOS ESTRUCTURADOS

359

Tipos de datos estructurados


Introduccin
Los lenguajes de programacin manejan tipos de datos simples y tipos de datos complejos Los tipos de datos complejos se construyen sobre la base de los tipos de datos simples Los tipos de datos complejos conocidos como registros o tipos de datos estructurados, permiten representar conjuntos de datos que juntos realizan una definicin Ejemplo:
Type Customer = Record Id: Name: City: Numeric(4) Character(30) Character(20) CompanyAddress: Character(30) HomeAddress: Character(30) end; end; Luego se definen variables de este tipo, listas de elementos de este tipo, etc.

Country: Character(20) Address: Record

360

Tipos de datos estructurados


GeneXus
Cmo definir un tipo de datos estructurado? 1. Object / New Object 2. En el rbol del ambiente de desarrollo: Structured Data Types... y en la ventana de al lado: botn derecho Editor similar al de transacciones y ofrece las mismas teclas de funcin:

Generadores que soportan este tipo de definicin: JAVA, .NET, VB

El editor de tipos de datos estructurados es sumamente similar al editor de transacciones y ofrece las mismas teclas de acceso rpido. Para cada tem de un tipo de datos estructurado, se debe especificar: La propiedad Name, con el nombre que identifica al tem. La propiedad Data type, en la cual se debe seleccionar un tipo de dato simple, o un dominio, o un tipo de datos estructurado que ya se haya definido. La propiedad Collection, para indicar si el tem tiene o no mltiples instancias (en breve veremos ejemplos que permitirn comprender su uso en detalle). En particular los tems que definen un nuevo nivel, se anteceden con el cono , no se les habilita la propiedad Data Type y se produce la indentacin correspondiente para los tems correspondientes a dicho nivel. Una funcionalidad interesante a tener en cuenta, es que adems de definir tem a tem en un tipo de datos estructurado, tambin est la posibilidad de definir rpidamente en la estructura de un tipo de datos estructurado, la misma definicin de cierta transaccin. Para realizar esto, una vez creado un nuevo tipo de datos estructurado y al estar editando el mismo, se debe pulsar el botn derecho del mouse sobre su raz, y seleccionar la opcin Copy structure from :

361

Tipos de datos estructurados


Utilizacin
Se definen variables (en cualquier objeto GeneXus) cuyo tipo de datos = tipo de datos estructurado:

No es posible utilizar tipos de datos estructurados en la definicin de atributos

362

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 1
En un proc. se define una variable (&Customer) cuyo tipo de datos es del tipo de datos estructurado: Customer El proc. recibe por parmetro un cdigo de cliente, accede con comando For Each a los datos del cliente recibido y carga los datos del cliente en la variable &Customer: Rule: Parm(CustomerId); Source: For each &Customer.Id=CustomerId &Customer.Name=CustomerName &Customer.Country=CountryName &Customer.City=CityName &Customer.Address.CompanyAddress= &Customer.Address.HomeAddress= Endfor

Como se est cargando una variable escalar y no una lista o coleccin, no hay necesidad de solicitar espacio de memoria, ya que el espacio de memoria est creado para la variable como para ser utilizada una vez.

Dado que en este ejemplo se est cargando una variable escalar y no una lista o coleccin, no hay necesidad de solicitar espacio de memoria, ya que el espacio de memoria est creado para la variable como para ser utilizada una vez; as que simplemente se deben asignar los valores que corresponda a los tems de la variable. Para cargar una coleccin, en cambio, s habr que solicitar espacio de memoria para la variable para cada instancia a ser agregada en la lista; luego de solicitado el espacio de memoria, habr que asignar los valores que corresponda a los tems de la variable, y por ltimo agregarla a la lista o coleccin, como veremos.

363

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Partiendo del tipo de datos estructurado: Customer, utilizamos la opcin Object / Save Structured Data Type As para crear un nuevo tipo de datos estructurado de nombre: Customers Hacemos una modificacin al tipo de datos estructurado: Customers propiedad collection de la raz = True:

364

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Configurar la propiedad collection=True para un tem, define que se trata de una coleccin de esos tems y no de uno solo. Notar que al configurar la propiedad collection de un tem con valor True, automticamente se define un nombre por defecto para la propiedad Item name de ese tem:

Esto permite que podamos definir variables del tipo de datos estructurado Customers, y a su vez variables del tipo de datos Customers.CustomersItem

Por ejemplo, de haber configurado para el tem CompanyAddress la propiedad collection con valor True, habramos indicado que se trata de una coleccin o lista (de largo variable) de Addresses de empresa, y no de una sola. Anlogamente, dado que lo que hemos implementado es que el tem: Customers (es decir, la raz del tipo de datos estructurado) tenga valor True en la propiedad collection, lo que hemos definido es que se trata de una coleccin de Customers y no de un Customer solo. Es importante notar que al configurar la propiedad collection de un tem con valor True, automticamente se define para la propiedad Item name de ese tem un nombre por defecto (en este caso: CustomersItem). Esto permite que podamos definir variables del tipo de datos estructurado Customers, y a su vez variables del tipo de datos Customers.CustomersItem. Es sencillo de comprender que definir una variable del tipo Customers significar que estaremos definiendo una coleccin o lista de Customers, mientras que definir una variable del tipo Customers.CustomersItem, significar que estaremos definiendo un solo Customer (o un tem de la coleccin de Customers, que veremos enseguida cmo hacer para agregarlo a la coleccin).

365

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Implementamos proc. que carga una lista de clientes El proc. recibe por parmetro un rango de cdigos de clientes, con comando For Each accedemos a los clientes que se encuentren en dicho rango, y los vamos agregando a la coleccin. Rule: Parm(&CustomerIdStart, &CustomerIdEnd); Se definen 2 variables: &Customers (Data Type: Customers) &CustomersItem (Data Type: Customers.CustomersItem) Source:

366

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Source: For each where CustomerId>=&CustomerIdStart and CustomerId<=&CustomerIdEnd &CustomersItem.Id=CustomerId &CustomersItem.Name=CustomerName &CustomersItem.Country=CountryName &CustomersItem.City=CityName &CustomersItem.Address.CompanyAddress= &CustomersItem.Address.HomeAddress= &Customers.add(&CustomersItem) /*se agrega el tem a la lista*/ &CustomersItem = new Customers.CustomersItem() /*se solicita nuevo Endfor

espacio de memoria para prximo tem*/

Como ya hemos mencionado, para una variable hay creado espacio de memoria como para ser utilizada una vez. Si se necesita crear otra instancia para la variable, habr que solicitar espacio de memoria para la misma, para lo cual contamos con el operador new.

367

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Qu pasara si no solicitamos nuevo espacio de memoria en cada iteracin del for each? ... es decir, si omitimos el new en el cdigo anterior ...

En cada iteracin estaramos sobreescribiendo el mismo espacio de memoria... y agregando a la lista siempre punteros al mismo espacio de memoria.

368

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 2:
Sin embargo lo que necesitamos implementar se esquematiza de la siguiente forma:

Por lo tanto, es necesario ir solicitando un nuevo espacio de memoria para cada referencia a ser agregada en la lista

369

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 3:
Hacemos lo mismo que en el ejemplo #2 (proc. que carga una coleccin de clientes), mostrando otra solucin En este caso: utilizamos la definicin del tipo de datos estructurado: Customer y definimos otro tipo de datos estructurado: CustomerList

Se definen 2 variables

&CustomerList (Data Type: CustomerList) &Customer (Data Type: CustomerList. CustomerListItem)

370

Tipos de datos estructurados


Ejemplos de utilizacin
Ejemplo # 3:
Source: For each where CustomerId>=&CustomerIdStart and CustomerId<=&CustomerIdEnd &Customer.OneCustomer.Id=CustomerId &Customer.OneCustomer.Name=CustomerName &Customer.OneCustomer.Country=CountryName &Customer.OneCustomer.City=CityName &Customer.OneCustomer.Address.CompanyAddress= &Customer.OneCustomer.Address.HomeAddress= &CustomerList.add(&Customer) //se agrega el tem a la lista &Customer = new CustomerList. CustomerListItem() /* se solicita nuevo
espacio de memoria

Endfor

para prximo tem */

En este caso la variable &customersitem es del tipo de datos ListaCustomers.ListaCustomersItem, el cual contiene un nico tem que es: OneCustomer; y dado que el tem OneCustomer es del tipo de datos Customer, este contiene los tems Id, Name, Country, City, etc. De modo que si bien el ejemplo #3 implementa exactamente lo mismo que el ejemplo #2, como en este ltimo hemos optado por otra alternativa de definicin de tipos de datos estructurados, la sintaxis en este caso queda un poquito ms extensa.

371

Tipos de datos estructurados


Operadores, mtodos y propiedades

New Es un operador que retorna una nueva instancia inicializada, o sea una nueva referencia o puntero al tipo de datos que se especifica. Sintaxis: &VbleDeTipoDeDatosEstructurado = new TipoDeDatosEstructurado()

Add Es un mtodo para aplicar a variable de tipo coleccin. Agrega un tem a una coleccin, en la posicin relativa especificada. Sintaxis: &VbleDeTipoColeccion.Add(&VbleItem [, Position])

Nota: Si se omite Position o se especifica 0, se agrega el Item al final de la coleccin. Position comienza en 1.

Item Es un mtodo para aplicar a variable de tipo coleccin. Sintaxis: &VbleDeTipoColeccion.Item(Position) Retorna una referencia al elemento que se encuentra en la coleccin en la posicin relativa Position. En caso de especificar posicin mayor a la ltima, el programa cancela. No es vlido asignar un valor con esta propiedad, por lo tanto no es correcto el cdigo &VbleDeTipoColeccion.item(&i) = Att. Para cambiar un valor se debe remover (mtodo remove) y agregar (mtodo add).

372

Remove Es un mtodo para aplicar a variable de tipo coleccin. Elimina el elemento que se encuentre en la coleccin en la posicin relativa que se especifique, y corre un lugar todas las posiciones. Sintaxis: &VbleDeTipoColeccion.Remove(Position)

Clear Es un mtodo para aplicar a variable de tipo coleccin. Elimina todos los elementos de la coleccin. Sintaxis: &VbleDeTipoColeccion.Clear()

Sort Es un mtodo que permite ordenar los elementos de una coleccin. El campo por el cual se quiere ordenar debe ir entre comillas. Sintaxis: &VbleDeTipoColeccion.Sort(NombreCampoPorElCualOrdenar") Es posible ordenar en forma descendente, poniendo dentro de las comillas al nombre del campo entre corchetes rectos. Es posible ordenar por ms de un campo, poniendo dentro de las comillas los nombres de los campos separados por coma.

Count Es una propiedad de variable de tipo coleccin. Retorna la cantidad de elementos de la coleccin. Es read only.

373

Tipos de datos estructurados


Comando para recorrer colecciones
For &Var in &Array ... Endfor
&Var: debe ser del tipo de datos de un tem de la coleccin &Array: debe ser del tipo de datos que es coleccin La variable &Var va tomando los valores de cada posicin de la lista Consideraciones: No es posible obtener la posicin del vector durante la recorrida, para esto es necesario definir un variable que acte como contador. No es posible modificar los tems de la lista en la recorrida. Esto significa que cambios en el valor de &Var, en el alcance de la estructura, no afectan al correspondiente valor del &Array(X) o viceversa. Es posible incluir comandos de corte de la recorrida, al igual que en for each o do while, como exit o return.

374

Tipos de datos estructurados


Cmo mostrarlos en form
Ejemplo: Insercin de variable &Invoice de tipo de datos estructurado Invoice:

en form de Transaccin, Work panel o Web panel

Es posible insertar en el form de Transacciones, Web y Work Panels variables de tipo de datos estructurados. Tambin es posible hacerlo en print blocks de reportes, siempre y cuando no sean collection. Desplegar una collection en un form se puede hacer de forma muy sencilla: solamente es necesario insertar la variable en el form, y quedar asociada a un grid que ser cargado automticamente, sin necesidad de cdigo alguno.

375

Tipos de datos estructurados


Cmo mostrarlos en form
2 posibilidades:
1) Pallete Toolbar shortcut 2) Insert/Variable permite seleccin mltiple

Hay que repetir este paso para c/atributo del 1er nivel que se desee mostrar en el form Notar que es una sola variable definida (NO una variable por c/atributo)

376

Tipos de datos estructurados


Cmo mostrarlos en form
En cuanto al grid:

Carga automtica: No se requiere cdigo!

Como hemos visto, hay 2 posibilidades para insertar una variable de tipo SDT con sus respectivos atributos en un form / layout: mediante el shortcut : cada &variable.atributo uno a uno

mediante insert/variable: mltiple seleccin de atributos de variable de tipo SDT Si utilizando la opcin insert/variable se selecciona algn (o algunos) atributo(s) correspondientes a una collection, dicho(s) atributo(s) se agregarn automticamente en un grid (y en las Grid Properties del grid, se podr observar que automticamente se habr asignado en el combo Collection, el nombre del nivel al cual pertenecen los atributos). Si en cambio se utiliza el shortcut para ir agregando atributos del primer nivel del SDT en el form, y se utiliza el shortcut para agregar un grid en el form con el fin de mostrar una collection, el analista tendr que seleccionar explcitamente en el combo Collection de las Grid Properties, el nivel del SDT, para luego poder seleccionar cules atributos de dicho nivel desea incluir en el grid. En tiempo de ejecucin, la carga del grid se realizar en forma completamente automtica, con el contenido de la collection. Esto podr verse en el listado de navegacin:

Nota: Un detalle a tener en cuenta es que independientemente de la forma en que se seleccionen los atributos de una collection para ser mostrados en un grid, los mismos estarn en columnas visibles del grid, y los restantes atributos del nivel (los no seleccionados) se agregarn hidden.

377

Tipos de datos estructurados


Cmo mostrarlos en form
Propiedad CurrentItem: Para collections Permite desplegar informacin de los atributos del tem actual en el grid Ejemplo: Event DisplayProductDescription'
msg(&invoice.line.CurrentItem.ProductDescription)

EndEvent

Si por ejemplo en el work panel visto (Invoice) deseamos agregar un botn con un evento asociado y mostrar un mensaje para la lnea del grid seleccionada, con informacin de ese tem de la coleccin, contamos a partir de la versin 9.0 con la propiedad CurrentItem.

378

BUSINESS COMPONENTS

379

Business Components
Objetivo Reutilizar la lgica del negocio definida en las transacciones. Usar el poder de las transacciones (sin sus forms) desde otros objetos GeneXus:
- Work panels, Web panels, Procedimientos, Reportes y desde otra Transaccin! - Java, .Net - Win, Web

Beneficios - Actualizacin a la BD garantizando la integridad de los datos. - Reutilizacin de cdigo. - Todos los objetos GX pueden actualizar la BD.

380

Business Components
Algunos ejemplos de uso

Work Panels / Web Panels / Transacciones:


Definir interfaces sofisticadas permitiendo insertar los datos correspondientes a 2 o ms transacciones por medio de una (o por medio de un Work Panel o Web Panel)! Personalizar UTL entre 2 o ms transacciones Web! Utilizar un nico form para insertar en una Especializacin u otro caso

Procedimientos:
Utilizar concepto de BC en vez de For Each, New, Delete cuando se deseen ejecutar las reglas definidas en la Transaccin, controles IR, mantenimiento de redundancia, sin duplicar cdigo

Web Services:
Es posible permitir que desde fuera de la KB se consuma un BC como web service

Consumir un BC como web service Un Web Service es un programa que puede ser invocado a travs de Internet para brindar un servicio, y utiliza el estndard XML para el formato de los datos recibidos/devueltos. La versin 9.0 de GeneXus ofrece que desde fuera de la KB sea posible consumir un BC como web service. Para esto hay que: Marcar a la transaccin como BC: Propiedad Business Component = True Marcar a la transaccin como Web Service: Propiedad Expose as Web Service = True

381

Cmo definir un Business Component?


1. Configurar la propiedad Business Component de la Transaccin con valor True (default=False). Una vez que la propiedad Business Component de cierta Transaccin = True

Business Components

2.

En cualquier objeto GeneXus se podr definir una variable del tipo de datos BC asociado a la transaccin, y configurar sus propiedades y mtodos.

Veamos un ejemplo

382

Ejemplo: Insercin de una invoice con 2 lneas mediante proc.

Business Components

Business Component = True

Dos nuevos tipos de datos creados por GeneXus: Invoice nombre de la transaccin Invoice.LineType nombre de la transaccin.valor de la columna Type del nivel En cualquier objeto ser posible definir variables de estos tipos de datos y las mismas tendrn: un conjunto de propiedades asociadas (los atributos de la TRN definida como BC) un conjunto de mtodos asociados (para insertar, eliminar, recuperar, etc.)
variable del tipo de datos BC Invoice

mtodos propiedades

Las transacciones tienen la propiedad Business Component. El valor predeterminado de esta propiedad es False. Si se cambia al valor True, la transaccin puede ser invocada desde cualquier objeto GeneXus como Business Component, sin ejecutar su form. Una vez definida una transaccin como Business Component, GeneXus crear automticamente un nuevo tipo de datos Business Component cuyo nombre ser el de la transaccin; y crear tambin tantos tipos de datos como niveles posea la transaccin, siendo sus nombres el resultado de la concatenacin del nombre de la transaccin con el nombre dado a cada nivel (valor de la columna Type del nivel).

383

Ejemplo: Insercin de una invoice con 2 lneas mediante proc.


Source del procedimiento: //invoice &Inv.InvoiceId = 1 &Inv.CustomerId = 50 //invoiceline &Invline.ProductId = 1 &Invline.InvoiceLineQuantity = 10 &Inv.Line.Add(&Invline) &Invline = new Invoice. LineType() &Invline.ProductId = 2 &Invline.InvoiceLineQuantity = 20 &Inv.Line.Add(&Invline) &Inv.Save() // &Messages= &Inv.GetMessages() for &Message in &Messages msg( &Message.Id) msg( &Message.Description) endfor Commit &Inv tipo de datos BC Invoice tipo de datos BC Invoice.LineType

Business Components

&InvLine

a partir del 2do registro a dar de alta en una lista es necesario el new

hay que hacer slo &Inv.Save(), NO hay que hacer &InvLine.Save() Recomendacin: despus de los mtodos Save, Delete Load y Check, manejar siempre los errores.

Los BC ignoran la property del objeto Commit on exit Nunca hacen commit/rollback automticamente. Recordar ponerlos explcitamente

Se ejecutan los controles de IR, mantenimiento de redundancias, frmulas, eventos Start y After Trn y las reglas de la transaccin Invoice. El form de la trn NO se ejecuta.

384

Reglas y eventos que se ejecutan


Reglas: Todas las reglas son ejecutadas excepto (son ignoradas por el especificador): las que incluyen user interface (Ej: call(Wxxx)). las que no aplican: Parm, Prompt, NoPrompt, Default_mode, etc. Eventos: Todos los eventos de la transaccin son ignorados, excepto los eventos Start y After TRN (y si stos incluyen referencias a objetos con user interface, se ignoran).

Business Components

ACLARACIN: lo explicado que se ignora, aplica solamente a cuando la trn es invocada como BC desde cualquier objeto GX.

385

Business Components
Manejo de errores
Existe un tipo de datos estructurado (SDT) predefinido por GeneXus de nombre Messages:

Hay que definir una variable del tipo de datos Messages y asignarle el resultado de aplicar el mtodo GetMessages a la variable de tipo BC : &Messages= &Inv.GetMessages() Se obtendrn: Los mensajes generados automticamente por GeneXus que se hayan disparado (Ej.: Record already exist) Las reglas Error y Msg definidas en la transaccin que se hayan disparado Hay que recorrer la lista de errores y trabajarlos

Cuando se ejecutan los mtodos: Save, Check, Load, Delete se disparan y cargan los mensajes generados automticamente por GeneXus as como las reglas Msg y Error definidos en la transaccin. Se recomienda que siempre se recupere la lista de estos mensajes y se haga un manejo de errores. Los mensajes ms comunes generados automticamente por GeneXus son:

Las reglas Msg y Error a partir de la versin 9.0 de GeneXus, aceptan en su definicin adems del parmetro con el mensaje a desplegar, un segundo parmetro que define el Identificador del mensaje. El objetivo de esto, es que cuando se ejecute a la transaccin como Bussiness Component, y se obtenga la lista de mensajes ocurridos luego de ejecutar una accin sobre la base de datos, se tenga de cada mensaje, adems del mensaje en s, su identificador, siendo posible as evaluar el identificador del mensaje para codificar el comportamiento en consecuencia: Msg|Error(<mensaje>, <Id del mensaje>) Ejemplos de <Id del mensaje>: "1", "2", "Error1", "Error2" o una descripcin como ser "CustomerNameCannotBeEmpty", etc. De no especificar un identificador para el mensaje, habr que preguntar por el texto del mensaje. Nota: Para los mensajes generados automticamente por GeneXus, el Id es siempre en Ingls (independientemente del idioma seleccionado en el modelo).

386

Mtodos asociados a las variables de tipo de datos BC


PK del primer nivel de la transaccin Load(PKAttri1, ..., PKAttriN) Carga en variable de tipo BC toda su estructura Ej: &Empleado.Load(&EmployeeId) Check() Valida los datos pero no actualiza la base de datos Usado para dilogos en los que se quiere validar los datos (dndole un feedback al usuario) antes de actualizar la BD Save()

Business Components

Valida los datos y actualiza la base de datos Slo vlido para aplicar a variables de tipo BC del primer nivel de la transaccin Ej: &Inv.Save() commit

Delete() Elimina en la base de datos el registro cargado en la variable de tipo BC Ej: &Empleado.Load(&EmployeeId) &Empleado.Delete() commit

387

Mtodos asociados a las variables de tipo de datos BC


GetMessages() Devuelve la lista de errores que ocurrieron luego de efectuar una operacin a la BD Ej: &Messages= &Inv.GetMessages()

Business Components

Fail()

Devuelve True si luego de haber efectuado una operacin a la BD dio algn error Ej: &Inv.Save() If &Bc.Fail() &Messages = &Inv.GetMessages() for &Message in &Messages .....

Success() Devuelve True si luego de haber efectuado una operacin a la BD, la operacin fue exitosa

Add(&BCLine) Permite agregar un tem a una coleccin (en este caso, a la coleccin de lneas correspondiente a un nivel subordinado de la variable BC) Ej.: &Inv.Line.Add(&Invline)

Los mtodos GetMessages(), Fail() y Success() se han explicado recientemente al mostrar el manejo de errores.

388

Cmo programar un BC en un work panel, web panel o reporte?


Ejemplo para un web panel, con variable de tipo de datos BC Invoice 1. Crear en web panel variable &Invoice del tipo de datos BC Invoice 2. Insertar la variable &Invoice en el form (vale lo mismo explicado para insertar variables de tipo SDT... ya que un BC es un SDT con la estructura de su transaccin). 3. Programar los eventos:
Event 'Get' &Invoice.Load(&Invoice.InvoiceId) do "error handling" EndEvent // 'Get Event 'Save' &Invoice.Save() do "error handling" if &Invoice.Fail() rollback else commit endif EndEvent // 'Save' Event 'Delete' &Invoice.Delete() do "error handling" if &Invoice.Fail() rollback else commit endif EndEvent // 'Delete' Sub "error handling" &Messages=&Invoice.GetMessages() for &Message in &Messages msg(&Message.Id) msg(&Message.Description) endfor EndSub

Business Components

Desventajas con respecto a la Trn Invoice: - Hay que poner noaccept para aquellas variables que no se deseen aceptar - No se cuenta con la property Client Side Validation - En la Trn no hay que hacer la codificacin de estos eventos

389

Qu es mejor: actualizacin directa o usando BC?


Directa: New CustomerId = &CustomeriId CustomerName = &CustomerName Endnew

Business Components

Usando BC: &Customer.CustomerId = &CustomerId &Customer.CustomerName = &CustomerName &Customer.Save()

Cul de los mtodos es el mejor? Depende. - Desde el punto de vista de la performance, la directa es la mejor ya que no se hacen controles. -Desde el punto de vista de la consistencia, es mejor usar BC ya que siempre (independientemente de si los datos vienen desde un form o de un procedimiento) se hacen todos los controles. Por lo tanto, una buena regla podra ser: Usar Business Components a menos que la performance sea crtica. De modo que para elegir una opcin u otra, el analista deber evaluar en cada caso qu necesita efectuar, si la transaccin implicada tiene muchas reglas definidas o no, frmulas, chequeos de IR relacionados, redundancias... y tener en cuenta los factores consistencia y performance.

390

KNOWLEDGE MANAGER

391

Distribucin

Se generar el archivo MyObjects.xpz en la raz de la KB

Una vez seleccionados los objetos a distribuir (exportar) e indicado el nombre del archivo de distribucin (en el ejemplo: MyObjects), se crea automticamente un archivo comprimido de extensin XPZ. Este archivo comprimido contiene dentro un archivo XML que contiene la informacin de los objetos y/o atributos distribuidos. En Distribution Name podemos poner un path donde guardar el archivo de distribucin. Si no se pone path, como en el caso de arriba, entonces quedar almacenado en el directorio raz de la Base de Conocimiento. En el ejemplo, si abrimos el archivo MyObjects.xpz con una herramienta tipo WinZip, veremos que contiene un archivo de nombre MyObjects_1.xml Distribute Options Append to File: Si en el Distribution Name del dilogo de distribucin se ingresa de nombre un archivo que ya existe, al salir del campo se habilita esta opcin para poder agregar la nueva distribucin al archivo existente. Si se marca la opcin Append to File, se crea un nuevo archivo XML dentro del mismo XPZ. Siguiendo con el ejemplo anterior, se creara un archivo MyObjects_2.xml en el archivo MyObjects.xpz. Si ya existe un archivo con ese nombre, se incrementa el sufijo en uno y se vuelve a intentar. Si no se marca la opcin Append to File, el archivo se reemplaza con la nueva distribucin. Version 7.0 (And prior): Mediante esta opcin es posible que el archivo de exportacin resultante sea creado con el formato utilizado hasta la versin 7.0 de GeneXus inclusive (extensin XPW).

392

Consolidacin

Pide el path del archivo a ser consolidado

La forma de importar objetos, atributos y dominios GeneXus dentro de una base de conocimiento es mediante la opcin Consolidate del Knowledge Manager. Lo que se importa son objetos previamente distribuidos, en un archivo que puede tener tres formatos: XPZ, XML o XPW. XPZ: Cuando se selecciona un archivo con este formato, el Knowledge Manager (KMW) recorre el contenido del archivo XPZ y consolida cada uno de los archivos internos, siempre y cuando tengan el formato XML apropiado. XML: En algunos casos puede ser necesario consolidar algn XML en particular de todos los que contiene el XPZ. Para este caso se puede descomprimir y consolidar directamente el XML. XPW: Para poder tener compatibilidad con las versiones anteriores de GeneXus, componente encargado de realizar la conversin de un archivo XPW a un archivo XML. existe un

La consolidacin solo puede ser realizada en el modelo de Diseo. Procesos de verificacin y consolidacin son ejecutados simultneamente una vez que hemos seleccionado el archivo de distribucin y presionado Ok. Una vez que esos procesos terminan se despliega una ventana con los resultados para que el usuario pueda observarlos.

393

GX OPEN

394

GX Open
GX Open es un sitio que ofrece compartir proyectos entre los miembros de la comunidad GeneXus. Cada proyecto puede tener varias versiones. Para cada versin, se pueden almacenar todos los archivos relacionados al mismo: XPZs, imgenes, propiedades salvadas, docs, etc. Cada proyecto y versin tiene un foro, as los usuarios pueden discutir acerca del mismo, y proponer cambios. Para bajar o subir proyectos es necesario registrarse como miembro (sin cargo).

www.gxopen.com

395

PUESTA EN PRODUCCIN

396

Puesta en Produccin

Una vez que el prototipo ha sido completamente testeado y aprobado, llega el momento de poner en produccin la aplicacin

397

Creacin de modelo de Produccin

Primera vez: 1. Una vez que el prototipo ha sido aprobado, es momento de pasar a produccin, creando un modelo de Produccin. Este modelo tendr como plataforma la del cliente, dado que los programas que se llevarn al cliente son los que se obtengan de aqu. Al crear este modelo, como con todo modelo de Prototipo o de Produccin, se crearn las tablas en la base de datos asociada. Para ello ocurre exactamente lo mismo que vimos para Prototipo: GeneXus genera un programa de creacin de tablas en el lenguaje de programacin asociado al modelo, (cuyo nombre depende del generador: por ejemplo, para visual basic, es RMenu , para .Net es Reor), ste programa se compila, crendose un ejecutable que luego es corrido y obteniendo la creacin de las tablas. Ejemplo: Creamos el modelo de Produccin: Sistema Facturacin y Compras, y elegimos la misma plataforma (recordar que esto no tiene por qu ser as: la plataforma de prototipo y produccin pueden diferir). GeneXus crea el programa Reor en .Net. Luego, si el usuario da el ok a la reorganizacin, este archivo Reor se compila, y el archivo resultante Reor.exe se coloca bajo el folder bin del modelo (DATA002) y a continuacin se ejecuta. Este programa contendr la lgica correspondiente a la creacin de las tablas INVOICE, CUSTOMER, PRODUCT y COUNTRY, con sus respectivas restricciones referenciales e ndices. 2. Como sucede en el pasaje de Diseo a cualquier modelo de Prototipo, al pasar a este modelo de Produccin, todos los objetos GeneXus son copiados del modelo de Diseo al nuevo modelo. Aqu se especifican y generan, obtenindose por tanto los programas ejecutables bajo el directorio del modelo. Con esto tenemos todo lo necesario para llevar la aplicacin pronta al cliente. Ejemplo: Especificamos y generamos las transacciones Invoice, Customer, Product y Country y todos los dems objetos que hayamos creado (reportes, procedimientos, work panels, etc.). 3. Debemos llevar la aplicacin a lo del cliente. De modo que debemos llevar el programa que crea la base de datos (Rmenu.exe o Reor.exe) y ejecutarlo en la mquina del cliente, obteniendo como resultado la creacin de la base de datos. Tambin debemos llevar los programas de la aplicacin. Dependiendo de la plataforma, ser necesario registrar dlls en la mquina destino. Para algunas plataformas que requieren modificar el registry de Windows, o que requieren seguir algunos pasos un poco ms complejos de configuracin, GeneXus brinda utilitarios de manera tal de poder obtener un setup de la aplicacin para ser ejecutado en el cliente y despreocuparse de hacer tales registraciones en forma manual. Para plataformas visuales, tales como Visual Basic y Visual FoxPro GeneXus cuenta con el Setup Wizard. Este utilitario es un wizard que va pidiendo, al pasar por sus distintas pantallas, la informacin necesaria cul es el modelo de Produccin, etc.- para poder armar el setup que incluya las dlls para hacer tanto las registraciones necesarias en el cliente, como incluya la aplicacin completa para que quede instalada y pronta para trabajar. El anlogo del Setup Wizard para plataforma Java es el Deployment Wizard.

398

La plataforma .Net por el momento no cuenta con un utilitario como estos, debido fundamentalmente a que las dlls necesarias no tienen que ser registradas, dado que corren bajo el Framework de .Net, por lo que simplemente deben copiarse los archivos del folder /bin que estn bajo el modelo de Produccin correspondiente, al cliente y ejecutar luego el Reor.exe para crear la base de datos. Llegado este punto, tenemos nuestro modelo de Produccin como un espejo de lo que tiene el cliente instalado. 4. Luego de la puesta en produccin, surgirn cambios a realizar en la aplicacin (el usuario nos pedir cambios, nos brindar nuevo conocimiento, etc.), que nos llevarn nuevamente a la fase de diseo, volviendo a iterar en el ciclo Diseo-Prototipo, hasta que los cambios implementados hayan sido suficientemente testeados y aprobados. En este punto, volveremos a pasar a Produccin, lo que conducir, otra vez, a que GeneXus realice un anlisis de impacto, comparando la base de datos de Produccin, con el diseo de la misma correspondiente al modelo de Diseo. Si encuentra cambios, entonces generar nuevamente el programa de reorganizacin (Reor.exe o RMenu.exe) de la base de datos, cuya lgica implementar la modificacin de la base de datos actual de Produccin, para llevarla al nuevo diseo. Este programa deber ser llevado y ejecutado en el cliente para transformar la base de datos que tena (era un espejo de la de Produccin) a la nueva. Tambin deberemos especificar y generar en el modelo de Produccin los programas que hayan cambiado y llevarlos al cliente (se utilizar el utilitario que corresponda: Setup Wizard, Deployment Wizard o se llevar el directorio /bin para instalar la 2da versin de la aplicacin al cliente). Terminado este punto, volveremos a tener un espejo en el modelo de Produccin de lo que hay en el cliente. Tendremos que dejar congelado el modelo de Produccin y volver a iterar en el ciclo DiseoPrototipo. Esto es fundamental porque la versin de Produccin es la versin fiel de lo que tiene el cliente. Nota: En el caso de hacerse dos pasajes de Diseo a Produccin consecutivos sin haber ido a lo del cliente, es imprescindible guardar cada uno de los programas de reorganizacin ejecutados en orden. Por qu? Porque si hacemos dos o ms pasajes de Diseo a Produccin sin guardar cada uno de los programas de reorganizacin que se ejecutaron (Reor.exe o RMenu.exe), no tendremos cada adaptacin hecha la base de datos en forma consecutiva y no podremos reorganizar la base de datos del cliente! De acuerdo a la plataforma del cliente de su aplicacin, dirjase al manual de GeneXus para dicha plataforma, a la GXDL, o a las Release Notes en la seccin especfica para la plataforma xxx- para estudiar los detalles particulares de la puesta en produccin de una aplicacin en esa plataforma.

399

INTRODUCCIN A LA METODOLOGA GENEXUS

Presentaremos una introduccin a la Metodologa GeneXus. De estar interesado en profundizar ms en este tema, el alumno podr inscribirse al curso Gestin de Proyectos GeneXus si as lo desea, y/o recurrir a la documentacin existente.

400

Filosofa de GeneXus

Integrar los sistemas en un gran sistema corporativo

Sistema de Compras Sistema de Ventas

Sistema de Sueldos

La filosofa de GeneXus tiende a la integracin de los sistemas en un gran sistema corporativo. Es decir, el objetivo es implementar para una empresa dada, un gran sistema integrado con base de datos corporativa, de la cual se pueda obtener informacin de gestin y gerencial para la toma de decisiones.

401

Con herramientas tradicionales...


Suele resultar muy complejo lograr el desarrollo de sistemas corporativos... Generalmente se desarrollan soluciones independientes para cada rea operativa de la empresa:
Sistema de Compras Sistema de Ventas PROBLEMA: no se cuenta en la empresa con informacin corporativa, resultando ser informacin no confiable

Sistema de Sueldos

Implementar un sistema corporativo suele resultar una tarea muy compleja cuando se utilizan herramientas tradicionales, por lo que generalmente no se lleva a cabo. Esto trae como resultado que se tengan aplicaciones independientes, cada una resolviendo un problema operativo particular, sin la posibilidad de obtener informacin corporativa. As encontramos por ejemplo en una empresa comercial: una aplicacin de Ventas, otra de Compras, otra Contable, etc. En consecuencia no se cuenta en la empresa con informacin corporativa, resultando por lo tanto ser informacin no confiable (por la aparicin de informacin redundante).

402

Sistemas Corporativos
La integracin de las Aplicaciones operativas de la Organizacin es la base para poder construir los sistemas para el rea de Gestin y Gerencial:

INFORMACION GERENCIAL

APLICACIONES PARA EL REA DE GESTION

APLICACIONES PARA EL AREA OPERATIVA

403

Cmo lograr Sistemas Corporativos?


1. Dividir el problema (modularizar) 2. Crear varios frentes de desarrollo 3. Asegurar la integrabilidad 4. Obtener una sola Base de Datos Corporativa

404

1. Dividir el problema (Modularizar)


Por qu modularizar? Para: Dividir el problema en partes ms pequeas Habilitar frentes de desarrollo en paralelo Reducir los tiempos de desarrollo Incrementar la calidad de cada solucin

Como resultado de la modularizacin, se obtiene un conjunto de mdulos a ser desarrollados

La razn principal para modularizar es entonces, dividir el problema en partes ms pequeas y habilitar varios frentes de desarrollo con el fin de hacer ms eficiente la labor. Realizar esta divisin (modularizacin) puede que no sea una tarea sencilla y depender de las caractersticas de cada aplicacin, sin embargo debemos hacerlo cuando el problema adquiere un determinado tamao tal que deba ser desarrollado por ms de una persona. No existen procedimientos exactos para esta tarea, pero cuando la realicemos no debemos olvidar que el principal objetivo es obtener ambientes de desarrollo lo ms independientes posibles, reconociendo que seguramente los mdulos no sern disjuntos y compartirn cierto conocimiento. Debemos sin embargo, intentar que el conjunto de los objetos que compartan sea lo ms pequeo posible para poderlo administrarlo mejor, y realizar posteriormente una ms fcil integracin en un nico modelo corporativo.

405

2. Crear varios frentes de desarrollo


Luego de asignado cada mdulo a cada persona o equipo de desarrollo, surge la pregunta es conveniente realizar el desarrollo en una sola KB o en KBs independientes ?

KB Compras

Desarrollo: KBs independientes Produccin: Todas las KBs son consolidadas en KB Corporativa

KB Sueldos

KB Corporativa

KB Ventas

El desarrollo de un mdulo tiene asociados ciclos de prototipacin y puesta en produccin propios. Estos ciclos tienen asociados reorganizaciones de la Base de Datos (considerar que las reorganizaciones son tareas monousuario), as como especificaciones y generaciones de objetos. No es recomendable que los ciclos de un mdulo en particular, afecten el desarrollo de los dems mdulos que estn siendo desarrollados en forma simultnea, como ocurre en el caso que compartan la Base de Datos. Por esta razn, es conveniente que los mdulos se implementen en Bases de Conocimiento independientes, para posteriormente integrarlos (consolidarlos) todos, en otra Base de Conocimiento.

406

3. Desarrollar asegurando la Integrabilidad de las KBs


Las KBs no son disjuntas, sino que comparten cierto conocimiento. La siguiente pregunta que surge es Cmo administrar el conocimiento en comn, para que al momento de consolidar todas las KBs el impacto sea mnimo? Plantearemos el tema suponiendo por un momento, que en una empresa se realiza la divisin del sistema a desarrollar en 2 mdulos y 2 equipos comienzan con el desarrollo de KBs diferentes sin coordinar nada de antemano...

407

Ejemplo
KB 1 COMPRAS KB 2 VENTAS Objetos: Objetos:

Proveedores Clientes FacturasCompra FacturasVta Productos - - - - - - - - - - - - - - - - - - - -Productos Bancos - - - - - - - - - - - - - - - - - - - - - -Bancos Agencias - - - - - - - - - - - - - - - - - - - - -Agencias Compras Ventas OrdenesCompra NotasCredito

DATOS

PROGRAMAS

DATOS

PROGRAMAS

En el ejemplo tenemos dos mdulos correspondientes a un sistema: el mdulo de compras y el mdulo de ventas. Sern desarrollados en forma independiente por dos equipos de desarrollo distintos, que probarn sus prototipos con sus propios datos, hasta que est todo listo para ponerlo en produccin. Ahora bien, observemos que estos dos mdulos no son disjuntos, sino que comparten informacin comn; entre otras cosas, ambos trabajan con productos, con bancos y con agencias. Observemos que pasar a la hora de integrar ambos mdulos en la KB Corporativa (a la cual solemos llamarla tambin KB Consolidado). Supongamos que primeramente consolidamos el mdulo de Compras

408

Ejemplo
Consolidacin de KB1 (COMPRAS) COMPRAS COMPRAS

KB CONSOLIDADO

Base de Datos

PROGRAMAS

Ha quedado en la KB Consolidado el conocimiento que aport el mdulo de Compras.

409

Ejemplo
Consolidacin de KB2 (VENTAS) COMPRAS COMPRAS VENTAS VENTAS
Proceso de consolidacin

Anlisis de Impacto

KB CONSOLIDADO

Base de Datos

PROGRAMAS

Ahora hemos consolidado en la KB Consolidado el mdulo de Ventas. Como los mdulos no son disjuntos, surgirn alteraciones a lo consolidado anteriormente, y los cambios a ser efectuados se mostrarn en el reporte de anlisis de impacto. Con este ejemplo pretendemos despertar la atencin sobre los problemas inherentes a la integracin de KBs, sin haber coordinado previamente el factor Integrabilidad.

410

Ejemplo
Problemas que surgen en la consolidacin del conocimiento
Objetos diferentes se llaman igual Objetos iguales se llaman diferente Atributos diferentes tienen el mismo nombre Atributos iguales tienen diferente nombre
COMPRAS KB2 VENTAS

KB1

Objeto: Invoice Descripcin: Supplier Invoice SupplierInvoiceId* SupplierId* SupplierName InvoiceDate (ProductId* ......)

Objeto: Invoice Descripcin: Customer Invoice CustomerInvoiceId* CustomerId CustomerName InvoiceDate (ProductNum* .......)

Qu problemas encontramos en el ejemplo que venimos viendo? 1. Objetos diferentes que se llaman igual Las Transacciones Supplier Invoice y Customer Invoice se llaman igual: Invoice Al integrar ambos modelos solo quedar la ltima consolidada.

2. Atributos diferentes tienen el mismo nombre En este caso tenemos dos atributos que son conceptualmente diferentes y tienen el mismo nombre: InvoiceDate Al momento de efectuar la segunda consolidacin, GeneXus asumir que se refieren al mismo concepto y tratar de normalizar encontrando un problema: "Existe un atributo secundario en dos tablas", por lo que informar el error y la Base de Datos no podr ser creada ni reorganizada.

3. Atributos iguales tienen diferente nombre Tambin encontramos el caso de que el atributo que identifica al Producto, debera llamarse igual en ambos objetos por tratarse del mismo concepto, pero fue llamado diferente : ProductId y ProductNum. As GeneXus no puede reconocer que se est haciendo referencia al mismo elemento y no establece ninguna relacin para el concepto de Producto.

411

Ejemplo
Problemas que surgen en la consolidacin del conocimiento
Visiones diferentes de las relaciones Por ejemplo: KB 1 Transaccin Bank BankId* BankName Transaccin Agency AgencyId* AgencyName BankId BankName KB 2 Transaccin Bancos BankId* BankName (AgencyId* AgencyName)

Otro problema que puede ocurrir es que los desarrolladores definan visiones diferentes de la relacin entre los objetos. Supongamos que tenemos 2 equipos desarrollando aplicaciones en un ambiente bancario. Ambas aplicaciones, hacen referencia a las entidades Banco y Agencia. Los 2 equipos de desarrollo tienen clara que la relacin que existe entre Bancos y Agencias es una relacin de 1 a N : BANCO ---->> AGENCIAS Sin embargo definen visiones diferentes, como se muestra arriba en la KB1 y KB2. En la KB1 el atributo AgencyId identifica unvocamente una agencia. Y en la KB2 la agencia queda identificada por la dupla BankId, AgencyId. En este caso, no tenemos problema de nomenclatura, pero al integrar, solo quedar definida la primer relacin , o sea: AgencyId* BankId y no: BankId* AgencyId* Dado que los identificadores en las transacciones juegan un papel fundamental, esto puede dejar invlidos objetos definidos en la segunda aplicacin. Concluimos entonces, que las relaciones entre atributos y los identificadores de las diferentes entidades, juegan tambin un papel fundamental en el momento de integrar diferentes aplicaciones.

412

Cmo trabajar para minimizar los problemas de integracin?


Definir y seguir un padrn de nomenclatura
para los objetos para los atributos (Nomenclatura GIK)

Disear y seguir una Metodologa para administrar el conocimiento comn


a continuacin...

Como hemos visto, los problemas de integracin se reducen a problemas de nomenclatura y de definicin de relaciones e identificadores. Veremos posibles soluciones para minimizar estos problemas: 1. Definir y seguir un padrn de nomenclatura Como sabemos GeneXus establece la relacin entre los objetos y define la normalizacin de la Base de Datos, basndose en los nombres de los atributos. Es por eso que al momento de consolidar, la nomenclatura utilizada para los atributos juega un papel primordial. Sin embargo, no son menos importantes los nombres de los objetos (transacciones, procedimientos, etc.) pues el Knowledge Manager reemplaza en la consolidacin, los objetos con igual nombre. Los nombres dados a las Tablas, ndices y Data Views sern tambin controlados en el momento de la consolidacin y debern ser nicos en el Modelo consolidado, por lo que debemos intentar reducir conflictos tambin en este sentido. En cuanto a los nombres de las variables, a pesar de que no son relevantes para la consolidacin, ya que son definiciones locales, igual se sugiere tener una nomenclatura para las mismas con el fin de tener uniformidad en el desarrollo y mejorar as la comprensin de las aplicaciones. 2. Disear y seguir una Metodologa para administrar el conocimiento comn Una vez definidos los mdulos y establecida la padronizacin para los objetos del sistema, es el momento de disear una metodologa para administrar el conocimiento de forma tal de mantener ambientes independientes de desarrollo y asegurar su integracin en un Modelo Corporativo que tenga asociada una sola Base de Datos corporativa. Hemos solucionado parcialmente los problemas de integracin definiendo una nomenclatura standard para objetos, pero queda an potenciarla y asegurar la integracin desde el punto de vista de relaciones, es decir asegurar que los objetos compartidos por ms de un mdulo guarden la misma relacin con el resto de los objetos. Para ello, expondremos a continuacin un esquema basado en tres tipos de Modelos, que cumplen funciones diferentes en la tarea de administrar el conocimiento.

413

Metodologa basada en 3 tipos de Bases de Conocimiento


Base de Conocimiento NCLEO: Contiene los objetos corporativos, compartidos por las diferentes aplicaciones. Base de Conocimiento asociada a una APLICACIN: Contiene el conocimiento de uno de los Mdulos, resultado de la modularizacin. Base de Conocimiento CORPORATIVA: Contiene la consolidacin de todas las bases de conocimiento asociadas a las aplicaciones y el Ncleo.

414

Metodologa basada en 3 tipos de Bases de Conocimiento


KB KB NUCLEO NUCLEO

KB KB COMPRAS COMPRAS

KB KB VENTAS VENTAS

KB KB SUELDOS SUELDOS

KB CORPORATIVA

BASE DE DATOS

PROGRAMAS

415

Metodologa basada en 3 tipos de Bases de Conocimiento KB Ncleo


Ser posible identificar los elementos comunes a varios mdulos antes de su desarrollo, e incluir stos en una KB Ncleo? S. En poco tiempo es posible definir un conjunto de transacciones que definan cuales son las entidades y/u objetos bsicos de la organizacin que a priori sabemos van a ser compartidos por los mdulos.

416

Metodologa basada en 3 tipos de Bases de Conocimiento Objetivo KB Ncleo


Administrar en forma centralizada el conocimiento compartido para tener un marco de referencia nico. La Base de Conocimiento Ncleo es el ambiente que habilita la administracin de este conocimiento. Darle nombre a lo que conocemos es de esencia corporativa, evitando as mltiples nominaciones para un mismo objeto y para sus atributos.

417

Metodologa basada en 3 tipos de Bases de Conocimiento


KB Ncleo = Interseccin de KBs Aplicaciones

KB COMPRAS KB NUCLEO KB SUELDOS KB CORPORATIVA KB VENTAS

418

Metodologa basada en 3 tipos de Bases de Conocimiento


FOLDER NUCLEO

KB KB NUCLEO NUCLEO
FOLDER VENTAS FOLDER NUCLEO FOLDER SUELDOS

FOLDER NUCLEO

FOLDER COMPRAS

FOLDER NUCLEO

KB KB COMPRAS COMPRAS

KB KB VENTAS VENTAS

KB KB SUELDOS SUELDOS

FOLDER COMPRAS

FOLDER NUCLEO

FOLDER VENTAS

FOLDER SUELDOS

KB CORPORATIVA

BASE DE DATOS

PROGRAMAS

En cada KB (Ncleo y Mdulos) se deber crear un folder, y los objetos propios de dicha KB, debern ubicarse dentro de ese folder. Es decir, en la KB Ncleo habr que crear un folder llamado Ncleo, en la KB Compras ser necesario crear un folder llamado Compras, en la KB Ventas un folder llamado Ventas, y en la KB Sueldos un folder llamado Sueldos. La primer KB a ser definida ser la KB Ncleo. Para ello habr que identificar los objetos comunes a todos los mdulos (por ejemplo, las transacciones Banks, Agencies, Products, Customers) y definirlos dentro del folder Ncleo de la KB Ncleo. Una vez definido el Ncleo, este deber distribuirse y consolidarse en cada una de las KBs asociadas a cada aplicacin, para asegurarse el compartir todas los mismos objetos comunes, exactamente. De modo que lo que se distribuir ser el folder Ncleo de la KB Ncleo, y se consolidar en cada una de las KBs asociadas a una aplicacin (KB Compras, KB Ventas y KB Sueldos) as como en la KB Corporativa. Recin luego de esto, cada desarrollador responsable de un mdulo podr comenzar a trabajar, debiendo crear todos los objetos propios de su mdulo, en el folder correspondiente a ese mdulo en particular. As, la KB Compras tendr 2 folders: el folder Nucleo con los objetos comunes a todos los mdulos, y el folder Compras con los objetos propios que implementen ese mdulo. Anlogamente, las KBs Ventas y Sueldos tendrn el folder Nucleo y su folder propio. Cada KB asociada a una aplicacin tendr un ambiente de Prototipacin, y un ambiente de Test en la plataforma de Produccin. Estos modelos permitirn tener un diseo completo de la aplicacin, minimizando los tiempos de desarrollo pues: 1. Se estar trabajando con KBs pequeas, asegurando la integrabilidad con el resto de las aplicaciones 2. Se estarn realizando los primeros niveles de test de funcionalidad para el mdulo en forma independiente asegurando un ciclo de prototipacin dinmico 3. No se afectar al resto del desarrollo En la medida que cada desarrollador de por finalizado su mdulo, distribuir el folder propio de su KB (por ejemplo el folder Sueldos de la KB Sueldos) y este se consolidar en la KB Corporativa. No distribuir el folder Nucleo de la KB Sueldos, ya que este folder solo se distribuye de la KB Nucleo).

419

Metodologa basada en 3 tipos de Bases de Conocimiento


Administracin de las KBs correspondientes a mdulos
1. Se consolida el Ncleo 2. Se crea un folder propio, es decir que identifique a la aplicacin, y en el mismo se crean los objetos de la aplicacin 3. Una vez finalizado el desarrollo y test del mdulo, se distribuir el folder propio para consolidarlo en la KB Corporativa. Cambios en objetos del Ncleo se deben realizar en la KB Ncleo y luego deben ser redistribuidos a todas las KBs. Incorporar objetos de esencia corporativa en el Ncleo

Cmo se procede si uno de los mdulos requiere modificar un objeto del Ncleo? Es decir, supongamos que el desarrollador de un mdulo se da cuenta que le resulta necesario para su aplicacin, agregar un atributo en una transaccin del Ncleo. Esto tendr un impacto en todas las KBs de aplicacin, y por tanto deber administrarse con cuidado. La forma de proceder es realizar el cambio en la KB Ncleo, y luego redistribuir el Ncleo (folder Ncleo de la KB Ncleo) a todas las KBs.

420

Metodologa basada en 3 tipos de Bases de Conocimiento


Caractersticas de la KB Corporativa
Contiene el Ncleo y las Aplicaciones Ventajas: Integridad total de la Base de Datos Minimiza la redundancia de Datos Base para construir la Informacin Corporativa de la Organizacin

421

S-ar putea să vă placă și