You are on page 1of 502

Desarrollo de

Aplicaciones Basadas
en Tecnologas
Genexus

Introduccin Terica

Herramientas y Metodologas

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.

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.

Desarrollo con GeneXus

REALIDAD
DESCRIPCIN
DE OBJETOS

BASE DE
CONOCIMIENTO

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.

Desarrollo con GeneXus


REALIDAD

BASE
DE
DATOS

DESCRIPCIN
DE OBJETOS

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.

Algunos objetos GeneXus

Transacciones
(Trns)

Procedimientos
(Procs)

Data Providers

Web Panels

(DP)

(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.
Procedimientos
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. Adems, permiten la
actualizacin de la informacin de la base de datos.
Data Providers
Permiten cargar y devolver datos jerrquicos para intercambio de informacin entre objetos de la
misma aplicacin o de otras aplicaciones.
Web Panels
Permiten al usuario realizar interactivamente consultas a la base de datos, a travs de una
pantalla. Ejemplo: un web 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 web muy flexibles que se prestan para mltiples usos. No permiten la actualizacin
de la base de datos, sino solo su consulta.

Proceso de desarrollo de una


aplicacin con GeneXus
Transacciones
(Trns)

Procedimientos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base
Basede
deConocimiento
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.

Creacin de la Base de Datos


Transacciones
(Trns)

Procedimientos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base
Basede
deConocimiento
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.

Generacin de los
Programas de la aplicacin
Transacciones
(Trns)

Procedimientos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base
Basede
deConocimiento
Conocimiento

Base
de
Datos

Programas de Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

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

10

Resultado final en la Etapa de


Desarrollo
Transacciones
(Trns)

Procedimientos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base
Basede
deConocimiento
Conocimiento

Base
de
Datos

Programas de Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

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

11

Las visiones de los usuarios cambian


Nuevas
Transacciones

Nuevos
Procedimientos

Nuevos
Data Providers

Nuevos
Web Panels

Base
Basede
deConocimiento
Conocimiento

Base
de
Datos

Nueva
Nueva
Base
Base
de
de
Datos
Datos

Programas de Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

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.

12

Anlisis de Impacto Automtico


Nuevas
Transacciones

Nuevos
Procedimientos

Anlisis
de
impacto

Base
de
Datos

Nuevos
Data Providers

Nuevos
Web Panels

Base
Basede
deConocimiento
Conocimiento

Nueva
Nueva
Base
Base
de
de
Datos
Datos

Programas de Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

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.

13

Generacin de Programas de
Reorganizacin de la Base de Datos
Nuevas
Transacciones

Nuevos
Procedimientos

Programas
de
Reorganiz.

Base
de
Datos

Nuevos
Data Providers

Nuevos
Web Panels

Base
Basede
deConocimiento
Conocimiento

Nueva
Nueva
Base
Base
de
de
Datos
Datos

Programas de Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

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.

14

Anlisis automtico del impacto


de los cambios sobre los programas
Nuevas
Transacciones

Nuevos
Procedimientos

Nuevos
Data Providers

Base
Basede
deConocimiento
Conocimiento

Nueva
Base
de
Datos

Nuevos
Web Panels

Anlisis
de Impacto
sobre los
programas

Nuevos Programas de
Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

Ya sea que se requiera reorganizar la base de datos o no, considerando las nuevas definiciones
introducidas, GeneXus estudiar el impacto de los cambios sobre los programas actuales.

15

Generacin automtica de nuevos


programas
Nuevas
Transacciones

Nuevos
Procedimientos

Nuevos
Data Providers

Base
Basede
deConocimiento
Conocimiento

Nueva
Base
de
Datos

Nuevos
Web Panels

Generacin
de
programas

Nuevos Programas de
Aplicacin
(Trns, Procs, Wbps, DPs, etc.)

Por ltimo, GeneXus proseguir con la generacin/regeneracin de los programas de


aplicacin que sean necesarios, obteniendo as una nueva versin de la aplicacin.

16

Nueva realidad, con los cambios en la


aplicacin
Nuevas
Transacciones

Nuevos
Procedimientos

Nuevos
Data Providers

Nuevos
Web Panels

Base
Basede
deConocimiento
Conocimiento

Nueva
Base
de
Datos

Nuevos Programas de Aplicacin

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

17

Environments
Ellugardondesealmacenalainformacinparagenerarla
aplicacinenciertaplataformadeejecucinsellamaEnvironment.
Environments:
Implementation #1
C# & SQL Server

C#
Application

SQL

Implementation #2
GeneXus
Project

C# & MySQL

C#
Application

MySQL

Implementation #3
Java Application

Java & MySQL

MySQL

Knowledge Base

ElusodevariosEnvironments permitedistintasimplementaciones
delamismaaplicacin.

18

Environments
Cuandosecreaunabasedeconocimiento(KB),GeneXuspideal
usuarioqueseleccioneelEnvironment conelquevaatrabajar:

Conestosdatos,secreaautomticamenteunEnvironment.

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 como el siguiente:

Se deber indicar;
Nombre de la Knowledge Base: en nuestro caso ser BillingSystem.
Directorio donde se crear.
El Environment por defecto: vea como se muestran lenguajes de programacin. GeneXus los utilizar para
crear los programas asociados a la base de datos. Las opciones ofrecidas son: C# Environment, Java
Environment y Ruby Environment.
Language: Idioma en el que aparecern los botones, mensajes, etc.
Al momento de crear la KB se comienza a definir el ambiente de implementacin (Environment) cuyas
definiciones sern luego completadas al momento de ejecutar la aplicacin (nombre de la base de datos,
servidor, forma de conexin, etc).

19

Environments
ParaverelEnvironment creado,seleccionamoslaventanade
Preferences delKnowledge BaseNavigator:

Default
Environment

20

Environments
Paratenerimplementacionesendistintasplataformas,creamos
variosEnvironments.

21

Environments
VemoslosEnvironments creados:
Environments:

C# & SQL Server

GeneXus
Project
Java & MySQL

Knowledge Base

El environment activo est sealado en negrita y tiene el cono de Play

22

Metodologa Incremental
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.

23

Metodologa Incremental
Paraaplicarundesarrolloincremental,puedomanejardistintas
versiones delaaplicacin.

Versin para prototipacin.


Versin para poner enproduccin.

Sobre el versionado (de qu se trata, cmo realizarlo, etc.) volveremos al final. Por ahora alcanza con
saber que al crear la base de conocimiento, los programas que estaremos ejecutando, programas
reales, sern una versin de la aplicacin, de prueba. Una vez que decidamos que esa versin est
lista para ser puesta en produccin, alcanzar con hacer otra versin de la aplicacin, y listo!.

24

Ventajas de la Prototipacin

Permiteverresultadosenformatemprana.
Permiteelseguimientodelosrequerimientosdelusuario.
Deteccindeerroresenformatemprana.
Lograelcompromisodelosusuariosconeldesarrollo.
Sistemasdemejorcalidad.

Toda comunicacin es susceptible de errores:

El usuario olvida ciertos detalles


El analista no toma nota de algunos elementos
El usuario se equivoca en algunas apreciaciones
El 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).

25

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.

26

Transacciones
Generalidades
Definicin
Objeto a partir del cual GeneXus crear en forma
automtica la base de datos en 3era forma normal
Describen las visiones de los usuarios.
Contienen toda la informacin necesaria acerca de los datos de
la aplicacin y de cmo los usuarios accedern al sistema para su
manejo (insertar, modificar y eliminar).
Elementos que las componen:

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.
Web Form: 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.
Variables: Permite la definicin de variables que sern 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.
Category y Work With: Patterns (patrones) que pueden ser aplicados a la Transaccin con el fin de
implementar en forma automtica cierta funcionalidad.
Algunos de estos elementos tambin estn asociados a otros tipos de objetos GeneXus.

27

Transacciones
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.

-------------------------------------------------------------------------------------------------------------1 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.

28

Transacciones
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.

29

Transacciones
Estructura
Ejemplo: Se necesita registrar informacin referente a facturas de venta.
Invoice
{
InvoiceId*
InvoiceDate
CustomerId
CustomerName

Identificador de factura
Fecha de factura
Identificador de cliente
Nombre de cliente

Detail
{
ProductId*
Identificador de producto
ProductDescription
Descripcin de producto
ProductPrice
Precio de producto
InvoiceDetailQuantity
Cantidad de producto llevada en la lnea
InvoiceDetailAmount
Importe de lnea de factura
}
InvoiceAmount
Importe total de la 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 llaves; el segundo nivel corresponde al conjunto de atributos que se encuentra entre llaves1.
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 llaves 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.

30

Transacciones
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:
Invoice {
InvoiceId*
InvoiceDate
CustomerId
CustomerName
InvoiceAmount
Detail
{ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount}
Payment
{InvoicePaymentDate*
InvoicePaymentAmount}
}

Invoice {
InvoiceId*
InvoiceDate
CustomerId
CustomerName
InvoiceAmount
Detail
{ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount
Payment
{InvoicePaymentDate*
InvoicePaymentAmount}}
}

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.
------------------------------------------------------------------------------------------------------------------1 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.

31

Transacciones
Definicin del modelo de datos: estructuras de las transacciones

Transaccin
Supplier
{
SupplierId*
SupplierName
SupplierAddress
SupplierPhone
}

Invoice
{
InvoiceId*
InvoiceDate
CustomerId
CustomerName

InvoiceId*
InvoiceDate
CustomerId
CustomerName
InvoiceAmount

Detail
{
ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount
}
InvoiceAmount

Tabla
SUPPLIER
SupplierId*
SupplierName
SupplierAddress
SupplierPhone

Tabla
INVOICE

Transaccin

Tabla
INVOICEDETAIL
InvoiceId*
ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount

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.

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

32

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

InvoiceAmount

Clave primaria: InvoiceId


Tabla INVOICEDETAIL correspondiente al segundo nivel de la transaccin:

INVOICEDETAIL

InvoiceId

ProductId

InvoiceDetailQuantity

ProductDescription

ProductPrice

InvoiceDetailAmount

Clave primaria: {InvoiceId, ProductId}


Clave fornea: InvoiceId
ya que las dependencias funcionales son:
InvoiceId {CustomerId, CustomerName, InvoiceDate, InvoiceAmount}
{InvoiceId, ProductId} {ProductDescription, ProductPrice, InvoiceDetailQuantity,
InvoiceDetailAmount}
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 INVOICEDETAIL, dado que el
nombre del primer nivel es el de la transaccin, INVOICE, y el del segundo nivel es DETAIL. Los
nombres de las tablas pueden ser modificados por el analista GeneXus cuando as lo desee.

33

Transacciones
Estructura
Al definir las nuevas transacciones:

Customer
{
CustomerId*
CustomerName
CustomerAddress
CustomerGender
}

Sexo del cliente

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 {CustomerName, CustomerAddress, CustomerGender, CustomerStatus}
ProductId {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

34

Transacciones
Normalizacin: cambios en las tablas
Tabla
INVOICE
InvoiceId*
InvoiceDate
CustomerId
CustomerName
InvoiceAmount

Tabla
INVOICEDETAIL
InvoiceId*
ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount

Tabla CUSTOMER
CustomerId*
CustomerName
CustomerAddress
CustomerGender

Tabla PRODUCT

Tabla
SUPPLIER
SupplierId*
SupplierName
SupplierAddress
SupplierPhone

ProductId*
ProductDescription
ProductPrice
ProductStock

El conjunto total de dependencias funcionales existentes requiere que deban realizarse algunas
modificaciones en las tablas INVOICE e INVOICEDETAIL 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
CustomerId CustomerName
InvoiceId 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.

35

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

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

ProductId ProductPrice

{InvoiceId, ProductId} ProductDescription

{InvoiceId, ProductId} ProductPrice

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

ProductDescription y ProductPrice solo quedarn en la tabla PRODUCT.

36

Transacciones
Relaciones: establecidas por los nombres de atributos
Conceptos iguales deben tener igual nombre
Invoice
{
InvoiceId*
CustomerId
CustomerName
...
}

Customer
{
CustomerId*
CustomerName
}

Invoice
{
InvoiceId*
InvoiceCustomerId
...
}

Customer
{
CustomerId*
CustomerName
}

Conceptos diferentes NO deben tener igual nombre


Invoice
{
InvoiceId*
Date
CustomerId
CustomerName
...
}

incorrecto

VendorInvoice
{
VendorInvoiceId*
Date
SupplierId*
SupplierName
...
}

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.

37

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:

Invoice
{
InvoiceId*
InvoiceDate
CustomerId
CustomerName
Detail
{
ProductId*
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount
}
InvoiceAmount
}

Customer
{
CustomerId*
CustomerName
CustomerAddress
CustomerGender
}

Product
{
ProductId*
ProductDescription
ProductPrice
ProductStock
}

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 INVOICEDETAIL; 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.

38

Transacciones
Estructura: nombrado de atributos
Es conveniente usar padrones para los nombres de los
atributos.
Facilitan la tarea de nombrado.
Facilitan la tarea de integracin de bases de conocimiento.
Facilitan la lectura del cdigo generado.

39

Transacciones
Estructura: nombrado de atributos

Nomenclatura GIK
Componente de Entidad + Categor
Categora [+ Calificador + Complemento]
Entity Component

Category

Cliente

Id

Qualifier

Cliente

Nombre

Cliente

Fecha

Inicial

Customer

Cliente

Fecha

Final

Customer

Factura

Id

Factura

Fecha

FacturaDetalle

Cantidad

Invoice

FacturaCompra

Id

Invoice

y en ingls:
Entity Component

Vencimiento

Qualifier

Category
Id
Name

Customer

Start

Date

Customer

End

Date
Id

Due

Date

InvoiceDetail

Amount

VendorInvoice

id

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] 1
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), InvoiceDetail (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.

40

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.
En la transparencia se muestran algunos ejemplos de nombres de atributos.
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.

41

Demo
Una vez creada la base de conocimiento: creacin
de las primeras transacciones.

Una vez creada la base de conocimiento (ver introduccin terica), la misma quedar abierta para que se
empiecen a crear las transacciones.
La creacin de objetos, se realiza presionando Ctrl+N. Los objetos creados quedarn en la carpeta Objects que
se puede ver en la Folder View de la ventana KB Navigator.
Si se desea que el objeto a crear quede guardado en otra carpeta, se deber posicionar en dicha carpeta y
luego hacer clic con el botn derecho del mouse. En el men elegir New Object.
Tambin se podr indicar la carpeta en el cuadro de creacin de un objeto como se ve en la imagen.
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: Transaction), dar un nombre al objeto que se est creando (por ejemplo: Customer o Invoice),
una descripcin larga, y la carpeta en la cual guardar el objeto.

Una vez creada la transaccin, la misma quedar abierta para que se defina su estructura y dentro de ella sus
atributos.

42

Transacciones
Definicin de atributos
F4

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 en la estructura, y el mismo se habilitar y se podr
editar. Luego se debern guardar 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, o presionar la
tecla F4. En la figura hemos cambiado la propiedad Autonumber que como veremos oportunamente,
permite autonumerar atributos clave primaria.
---------------------------------------------------------------------------------------------------1 Veremos su utilidad cuando estudiemos los business components.
2 Tambin llamados contextuales dado que varan segn el contexto.

43

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 el objeto de tipo query, ejecutando reportes dinmicos (tema bastante
simple, pero que no se abordar en este curso).
Relacionadas a esta propiedad, estn las propiedades Title, Column Title y Contextual Title. Las 2 primeras por
defecto toman el mismo valor que se especifica en Description, pudindose modificar:
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 (veremos en breve los forms).
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) (en el caso de una transaccin solo si se trata de un atributo inferido, como por
ejemplo el atributo ProductDescription en la transaccin Invoice)1.
Contextual Title: Cuando el atributo pertenece al segundo nivel de una transaccin, y no es inferido (ejemplo
InvoiceDetailQuantity en Invoice), el nombre de la columna del grid de la transaccin ser tomado de esta propiedad.
Obsrvese que por defecto se toma de la propiedad Description, pero quitando el nombre de la transaccin, pues se
asume del contexto.
Type Definition
Based on: Permite asociarle un dominio2 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.
Validation
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 El atributo tambin podr estar en un objeto Web Panel. En ese caso, de aparecer como columna, siempre se
ofrecer por defecto para el nombre de la misma el de su propiedad ColumnTitle
2 Los dominios se abordarn unas pginas 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.

44

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 con un tipo de datos bsico, el tipo de control que tiene asociado es Edit, pudiendo el
programador cambiarlo a cualquiera de los otros tipos. En general GeneXus elige el tipo de control para un atributo
dependiendo de su tipo de datos. Si es un dominio enumerado, como veremos, elegir Radio Button o Como Box,
dependiendo de la cantidad de valores del dominio.
En el grupo 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 (ver grupo Appearance).

45

Transacciones
Atributos: Tipos de Datos
Numeric, Character, Date, Boolean
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.

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 InvoiceAmount 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.
Boolean: permite que un atributo o variable asuma los valores lgicos: True, False.

46

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.
Para profundizar en el conocimiento de este tipo de datos puede dirigirse al Help de GeneXus.

47

Transacciones
Definicin de variables
En todo objeto GeneXus es posible definir variables.
Las variables son nicamente visibles dentro del objeto; es decir, son
locales.
Editor similar al de la estructura de las transacciones:

Es posible definir variables coleccin (de cualquier tipo de datos).

Para definir variables en determinado objeto, se debe seleccionar el selector Variables, como se muestra en la
figura.
Este selector muestra variables definidas por defecto (Standard variables, como por ejemplo la variable Today
que contiene la fecha del sistema) para el objeto, y permite definir variables nuevas a travs de un editor
similar al de las transacciones.
Tambin se puede ir a la opcin Insert de la menubar y elegir Variables. En el cuadro de dilogo que se
desplegar seleccionar New 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.

48

Transacciones
Definicin de variables

Compartenvariaspropiedadescon
losatributos:
DataType:aunquenotodotipodedatos
vlidoparaatributotambinloespara
variable(ej:Blob)yviceversa(ej:tiposde
datosestructurados).
F4

Based On
Ofrece una forma rpida de definir una variable. Cuando se selecciona, se despliega un dilogo que muestra
todos los atributos (y dominios) 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.
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 y presionar botn derecho del mouse. En el men contextual luego elegir Add
Variable.
Variables coleccin
Es posible definir variables coleccin sobre cualquier tipo de datos ofrecido por GeneXus.
Para eso alcanza con clickear la correspondiente casilla en el editor de variables, o indicar el valor True en la
propiedad Collection asociada a las variables.
Para recorrer luego los items coleccionados en dicha variable, se deber utilizar la estructura de control For
in.
Por ejemplo, hemos definido la variable &myNumbers de tipo Numeric(4.0)
Para recorrer los valores almacenados se deber crear una nueva variable de tipo Numeric(4.0). Creamos
entonces la variable &OneNumber, y declaramos:
For &OneNumber in &myNumbers
---------Endfor

49

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

ProductPrice
InvoiceDetailAmount

Precio de producto
Importe total de lnea

Dominios

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
InvoiceDetailAmount 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 luego uno Amount de tipo de datos el dominio Price anterior; a cada uno
de los atributos anteriores le asignaramos estos dominios. 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 InvoiceDetailAmount y ProductPrice.

50

Transacciones
Dominios
Dominios enumerados: queremosmantenerelestadodelcliente:Active,

OnHold,Closed dominioStatus

Luego atributo CustomerStatus de dominio Status


Se trabaja con los nombres en lugar de con los
valores:
CustomerStatus = Status.Active

Existe la posibilidad de trabajar con dominios enumerados (aquellos que representan valores finitos y
particulares. Son muy conocidos en los lenguajes de programacin. El caso de uso tpico es para los das de la
semana: cuando se necesita que una variable tome uno de los siguientes valores: Lunes, Martes, Mircoles,
Jueves, Viernes, Sbado, Domingo).
En nuestro caso, agregaremos a la estructura de la transaccin Customer, un atributo que representa el estado
del cliente en el sistema en un momento dado. Puede estar active, on hold o closed.
Una forma de representarlo es definiendo un dominio Status, que corresponde al tipo de datos Character(1) pero
para el que decimos explcitamente que no queremos que pueda tomar todos los valores de ese tipo de datos,
sino solo 3: A, H y C, y adems le decimos que queremos trabajar dndole nombres a estos 3 valores y trabajar
con sus nombres. As, a A le asociamos el nombre Active, a H OnHold y a C Closed.
Al asociarle al atributo CustomerStatus el dominio Status (observar que GeneXus automticamente lo sugiere al
ingresar el atributo en la estructura luego de haber definido el dominio, debido a la terminacin del nombre del
atributo) internamente en el atributo de la tabla se guardar uno de los 3 valores: A, H o C, pero nosotros no
tendremos que recordar esos valores, sino sus cdigos: Active, OnHold y Closed.
Ya tenamos otro atributo con dominio enumerado: CustomerGender. En ese caso se compona de solamente 2
valores: Female y Male.
Observar cmo el Control Info ofrece para ControlType un Combo Box en lugar de un Edit. Esto tomar sentido
cuando veamos el Form de una transaccin un poco ms adelante.

51

Transacciones
Dominios

As como podemos asociarle a un atributo un dominio (y a otro 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) Opcin Domains de el Folder View: Mediante un editor similar al de las variables, se podr definir un nuevo
dominio.
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).

52

Transacciones
Web Form

Cada transaccin tiene asociado un Web Form.

Es creado por defecto al grabar la estructura de la transaccin,


pudiendo ser modificado por el programador.

Para cada transaccin, GeneXus crea un form web, que ser la interfaz con el usuario.
Es creado 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 es creado por defecto, es posible modificarlo para dejarlo ms vistoso, cambiar por ejemplo
controles de tipo edit a otros tipos de controles, agregar y/o quitar botones, etc.

53

Transacciones
Web Form de la transaccin Invoice
Control Error Viewer

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.
El control Error Viewer se utiliza 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.
Observar que el segundo nivel de la transaccin aparece en el form como un control grid.

54

Transacciones
Web Form de la transaccin Customer

Dominios bsicos
controles Edit
Dominios enumerados
controles Combo Box

55

Transacciones
Paletas de herramientas para el diseo de Forms

Insertar controles:
Opcin View de la Menubar \ Other Tool Windows \
Toolbox

Cortar, copiar y pegar controles:

Podemos definir un control como un rea de la interfaz con el usuario, que tiene una forma y un
comportamiento determinado.
Existen distintos controles:
- Texto: Permite colocar texto fijo
- Atributo/Variable: Permite colocar atributos o variables.
- Lnea horizontal
- Error Viewer
- Table: Insertar tablas en el form
- Grid: Permite definir grillas de datos.
- Botn: Permite incluir botones en los forms.
- Bitmap: Permite definir bitmaps estticos, etc.

Paleta de herramientas para insertar controles: Cuando se est editando un form, se encuentra disponible
una paleta de herramientas (Toolbox) que ofrece los controles posibles de insertar en el mismo. Simplemente
se deber seleccionar el control y arrastrarlo sobre el form.

56

Transacciones
Controles en Web Form
Cada control del Web form podr tener una clase asociada, de un
objeto theme (tema) determinado, asociado al objeto.

Al crear una KB, se crea por defecto el tema


GenexusX y todos los objetos que se creen tendrn
este tema asociado.

Esto permitir independizar el diseo de la interfaz,


de la programacin.

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.

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).
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, y el programador slo deber aplicarlo a los objetos de su base de conocimiento.
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 del Folder View la carpeta
Customization con objetos Theme predefinidos que podrn importarse en la KB. Por defecto se importa el
de nombre GeneXusX. Este tema contiene un conjunto de clases asociadas a los distintos controles
existentes.
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.

57

Transacciones
Controles en Web Form

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 GeneXusX y todos los
controles que se coloquen en el form, tendrn clases de este tema asociadas.
Si sobre el Text Block (control de texto) que se muestra arriba (Name), se editan sus propiedades (F4), se
puede observar la propiedad Class, que tiene configurada la clase TextBlock. Esta propiedad puede ser
cambiada por el analista. Al cliquear el combo box podremos ver una lista de clases posibles para ese
control (son las que figuran en el tema asociado). A la derecha hemos cambiado la clase por una de
nombre Title y en el form podemos ver la repercusin en el diseo del TextBlock.
No entraremos en detalle en este tema en el presente curso.

58

Demo
Cmo ejecutar la aplicacin?
Opcin Build \ Run Developer Menu, o presionar la tecla F5.
F5: Dispara
automticamente
todas las acciones
necesarias para
ejecutar la aplicacin
Si BD no existe, se
crea automticamente
(siempre y cuando
usuario y password
tengan permisos de
DBCreator)

Recordemos que al momento de creacin de la KB, se indic el generador por defecto a utilizar. Ahora
se debe completar la informacin necesaria para terminar de definir el ambiente de implementacin.
Database name: Nombre de la base de datos que estar asociada a la aplicacin.
Server name: Nombre del servidor de base de datos que la manejar.
Use trusted connection: Yes
No (deber indicarse usuario y contrasea vlido en el DBMS)
Consideraciones:
Si la base de datos no existiera, GeneXus la crear, siempre y cuando el usuario y contrasea
configurados en la ventana de dilogo tengan permiso de DBCreator en el DBMS.

59

Proceso de Build
El proceso de Build incluye todas las tareas necesarias para la ejecucin
de la aplicacin: Verificacin de cambios en la BD, Reorganizacin (si es
necesario), Especificacin, Generacin y Compilacin. No incluye la
ejecucin.
KB

REORGANIZATION
DBASE IMPACT
ANALYSIS

SPECIFICATION

GENERATION

COMPILATION

Aplicacin pronta
para ejecutar
APPLICATION

El proceso de Build se ejecuta en background, permitiendo realizar otras tareas


mientras el mismo est corriendo, por ejemplo continuar con el desarrollo.

Cada vez que se ejecuta la aplicacin (F5), GeneXus realiza una comparacin entre las definiciones actuales
de todos los objetos y las definiciones de la ltima ejecucin. Esta comparacin se llama anlisis de impacto.
Este nombre es autodescriptivo: GeneXus analiza el impacto causado por las nuevas definiciones, y 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.
Si por ejemplo se cre una nueva transaccin, esto provocar (tal como es el objetivo de las transacciones)
que se creen las tablas correspondientes en la base de datos (ver siguiente pgina).

60

IAR y Reorganizacin
Create si est todo OK se
construirn los programas en el
Environment y se ejecutar...

En el ejemplo, tras crear las 2 transacciones Customer e Invoice y dar F5, aparece el reporte de anlisis de
impacto que puede verse, donde se listan entre otras cosas, la estructura que tendr cada tabla que se crear,
con sus atributos, tipos de datos, los ndices que se crearn sobre las tablas, las claves forneas (observar que
el reporte de la tabla INVOICE dice que se referenciar la tabla CUSTOMER (esto se debe al atributo
CustomerId de la transaccin Invoice que se llama igual que el atributo CustomerId de CUSTOMER,
constituyendo por tanto una clave fornea a dicha tabla).
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 efectuar en cambio las redefiniciones que crea
convenientes.
Cuando se decide efectuar una reorganizacin GeneXus genera programas (en el lenguaje elegido cuando se
cre la KB) 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.
El siguiente paso ser obtener los programas de aplicacin asociados a los objetos GeneXus. Para ello
GeneXus deber especificar, generar y compilar los programas de aplicacin.
Especificar un objeto significa que GeneXus analizar todo lo definido en cada uno de los elementos que lo
componen: estructura, forms, u otros elementos segn corresponda. GeneXus verificar la sintaxis de las
definiciones, la validez de lo definido, y como resultado de la especificacin mostrar al usuario un listado de
navegacin, en el cual informar la lgica que ha interpretado, y si hay alguna advertencia o error.
Generar un objeto, significa que GeneXus escribir lneas de cdigo que implementen la programacin del
mismo, en el lenguaje elegido.
Compilar los programas significa que el cdigo escrito (generado) sea convertido a lenguaje mquina (binario)
para que puedan ser ejecutados.

61

Ejecucin

62

Opcin Build de la barra de


men de GeneXus

Opciones del tem Build:


Build All y Rebuild All: Estas opciones se utilizan cuando no se est seguro del impacto de los cambios y se
necesita tener actualizadas las ltimas definiciones. La opcin Build All realiza todas las acciones que estn
pendientes, mientras que Rebuild All forzar todas ellas.
Las acciones son:
- Salvar todos los objetos que no estn salvados.
- Reorganizar la base de datos, si es necesario.
- Especificar solo los objetos que han sido modificados (si se seleccion Build All), o
forzar la especificacin de todos (si se seleccion Rebuild All).
- Generar los objetos
- Compilar los objetos definidos Main
- Compilar el Developer Menu
Build / Rebuild Developer Menu: Similar a las opciones anteriores pero aplicadas solamente al Developer
Menu. No lo ejecuta.
Run Developer Menu: Ejecuta todas las acciones que estn pendientes y ejecuta el Developer Menu.
- Salva todos los objetos que no estn salvados.
- Reorganizarla base de datos, si es necesario.
- Especifica solo los objetos que han sido modificados.
- Genera los objetos
- Compila y ejecuta el Developer Menu

63

Build / Rebuild / Run options: Opciones que aplican a objetos definidos como Main. Disparan las siguientes

acciones:
- Salvan los objetos que no estn salvados.
- Reorganizan la base de datos, si es necesario.
- Se especifican solamente los objetos que sufrieron cambios (si se seleccion Build), o se
fuerza la especificacin de todos los objetos pertenecientes al rbol de llamadas del
objeto Main (si se seleccion Rebuild).
- Generacin
- Compilacin del objeto Main
- Ejecucin del objeto Main (si se seleccion la opcin Run)
Build / Run with this only options: Build y ejecucin del objeto definido como Startup. Por defecto el objeto
Startup es el Developer Menu.
- Salvan todos objetos que no estn salvados.
- Reorganizan la base de datos, si es necesario.
- Especifican solamente el objeto seleccionado.
- Generan solamente el objeto seleccionado.
- Compilan el objeto Startup
- Se ejecuta el objeto Startup (si se seleccion Run).

Set As Startup Object: El objeto indicado pasar a ser el objeto Startup de la aplicacin, o sea el objeto que
finalmente se ejecutar cuando se presione la tecla F5. Por defecto el objeto Startup es el Developer Menu.
Create Database Tables: Crea nuevamente las tablas. Se pierden los datos que pudieran estar almacenados
previamente.
Impact Database Tables: Se realiza un impacto sobre las tablas de la base de datos.

64

Transacciones
Modos 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.

65

Transacciones
En tiempo de ejecucin

&GxRemove:
Variable del
sistema para
eliminar
lneas.

Para agregar una


nueva lnea

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 New Row., o
simplemente presionar Enter y se agregar una nueva lnea.
Para poder eliminar lneas en ejecucin, GeneXus incorpora automticamente en el grid del form
Web una primera columna conformada una variable del sistema de nombre &GxRemove, en forma de
check box. Para visualizar este check box, se debe presionar el botn derecho del mouse sobre la
lnea a eliminar. Luego se deber presionar el botn Confirm.

66

Transacciones
Master Pages
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.

Creadas automticamente
con la KB

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 toma
gran tiempo de programacin.
Al crear una base de conocimiento GeneXus X crear tambin dos objetos de tipo Master Page:
AppMasterPage: Para la aplicacin.
PromptMasterPage: Para los prompts.
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!.
En una misma base de conocimiento se pueden definir tantas Master Pages como se desee.
Cuando estudiemos el objeto Web Panel comprenderemos que una Master Page ser en particular un Web
Panel categorizado como Master Page con todo lo que sea el Layout y comportamiento comn a todas las
pginas del sitio; dentro de este objeto se dejar un espacio para cargar en cada oportunidad la pgina que
corresponda (el contenido variable del sitio). Eso se har en el control presente en el form de nombre Content
Placeholder.

67

Transacciones
Master Pages
Propiedad Master Page

Las pginas web que implementan el contenido variable, se asocian a la Master Page, de manera que cada
vez que se ejecuten, se carguen con ese contexto (el de la Master Page).

68

Demo
AgregarlatransaccinProduct faltanteyvercmose
modificanlosconosenInvoice

Qu pasar al hacer F5?

Obsrvese cmo luego de crear la transaccin Product GeneXus normaliza e indica grficamente en la
estructura de la transaccin Invoice que los atributos, antes propios de la tabla INVOICEDETAIL, ahora sern
inferidos, a travs de la nueva clave fornea ProductId.
La clave primaria de la tabla INVOICEDETAIL seguir siendo compuesta: {InvoiceId, ProductId}, pero adems,
el atributo ProductId slo, ser una FK a la tabla PRODUCT, a partir del cul se inferirn los atributos
ProductDescription y ProductPrice.
Luego del F5, naturalmente se informar de la necesidad de reorganizar la base de datos, crendose la tabla
PRODUCT y modificndose la tabla INVOICEDETAIL de la manera que indicamos en los prrafos anteriores.
Qu pasar con los registros ya existentes en la tabla INVOICEDETAIL, para los que existan valores de
ProductDescription y ProductPrice?
Como se ver cuando se ejecute, el programa de reorganizacin agrega una rutina para crear los registros de
productos en la tabla PRODUCT con esa informacin pre-existente. Qu pasar si exista el mismo producto
en varias lneas de distintas facturas?

69

Integridad referencial

70

Integridad Referencial
Diagramas

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, CountryId, CustomerAddress, CustomerGender,
CustomerStatus)
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.
En dicho diagrama, 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).

71

Integridad Referencial
Diagramas
Hay que verificar existencia del COUNTRY referenciado.

COUNTRY
1
N

CUSTOMER

COUNTRY

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

En transaccin Country:
si se quiere eliminar un registro

1
N

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.

72

Integridad Referencial
Indices

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.

73

Integridad Referencial
Indices primarios y forneos
CountryId*
CountryName

PK

ICountry

CountryId CountryName
1
2
3

Uruguay
United States
China

Si en transaccin Country
queremos eliminar United
States:

PK

ICustomer
CustomerId*
CustomerName
...
FK ICustomer1
CountryId

CustomerId
4
1
3
2

CustomerName
Ann Silver
John Smith
Mary Jones
Jessica Deep

CountryId
1
1
1
2

El programa debe buscar sobre CUSTOMER


si existe 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.

74

Integridad Referencial
Indices 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

CustomerName

1
2
3

Ann
Ann
Mary

CountryId
1
2
1

ndices de usuario
Estos ndices deben ser definidos explcitamente por el analista. No son definidos
automticamente. Se dividen en duplicate y unique.
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.

75

Integridad Referencial
Indices de Usuario
Si un mismo nombre no puede repetirse (es por tanto un atributo
clave de la tabla)
CustomerId
1
2
3

CustomerName
John Smith
Ann Jones
Richard Land

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 Ann Jones
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)

76

Integridad Referencial
Indices 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.
En algunas 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.

77

Integridad Referencial
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).

78

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

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).

79

Integridad Referencial
Manejo de nulos

Repercusin en controles de integridad referencial

CountryId*
CountryName

CountryId*
CityId*
CityName

FK
compuesta

CustomerId*
CustomerName
CountryId
CityId

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 si se deja nulo
CityId, se realizar chequeo contra COUNTRY.

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.

80

Integridad Referencial
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();

81

Tabla base
y
Tabla extendida

82

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 representa nuestro modelo de datos:

para listar las facturas sera necesario consultar las tablas: INVOICE e INVOICEDETAIL (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).

83

Tabla Base y Tabla Extendida


INVOICE
InvoiceId*
InvoiceDate
CustomerId

INVOICEDETAIL
InvoiceId*
ProductId*
InvoiceDetailQuantity
InvoiceDetailAmount

CUSTOMER

COUNTRY

CustomerId*
CustomerName
CountryId
CustomerGender
CustomerStatus

CountryId*
CountryName

PRODUCT
ProductId*
ProductDescription
ProductPrice
ProductStock

Utilizando el diagrama 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.

El siguiente cuadro muestra la tabla extendida correspondiente a cada una de las tablas de nuestro
modelo de datos:

84

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).

85

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( InvoiceDetailAmount, ProductPrice*InvoiceDetailQuantity); /* Regla definida en Invoice */
Cuando se est insertando una lnea de factura, se sugiere que el atributo InvoiceDetailAmount (importe de la lnea)
tome el valor resultante de evaluar la expresin ProductPrice*InvoiceDetailQuantity (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).

86

EJEMPLO:
InvoiceDetailAmount = ProductPrice*InvoiceDetailQuantity; /*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.

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 component (estudiaremos este tema
mas adelante en el curso), 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 el Error Viewer.

87

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.

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 InvoiceDetailQuantity;
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.

88

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 InvoiceDetailQuantity if Insert;
ProductStock = ProductStock + InvoiceDetailQuantity if Delete;
ProductStock = ProductStock + old(InvoiceDetailQuantity) InvoiceDetailQuantity 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( InvoiceDetailQuantity, ProductStock);
Esta regla tiene la inteligencia para, dependiendo del modo, restar o sumar.

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 (InvoiceAmount) 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 + InvoiceAmount if Insert;
CustomerTotalPurchases = CustomerTotalPurchases InvoiceAmount if Delete;
CustomerTotalPurchases = CustomerTotalPurchases old(InvoiceAmount) + InvoiceAmount if Update;
y en su lugar nos provee de la regla add, que se encarga de sumar o restar, dependiendo del modo.

89

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( InvoiceAmount, 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
InvoiceAmount
si se elimina una factura (Delete): se le sustrae al valor del atributo CustomerTotalPurchases el valor del atributo
InvoiceAmount
si se modifica una factura (Update): se le suma al valor del atributo CustomerTotalPurchases, la diferencia entre
el valor nuevo y el viejo de InvoiceAmount

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 InvoiceDetailId)
como identificador nico del segundo nivel, la estructura de la transaccin sera:
Invoice
{
InvoiceId*
CustomerId
CustomerName
InvoiceDate
InvoiceLastLineId
Detail
{
InvoiceDetailId*
ProductId
ProductDescription

}
}

90

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 InvoiceDetailId, definiendo la regla:
serial(InvoiceDetailId, 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 (InvoiceDetailId). 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 (InvoiceDetailId).
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 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.

91

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.

92

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);

93

Reglas
Conceptos importantes

En qu nivel de una transaccin se ejecutarn las reglas


definidas en la misma?

Cmo condicionar reglas


determinados modos?

para

que

se

ejecuten

en

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( InvoiceDetailQuantity, 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.

94

3) Si se define la siguiente regla en la transaccin Invoice:

InvoiceDetailDiscount= InvoiceDetailAmount * CustomerDiscountPercentage/100;


siendo InvoiceDetailDiscount (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(InvoiceDetailQuantity, 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:
InvoiceDetailDiscount = InvoiceDetailAmount * 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 InvoiceDetailAmount;

95

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:
InvoiceDetailDiscount= InvoiceDetailAmount * 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 InvoiceDetailQuantity;
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.

96

Frmulas

97

Frmulas
Objetivos y Definicin
Definir frmulas nos brinda una forma clave de compartir conocimiento y
obtener cdigo generado optimizado
Cuando el valor de un atributo o variable puede calcularse a partir de
otros atributos, constantes y/o funciones, puede definirse como una frmula
Contamos con 2 formas de definir frmulas:
- Globales: A nivel de la Base de Conocimiento
- Locales: En medio de cierto cdigo

Veremos este
concepto en
primer lugar

Veremos este concepto ms adelante


con ms conocimientos de GeneXus

Cuando definimos una frmula, GeneXus puede combinar la consulta / clculo asociada a la frmula con la
consulta en la cual la frmula est presente y as generar sentencias optimizadas.

98

Frmulas
Globales
Frmula Global = atributo al cual el analista GeneXus le asigna un
clculo asociado.

Slo atributos pueden definirse como frmulas globales, no


variables.
Cmo se realiza esta definicin?

Accediendo al
editor de
frmulas desde la
estructura de la
transaccin

99

Frmulas
Globales
Decimos que:
atributos frmula globales = atributos virtuales

Significando que:
No se crean como atributos fsicos.
Para cada objeto que referencie un atributo frmula global,
GeneXus incluir en su programa generado el cdigo necesario
para realizar el clculo y desplegarlo en tiempo de ejecucin.
Tabla base / Tabla asociada a un atributo frmula global:

Tabla en la cual el atributo se almacenara si no fuera frmula.

Como explicamos en esta diapositiva, los atributos definidos como frmula global, no se crean como campos
fsicos en tablas, por lo cual decimos que son atributos virtuales.
Sin embargo, decimos que tienen una tabla asociada o tabla base, para conocer el contexto en el cual se
han definido, y contar con ese contexto al momento de disparar el clculo correspondiente donde sea que se
referencien.

100

Frmulas
Clasificacin
Horizontales: Una o varias expresiones aritmticas

Aggregate: Sum, Count, Average, Max, Min, Find


Compuestas: Conjunto de expresiones Horizontales
y/o Aggregate

APLICA A
GLOBALES
Y LOCALES

TODAS PERMITEN QUE SE LES INCLUYA


CONDICIN DE DISPARO
Importante:
- Cuando definimos frmulas en GeneXus no indicamos clasificacin.
- La clasificacin es externa a GeneXus y su finalidad es agrupar frmulas
por:
9
9

Tipo de clculo que ofrecen.


Atributos que se pueden involucrar en su definicin.

101

Frmulas
Clasificacin
Ejemplo de Frmula Horizontal (Global) :
Customer
{ CustomerId*
CustomerName
CustomerTotalPurchases
CustomerTotalPayments
CustomerBalance
}

CustomerTotalPurchases CustomerTotalPayments
DEJA DE PERTENECER
FSICAMENTE A LA TABLA

TABLA CUSTOMER
CustomerId*
CustomerName
CustomerTotalPurchases
CustomerTotalPayments

En la definicin de un atributo como frmula horizontal, es posible involucrar atributos pertenecientes a la


tabla asociada al atributo que se est definiendo frmula y a su tabla extendida.
En el ejemplo, al definir que el atributo CustomerBalance es frmula, el mismo dejar de existir como campo
fsico de la tabla CUSTOMER.
Diremos a partir de ese momento CustomerBalance es un atributo virtual y que su tabla base o asociada ser
CUSTOMER, ya que de almacenarse dicho atributo nuevamente (ya sea por definir el analista que deja de ser
frmula o que es frmula redundante) se creara como atributo fsico en la tabla CUSTOMER.
El tipo de clculo de esta frmula definida es horizontal, ya que consiste en una expresin aritmtica; por lo
tanto los atributos que se pueden referenciar en la definicin de esta frmula son los pertenecientes a la tabla
CUSTOMER (tanto almacenados como frmulas) y su tabla extendida.

102

Frmulas
Clasificacin
Ejemplo II de Frmula Horizontal (Global) :
Invoice
{ InvoiceId*
CustomerId
CustomerName
InvoiceDate
Detail
{
InvoiceDetailId*
ProductId
ProductDescription
ProductPrice
InvoiceDetailQuantity
InvoiceDetailAmount
}
ProductPrice*InvoiceDetailQuantity if InvoiceDetailQuantity<=100;
}
ProductPrice*InvoiceDetailQuantity*0.9 otherwise;

En este ejemplo el atributo InvoiceDetailAmount ha sido definido como frmula global tambin. Es decir,
utilizando el editor de frmulas, se ha asociado un clculo a este atributo y el mismo pasar a ser un atributo
virtual.
La tabla asociada al atributo InvoiceDetailAmount ser INVOICEDETAIL, ya que de almacenarse dicho atributo
nuevamente, se creara en dicha tabla fsica.
Como podemos observar la frmula definida cae en la clasificacin de horizontal, ya que consiste en 2
expresiones aritmticas condicionales. Los atributos involucrados en la definicin de la frmula pertenecen o
bien a la tabla INVOICEDETAIL o bien a su tabla extendida.

103

Frmulas
Clasificacin
Ejemplos de Frmulas Aggregate (Globales) :
Invoice
{ InvoiceId*
CustomerId
CustomerName
InvoiceDate
InvoiceDetails Count(InvoiceDetailQuantity)
InvoiceAmount Sum(InvoiceDetailAmount)
Detail
{
InvoiceDetailId*
ProductId
ProductDescription
En ambos clculos solo intervienen los registros que
ProductPrice
cumplen:
InvoiceDetailQuantity
InvoiceDetailAmount
INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId
}
}

En el ejemplo los atributos InvoiceDetails e InvoiceAmount han sido definidos como frmulas globales, ya que utilizando el
editor de frmulas se ha definido una frmula para cada uno de estos atributos (pasando ambos a ser atributos virtuales).
Dado que las frmulas definidas son Count y Sum respectivamente, en ambos casos se trata de frmulas Aggregate.
La tabla asociada a ambos atributos frmula es INVOICE, ya que de almacenarse estos atributos, se crearan en dicha tabla
fsica.
Las frmulas Aggregate no solo tienen una tabla base asociada (como todas las formulas), sino que tambin involucran una
tabla a ser navegada.
Si bien resulta intuitivo, la tabla a ser navegada en una frmula Aggregate, es la tabla que se navegar para realizar el
clculo. GeneXus inferir cul es la tabla a ser navegada por una frmula Aggregate, por los atributos involucrados en la
definicin de la frmula. En nuestro ejemplo, la tabla a ser navegada en ambas frmulas Aggregate es INVOICEDETAIL, ya
que tanto en la definicin de Sum como Count, hemos referenciado a un nico atributo asociado a INVOICEDETAIL.
Cuando definimos una frmula Aggregate, ya tenemos conocimiento de qu tabla pretendemos navegar para efectuar el
clculo. Los atibutos que podremos referenciar en la definicin de una frmula Aggregate debern pertenecer a la tabla a
ser navegada y su tabla extendida + a la tabla asociada al atributo que se est definiendo como frmula y su tabla
extendida. De involucrar en una frmula Aggregate atributos que no pertenezcan a este contexto mencionado, un error se
reportar en el listado de navegacin correspondiente.
Por ltimo, de haber atributos en comn (de igual nombre) en las tablas involucradas en la definicin de una frmula,
GeneXus aplicar esa relacin (es decir, filtrar automaticamente por igualdad por los atributos de igual nombre). Esto es lo
que sucede en estos 2 ejemplos, que GeneXus cuenta y suma las lneas relacionadas a sus cabezales (al sumar y contar,
aplica automticamente el filtro INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId ).

104

Sintaxis completa de Sum, Count, Average:


Sum | Count | Average( Expresin, [Condicin Explcita, Valor por Defecto]) [if Condicin
Disparo];
En los 2 ejemplos de frmulas Sum y Count que hemos visto, solamente hemos definido el
parmetro obligatorio, es decir la expresin a ser sumada o contada (que en un caso consisti en
un atributo almacenado y en otro caso en un atributo frmula). Tambin dicha expresin podra
haber involucrado constantes y/o funciones.
Vimos que GeneXus determina condiciones de filtro implcitas al realizar la suma, cuenta o
promedio. Tambin podramos haber definido condiciones de filtro explcitas y en caso de
haberlas, GeneXus tendr en cuenta a ambas: implcitas + explcitas.
A su vez opcionalmente es posible definir un valor por defecto a ser retornado cuando no se
encuentran registros para contar, sumar o promediar.
Al igual que todas las frmulas, estas tambin permiten incluir condicin de disparo.
Por ltimo, vale mencionar una excepcin y es que en particular en las frmulas Count, el primer
parmetro debe corresponder a un atributo y no a una expresin. Puede referenciarse cualquier
atributo de la tabla en la cual se quieran contar registros (que cumplan con condiciones explcitas
y/o implcitas).

105

Frmulas
Clasificacin
Ejemplos de Frmulas Aggregate (Globales) :
Invoice
Product
{
{
InvoiceId*
ProductId*
CustomerId
ProductDescription
CustomerName
PriceList
InvoiceDate
{
InvoiceDetails Count(InvoiceDetailQuantity)
ProductPriceListDate*
InvoiceAmount Sum(InvoiceDetailAmount)
ProductPriceListPrice
Detail
}
{
}
InvoiceDetailId*
ProductId
ProductDescription
InvoiceDetailQuantity
Max(ProductPriceListDate,
InvoiceDetailProductPrice
ProductPriceListDate<=InvoiceDate,
InvoiceDetailAmount
0, ProductPriceListPrice)
}
}
InvoiceDetailProductPrice*InvoiceDetailQuantity

Hemos modificado el diseo de las transacciones para que en lugar de representar que cada
producto tiene un nico precio, representamos que cada producto tiene una lista de precios de
acuerdo a la fecha de cambio de los mismos.
Al efectuar este cambio, el atributo ProductPriceListPrice no podr estar presente en el
segundo nivel de la transaccin Invoice. Por qu? Porque el nuevo diseo estar
representando que un producto ya no tendr solamente un precio, sino muchos: uno por cada
fecha de cambio de precio del mismo. Por lo tanto, para un producto en una lnea de una
factura, tendremos que buscar el precio vigente del mismo, teniendo en cuenta la fecha de la
factura.
Recordemos que los atributos que se pueden inferir en determinado nivel de una transaccin,
son los que pertenecen a la tabla extendida de la tabla base asociada al nivel en cuestin. En
este ejemplo, la tabla extendida de la tabla INVOICEDETAIL, no incluye a la tabla
PRODUCTPRICELIST (en la cual se encuentra el atributo ProductPriceListPrice):

por lo tanto en el nivel Detail de la transaccin Invoice (asociado a la tabla INVOICEDETAIL)


no es posible inferir al atributo ProductPriceListPrice (almacenado en la tabla
PRODUCTPRICELIST).

106

Qu ocurre si dejamos al atributo ProductPriceListPrice en el nivel Detail de la transaccin Invoice?


Como no se podr inferir, entonces GeneXus no tendr otra opcin que determinar almacenarlo en
la tabla INVOICEDETAIL pese a que ya estar este atributo secundario en otra tabla
(PRODUCTPRICELIST). Como el resultado de esto es un modelo de datos no normalizado, se
reportar el error al querer reorganizar la base de datos.
Y cmo hacemos para desplegar en cada lnea de la factura, el precio vigente del producto de la
misma? De todos los precios correspondientes al producto de una lnea, cul queremos recuperar?
Evidentemente, de todos los precios que tengan fecha menor o igual a la fecha de la factura,
queremos aquel que tenga fecha mayor.
Procedemos entonces a crear en el nivel Detail de la transaccin Invoice, un nuevo atributo de
nombre InvoiceDetailProductPrice, al que definiremos como frmula global y por lo tanto ser un
atributo virtual.
Le asociaremos a dicho atributo la frmula Max:
Condiciones que deben
cumplir los registros para
ser considerados

Valor de retorno si no se
encuentra ningn registro
que cumpla con las
condiciones

Max(ProductPriceListDate, ProductPriceListDate<= InvoiceDate, 0, ProductPriceListPrice)

Atributo a maximizar de
entre los registros que
cumplan las condiciones

Para el registro
encontrado, se retorna
este atributo

GeneXus inferir la tabla a ser navegada por el ltimo parmetro de la frmula (el atributo de
retorno).
Como ya se ha explicado, los atibutos que podremos referenciar en la definicin de una frmula
Aggregate debern pertenecer a la tabla a ser navegada y su tabla extendida + a la tabla
asociada al atributo que se est definiendo como frmula y su tabla extendida. De involucrar
atributos que no pertenezcan a este contexto mencionado, un error se reportar en el listado de
navegacin correspondiente.
GeneXus considerar al momento de efectuar la bsqueda, la condicin explcita de filtro + las
condiciones mplicitas detactadas.
La frmula Min es totalmente anloga a Max, con la nica diferencia de que al encontrar un conjunto
de registros que cumplan con las condiciones, se seleccionar aquel registro que tenga valor
mnimo para el atributo indicado en el primer parmetro y se retornar el valor de retorno que se
haya indicado en el ltimo parmetro.
La frmula Find por su parte, tambin permite buscar un registro que cumpla con ciertas
condiciones, sin embargo de haber ms de 1 registro que cumpla con ellas, la frmula devolver el
atributo de retorno correspondiente al primer registro encontrado (sin maximizar ni minimizar un
valor en el conjunto de registros que cumplan con las condiciones). La sintaxis Find es:

Find (Expresin de retorno, [Condicin explcita], [Valor por defecto]) [if Condicin de
disparo]
107

Frmulas
Clasificacin
Ejemplo de Frmula Compuesta (Global):
Customer
{ CustomerId*
CustomerName
CustomerTotalPurchases
CustomerTotalPayments
CustomerBalance
CustomerAverage
}

Sum(InvoiceAmount) / Count(InvoiceAmount)

108

Comunicacin
entre objetos

109

Comunicacin entre objetos


Data Provider

Procedimiento

Transaccin

Web Panel

Procedimiento 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 parmetros.
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 Procedimiento PDF (as como
entre Transaccin y Procedimiento PDF) indica que un Web Panel podr invocar a un Procedimiento
PDF pero un Procedimiento PDF no podr invocar a un Web Panel (o transaccin Web).

110

Comunicacin entre objetos


2posibilidades:
1) PgmName.Call(par , , par )
1
N
Parm(par1 , , parN);

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

puede omitirse

2)

att|&var = PgmName.Udp(par1, , parN) /*Invocacin a PgmName*/


Parm(par1, , parN , parsalida);

/*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 ambientes Web, un
objeto con interfaz una vez invocado no devuelve el control al llamdor, por lo que UDP se utiliza
nicamente para invocar a Procedimientos y Data Providers (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.
Cuando en la sintaxis de la invocacin se escribe el nombre del objeto invocado y ningn mtodo de
invocacin, se asume que se est invocando con udp, por lo que puede omitirse y escribirse
directamente:
att|&var = PgmName( par1, ..., parN)
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.

111

Comunicacin entre objetos


2posibilidades Ejemplos:
1) Desde la transaccin Invoice invocamos un procedimiento para imprimir
lafactura: ListInvoice.Call(InvoiceId)
Y en las reglas del procedimento ListInvoice:

2)Ej:

Parm(InvoiceId)

&discount = GetDiscount.udp(ProductId,CustomerId)

En el proc GetDiscount

Parm(ProductId,CustomerId , &disc);

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 procedimiento pdf (objeto ListInvoice)
pasndole un parmetro (InvoiceId). En el procedimiento 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 GetDiscount)
pasndole dos parmetros (ProductId, CustomerId). Ahora, observemos en la sintaxis de la
invocacin al procedimiento, que el mismo retorna un valor (en la variable &disc). Por este motivo, en
el procedimiento invocado se han declarado tres parmetros utilizando la regla parm: los dos
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 (a menos que se
trate del caso particular de un Data Provider, caso que veremos ms adelante):
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.

112

Qu declarar en la regla parm:


variable o atributo?
Variable: Se podr utilizar libremente, en la lgica del objeto
invocado:
comocondicindefiltropor=,>,>=,<,<=,LIKE,etc.
paraalgunaoperacinaritmtica.
comobandera.
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 el mismo; y si se encuentra en una variable, habr que enviar 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 procedimientos pdf para
listados, pasndoles parmetros, as como a otros objetos, podremos terminar de comprender mejor
este tema.

113

Definicin de tipo de pasaje de


parmetros (in, out, inout)
Paracadaparmetroquesedeclaraenlareglaparm,esposibledefinirsise
deseaqueelmismoopere:
deentrada(in)
desalida(out)
deentradasalida(inout)

Ejemplo:parm(out:&par1,in:&par2,&par3,inout:&par4);
Ventajas:
Mejor especificacin delasemntica delas interfaces.
Independenciadellenguajedegeneracin.
Optimizar el pasaje de parmetros de las aplicaciones de acuerdo a la
arquitectura en la que stas se implementan (ventaja contrapuesta a la
anterior).

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:
- 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.

114

Comunicacin entre objetos


Web
Msposibilidadesparadefinirinvocaciones FuncinLink

1)

control.Link = PgmName.Link([,par1 , parN])


Ej: imagen.Link = Customer.Link()

2)

Los parmetros son


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

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 panel, 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 procedimiento PDF1.

--------------------------------------------------------------------------------------------------------------------------------Tambin un procedimiento HTTP, pero no profundizaremos sobre este concepto en este curso

115

Comunicacin entre objetos


Web
Msposibilidadesparadefinirinvocaciones ComandoLink

1)

PgmName.Link([,par1 , parN])
Ej: Customer.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 procedimiento 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 Tambin un procedimiento HTTP, pero no profundizaremos sobre este concepto en este curso.

116

Orden de ejecucin de
reglas y frmulas

117

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( InvoiceDetailAmount )
InvoiceTotal
= InvoiceSubTotal InvoiceDiscount
+ InvoiceShippingCharge
(ProductId*
ProductPrice
ProductStock
InvoiceDetailQuantity
InvoiceDetailAmount) = InvoiceDetailQuantity *
ProductPrice

Reglas:

Customer

CustomerId*
CustomerName
CategoryId
CustomerTotalPurchases

Category

CategoryId*
CategoryDiscount

Shipping

ShippingDate*
ShippingCharge

Product

ProductId*
ProductPrice
ProducStock

Add( InvoiceTotal, CustomerTotalPurchases);


Error( Insufficient Stock ) if ProductStock<0;
Subtract( InvoiceDetailQuantity, 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 y sus reglas declaradas.
En qu orden se dispararn las reglas y frmulas de la transaccin "Invoice"?

118

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( InvoiceDetailAmount )
F. InvoiceDetailAmount = InvoiceDetailQuantity *ProductPrice
R. Subtract(InvoiceDetailQuantity, ProductStock) ;
R. Error( Insuffcient Stock) if ProductStock < 0 ;

CustomerTotalPurchases

InvoiceTotal

InvoiceDiscount
InvoiceShippingCharge
error (Insufficient Stock )

ProductStock

InvoiceSubTotal

InvoiceDetailAmount

InvoiceDetailQuantity

ShippingDate

CategoryDiscount

InvoiceDate

ShippingCharge

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 (InvoiceDetailQuantity), como este atributo
interviene en la frmula que calcula el importe de la lnea (InvoiceDetailAmount), 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
InvoiceDetailQuantity, tambin se dispararn las frmulas y reglas involucradas en la rama izquierda. Es decir,
que al cambiar el valor del atributo InvoiceDetailQuantity, se
redisparar tambin la regla
Subtract(InvoiceDetailQuantity, 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.

119

Observemos las 2 ltimas reglas definidas:


Subtract(InvoiceDetailQuantity, ProductStock);
Error(Insufficient Stock) if ProductStock < 0;

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 InvoiceDetailQuantity > 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 InvoiceDetailQuantity > 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 InvoiceDetailAmount,
InvoiceSubTotal, ...., CustomerTotalPurchases).

120

Alteraciones del orden de disparo


de las reglas
Error

Total
Calculado

Total
Ingresado

SupplierId*
InvoiceId*
...
InvoiceEntTotal
Entered Total
InvoiceDetailAmount
( ProductId*
InvoiceDetailQuantity
InvoiceDetailPrice
InvoiceDetailAmount = InvoiceDetailPrice * InvoiceDetailQuantity)
...
InvoiceCalcTotal = SUM(InvoiceDetailAmount) 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(InvoiceDetailAmount), 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:

121

vemos que las dependencias indican que cada vez que se agreguen, modifiquen o eliminen valores de los
atributos InvoiceDetailPrice e InvoiceDetailQuantity en las lneas, se recalcular el valor del atributo
InvoiceDetailAmount 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 InvoiceDetailAmount 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 ProductId.
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.

122

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( InvoiceDetailQuantity, 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.

123

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.
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 literal; 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.

124

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 BeforeDelete..
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 If Insert on AfterValidate
on BeforeUpdate If Update on AfterValidate
on BeforeDelete If Delete on AfterValidate

tiempo

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?

---------------------------------------------------------------------------------------------------------------------------------------------------1 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.

125

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;
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.

126

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;
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.

tiempo

Ampliamos el esquema que habamos efectuado antes, de las acciones que rodean a los eventos de disparo vistos
hasta ahora:
VALIDACIN DE LOS DATOS
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:

tiempo

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

loop

ABANDONAR NIVEL 2
AfterLevel - BeforeComplete
COMMIT
AfterComplete

127

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.

128

Ejemplo en transaccin de 2 niveles


Interactivamente y antes de confirmar:

REGLAS STAND-ALONE

EVALUACION DE REGLAS Y
FORMULAS SEGN ARBOL

PARA CADA LINEA


EVALUACION DE
REGLAS Y
FORMULAS
SEGN ARBOL

El siguiente ejemplo pretende mostrar visualmente en qu momentos se irn disparando las reglas y frmulas
definidas en una transaccin.
El disparo de reglas y frmulas se ir haciendo de acuerdo al rbol de evaluacin, siguiendo el orden que ste
determina.

129

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;

130

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( InvoiceDetailQuantity, ProductStock );
la frmula
InvoiceDetailAmount = InvoiceDetailQuantity*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: INVOICEDETAIL).
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 de
estas
operaciones
sombreadas
gris claro,
se ejecutarn
en el
descrito,
cada
Luego
la iteracin
de todas
las lneas,depodemos
suponer
la existencia
de orden
una accin
que para
podramos
llamar
una
deabandono
las lneas.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,
entonces coincidir con el evento de disparo BeforeComplete.

131

Aclaracin importante: Todas las operaciones sombreadas, tanto en gris claro como en gris oscuro, se 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,
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.

132

Ejemplos
Cundo se dispararn las siguientes reglas?
Something.call( InvoiceId ) if Insert;
Luego de validado el campo InvoiceId e inferido que se est en modo Insert

Something.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.

Something.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.

Something.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.

133

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)

Something.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.

Something.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?

134

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(CustomerId, &flag) on AfterComplete;
error() if &flag=N on AfterComplete;
2.2) O definir las reglas:
&flag = PXXX.udp(CustomerId) on AfterComplete;
error() if &flag=N on AfterComplete;

135

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.

136

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.

137

Eventos en Transacciones
Evento Start
Evento User Event
Evento After Trn
Evento Exit
Evento TrackContext

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, se disparar el evento Start cada vez que se enve al servidor la informacin de la instancia con la
que se est trabajando.
En cuanto al evento Exit, se ejecutar por cada iteracin, al final de la misma.
El evento TrackContext apunta a obtener interfaces de usuario sensibles al contexto. Programando este evento
se podr recibir informacin del contexto para luego tomar las decisiones necesarias.

138

Eventos Start
Start: Se ejecuta cada vez que se somete el form de una
transaccinalservidor.
SINTAXIS: Event Start
cdigo
EndEvent

EJEMPLO: Event Start


&entrada=Now()
EndEvent

El evento Start es un evento del sistema, por lo tanto ocurre automticamente.


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
Se ejecutar cada vez que se someta el form de la transaccin, es decir cuando se presione cualquier botn
del form.
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.

139

Eventos de Usuario
Adems de los eventos ofrecidos por GeneXus, el analista puede
definir eventos creados por l, llamados eventos de usuario.
Propiedades

Web:

Orden de
ejecucin

1. Evento Start
2. Lectura de atributos y variables del form
3. Evento de usuario seleccionado

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 el botn:
Event Print Invoice //evento definido en la transaccin "Invoice"
PrintInvoice.Call( InvoiceId )
EndEvent
Cmo asociar un evento de usuario a un control?
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. Volveremos sobre este tema en el captulo de Web Panels.

140

Evento After Trn


Ocurre inmediatamente despus de la ejecucin de las reglas
con evento de disparo AfterComplete.
Sintaxis:

Ejemplo:

Event After Trn


cdigo
Endevent
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 actualizarlos1.
--------------------------------------------------------------------------------------------------------------------------------------------------------------1 Hay dos motivos por los cuales no es posible actualizar atributos en reglas con evento de disparo AfterComplete ni en el
evento After Trn. El primer motivo es que ya se han hecho las grabaciones correspondientes e incluso se ha efectuado
COMMIT, de modo que ya es tarde para asignar valores a atributos. Y adems, en lo que respecta al evento After Trn, en
los eventos no se permite realizar asignaciones a atributos.

141

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 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.

142

Integridad Transaccional
IT

143

Qu es el concepto:
integridad transaccional?
Un conjunto de actualizaciones a la base de datos tiene
integridadtransaccional cuandoencasode unafinalizacin
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.

144

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
todasobienningunadeellas.

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.

145

Qu es efectuar COMMIT?
ElcomandoCOMMITpermiteespecificarqueciertoconjuntodeoperaciones
realizadas sobre una base de datos, ha culminado de efectuarse
correctamente:
...........
OperacinsobreBasedeDatos
COMMIT

COMMIT

OperacinsobreBasedeDatos

FinalizaUTL
ComienzaUTL
OperacinsobreBasedeDatos
OperacinsobreBasedeDatos
OperacinsobreBasedeDatos
OperacinsobreBasedeDatos

FinalizaUTL

DemodoqueefectuarCOMMITenunabasededatos,significaquesedapor
finalizadaunaunidaddetrabajolgica(UTL).

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

146

Qu es efectuar ROLLBACK?
HacerROLLBACK(vueltaaatrs)provocaquesedeshagan
todas las operaciones efectuadas en la base de datos que
nohayanquedadoconCOMMIT.
Esto se resuelve deshaciendo todas las operaciones
posterioresalltimoCOMMIT.

147

Unidad de trabajo lgica (UTL)


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).
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 (E
inmediatamente despus de las BeforeComplete). 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 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.

148

Personalizacin de UTL
en GeneXus
PropiedadCommit onExitdetransaccionesy
procedimientos:
Valores:

Yes (Default): SeejecutaCOMMIT


No: NoseejecutaCOMMIT

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.

149

Personalizacin de UTL
en GeneXus
EjemplodeusodeCommit onExit=No

Trn. X

Commit on Exit = Yes

call

Proc. Y

Commit on Exit = No

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.

150

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 AfterComplete, 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. 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).

151

Personalizacin de UTL
NopuededefinirseunaUTLcompuestaporvariastransaccionesWeb.
call

Trn.Y

Trn.X
UTL 1

UTL 2

UnatransaccinWebsolopuedeCommitear losregistrosinsertadosporellamisma,opor
procedimientosenunacadenadeinvocaciones,peronopuedeCommitear losregistrosinsertados
porotratransaccin.

call

Trn.X

(luego del

Trn.Y

Commit)

call
(antes del

Proc.Z

UTL

Commit)

No pueden quedar dentro


de una misma 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.

152

Personalizacin de UTL
Sideseamosquelasinsercionesmediantedostransaccionesdistintas
conformenunanicaUTL:

Trn.X

Trn.Y

Tenemosunasolucin:utilizarBusinessComponents yelcomandoCommit al
terminardeinsertarmediantelasvariablesBusinessComponents losregistros
asociadosaambastransacciones(sever msadelante).

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.

153

Comandos COMMIT y ROLLBACK


de GeneXus
GeneXusofreceloscomandos:COMMITyROLLBACK
Se pueden incluir en Procedimientos, Web Panels, as
comoencombinacinconBusinessComponents.
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
ejecutarelcomandoCOMMIToROLLBACK

154

Objeto Procedimiento

155

Procedimientos
Definicin
Procesos nointeractivos deconsulta yactualizacin delabase
dedatos.

Procedimientos:
Definen procesos no interactivos de consulta y actualizacin de la base de datos. Los procedimientos
pueden generar un archivo formato PDF, mediante el cual es posible listar informacin por pantalla o
impresora. Adems, los procedimientos pueden actualizar la base de datos1.

-------------------------------------------------------------------------------------------------------------------------------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
web panels.

156

Caractersticas
Definicinprocedural.
Definicinsobrelabasedeconocimiento.
Independenciadelabasededatos:definicinanivelde
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 los 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 los 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 los 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.

157

Elementos

Comoenlastransacciones,puedendefinirsevariablesquesern
localesalobjeto.

Para cada procedimiento se puede definir:


Source: Aqu se escribe el cdigo correspondiente a la lgica del procedimiento. Tambin pueden
definirse al final del cdigo subrutinas1 que podrn ser invocadas desde el propio cdigo mediante el
comando adecuado.
Layout: As como las transacciones tienen una pantalla (form), los procedimientos tienen un
layout de la salida. En esta seccin se define la presentacin del procedimiento: los datos que se
quieren listar y el formato de la salida.
Rules: permiten definir cierto comportamiento particular, como los parmetros que recibe el objeto,
si el procedimiento implementar un listado pdf, etc.
Conditions: Condiciones que deben cumplir los datos para ser recuperados (filtros).
Variables: Variables locales al objeto (dem que con el objeto transaccin)
Help: Permite la inclusin de texto de ayuda, para ser consultado por los usuarios en tiempo de
ejecucin, para el uso del procedimiento. Se puede redactar una ayuda para cada lenguaje.
Documentation: Permite la inclusin de texto tcnico, de tipo wiki, para ser utilizado como
documentacin del sistema.
Propiedades: Definen aspectos generales del procedimiento, como su nombre, descripcin, tipo de
salida (impresora, archivo, pantalla). Recordemos que alcanza con presionar F4 para obtener las
propiedades.

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

No se tratarn en el presente curso.

158

Ejemplo
Queremosimplementarunlistadocomoelquesigue:
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 procedimiento 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 Printblock.
Los primeros dos Printblocks 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 Printblock.
El tercer Printblock 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
Printblock contendr los tres controles atributo CustomerId, CustomerName y CountryName.
Transformando las reas en Printblocks, el Layout del procedimiento nos quedar como el que figura
en la pgina siguiente.

159

Layout
Nombre de cada Printblock

Printblock

SucesindePrintblocks.
Noimportaelordendedefinicin.
CadaPrintblock debetenerunnombrenico.
Solosedeclaran,soninvocadosdesdeelSource conel
comandoprint (Ej.:print header).

El Layout de un procedimiento ser una sucesin de Printblocks que no tienen por qu seguir el
orden en el que se desea que aparezcan en la salida.
En el ejemplo anterior, el mismo procedimiento habra sido impreso si se hubieran especificado los
Printblocks 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 procedimiento. Desde all sern invocados mediante un
comando especfico para tal fin (el comando print).
Por esta razn, cada Printblock deber tener un nombre nico para poder ser referenciado luego desde
el Source.
En el ejemplo, para listar todos los clientes, el Printblock 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.

160

Layout: Printblock
ParadefinirlosPrintblocks tenemoslossiguientes
controlesdisponibles:

yparainsertarunPrintblock damosbotn derecho


sobre ellayoutyelegimos InsertPrintblock.

El Printblock es un tipo de control vlido solamente en los 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 toolbox. La misma
toolbox se utiliza para insertar los controles en el Layout. De hecho esta toolbox est disponible para
todos los objetos GeneXus que se creen, y en cada caso tendr los controles disponibles segn el
tipo de objeto.
Para insertar un Printblock damos botn derecho en cualquier lugar del layout y seleccionamos Insert
Printblock.
Como todo control, el Printblock tiene propiedades que pueden ser configuradas por el usuario. En
particular, tiene la propiedad Name, muy importante dado que es el identificador del Printblock. Con
este identificador es que el Printblock puede ser invocado desde el Source para ser impreso.
Para acceder a la propiedades de un Printblock, lo seleccionamos y presionamos F4 o
View/Properties.

161

Source
Definelalgicadelprocedimientomedianteprogramacin
procedural
Lenguajemuysimple
Comandosusualesdecontrol:If,Docase,Dowhile,For
Comandosdeimpresin:Print,Header,Footer
ComandodeaccesoyactualizacindelaBD:For each,New,Delete
Comandosparasalirdeunbucle,abandonarelprograma,invocaraotro
objeto,invocaraunasubrutina,etc.:Exit,Return,Call,Do

En esta seccin se define la lgica del procedimiento.


El lenguaje que se utiliza para programar el cdigo fuente de los 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 Printblock del Layout (print), para acceder a la base de datos (For each),
para insertar nuevos registros en una tabla (new), para invocar a una subrutina (do), etc.
Al final de la sucesin de comandos que constituye el cdigo general o principal del procedimiento,
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.

162

Comando For each


Seutilizaparaaccederalainformacindelabasededatos.
ConunFor each serecorreunatabladelabasededatos:la
tablabasedelFor each.
Paracadaregistrodeesatabla,sequierehaceralgoconla
informacinasociada.(Ejemplo:imprimirla)
TodocomandoFor each terminaconunEndfor.

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 procedimiento 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.

163

Comando For each


Ejemplo:Listadodeclientes
CUSTOMER

COUNTRY

Layout:

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?

164

Comando For each


Tablaqueserecorre:CUSTOMER
Tablaqueseaccedeparacadacliente:COUNTRY
CUSTOMER

COUNTRY

INTERPRETACIN:
For each record in CUSTOMER table
Find the corresponding CountryName in table COUNTRY
print customer
Endfor

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.

165

Comando For each: determinacin


de tabla base
Elaccesoalabasededatosquedadeterminadoporlos
atributosquesonutilizadosdentrodelcomandoFor each.
Paraeseconjuntodeatributos,GeneXus buscar lamnima
tablaextendidaqueloscontenga.
Sutablabaseser latablabasedelFor 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.

166

Comando For each: determinacin


de 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 Printblock 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 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.

167

Listado de navegacin

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

Se accede para recuperar info


relacionada (CountryName)
tabla base: la que se navega

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 procedimientos, 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 procedimiento 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).
Tambin se muestra en un pequeo diagrama de tablas, 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 este caso se muestra solamente la tabla COUNTRY.
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.

168

For each: clusulas Where


Permitenestablecerfiltrossobrelosdatosarecuperar.Ejemplo:
For each
where CustomerName >= &Start when not &Start.IsEmpty()
where CustomerName <= &End when not &End.IsEmpty()
print customer
Endfor

Soloparalosregistrosquecumplanlascondicionesbooleanas
delasclusulaswhere debenejecutarseloscomandosinternos
alFor each.
Lasclusulaswhere aplicanslosisesatisfacenlascondiciones
desusclusulaswhen.

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 procedimiento 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).
Cada condicin booleana de un where puede estar compuesta de varias expresiones booleanas
concatenadas con los operadores lgicos and, or y not.
-------------------------------------------------------------------------------------------------------------------------------------------------1 A travs de un objeto que los pide al usuario, por ejemplo un Web Panel.

169

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 Printblock customer: CustomerId,
CustomerName, CountryName.
que debe acceder a la tabla COUNTRY cuya clave primaria es CountryId para obtener algn dato
(CountryName)

170

For each: clusulas Where


Atributospermitidos:losdelatablaextendidadelatablabase
delFor 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.

171

For each: clusula Order


Permiteestablecerelordenenelquesequierenrecuperarlos
datos.Ejemplos:
For each order CustomerName
print customer
Endfor
For each
order CustomerName when not (&Start.IsEmpty() and &End.IsEmpty())
print customer
Endfor

Paradeterminarordendescendentesedebencolocarparntesis
rodeandoalosatributosdelorden.Ej: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 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, 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 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.
Si se utiliza la clusula Order None, GeneXus entiende que no desea establecer ningn orden de
recorrida en particular y delega esta tarea al DBMS.
La clusula order none admite condicin para aplicarse (when).

172

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
procedimiento 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
procedimiento. De cualquier manera, si al comienzo no se defini el ndice de usuario y
posteriormente se decide definirlo, alcanza con regenerar el procedimiento (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).

173

OPTIMIZACIN:
Orden compatible con los filtros
For each
where CustomerName >= &Start
where CustomerName <= &End
print customer
Endfor

Se recorre
toda
la tabla base

For each order CustomerName


where CustomerName >= &Start
where CustomerName <= &End
print customer
Endfor

No se recorre
toda
la tabla base:
optimizado!

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.

174

OPTIMIZACIN:
Orden compatible con los filtros
GeneXus siempre
intentar
encontrar el mejor
orden posible para
que la consulta
sea optimizable,
es decir, coincida
con algn ndice
definido en la
base de datos.

El listado de navegacin nos informa que la consulta est optimizada ya que recorre solamente los
registros incluidos en el filtro (desde CustomerName>=&Start hasta CustomerName <=&End).
Para determinar el orden se tiene en cuenta:
Los atributos de la clusula Order especificada por el usuario
Las restricciones que aplican al nivel (atributos mencionados en la regla Parm del procedimiento,
condiciones explcitas tanto en el Where como en las Conditions)
La existencia de ndices sobre estos atributos.
Distinguimos 2 casos:
1) Se escribe una clusula order
El For each quedar ordenado por esos atributos, exista o no un ndice por stos.
Si no existe un ndice con los atributos del order, pero existen condiciones implcitas o
condiciones explcitas por igualdad, se busca si existe un ndice que contenga los atributos
de las condiciones ms los del Order. La condicin explcita prevalece sobre la mplcita para
la determinacin del Order, en caso que sean diferentes y exista ndice por cada una de
ellas.
Si existe un ndice, los atributos de las condiciones sern agregados en la lista del Order
para que dicho ndice sea considerado en su lugar.
2) No se escribe clusula order
En este caso, si existe algn ndice por los atributos de la condicin, el Order quedar
determinado por los atributos del ndice.
Si no existe un ndice que corresponda con las condiciones, o sea que no se puede
optimizar la recorrida segn las condiciones del nivel, entonces se ordenar por los atributos
de la Primary Key.

175

Por ejemplo, si tenemos las transacciones:


COUNTRY
{
CountryId*
}

CITY
{
CountryId*
CityId*
}

El For each:
For Each order CityId
Where CountryId = 1
...
Endfor
Recorrer la tabla CITY, ordenando por: CountryId, CityId y utilizando el ndice ICITY (ndice por
clave primaria que contiene ambos atributos).
Aunque es el propio DBMS el que resuelve el plan de acceso ms apropiado, la informacin antes
mencionada influir en su determinacin.

176

For each:
clusula Defined by
For each
defined by InvoiceDate
print customer
Endfor
Noofrecefuncionalidadalgunaenloquerespectaalosdatosa
recuperar.
Seutilizaexclusivamenteparadarunelementomsparala
determinacindelatablabasedelFor each deseada.
Ejemplo: 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 procedimientos 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 procedimiento.
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 Printblock 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.

177

For each:
clusula Defined by
Atributospermitidos:puedenaparecervariosatributosdela
tablaextendida,peroalmenosunodebecorresponderalatabla
basequesedesea(encasocontrariodar unerror).
Sesugiereutilizaratributossecundarios,dadoquelosmismos
estnenunanicatabladelmodeloyestoevitaambigedades.

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 procedimiento
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).

178

For each:
clusula When none
PermiteejecutardeterminadocdigocuandoenunFor each no
seencuentraningnregistroquecumplalascondiciones.
Ejemplo:
For each
where CustomerName >= &Start
where CustomerName <= &End
print customer

When none

print message

Endfor

El Printblock 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.

179

Comando For each - Sintaxis


For each
[{[order] order_attributesi [when condi]}... | [order none] [when
condx]]
[using DataSelectorName([[parm1 [,parm2 [, ...] ])]
[{where {conditioni when condi} |
{attribute IN DataSelectorName([[parm1 [,parm2 [, ...] ]} }...]
[defined by defined_attributes]
[Blocking NumericExpression]
code1
[when duplicate
code2]
[When none
code3]
Endfor

La sintaxis presentada generaliza el ejemplo con el que vinimos trabajando.


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.
Pueden mencionarse atributos de la tabla extendida.
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.

180

Eleccin del ndice: GeneXus elige automticamente el ndice a utilizar para satisfacer el orden. GeneXus siempre
intentar encontrar el mejor orden posible para que la consulta sea optimizable, es decir, coincida con algn ndice
definido en la base de datos. Para determinar el orden se tiene en cuenta:
Los atributos de la clusula Order especificada por el usuario
Las restricciones que aplican al nivel (atributos mencionados en la regla Parm del procedimiento, condiciones
explcitas tanto en el Where como en las Conditions)
La existencia de ndices sobre estos atributos.
Aunque es el propio DBMS el que resuelve el plan de acceso ms apropiado, la informacin antes mencionada
influir en su determinacin.
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.
Using DataSelectorName
Permite definir filtros acorde al criterio definido en el DataSelector1 definido en DataSelectorName.
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).
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.

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, Wiki)

------------------------------------------------------------------------------------------------------------------------------------------------------------------1 El objeto DataSelector se ver ms adelante en el curso.

181

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 procedimientos 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.
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.
Blocking
Si bien se abordar este tema ms adelante en el curso, a modo de idea general diremos que la especificacin de
esta clusula permite realizar actualizaciones y eliminaciones en bloque, reduciendo as el nmero de accesos a la
base de datos.
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).

182

Comando For each


PodemoshacerqueGeneXus escribaelcdigobasedelFor each
pornosotros,insertandosnippets (conelmen Insert odesde
laToolbox):

Los code snippets son plantillas de cdigo que GeneXus tiene predefinidas, que nos ayudan a
escribir el cdigo fuente. Cuando estamos trabajando en el Source de un procedimiento, la Toolbox
nos muestra varios snippets que nos facilitan la escritura del comando For each.
Los snippets tienen a su vez un atajo (shorcut), que hacen que la escritura de cdigo sea ms
rpida todava. Por ejemplo, digitando simplemente fe se escribe automticamente el siguiente
cdigo:
For each
/*For each Code*/
Endfor
Luego el usuario sustituye la lnea de comentarios con el cdigo necesario.
La lista de los atajos de cada snippet, es la siguiente:
fe (For each)
feu (For each using)
fen (For each When none)
feun (For each using When none)
few (For each where)
feuw (For each using where)
fewn (For each where When none)
feuwn (For each using where When none)

183

For eachs paralelos


LlamamosdeestaformaalcasodeFor eachs queestnescritos
enformasecuencial(noanidada).Ejemplo:
For each
print invoice
Endfor
For each
print bill
Endfor

TambinaplicaalcasoenelqueunFor each aparecedentrode


laclusulaWhen none owhen duplicate deotro.
Lasnavegacionessontotalmenteindependientes.

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 Printblocks 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.

184

For eachs anidados


SebuscarecuperarporcadaregistrodelFor each principal,
muchosregistrosdelanidado
For each
...
For each
...
Endfor
...
When none
...
Endfor

CuerpodelFor 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 una tabla recuperar algunos de otra: los relacionados.
para cada registro de una tabla recuperar todos los de otra.
procesar informacin por grupos, esto es, agrupar los registros de una tabla segn el valor de un
atributo o conjunto de atributos y para cada grupo, recuperar algunos registros: los correspondientes al
grupo.
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 INVOICEDETAIL (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.

185

For eachs anidados


Ejemplo:imprimirtodaslasfacturasconsusrespectivaslneas

For each
print invoice_header
For each
print invoice_lines
Endfor
print invoice_amount
Endfor

{InvoiceId, InvoiceDate, CustomerName}


{ProductDescription, ProductPriceListPrice,
InvoiceDetailQuantity, InvoiceDetailAmount}

{InvoiceAmount}

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 INVOICEDETAIL,
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
INVOICEDETAIL 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 InvoiceAmount,
donde la condicin de filtro sobre los registros a ser sumados o contados quedaba implcita, y no
haba que especificarla).

186

For eachs anidados


Ejemplo:imprimirtodaslasfacturasconsusrespectivaslneas
INVOICE

INVOICEDETAIL

Paracadaregistro deINVOICEimprimiralgunosdesusdatos
(InvoiceId,InvoiceDate)ydesuextendida(CustomerName).
LuegonavegarINVOICEDETAILyrecuperarlosregistrosque
correspondanalafacturaqueseest imprimiendo.
Losquecumplanlacondicinimplcita:
INVOICEDETAIL.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 INVOICEDETAIL.
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 INVOICEDETAIL que se indica arriba.

187

For eachs anidados


GeneXus debe:
DeterminarlatablabasedecadaFor each.

Apartirdeesodefinirlasnavegacionesquerealizar paracadaFor each


(existen3casosposibles).

LalgicadelosFor eachs depender delasrelacionesqueencuentre


entrelastablasdeterminadas.

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.

188

For eachs anidados:


determinacin tablas base
Seprocedeenformaordenada,determinando
cadavezlatablabasedeunniveldeanidacin,
yendodeafuerahaciaadentro:primerose
determinalatablabasedelFor each ms
externo,luegodelqueest anidadoaste
yas sucesivamente.
ParacadaFor each,intervienennicamente
losatributospropiosdeeseFor each:del
order,where,defined byytodoslosdelcuerpo
quenopertenezcanaunFor each anidado
(tampocointervienenlosdelaclusulaWhen none).

For each
...
For each
...
Endfor
...
When none
...
Endfor

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 y que tenga alguna relacin con la tabla base dell For each principal. La tabla
base de dicha tabla extendida, ser la tabla base del For each.
Si no puede encontrar una tabla extendida mnima que cumpla ambas condiciones, pero cumple que
contenga a los atributos, finalmente la elige, pero siempre busca la forma de encontrar relaciones
entre ambas tablas bases. Slo en este ltimo caso de que no se encuentran relaciones, se procede
a determinar la tabla base como si se tratase de For eachs independientes.
Veremos un esquema resumiendo lo anterior ms adelante.

189

For eachs anidados:


determinacin tablas base
For each
print invoice_header
For each
print invoice_lines
Endfor
print invoice_amount
Endfor
For each
print invoice_header
For each
print invoice_lines
Endfor
print invoice_amount
Endfor

Tabla base For each externo


{InvoiceId, InvoiceDate,
CustomerName}
{InvoiceAmount}

INVOICE

Tabla base For each interno


{ProductDescription,
ProductPriceListPrice,
InvoiceDetailQuantity, INVOICEDETAIL
InvoiceDetailAmount}

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 se
explic anteriormente: se busca la tabla extendida mnima que contenga a ProductDescription,
ProductPriceListPrice, InvoiceDetailQuantity e InvoiceDetailAmount, y que de ser posible est
relacionada con INVOICE.
La tabla que cumple ambos requisitos en INVOICEDETAIL.

190

For eachs anidados:


lgica asociada
Tablasbasedistintas
Fe externo

Existe relacin implcita que lo vincule con


un nmero N de registros del For each anidado?

Fe 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)

Tablasbaseiguales
CortedeControl:Correspondealcasoenelquequeremosrecuperar
(Caso 3)
informacinporgrupos.

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.

191

Caso 1: Join
Distintastablasbaseperoexisteunarelacin1Ndirectao
indirectaentreellas.
Ejemplo:Listadodetodoslosclientesysusfacturas.
For each
print customer
For each
print invoice
Endfor
Endfor

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

CustomerId

INVOICE

ext(principal) base(anidado) = {CustomerId}

EnelFor each anidadoseordenaporatributorelacin: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 procedimiento 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 INVOICEDETAIL 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.

--------------------------------------------------------------------------------------------------------------------------------------------------1 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.

192

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 InvoiceAmount, 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.

193

Caso 1: Join
Ejemplo:Listadodetodaslasfacturasporpas
{CountryId, CountryName}

For each
print country
For each
print invoice
Endfor
Endfor

CountryId
CUSTOMER

COUNTRY

CustomerId
INVOICE

{InvoiceId, InvoiceDate, InvoiceAmount}


base(principal) ext(anidado)
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.

194

Caso 2: Producto Cartesiano


Distintastablasbase,peronoexisterelacin1Ndirectani
indirectaentrelasmismas.
Elresultadoqueobtenemoseselproductocartesianodedichas
tablas:paracadaregistrodelatablabasedelFor each principal,
serecuperantodoslosregistrosdelatablabasedelanidado.
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) = y
base(For each principal) ext(For each anidado)
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.

195

Caso 3: Corte de Control


Ejemplo:Paracadaclientequetienefacturas,listarsusfacturas.

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 procedimiento 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 InvoiceAmount 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).

196

Caso 3: Corte de Control


Ejemplo:Paracadaclientequetienefacturas,listarsusfacturas.
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 procedimiento
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).

197

Caso 3: Corte de Control


CondicionesquedebencumplirseparaimplementarCortesde
Control:
1.For each anidados
2.Tienenlamismatablabase
3.CuntosFor each?Unomsquelacantidaddecortes
4.Debemosestablecerenlaclusulaorder decadaFor each
externo,elatributooconjuntodeatributosporlosque
queremoscortar.

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.

198

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
2
Date: 12/08/05
Invoice
4
8
Date: 02/02/06
Invoice
7

Total
20
Total
40
15
Total
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
procedimiento.
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.

199

For each order CustomerId


defined by InvoiceDate
print customer
For each order InvoiceDate
print date
For each
print invoice
Endfor
Endfor
Endfor

For each order CustomerId


defined by InvoiceDate
print customer
For each order InvoiceDate
print date
For each
print invoice
Endfor
Endfor
Endfor

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)

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

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

200

Recomendamos al lector implementar en GeneXus este procedimiento 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.
Una vez determindo el Order del Corte de Control se optimizar, buscando el mejor ndice teniendo
en cuenta las condiciones explcitas o implcitas del nivel.

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, se determina de la siguiente manera: busca la mnima tabla extendida que
contenga a todos los atributos del For each anidado, tratando de encontrar aquella que tenga alguna
relacin con la tabla base del for each principal.
Si no encuentra una tabla extendida que contenga a todos los atributos del For each anidado y que
adems est relacionada, se queda con la tabla extendida mnima que contenga a los atributos
aunque no tenga relacin.

201

Comandos de control
if cond
bloque1
[else
bloque2]
endif

do while cond
bloque
enddo

for &var=inicio to fin [step salto]


bloque
Endfor
for &var in Expression
bloque
Endfor

do case
case cond1
bloque1
[case cond2
bloque2]
......
[case condn
bloquen]
otherwise
bloquen+1
endcase

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

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

202

For in Expression:
Expression es cualquier expresin cuyo valor sea una coleccin, vector o matriz.
var es una variable que debe tener el mismo tipo de datos que los elementos de Expression.
Esta estructura de programacin permite recorrer con menos cdigo una coleccin o una variable array
de una o ms dimensiones. Se almacena en la variable &var los valores de cada elemento de la
coleccin, array o matriz.
Para el caso de arrays de una dimensin:
for &var in &varArray()
// code
Endfor
el cdigo se expande (es equivalente) a:
&x = 1
do while &x <= rows(&array())
&var = &Array(&x)
bloque
&x += 1
enddo
En el caso de dos dimensiones:
for &var in &varMatrix()
// code
Endfor
el comando se expande (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

Tambin puede ser una variable coleccin de cualquier tipo, incluyendo una variable con la propiedad
Collection en 'False' pero de un tipo de datos 'SDT collection' .
for &var in &collection
...
endfor
La expresin tambin puede no ser una variable, por ejemplo en el caso del resultado de un DataProvider o de un
Procedure:
for &var in DataProvider(parms)
...
Endfor
for &var in Procedure(parms)
...
endfor

Consideraciones:
No es posible modificar los valores de la coleccin, array o matriz en la recorrida. Esto significa que
cambios en el valor de &var en el alcance de la estructura, no afectan al correspondiente valor de la
&collection o del &array(&x), o de &array(&x, &y)).
No es posible obtener la posicin de la coleccin/array/matriz durante la recorrida, para esto es
necesario definir una variable que acte como contador.
Estas estructuras pueden anidarse para recorrer varios arrays, matrices o colecciones. Esto incluye el
caso de que se invoque a una Subrutina que tambin tiene un For In Expression.
Al igual que en un For Each o un Do While, es posible incluir comando que corten la recorrida, como
Exit o Return.

203

Comandos de impresin
Print
SeutilizaparaimprimirenlasalidaunPrintblock definidoenelLayout
Sintaxis:Print nombrePrintBlock

Header
Seutilizaparadefinirloquesequiereimprimircomoencabezadodecadapgina
dellistado
Sintaxis: Header
bloque
end

Footer
Definelaslneasdepiedepginaaserimpresasalfinaldecadapginadel
procedimiento.
Sintaxis: Footer
bloque

end

Aqu veremos algunos comandos de impresin, que permiten disear la salida del procedimiento.
Print
donde nombrePrintBlock es el identificador de un Printblock del Layout. Si no existe en el Layout un
Printblock 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 Printblocks del Layout.
Cuando el Printblock 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 Printblock que se est
queriendo imprimir contiene atributos.
La nica excepcin a esta regla se produce cuando los atributos del Printblock estn incluidos entre
los parmetros recibidos por el procedimiento, 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.

204

Ejemplo: En el procedimiento 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 Printblock del Layout que contiene este texto.

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 procedimiento.
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 Printblock del Layout

205

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

MT nlines: nlines 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 nlines: nlnes 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 nlines: 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 Printblock. Si el comando se encuentra entre
dos lneas, este comando las imprimir en la misma lnea.

206

Procedimientos PDF
Configurarlaspropiedades:
Main Program =True
Call Protocol =HTTP
Report Output=Only to file

Regla
Output_file(xx.pdf,PDF)

En Web los listados 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 procedimiento, 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.

207

Condiciones
Permitenespecificarcondicionesglobalesquedeberncumplir
losdatosaserrecuperados.
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 procedimiento se indican los For eachs a los que se aplica cada
condicin de las especificadas en la seccin Conditions.
Si en el Source del procedimiento 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).

208

Condiciones
SielSource delprocedimientoes:
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 Printblock que contiene los atributos CustomerId, CustomerName, CountryName
invoice es un Printblock que contiene los atributos InvoiceId, CustomerId, CustomerName,
InvoiceDate, InvoiceAmount
product es un Printblock que contiene los atributos ProductId, ProductDescription, ProductStock
Si el procedimiento anterior tiene definidas las condiciones mostradas arriba, el procedimiento 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.

209

Filtros en la navegacin
Formas defiltrar losdatos:
Clusulas Where

Condiciones

Participan en determinacin de tabla base

NO participan en determinacin de tabla base

Regla Parm (Atributos recibidos como parmetros)


Ejemplo:Parm(Att1...Attn)

Resumimos aqu las distintas formas de filtrar en un 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 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.

210

Objeto Data Selector


DS

211

Data Selectors - Concepto

Objeto GeneXus: permite almacenar un conjunto de orders, filtros y un


defined by, con el objetivo de reutilizar navegaciones (ser referenciado
desde distintas consultas y clculos).
Ejemplo:
Customer
{
CustomerId*
CustomerName
CustomerAddress
CustomerGender
CustomerStatus
}

En varios objetos, se repite la necesidad de consultar los


clientes activos ( CustomerStatus= Status.Active )

Por ejemplo:
Procedimiento que imprime clientes activos, agrupados por sexo.
Procedimiento que aplica un descuento, slo para clientes activos.
Web Panel que muestra el total de ventas por cliente, slo de clientes activos.

CREAMOS DATA SELECTOR CON DICHO FILTRO (+ ORDER + DEFINED BY)


Y LO REFERENCIAMOS DESDE LOS LUGARES NECESARIOS

El atributo CustomerStatus est basado en un dominio enumerado, Status, que tiene 3 valores:
Active
On Hold
Closed
Los clientes activos sern aquellos que tengan el valor Status.Active.

212

Data Selectors - Definicin

Crear objeto de tipo Data Selector, darle un nombre y definirlo:

La estructura consta de:

Parameters: Parmetros recibidos desde la invocacin del Data Selector, para ser usados en conditions.
Conditions: Condiciones para filtrar los datos a ser recuperados.
Orders: Orders condicionales (cada order con sus atributos separados por coma y when opcional).
Defined by: Atributo o lista de atributos que colaboran en la definicin de la tabla base final.

213

Data Selectors - Ejemplo


Primer ejemplo planteado (Cont.): En varios objetos de una KB, se repite
la necesidad de consultar a los clientes activos
Definimos Data Selector: ActiveCustomers:

Ejemplo:
Customer
{
CustomerId*
CustomerName
CustomerAddress
CustomerGender
CustomerStatus
}

CustomerStatus=
Status.Active

Luego de definido un Data Selector, puede ser referenciado en:

Comandos For Each


Grupos de Data Providers
Frmulas Aggregate
Grids en Web Panels

La forma de referenciar a un Data Selector depender desde cul de los casos se desee invocar. Veremos la
sintaxis para cada caso.

214

Data Selectors - Beneficios


Ahorroyreutilizacindecdigo:Serealiza cierta definicin una
vez ysereutiliza envarias consultas yclculos enlaKB.

Facilitanelmantenimiento:Secambialadefinicin enunnico
lugar yelcambio aplica automticamente atodo lugar delaKB
enelque seutilice.

Optimizanelconocimiento:Facilitanelentrenamientode
personalnuevoparaunproyecto,graciasalencapsulamiento
queproveen.

215

Data Selectors Usos


En For Each
Dos maneras de uso:
Con clusula USING
Con operador IN en clusula WHERE
Importante:
Un Data Selector siempre tiene tabla base.
Segn la forma de uso, los atributos presentes en la definicin del
Data Selector intervienen o no en la determinacin de la tabla base del
For Each:

Con clusula USING: interviene en la determinacin de la tabla base.

Con operador IN: no interviene en la determinacin de la tabla base.

216

Data Selectors Usos


En For Each
For Each con clusula USING
Sintaxis:

Ejemplo 1:

For Each USING DataSelectorName([[parm1 [,parm2 [, ..] ])

EndFor
For Each USING ActiveCustomers()

EndFor

Ejemplo 2:

For Each USING ActiveCustomers()


Where CountryName = "Uruguay"

EndFor

Esto se
Expande a:

For Each
Where CustomerStatus = Status.Active
Where CountryName = "Uruguay"

EndFor

Clientes activos
de Uruguay

ATRIBUTOS DEL DATA


SELECTOR PARTICIPAN
EN DETERMINACIN DE
TABLA BASE DEL FOR
EACH

Nota:
La performance ser la misma si se escriben 2 where en el For Each que si se referencia un Data Selector en
el For Each (que tiene definida una condition) + un where en el For Each.
GeneXus siempre tratar de optimizar el cdigo generado, sin embargo no ms por utilizar el concepto de Data
Selectors , ya que su objetivo como venimos explicando, es: centralizar el conocimiento reusable en una sola
definicin y luego referenciar esa definicin en todas las consultas y clculos de la KB que aplique.
Dado que en estos ejemplos presentados, se est referenciando en For Each al Data Selector con clusula
USING, los atributos presentes en la definicin del Data Selector intervienen en la determinacin de la tabla
base del For Each. Por esto, en ambos ejemplos, la tabla base del For each es: CUSTOMER.

217

Data Selectors Usos


En For Each
For Each con operador IN (en clusulas WHERE)

El atributo que antecede al


operador IN debe pertenecer a
la tabla extendida de la tabla
base del Data Selector

Sintaxis:

For Each
Where <attribute> IN DataSelectorName([[parm1 [,parm2 [, ..] ])

EndFor

Ejemplo:

For Each
Where CustomerId IN InvoicesByDate(&FromDate, &ToDate)

CONSISTE EN UNA CONSULTA APARTE / INDEPENDIENTE DEL FOR EACH


EndFor

Definicin del Data Selector InvoicesByDate:


SE GENERA UN SELECT PARA EL DATA
SELECTOR, INDEPENDIENTE DEL SELECT
QUE SE GENERA PARA EL FOR EACH
TABLA BASE: INVOICE

ATRIBUTOS DEL DATA SELECTOR


PARTICIPAN EN DETERMINACIN
TABLA BASE DEL FOR EACH

NO
DE

En este ejemplo:
La tabla base del Data Selector es: INVOICE
El atributo que antecede al operador IN pertenece a la tabla extendida de INVOICE (CustomerId) y la
consulta asociada al Data Selector devolver una lista de valores correspondientes a dicho atributo (devuelve
una lista de clientes que tienen facturas en el rango de fechas dado).
El For Each tiene su tabla base determinada por los atributos incluidos en el For Each y sin tener en cuenta a
la informacin almacenada en el Data Selector.
El For Each navegar su tabla base y extendida, filtrando los registros que contengan a alguno de los clientes
de la lista devuelta por el Data Selector.

218

Data Selectors Usos


En Frmulas Aggregate

Es posible utilizar Data Selectors en frmulas Aggregate tanto globales como locales.
Sintaxis: NombreFormulaAggregate '(' <Expresin> ',' [<CondicinAgg>] ',' [<ValorDef>]')'
Find | Max | Min | Sum | Count | Average
Expresin a ser buscada, maximizada, minimizada, sumada o promediada
[<CondicinBsqueda>] ['USING' <DataSelector> '(' <Parmetro1> ',' <Parmetro2> ',' <Parmetro3>')']
Valor a devolver si no hay registros que cumplan con <CondicinAgg>

Ejemplo:

atributo frmula
cant. de clientes
activos del pas

Consideraciones acerca de la sintaxis de las frmulas Aggregate:


Como se detall en la diapositiva, en la sintaxis de las frmulas Aggregate la expresin corresponde a la
expresin a ser buscada, maximizada, minimizada, sumada o promediada. Puede ser un atributo (almacenado
o frmula) o bien una expresin que involucre atributos, constantes, variables.
Sin embargo hay que tener en cuenta que:
Variables solo pueden involucrarse en frmulas locales.
Para Sum y Average, el resultado de Expresin debe ser un valor numrico.
nicamente para el caso de Count, no vale una Expresin sino un atributo.

219

Data Selectors Usos


Consideraciones

En los parmetros del Data Selector pueden incluirse tanto


variablescomoatributos.
Incluiratributosimplicaquesefiltreporigualdadporellos.

Un mismo Data Selector definido, tendr cierto


comportamiento u otro y participar o no en la determinacin
de la tabla base de la consulta dependiendo de cmo se haya
invocado enelcontextoqueseausado.

220

Frmulas locales

221

Frmulas Locales
Generalidades

Ademsdedefinirfrmulasasociadasaatributos(globales,aniveldelaKB)
tambinesposibledefinirfrmulasenelpropiocdigo.
Llamamosaestecasodeusodelasfrmulas:frmulas inline ofrmulas
locales.
Esposibledefinirfrmulasinline =locales ensource deprocedimientos,
subrutinas,eventos,etc.

Comportamientodependedesisedefinen:
DentrodeFor Each
FueradeFor Each

222

Frmulas Locales
Dentro de For Each

Tabla basedelafrmula =Tabla basedelForEach.


Esposibleincluirenladefinicindelafrmula:
atributosdelatablabasedelafrmula+extendida
atributosdelatablanavegadaporlafrmula+extendida
variables
TABLA BASE FOR EACH = COUNTRY
TABLA BASE FRMULA = COUNTRY

Ejemplo:

TABLA NAVEGADA FRMULA = CUSTOMER


ATRIBUTO EN COMN: CountryId

For Each order CountryId


&NumberCustomers = Count( CustomerName )
EndFor
ATRIBUTOS QUE PERTENECEN A LA DEF. DE LA FRMULA NO
PARTICIPAN EN DETERMINACIN DE TABLA BASE DEL FOR EACH

Otro ejemplo de codificacin posible es el que sigue, en el cual la frmula se define en el propio where del For
Each, para filtrar por dicho clculo:
For each order CountryId
where Count(CustomerName)>50

Endfor

223

Frmulas Locales
Fuera de For Each

No se est posicionado en ninguna tabla al momento de disparar la frmula


no hay tabla asociada a la frmula.

Es posible incluir en la definicin de la frmula:


atributos de tabla a ser navegada + tabla extendida
variables

En este caso de uso, no hay filtros implcitos:


For each
defined by CustomerName
&total=sum(InvoiceAmount)
Endfor

VERSUS

&total=sum(InvoiceAmount)

SUMARIZA FACTURAS
FILTRANDO POR CLIENTE

SUMARIZA TODAS LAS FACTURAS

Consideracin importante: El disparo de la frmula se realiza al comenzar el grupo


donde se encuentra. Por lo tanto:
&CustomerId = 1
&total = Sum(InvoiceAmount, CustomerId = &CustomerId)

&CustomerId no tiene valor

Solucin:
&CustomerId = 1
do CalcAmount

sub CalcAmount
&total = Sum(InvoiceAmount, CustomerId = &CustomerId)
endsub

Consideracin importante
Una frmula se dispara cuando comienza el grupo que la contiene.
Esto significa que si se tiene definida una frmula con sus parmetros en determinada lnea de cdigo, los
valores de los parmetros van a ser aquellos que fueron ledos cuando el grupo fue ejecutado en la base de
datos. Entonces, si el grupo fue ejecutado en la base de datos, y luego de eso ud. asign valores diferentes a
los parmetros que involucrar en la definicin de la frmula, los valores de los parmetros que se tendrn en
cuenta no sern los que usted asign; por el contrario sern los ledos cuando se ejecut el grupo que contiene
a la frmula en la base de datos.
Y cundo se ejecutan los grupos?
- Cuando comienza un programa.
- Cuando comienza un For Each.
- Luego de un Endfor.
- Cuando comienza una subrutina o un evento.
En particular como en este caso estamos explicando frmulas locales definidas fuera de comandos For
Each, los tems que aplican son 1, 3 y 4.
Lo mismo ocurre con las variables. Los valores de las variables que son tenidos en cuenta al momento de
disparar las frmulas, son los valores que las variables tienen asignados cuando el grupo que contiene a la
frmula se ejecuta. De modo que si escribimos el siguiente cdigo:
&CustomerId = 1
&total = Sum(InvoiceTotal, CustomerId = &CustomerId)

224

La variable &CustomerId no tendr valor cuando la frmula se dispare.


Esto puede resolverse como sigue:
&CustomerId = 1

sub AmountCalc

do

&total
endsub

AmountCalc

Sum(

InvoiceAmount,

CustomerId

&CustomerId

ya que as logramos un nuevo comienzo de grupo (cuando la subrutina comienza), y en ese momento la
variable ya est cargada con el valor deseado. De modo que con esta solucin, cuando la frmula se ejecute la
variable &CustomerId valdr 1.

225

Tipos de datos
estructurados
SDT

226

SDT: Introduccin
Lenguajesdeprogramacinmanejan:
Tiposdedatossimples (Numeric,Character,etc.)
Tiposdedatoscompuestos.

EjemplodeTiposdedatoscompuestos(registrosotiposde
datosestructurados)
Type Client = Record
Name:

Character(30)

Country: Character(20)

Luego se definen variables


con este tipo de datos y se
trabaja con ellas...

City:

Character(20)

Phones:

Record
Home:

Character(15)

CellPhone: Character(15)
end;
end;

227

SDT en GeneXus
SecreancomocualquierotroobjetoGeneXus.
Editorsimilaraldeestructurasdetransacciones.
SDTsecomponede:miembros,subestructurasycolecciones:
botn
derecho

El editor de tipos de datos estructurados es similar al editor de transacciones.


Contiene:
Propiedad Name, con el nombre que identifica al miembro, subestructura o coleccin.
Propiedad Type, en la cual se debe seleccionar un tipo de dato simple, un dominio, o un tipo de datos
estructurado que ya se haya definido en la KB (propiedad Type solo adquiere valor si se est definiendo
un miembro y no una subestructura o coleccin).
Propiedad Is Collection, para indicar si el miembro representa una lista (en seguida veremos un
ejemplo).
Obsrvese que una subestructura es un miembro compuesto, en lugar de ser uno simple. Es decir, es,
en particular, tambin l, un tipo de datos estructurado.
Haciendo botn derecho sobre un miembro de la estructura, se despliega la ventana que se ve a la
izquierda, donde se puede insertar otro miembro, o una subestructura.
Tip: Si se desea crear un SDT con exactamente la misma estructura que la de una transaccin,
entonces en lugar de definir uno a uno todos los miembros, subestructuras y colecciones, alcanza con
arrastrar (hacer Drag & Drop) el nombre de la transaccin desde el Folder View hacia la estructura en
edicin del SDT.
De la misma forma, si se desea que un miembro de la estructura corresponda a un atributo, puede
seleccionarse y arrastrarse el atributo desde el Work With Attributes (ventana editable desde opcin
View del men de GeneXus) o insertarse con el dilogo Insert/Attribute del men de GeneXus.

228

SDT en GeneXus
Ejemploconteniendocoleccin:

Un country tiene muchas ciudades...

Marcando el check box Is Collection se abrir una rama de la estructura como puede verse, donde se le
pedirn dos nombres: el de la coleccin en s, y el de cada tem de la misma.
Como se ver a continuacin, cuando se define una coleccin, junto con el SDT se estar creando
implcitamente otro, que corresponder a los items de la coleccin.
Esto se debe a que de esta forma se podr luego definir una variable del tipo de datos del tem, para
luego agregarla a la coleccin.

229

SDT: Utilizacin
Seutilizanatravsdevariables.
Losatributosno puedenserSDT.
&country
Id

Name

Uruguay

Cities

CityName

Montevideo

CityName

Colonia

CityName

Paysand

A la derecha puede verse el dilogo de propiedades de una variable &country que se est definiendo
dentro de algn objeto.
El SDT Country definido en la KB tal como se aprecia en la pgina anterior, da lugar a la creacin de
dos tipos de datos estructurados: uno correspondiente al propio tipo de datos country y otro
correspondiente a los tems de la coleccin country.City. El por qu de este ltimo caso se debe a que
uno podra querer definir una variable solo de ese tipo de datos, para luego agregarla con el mtodo
Add que ya mencionaremos, a la coleccin.
Obsrvese que la variable &country se ha definido del tipo de datos country que aparece en la lista
obtenida al hacer clic en el combo box de la propiedad Data Type del dilogo de definicin de
propiedades de la variable.

230

SDT: Utilizacin
Paradatosnorepetitivos,seaccedeacadamiembromediante
elnombre,comopropiedaddelavariable.
Name

JuliaJames

Country

Uruguay

City

Montevideo

Phones

Home

555155.55.44

CellPhone

092155.12.33

&client.Name = Julia James


&client.Country = Uruguay
&client.City = Montevideo
&client.Phones.Home = ...
&client.Phones.CellPhone = ...

231

SDT: Utilizacin
Ejemplo:Transaccinqueregistralosrecibosefectuadosalosclientesy
SDTbasadoenlatransaccin:

drag
&
drop

For each where BillId = 7


...de tabla BILL
&bill.BillDate= BillDate
&bill.CustomerId = CustomerId
&bill.CustomerName = CustomerName
&bill.BillInvoicePeriodStartDate = BillInvoicePeriodStartDate
...podra devolverse:
&bill.BillInvoicePeriodEndDate = BillInvoicePeriodEndDate
parm(..., out: &bill)
&bill.BillAmount = BillAmount
endfor
En un proc. se carga
&bill con datos del
recibo 7 de la BD...

Aqu se presenta un ejemplo con el que continuaremos trabajando en lo que sigue. Agregamos a
nuestra realidad una transaccin de recibos. Supongamos que una vez al mes, se lanza un proceso de
generacin de recibos, en el que, tras elegir un perodo de facturacin (usualmente todo el mes anterior)
para cada cliente se sumarizan todos los montos de las facturas que se le efectuaron en dicho perodo,
y se le genera un recibo (autonumber). La generacin del recibo ser automtica (la realizar nuestro
sistema); ese es un tema que veremos en breve.
Por ahora, supongamos que necesitamos un procedimiento que devuelva los datos de un recibo
determinado de los generados automticamente como explicamos recientemente (por ejemplo, el de id.
7). Una opcin es acceder mediante un for each a la tabla BILL creada a partir de la transaccin de igual
nombre, y junto con la regla parm:
parm( out: BillDate, out: CustomerId, out: CustomerName, out: BillInvoicePeriodStartDate, out:
BillInvoicePeriodEndDate, out: BillAmount);
implementar lo pedido.
La otra opcin, es devolver toda esa informacin en una sola variable estructurada!
parm( out: &bill);
cargada como se muestra arriba. Para ello se define un SDT basado en la transaccin Bill (los SDTs no
pueden tener el mismo nombre que una transaccin, razn por la cul le llamamos BILL_SDT). Para no
tener que ingresar uno a uno los miembros del SDT de igual nombre que los atributos de la transaccin,
alcanza con arrastrar la transaccin Bill desde el Folder View, dentro de la estructura del SDT y
automticamente se inicializar como se muestra arriba.

232

SDT: Utilizacin
Ysiqueremosdevolverunalistaderecibos?
Opcin1:nomodificarelSDTyagregarvariable&bills coleccin:

For each where...


&bill.BillDate= BillDate
&bill.CustomerId = CustomerId
&bill.CustomerName = CustomerName
&bill.BillInvoicePeriodStartDate = BillInvoicePeriodStartDate
&bill.BillInvoicePeriodEndDate = BillInvoicePeriodEndDate
&bill.BillAmount = BillAmount
&bills.Add( &bill )
&bill = new Bill_SDT()

endfor

Supongamos que queremos devolver una lista de recibos (por ejemplo, los que se hayan efectuado en
un rango de fechas dado).

233

SDT: Utilizacin
&bills

add

&bill.BillDate= BillDate
&bill.CustomerId = ...
&bill.CustomerName = ...
&bill.BillInvoicePeriodStartDate = ...
&bill.BillInvoicePeriodEndDate = ...
&bill.BillAmount = ...

&bills.Add( &bill )
&bill = new Bill_SDT()

&bill

new

Bajo nivel! No existir otra forma


de ms alto nivel?

Hay que pedir nuevo espacio de memoria para la variable &bill, para la siguiente iteracin.
Como veremos en breve, existe un modo mucho ms sencillo, de ms alto nivel, DECLARATIVO, de
obtener la coleccin de SDTs cargada, sin tener que preocuparnos de realizar operaciones de bajo
nivel, como agregar una variable a la coleccin y pedir memoria...

234

SDT: Utilizacin en Data Provider

Bills
{
Bill where ...
{
BillDate= BillDate
CustomerId = CustomerId
CustomerName = CustomerName
BillInvoicePeriodStartDate = BillInvoicePeriodStartDate
BillInvoicePeriodEndDate = BillInvoicePeriodEndDate
BillAmount = BillAmount
}
}

Data Provider: procedimiento especializado, devuelve info estructurada

...este modo declarativo, por tanto de alto nivel, de cargar una coleccin de SDTs se conoce con el
nombre de Data Provider. Podemos pensarlo como un procedimiento especializado, que devolver
siempre informacin estructurada (ya sea simple como coleccin).
Aqu presentamos el ejemplo, que luego ampliaremos cuando entremos de lleno en este tema.

235

SDT: Utilizacin
Opcin2:modificarelSDTparaqueseacoleccinyluego
trabajardelamismaforma,definiendolasvariables:

&bills
&bill

236

SDT: Utilizacin
Paradatosrepetitivos,seaccedeacadaitemmediantecomando:
For &var in expression
code
endfor

&var:
variable de tipo de datos A
expression: expresin cuyo tipo de datos
es coleccin de A, o array
de A

Es posible incluir comandos de corte de la recorrida, al igual que en for each


o do while, como exit o return.

Ejemplo: A = SDT

For &bill in &bills


msg( &bill.Id.ToString() )
msg( Name: + &bill.CustomerName )
...
endfor

La variable &var va tomando los valores de cada posicin de la lista.


No es posible obtener la posicin del tem durante la recorrida, para esto es necesario definir un variable
que acte como contador.
Como puede fcilmente inferirse, este comando es vlido para colecciones de cualquier tipo de datos,
no solo SDTs.

237

SDT: propiedades
Los nombres de los miembros de una variable SDT se muestran como
propiedades:
Adems,
para
variables
collection:

&cVar.Count

Retornalacantidaddeitemsdelacoleccin.

&cVar.CurrentItem

CuandounavariableSDTcollectionsedespliegaenunform
(comogrid)permiteseleccionareltemquesehaseleccionado
conelmousecomolneadelgrid.

Las propiedades Count y CurrentItem solo estn disponibles para variables SDT Collection.

238

SDT: operadores y mtodos


&var =new SDT()

RetornaunanuevareferenciaopunteroalSDTespecificado

&cVar.Add(&item [, Position])

Agregatemacoleccinenlaposicinrelativaespecificada.Si
seomiteseagregaalfinal.Positioncomienzaen1.

&cVar.Clear()

Eliminatodoslostemsdelacoleccin

&var.Clone()

Creaunanuevareadememoriaycopialosdatosdela
variableenesta: &var1 = &var2.Clone()

&var.FromXML( &xml )

CargavariableSDTapartirdestringconteniendouna
estructuraxml.

&cVar.Item( Position )

RetornareferenciaalelementoconposicinrelativaPosition
enlacollection.

&cVar.Remove( Position)

Eliminatemqueseencuentreenlaposicinespecificaday
correunlugartodaslasposiciones.

&cVar.Sort( memberName)

Ordenaloselementosdelacoleccindeacuerdoamiembro.

&var.ToXml()

RetornaunstringconelformatoXMLdelosdatosdela
variableSDT(quepuedesercollection):ml = &var.ToXml()

Aqu se presentan la mayora de los mtodos con los que cuentan los tipos de datos estructurados.
Algunos aplican a variables SDT no coleccin, se representan con &var, otros a colecciones, se
representan con &cVar.
Para la lista completa, as como ejemplos, acceder al wiki o al help de la versin.

239

SDT: Ejemplo
MtodoToXml:

&xml = &client.ToXml()

Name

JuliaJames

Country

Uruguay

City

Montevideo

Phones

Home

555155.55.44

CellPhone

092155.12.33

<Client>
<Name> Julia James </Name>
<Country> Uruguay </Country>
<City> Montevideo </City>
<Phones>
<Home> 555-155.55.44 </Home>
<CellPhone> 092-155.12.33 </Home>
</Phones>
</Client>

240

SDT collection en FORM


SiseinsertaenunformunavariableSDTcollection:

aparece ventana para seleccionar los


miembros a insertar
que se presentarn como grid que ser
cargado automticamente :

Puede seleccionarse del SDT los miembros que quieren cargarse como columnas del grid. Obsrvese
que en nuestro caso hemos omitido los miembros CustomerId, BillInvoicePeriodStartDate y
BillInvoicePeriodEndDate.

241

Objeto Data Provider


DP

242

DP: Escenario
Intercambiodeinformacinjerrquicaentreaplicaciones,o
dentrodeunamismaaplicacin.
APPLICATION A

Sistema
de
Facturacin

Data
Interchange

APPLICATION B

envo de info de los recibos


Bill
Id:
Customer:
Date:
Amount:

2516
John Drotts
12/12/2008
1000

Sistema
de
Deudores/Acreedores

Bill
Id:
Customer:
Date:
Amount:

158
Dane Smith
12/12/2008
750

...

Supongamos que desde nuestro Billing System, queremos enviar a un sistema de deudores y acreedores, un
listado de los recibos correspondientes a cierto perodo de facturacin (es decir, para un perodo determinado
se desea sumarizar para cada cliente el importe total que se le ha facturado y generarle un recibo).
Se trata de informacin jerrquica (enviaremos info de recibos, cada uno de los cules tiene determinados
datos).
El formato ms usual de intercambio de informacin jerrquica suele ser Xml, aunque no sabemos qu
deparar el futuro en ese aspecto (por ejemplo se est volviendo comn el formato Json).

243

Procedimientos procedurales
Cmoobtenemoslosrecibosparaunrangodefechasdado?
Utilizando un procedimiento que reciba el rango de
fechas de facturacin: &start y &end
y devuelva una coleccin de recibos: Bill?
for each using ActiveCustomers()
&bill.BillDate = &today
&bill.CustomerName = CustomerName
&bill.BillInvoicePeriodStartDate = &start
&bill.BillInvoicePeriodEndDate = &end
&bill.BillAmount = sum( InvoiceAmount, InvoiceDate>=&start and
InvoiceDate <= &end and
InvoicePendingFlag )
&bills.Add( &bill )
&bill = new Bill ()
...
endfor

Teniendo el mismo SDT Bill que definimos cuando estudiamos los tipos de datos estructurados (all le
llamamos Bill_SDT, aqu le llamaremos Bill), estamos utilizando un procedimiento con los siguientes
parmetros:
parm( in: &start, in: &end, out: &bills );
siendo &start y &end variables de tipo Date que reciben el rango de facturacin, y &bills una variable collection
del SDT Bill.
Obsrvese que estamos utilizando el Data Selector ActiveCustomers para filtrar por clientes activos y utilizando
la frmula inline sum, en la que nicamente sumamos los totales de aquellas facturas que pertenezcan al
cliente de la actual iteracin del For each y cuyas fechas se encuentren en el rango dado y tengan el valor True
en el atributo Booleano InvoicePendingFlag.
Este atributo ser cambiado a False una vez que la factura haya sido procesada dentro del proceso de
generacin de recibos que iniciamos aqu pero que completaremos ms adelante, cuando estudiemos las
formas de actualizar la informacin de la base de datos (aqu solamente estamos obteniendo la informacin de
los recibos, pero an no los registraremos en la base de datos... ).

244

Procedimientos procedurales
Lenguaje de Input
Lenguaje de Transformacin
Lenguaje de Output

INPUT

Transformation

OUTPUT

Ejemplo:
For each using ActiveCustomers()
&bill.BillDate = &today
&bill.CustomerName = CustomerName
&bill.BillInvoicePeriodStartDate = &start
&bill.BillInvoicePeriodEndDate = &end
&bill.BillAmount = sum( InvoiceAmount, ...)
&bills.Add( &bill )
&bill = new Bill()
endfor

embebido
dentro del
cdigo

?
La intencin
del
procedimiento?

Todo procedimiento toma un Input, y mediante alguna transformacin, obtiene un Output.


Para obtener el Input se tiene cierto lenguaje (en GeneXus si se trata de la base de datos, nombrando los
atributos alcanza, como se puede ver en el ejemplo, a la derecha de las asignaciones; as como tambin se
obtiene de los parmetros).
Para realizar la Transformacin se tiene otro lenguaje (el cdigo que podemos ver en el ejemplo) y luego para
expresar el Output otro ms.
Como puede verse, en el caso de los procedimientos GeneXus, tanto el Input como el Output se encuentran
embebidos dentro del propio cdigo de Transformacin. Puede decirse entonces que el foco est puesto en la
transformacin.
De esta forma la intencin del procedimiento, su salida, queda oscurecida dentro de ese cdigo, que mezcla:
elementos de salida,
con elementos de transformacin (en nuestro caso, el comando for each, el mtodo add y el
operador new, que implementan el armado de la coleccin de recibos)
y con elementos de entrada.

245

Procedimientos declarativos
Lenguaje de Input
Lenguaje de Transformacin
Lenguaje de Output

FORMAT

Transformation
INPUT

Data Provider

OUTPUT

hierarchical structure

Bills using ActiveCustomers()


{
Bill
{
BillDate = &today
CustomerName = CustomerName
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, ...)
}
}

TXT
HTML
XML
JSON
SDT
...

Intencin clara
Bills
Bill
BillDate:
12/12/08
CustomerName: John Drotts
...
BillAmount
1000
Bill
BillDate:
12/12/08
CustomerName: Dane Smith
...
BillAmount:
750
...

Con un Data Provider, el foco est ubicado en el lenguaje de salida: obsrvese que se indica en una
estructura jerrquica de qu se compone ese Output.
Luego, para cada elemento de la estructura jerrquica, habr que indicar en el Source del Data Provider, cmo
se calcula.
Por tanto, alcanza con observar el lado izquierdo para deducir cul ser la estructura resultante.
Luego, alcanzar con indicar el formato deseado para esa estructura jerrquica resultante...

246

Procedimientos declarativos
Lenguaje de Input
Lenguaje de Transformacin
Lenguaje de Output

FORMAT

Transformation
INPUT

Data Provider

TXT
HTML
XML
JSON
SDT
...

OUTPUT

hierarchical structure
Bills
Bill
BillDate:
12/12/08
CustomerName: John Drotts
...
BillAmount: 1000
Bill
BillDate:
12/12/08
CustomerName: Dane Smith
...
BillAmount: 750

...

<Bills>
<Bill>
<BillDate>12/12/08</BillDate>
<CustomerName>John Drotts</CustomerName>
...
<BillAmount>1000</BillAmount>

</Bill>
<Bill>
<BillDate>12/12/08</BillDate>
<CustomerName>Dane Smith</CustomerName>
....
<BillAmount>750</BillAmount>

</Bill>
...
</Bills>

Bill
BillDate

12/12/08

CustomerName

John Drotts

...

...

BillAmount

1000

Bill

Bills

BillDate

12/12/08

CustomerName

Dane Smith

...

...

BillAmount

750

Luego, una misma informacin estructurada, podr representarse utilizando los diferentes formatos existentes.
Esa es la idea del Data Provider. Si en el futuro aparece un nuevo formato de representacin de informacin
estructurada, el Data Provider continuar invariable... GeneXus implementar el mtodo de transformacin a
ese formato, y solo habr que utilizarlo.

247

Data Providers
Estructuras jerrquicas
en GeneXus?
SDTs
Bill

OUTPUT

BillDate

12/12/08

CustomerName

John Drotts

...

...

BillAmount

1000

Bill

INPUT

DB

CustomerId

CustomerName

12/12/08

CustomerName

Dane Smith

...

...

BillAmount

750

CustomerStatus

1542

John Drotts

1543

Dane Smith

...

...

...

BillDate

invoices...

Hasta aqu hicimos un anlisis descriptivo. Surge inmediatamente la siguiente pregunta: cmo se representan
en GeneXus las estructuras jerrquicas de datos?
Por tanto, la salida de un Data Provider ser un SDT (o una coleccin de SDTs).
Luego, con esa salida puede realizarse lo que se desee, en particular, convertirla a formato XML, con el
mtodo toXml de los SDTs.
Veamos cmo declaramos la salida... no ser de la forma convencional (como parmetro de out de la regla
parm)...

248

Data Providers
Bill
BillDate

12/12/08

CustomerName

John Drotts

...

...

BillAmount

1000

Bill
BillDate

12/12/08

CustomerName

Dane Smith

...

...

BillAmount

750

OUTPUT

Aqu vemos para el ejemplo que venimos estudiando, que teniendo el SDT definido Bills, collection, que
coincide con la estructura que se infiere del Source del Data Provider GetBills, habr que declarar ese SDT en
la propiedad Output del Data Provider.
Pero no es la nica posibilidad... veremos otra en la pgina siguiente, donde cobrar sentido la propiedad
Collection.

249

Data Providers
Otra posibilidad (mismo resultado):
Bill
BillDate

12/12/08

CustomerName

John Drotts

...

...

BillAmount

1000

Bill
BillDate

12/12/08

CustomerName

Dane Smith

...

...

BillAmount

750

OUTPUT

Si en lugar de tener el SDT collection Bills, tuviramos el que aparece arriba, Bill, entonces podramos
programar el Source del Data Provider como vemos y luego configurar la propiedad Collection en True, con lo
cul se abrir una nueva propiedad, Collection Name, que permitir dar nombre a la coleccin.
Este Data Provider es equivalente al anterior.
Obsrvese que en este caso no es necesario poner la raz de la jerarqua, Bills, puesto que se infiere de la
propiedad Collection Name. De todas formas, si bien no es requerido, podra programarse el Source
exactamente igual al anterior, es decir, con el grupo Bills encabezando la jerarqua.
Bills
{
Bill using ActiveCustomers()
{
...
}
}
Nota: la clusula using, as como las where que veremos luego, order, etc., podrn especificarse tanto a nivel
del grupo Bills, como del grupo Bill, en casos como este. Volveremos sobre este tema ms adelante.

250

Data Provider
Objetivo:Retornodedatosestructurados.
Con Procedimiento: hay que armar el SDT con operaciones
debajonivel.
Con Data Provider: facilidad de escritura y claridad. Es
declarativo independientedeimplementacin.
paradevolverdatosestructuradosutilizaremosunDPen
lugardeunProcedimiento.

Los Data Providers atacan eficientemente un tipo de problema: aquel que consiste en retornar datos
estructurados. Para ese tipo de problemas contbamos con los procedimientos, pero su desventaja evidente
era que necesitbamos implementar la forma de armar esas estructuras con operaciones de bajo nivel, como
agregar un tem a una coleccin con Add, y pedir memoria (new). Asimismo, si hubiera que hacer clculos
complejos para dar valor a cada miembro de la estructura, quedaran en el cdigo embebidos los elementos de
la salida, sin que fuera sencillo visualizar en un golpe de vista la salida resultante del Procedimiento.
Todos estos inconvenientes se evitan con un Data Provider. Aqu el foco est puesto en la salida, razn por la
cul con un solo vistazo quedar evidenciada la estructura del Output. Por otro lado, siendo absolutamente
declarativo, nos independizamos de la forma en que se implementa realmente la carga del SDT. De eso se
encarga GeneXus.
Cuanto ms declarativa sea una herramienta, ms fcil de programar, ms adaptable al cambio, ms
independiente de una implementacin particular. GeneXus tiende a permitir declarar lo ms posible y cada vez
programar proceduralmente menos. Lo declarativo traslada el problema de la implementacin a la
herramienta, y se la quita al programador. Cuanto ms inteligente una herramienta, menos necesidad tendr el
programador de resolver el problema: le alcanzar con enunciarlo.

251

Data Provider
Utilizacin

Igual que un procedimiento que devuelve informacin


estructurada:
Procedimiento GetBills
Parm( in: par1, ..., in: parn, out: &bills );

Objeto GeneXus
&TheBills = GetBills( par1, ..., parn)
udp

Data Provider GetBills


Parm( in: par1, ..., in: parn);
Output: Bill
Collection: True
CollectionName: Bills

Objeto GeneXus
&TheBills = GetBills( par1, ..., parn)

&xml = &TheBills.ToXml()

Un Data Provider tambin puede recibir parmetros va regla parm, pero a diferencia de un procedimiento
donde todos los parmetros pueden ser de entrada/salida, aqu solo podrn ser de entrada.
Por otro lado, un procedimiento que devuelve informacin estructurada lo hace mediante una variable que se
carga en el cdigo, y que debe declararse como de salida, en el ltimo parmetro de la regla parm.
En un Data Provider, la declaracin del tipo de datos de salida se hace mediante las propiedades Output, no
en la regla parm.
La invocacin desde cualquier objeto GeneXus de un Data Provider es idntica a la invocacin de un
procedimiento, es decir, con udp.
Recuerde que al invocar a un objeto y no especificar el mtodo de invocacin, se asume udp.
La variable &TheBills deber estar declarada en el objeto GeneXus en el que se realiza la invocacin. Es la
variable en la que se devolver el resultado. Recuerde que si el SDT definido en la KB es el correspondiente a
los tems individuales: Bill, (y no a la coleccin Bills), entonces la variable &TheBills se definir como
Collection, de tipo de datos Bill.
Luego, con la estructura jerrquica devuelta se podr, por ejemplo, convertir al formato deseado, como XML.
Importante:
Como veremos, un Data Provider no solo puede retornar un SDT o coleccin de SDT, sino tambin otro tipo, el
Business Component, que tambin representa informacin estructurada. Vea ese tema para completar el
conocimiento de Data Providers.

252

Lenguaje de DP
Componentesbsicos:
Grupos
Elementos
Variables

BillsInfo
{
Bills
{
Bill
{
BillDate = &today
CustomerName = CustomerName
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, ... )
&quantity = &quantity + 1
}
}
BillQuantity = &quantity
}

El ejemplo que podemos ver aqu es parecido al que estuvimos trabajando. Hemos agregado el elemento
BillQuantity. Tmese unos instantes para pensar cmo deber ser el SDT BillsInfo, para que matchee con este
Source. A la izquierda lo hemos presentado.
De todos modos, el Source no tiene por qu escribirse tal cual la estructura del SDT. Cuando en el SDT
tenemos un miembro collection de un determinado tem, podemos omitir del Source el Item como grupo.
Ejemplo: con el SDT que tenemos arriba, podramos haber escrito el Data Provider:
Billsnfo
{
Bills
{
BillDate = &today
CustomerName = CustomerName
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum (InvoiceAmount, ... )
&quantity = &quantity + 1
}
BillQuantity = &quantity
}
con el mismo resultado. GeneXus tiene la inteligencia suficiente como para matchear con el SDT.

253

Lenguaje de DP
Grupos

Agrupantantoelementos,grupos comovariables enunmismo


niveldejerarqua.
Puedeserrepetitivocomonoserlo(inteligenciaparadeterminarlo).
BillsInfo
{
Bills
{
Bill
{

}
}
BillQuantity = &quantity
}

Ser una coleccin


de muchos

BillsInfo
{
Bills
{
Bill
{
BillDate = &today
CustomerName = CustomerName
...
&quantity = &quantity +1
}
}
BillQuantity = &quantity
}

254

Lenguaje de DP
Grupos

Ungruporepetitivoesanlogoaunfor each:
Determinatablabase(deigualformaqueenunfor each)
Tienedisponibleslasmismasclusulasqueparaunfor each:
BillsInfo
{
Bills
{

Bill
{

[{[order] order_attributesi [when condi]}... | [order none] [when condx]]


[using DataSelectorName([[parm1 [,parm2 [, ...] ])]
[{where {conditioni when condi} |
{attribute IN DataSelectorName([[parm1 [,parm2 [, ...] ]} }...]
[defined by att]

BillDate = &today
CustomerName = CustomerName
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, ...)
&quantity = &quantity + 1

Ver ms adelante opciones avanzadas

}
}
BillQuantity = &quantity
&quantity = 0
}

En el ejemplo, el grupo de nombre Bill ser repetitivo. Por qu? Para contestar la pregunta, hagamos otra: y si
fuera un for each, donde los elementos de la izquierda de las asignaciones corresponden a los distintos
elementos de una variable SDT? En este caso la presencia de CustomerName (a la derecha de la segunda
asignacin) permite afirmar que hay tabla base: CUSTOMER.
Por tanto el grupo ser repetitivo, iterando sobre la tabla CUSTOMER.
En el ejemplo que venamos trabajando, podamos tener la clusula:
Bill using ActiveCustomers()
que es como tener:
For each using ActiveCustomers()
por lo que as no estuviera el atributo CustomerName en la segunda asignacin, de todos modos sera con tabla
base, por la presencia del atributo CustomerStatus en el Data Selector ActiveCustomers.
Obsrvese que el grupo de nombre BillsInfo, en cambio, no ser repetitivo, no tiene clusulas asociadas, y los
elementos que contiene estn definidos a base de variables y no de atributos:
BillQuantity = &quantity
&quantity = 0
Y qu pasa con el grupo Bills? Obsrvese que en este caso, es un grupo que slo contiene otro grupo. El grupo
contenido ser repetitivo, por lo que Bills ser una coleccin de Bill. Por este motivo, el subgrupo Bill podra
omitirse (solamente dejar Bills) y que quede implcito. De este modo, las clusulas del grupo que permiten definir
order, filtros, defined by, se pueden asociar a este grupo.

255

Lenguaje de DP
Grupos

Tambinpuedenrepetirsegrupos:
Clients
{
Client
{
Name = Lou Reed
Country = United States
City = New York

}
Client where CountryName = Mexico
{

El resultado retornado ser


una coleccin de N+1 tems:
siendo N el nmero de
clientes de Mxico.

Name = CustomerName
Country = CountryName
City = CityName

}
}

Si la condicin se hubiese colocado en el grupo Clients, aplicara a los dos subgrupos Client. Por eso es que se
permite que las clusulas operen a nivel de los grupos que se repiten (items), y no solo a nivel del grupo que es
coleccin de tems.

256

Lenguaje de DP
Elementos

UnElementoesunvaloratmicoenelOutput.
CadaElementodebeserasignadoysusintaxisesladelas
frmulas.
Ejemplo:
Clients
{
Client
{
Name = CustomerName
Active = True if CustomerStatus = Status.Active; False otherwise;
}
}

257

Lenguaje de DP
Elementos

ElementosyAtributosusualmentetienenelmismonombre
notacinmscompacta:
Ejemplo:
BillsInfo
{
Bills
{
Bill
{
BillDate = &today
CustomerName = CustomerName
BillInvoicePeriodStartDate = &start
...
}
}
}

BillsInfo
{
Bills
{
Bill
{
BillDate = &today
CustomerName
BillInvoicePeriodStartDate = &start
...
}
}
}

258

Lenguaje de DP
Variables

Algunasvecesesnecesariorealizarclculosinternos:

Ejemplo:

BillsInfo
{
Bills
{
&quantity = 0
Bill
{
BillDate = &today
CustomerName
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, ... )
&quantity = &quantity + 1
}
}
BillQuantity = &quantity
}

259

Lenguaje de DP

Grupos: Opciones avanzadas


ClusulaDefault (~When none)
elgruposoloir alasalidasielgrupoprecedente(deigualnombre)noest
presente.

ClusulasdePaginado:Count ySkip
Paramanejarcuntosregistrosirnalasalida.

ClusulaNoOutput
enunGruposignificaqueelgruponodeber estarpresenteenlasalida,sinosolo
suselementossubordinados.

ClusulaOutputIfDetail
Paragrupocabezalconteniendogrupoconsuslneas:solosepresentaelprimeroen
lasalidasitienelneas.

ClusulaInput
sisenecesitatrabajarconcolecciones(devueltasporProcedimientooDataProvider)
comoInput delDP.
http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Data+Provider+Language

Podr encontrar la informacin completa de este tema en ingls en nuestro community wiki, en la siguiente
pgina:
http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Data+Provider+Language

260

Lenguaje de DP

Group: clusula Default


ClusulaDefault:elgruposoloir alasalidasielgrupoprecedente(de
igualnombre)noest presente.
(~When none enfor each)
CurrentTaxes
Where TaxInitialDate >= today()
Where TaxFinalDate <= today()
{
VAT = TaxVAT
Income = TaxIncome
}
CurrentTaxes [Default]
{
VAT = 0.7
Income = 0.3
}

Tabla TAXES
TaxInitialDate*
TaxFinalDate*
TaxVAT
TaxIncome

Slo se incluye en el Output si no se


encontr registro en el da de hoy

261

Lenguaje de DP

Grupos: clusulas de paginado


Count ySkip.
Paramanejarcuntosregistrosirnalasalida.

Customers
{
Customer [Count = 20] [Skip = 100]
{
Code = CustomerId
Name = CustomerName
}
}

Se saltean los primeros 100 customers y


se incluyen en el Output los 20
siguientes.

262

Lenguaje de DP

Grupos: clusula NoOutput


EnunGruposignificaqueelgruponodeber estarpresenteenlasalida:sino
solosuselementossubordinados.

Employees
{
Employee
{
Id = EmployeeId
Name = EmployeeName
EarningInfo [NoOutput]
Where IsAutorized(&UserId)
{
Salary = EmployeeSalary
Bonus = EmployeeBonus
}
}
}

<Employees>
<Employee>
<Id>123</Id>
<Name>John Doe</Name>
<Salary>30000</Salary>
<Bonus>5000</Bonus>
</Employee>
...
</Employees>

<Employees>
<Employee>
<Id>123</Id>
<Name>John Doe</Name>
<EarningInfo>
<Salary>30000</Salary>
<Bonus>5000</Bonus>
</EarningInfo>
</Employee>
...
</Employees>

en lugar de

263

Lenguaje de DP

Grupos: clusula OutputIfDetail


Cadatemdelacoleccindesalidatieneuncabezalyalgunaslneas:clusula
aniveldelgrupocabezal slosepresentarnenlasalidaaquellosgrupos
quetenganlneas.
Countries
{
Country [OutputIfDetail]
{
Id = CountryId
Name = CountryName
Customers
{
Id= CustomerId
Name = CustomerName
&quantity = &quantity + 1
}
Quantity = &quantity
}

Tabla base: COUNTRY

Tabla base: CUSTOMER


Si un pas no tiene clientes asociados
no aparecer como tem de la coleccin
Countries en la salida.

No lo hemos mencionado, pero como intuitivamente podemos pensar, de tener un par de grupos anidados
(un grupo que, entre otras cosas, contiene a otro), si cada uno debe acceder a la base de datos, entonces las
tablas base, as como el criterio de navegacin se determinan exactamente igual que en el caso de un par de
for eachs anidados.
Por ese motivo, en el ejemplo, el grupo Country tiene tabla base COUNTRY; el grupo Customers tiene tabla
base CUSTOMER, y se har un join entre ambas tablas a la hora de recuperar la informacin para cargar la
coleccin de pases. Es decir, por cada registro de COUNTRY se cargar la informacin de sus atributos
CountryId y CountryName en los elementos Id y Name del tem Country del SDT coleccin Countries que se
est cargando, y luego se recorrer la tabla CUSTOMER filtrando por aquellos registros para los cuales
CUSTOMER.CountryId = COUNTRY.CountryId, cargando para cada uno los elementos Id y Name.
La presencia de la clusula OutputIfDetail hace que solamente se presenten en la salida aquellos pases que
cuenten con clientes asociados. Si un pas de la base de datos no tiene cliente alguno, entonces no se
presentar como item de la coleccin de salida, Countries.

264

Lenguaje de DP
Clusula Input

Hastaaqu asumimosqueelInput venadelaBD;perotambin


senecesitanotrotipodeentradas.Porejemplo,lasalidadeun
ProcedimientooDataProvider. La formaobviadetrabajoesa
travsdevariables,queunavezasignadassemanejandeforma
usual:
&var = Proc.udp( parm1, ..., parmn)
&SdtVariable = DataProvider( parm1, ..., parmn )

Pero si se necesita trabajar con una coleccin se necesita la


clusulaInput

265

Lenguaje de DP
Clusula Input

Paratrabajarconcolecciones.
VerySimple
{
Month Input &i = 1 to 12
{
MonthNumber = &i
}
}

Similar al For &i=1 to 12


del lenguaje procedural

Otro Input puede ser un SDT collection:

CustomersFromAnotherDataProvider
{
&CustomersSDT = GetCustomers() // a DataProvider that Outputs Customers collection
Customer Input &Customer in &CustomersSDT
{
Id = &Customer.Code
Similar al For &var in Expression
Name = &Customer.Name
del lenguaje procedural
}
}

266

Actualizacin de la Base
de Datos

267

Actualizacin BD
Insert-Update-Delete

Actualizacin interactiva:
Transacciones:
Atravs delformelusuario ingresa/modifica/elimina losdatos.
Ventajas:
Seejecutan las reglas delnegocio (ynoseactualiza registro que viole
regla Errorespecificada)
Noseactualiza registro que viole integridad referencial.

BusinessComponents(BC)

Actualizacin nointeractiva:
BusinessComponents(BC)
Procedures

Hasta aqu slo conocemos una forma de actualizar la base de datos de nuestra aplicacin: las
transacciones.
Como sabemos, una transaccin determina la o las tablas requeridas para almacenar su informacin. A
su vez, al ser generada, se convertir en un programa que implementa la lgica de insercin,
eliminacin y modificacin de datos en esas tablas, en forma totalmente transparente para el
programador. Tambin la transaccin permite definir todas las reglas de negocio que debern cumplir
los datos asociados. El programa generado se encarga de ejecutarlas. As, si en una transaccin
tenemos una o varias reglas Error, que se disparan al satisfacerse determinadas condiciones, esas
reglas estarn incluidas en el cdigo generado, y no se permitir actualizar la base de datos hasta tanto
las condiciones que disparan esas reglas dejen de satisfacerse para los datos que se estn manejando
en esa oportunidad.
Asimismo, como vimos, las transacciones aseguran el control de integridad referencial, muy importante
para asegurar la consistencia de la base de datos.
Pero las transacciones no cubren todas las necesidades en cuanto a la actualizacin de datos. Tambin
se necesitar una forma no interactiva, batch, de realizar actualizaciones sobre tablas.
Para ello existen dos alternativas: actualizacin utilizando lo que se conoce como Business Component,
absolutamente relacionado con las transacciones, o utilizar comandos especficos para tal fin dentro de
objetos de tipo Procedure.
Luego veremos que los Business Components permiten gran flexibilidad, dado que permiten actualizar
la base de datos de cualquier forma: tanto interactiva como no interactivamente.
En lo que sigue introduciremos los Business Components y luego los comandos de actualizacin directa
dentro de Procedimientos.

268

Business Components
Escenario

Necesitamosregistrarlosrecibosqueefectuamosanuestros
clientes.
autonumber
Rules:
Default( BillDate, &today);
Error( The invoice period considered must be past ) if
BillInvoicePeriodEndDate > BillDate;
Error( Wrong invoice period ) if
BillInvoicePeriodStartDate > BillInvoicePeriodEndDate;

Pero este es un caso en el que no nos sirve la transaccin, dado que la


generacin de recibos es una tarea batch: se lanza una vez al mes un
proceso que calcula y registra todos los recibos correspondientes a las
facturas dentro de determinado perodo.

269

Business Components
Escenario

YatenamosdeclaradoelDataProvider GetBills querealizaba


elprocesodeclculoderecibosdeseado,peronogrababa:
Bill
{

parm( in: &start, in: &end);


Output: Bill

BillDate = &today
Collection: True
CustomerId
Collection Name: Bills
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, InvoiceDate >= &start and InvoiceDate <= &end and
InvoicePendingFlag )
}

Y nos devolva una coleccin de tipos de datos estructurados (SDT).


Si observamos, la estructura jerrquica de este DP es casi idntica a la estructura
de la transaccin Bill...

270

Business Components
Escenario

...ysipudiramosguardarenunaestructuralosdatosyluego
grabarlosenlabasededatos?
For &bill in GetBills( &start, &end )
&bill.Save()
endfor

Bill
BillDate

12/12/08

CustomerId

2516

...

...

BillAmount

1000

Bill

Bills

BillDate

12/12/08

CustomerId

158

...

...

BillAmount

750

y si adems esta grabacin se realizara


ejecutando las mismas reglas que se
ejecutan cuando se graba mediante la
transaccin Bill, y controlando adems la
integridad referencial?

&bill no ser una variable de tipo SDT, sino Business Component!

271

Business Components
BC

A partir de una transaccin, se puede crear su Business


Component (BC).
Permite encapsular la
lgica de la transaccin
(reglas, eventos, controles
de integridad referencial,
estructura de los datos) de
manera de poder realizar
inserciones,modificaciones
y eliminaciones, sin
necesidad del form...

Se crear automticamente en la KB un tipo de datos Business Component,


que podr asociarse a variables, y cuyo nombre ser el de la transaccin.

Por defecto la propiedad Business Component estar apagada. Eso significar que la lgica de negocio
dada por la transaccin, solo se utilizar dentro de la propia transaccin, y no se crear un tipo de datos
de igual nombre que la transaccin, Bill, que permita encapsular la lgica de la transaccin para
utilizarla desde otros objetos.

272

Business Components
En cualquier objeto GeneXus (ej: un procedimiento):
La variable &bill tendr la
misma estructura que el
SDT obtenido a partir de la
transaccin, y se trabaja de
forma anloga, pero adems
ofrecer mtodos para
actualizar la base de datos
en funcin de esos valores.

&bill.BillInvoicePeriodStartDate = #10-10-08#
&bill.BillInvoicePeriodEndDate = #09-10-08#
&bill.Save()

Se insertar registro en la tabla BILL?

Obsrvese que en este caso la fecha inicial corresponde al da 10 de octubre, mientras la fecha final
corresponde al da 9 de octubre... es decir, la fecha inicial ser posterior a la fecha final...

273

Business Components
Insert

Qu pasara en la transaccin si intentramos


grabar con estos datos?

&bill.CustomerId = 3456
&bill.BillInvoicePeriodStartDate = #10-10-08#
&bill.BillInvoicePeriodEndDate = #09-10-08#
&bill.Save()

Default( BillDate, &today);


Error( The invoice period considered must be past ) if BillInvoicePeriodEndDate > BillDate;
Error( Wrong invoice period ) if BillInvoicePeriodStartDate > BillInvoicePeriodEndDate;

No se insertar!

10/10/08

>

09/10/08

Obsrvese que se llenan algunos miembros de la estructura de la variable &bill, Business Component, y
luego se ejecuta el mtodo Save (inexistente en SDTs).
Esto es equivalente a lo que en forma interactiva ocurrira si el usuario final ingresa esos mismos
valores en los atributos correspondientes del form de la transaccin, y luego presionara el botn
Confirm.
Por tanto, al igual que como ocurre con la transaccin, debern dispararse las reglas y realizarse los
controles de integridad referencial. Qu pasar con ese juego de datos si se intenta grabar mediante la
transaccin? Se impedir la grabacin, debido a que se est cumpliendo la condicin de la segunda
regla de error (tambin podra cumplirse la de la primera si la fecha de hoy fuera anterior al 10 de
setiembre de 2008). Por otro lado, si no existiera en la tabla CUSTOMER un cliente con identificador
3456, fallar la integridad referencial y as tampoco se dejara ingresar el registro en la tabla BILL de
base de datos.

274

Business Components
Insert

Y ahora que los datos no violan reglas y suponiendo


que el cliente 3456 existe y &today>10/10/08?
&bill.CustomerId = 3456
&bill.BillInvoicePeriodStartDate = #09-10-08#
&bill.BillInvoicePeriodEndDate = #10-10-08#
&bill.Save()

Se insertar registro en tabla BILL!

Con qu valores de BillId, BillDate y BillAmount?


BillId era autonumber...
BillDate = &today... se dispara regla Default
BillAmount vaco... no hay regla

y CustomerName?

Antes de ejecutar el mtodo Save del Business Component, el valor de BillId en la estructura de &bill
ser vaco. Sin embargo, una vez que se ejecute el Save, como el atributo BillId era autonumber en la
tabla BILL, se ejecutar la propiedad a nivel de la tabla y el registro se insertar con el nmero siguiente
al ltimo dado.
En el caso de BillDate, anlogamente, como no se le asigna valor en la estructura de &bill, antes del
Save estar vaco, pero cuando ste se ejecute, se disparar la lgica de la transaccin, y en particular
la regla Default( BillDate, &today ) declarada. Por tanto en el registro insertado en la base de datos, el
valor del atributo BillDate corresponder a la fecha de hoy.
Para BillAmount podramos hacer el mismo anlisis. Pero a diferencia del caso anterior, no hay regla
que le asigne valor, por lo cul se insertar el registro con valor vaco en este atributo.
De asignarse valor para &bill.CustomerName no ser considerado a la hora de la insercin, dado que
CustomerName es un atributo inferido, y no tiene regla Update que permita modificarlo.
Lo mismo sucedera para atributos definidos a nivel de la estructura de la transaccin pero que fueran
frmulas. Es decir, son atributos virtuales en la transaccin, por lo que tambin lo son a nivel del
Business Component. Se disparar su valor.

275

Business Components
Update-Delete

Y si lo que deseo es actualizar un registro, no


insertar uno nuevo?
&bill.Load( 100 )
&bill.BillDate = #06-01-08#
&bill.CustomerId = 1258
&bill.Save()

Se actualizar registro 100 de tabla BILL!


(siempre que exista cliente 1258 y
06/01/08>=BillInvoicePeriodEndDate)

Y para eliminar el recibo 100?

&bill.Load( 100 )
&bill.Delete()

Se realizar siempre y cuando no exista ninguna tabla que referencie al Bill 100!

276

Business Components
Manejo de errores

En transacciones vemos los errores interactivamente (y en el


Error Viewer).

Cmo nos enteramos de los errores o mensajes


resultantes de un intento de actualizacin va BC?
&bill.Load( 100 )
&bill.BillDate = #06-01-08#
&bill.CustomerId = 1258
&bill.Save()

Tenemos los mtodos

Booleanos:

Y en caso de falla (por regla Error, falla de IR o de


duplicados) y/o de reglas Msg podemos obtener la
lista de mensajes de advertencia o de error:
&messages = &bill.GetMessages()

&bill.Fail()
&bill.Success()

de tipo
predefinido SDT...
enum

Warning
Error

Para manejar los errores habr que definir una variable de tipo de datos SDT predefinido (viene con la KB)
Messages (collection).

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 aceptan en su definicin adems del parmetro con el mensaje a desplegar, un
segundo parmetro que define el Identificador del mensaje. El objetivo es que cuando se ejecute 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).

277

Business Components
Caso de uso

Data Provider tiene como


output una coleccin de
Business Component Bill!

Business Component omite valor de


propiedad Commit on Exit de la transaccin:
hay que utilizar comando Commit/Rollback
en forma explcita!
Necesitamos pasar a False atributo InvoicePendingFlag de invoices facturadas...

Aqu completaramos el proceso de generacin de recibos.


Observemos primeramente un hecho importante: un data provider no solo puede devolver un SDT
simple o coleccin, sino tambin un BC simple o coleccin.
Importante: el BC devuelto solo podr insertarse en la base de datos. Es decir, un Data Provider solo
permite llenar su estructura, para luego hacer una operacin de INSERT sobre la base de datos. No
ser posible hacer una actualizacin o eliminacin con un BC cargado va Data Provider.
Obsrvese por otro lado cmo se ha definido la variable &message de tipo de datos
Messages.Message, correspondiente a los tems del SDT predefinido Messages devuelto por el mtodo
GetMessages del BC.
Una vez que hemos obtenido e ingresado en la tabla BILL todos los recibos correspondientes a la
facturacin, deberamos recorrer las facturas procesadas, y modificar el valor de su atributo
InvoicePendingFlag, pasndolo a False. Recordemos que el valor de este atributo se utiliza para no
procesar dos veces una misma factura. Recordemos que este valor se utiliza en el Data Provider en el
clculo del elemento BillAmount:
sum( InvoiceAmount, InvoiceDate >= &start and InvoiceDate <= &end and InvoicePendingFlag )
Dejaremos pendiente esta ltima parte para cuando estudiemos, unas pginas ms adelante, las formas
de actualizacin directa ( dentro de procedimientos exclusivamente ), de los registros de las tablas.

278

Business Components
Otra opcin

Este objeto es del tipo Web Panel. Lo utilizamos para


pedirle al usuario final el perodo de facturacin
&start
&end

Desde un Web Panel tambin


puede utilizarse un BC para
actualizar la base de datos

Adelantndonos aqu a presentar el otro tipo de objeto interactivo que estudiaremos un poco ms
adelante, el Web Panel, mostramos un objeto de este tipo en ejecucin. Su funcin ser pedir al usuario
final un par de valores, que almacenar en las variables correspondientes de tipo Date (&start y &end) y
luego, cuando el usuario presione el botn asociado al Evento Enter del Web Panel, se ejecutar su
cdigo.
Obsrvese que el cdigo es idntico al del procedimiento visto antes. Con este ejemplo pretendemos
mostrar que mediante un Business Component puede actualizarse la base de datos desde cualquier
objeto GeneXus.

279

Business Components
Caso de uso interactivo

Problema:seinsertapassolosisetieneclientenuevodel
mismoynopuedequedarpassinclienteenelsistema.
1

3
si se
cae el
sistema
aqu?

2 commit automtico

commit automtico

Recordemos que no se puede armar una sla UTL con dos transacciones.
Entonces?

Supongamos que cada vez que se inserta un nuevo pas en el sistema, es necesariamente debido a
que se tiene un nuevo cliente de ese pas. Supongamos que como requerimiento, adems, no debe
quedar bajo ninguna circunstancia ingresado un pas sin por lo menos un cliente asociado.
Tal como tenemos implementada la aplicacin, esto no se est controlando. Cmo se ingresa un pas
y un cliente para el mismo? El usuario debe ejecutar la transaccin Country, ingresar el pas. Luego
abrir la transaccin Customer, e ingresar los datos del cliente y confirmar. Pero qu suceder si se cae
el sistema cuando se est ingresando el cliente? Quedar el pas ingresado (recordar que cada
transaccin por defecto hace commit al final).

280

Business Components
Caso de uso interactivo

Solucin:enlatransaccinCountry,crearvariable&customer de
tipoBCCustomer einsertarlaenelForm yagregarreglaAccept.
1

&customer.CountryId = CountryId
on AfterInsert;
&customer.Save() on AfterInsert;
msg( It fails) if &customer.Fail()
on AfterInsert;

Commit automtico

Desventaja: no se dispararn en
forma interactiva las reglas
asociadas a Customer...

Necesitamos que la insercin del pas en la tabla COUNTRY y la insercin del cliente en la tabla
CUSTOMER se realicen dentro de una misma UTL. Como hemos visto, las operaciones efectuadas por
dos transacciones no pueden incluirse en una nica UTL. Por esta razn, necesitaremos hacer la
insercin dentro de la misma transaccin.
Cmo? Dentro de la transaccin Country, definimos una variable &customer, de tipo business
component Customer (para ello, tendremos previamente que haber prendido la propiedad Business
Component de la transaccin Customer, de manera tal que se cree este tipo de datos en la KB). Una
vez efectuado esto, simplemente insertando en el form la variable (al igual que suceda con un SDT),
GeneXus colocar controles para cada uno de los miembros de la estructura: &customer.CustomerId,
&customer.CustomerName, &customer.CustomerAddress, etc.
Las variables por defecto en las transacciones son de salida, por lo que habr que especificar regla
Accept para que puedan ser de escritura en ejecucin y el usuario pueda ingresar valores para las
mismas.
El Save del customer deber realizarse necesariamente luego de insertarse el pas en su tabla (de lo
contrario fallar la integridad referencial). Por tanto en las reglas:
&customer.Save() on AfterInsert;
Sabemos que en este momento ya se habr grabado el registro correspondiente al pas, y luego vendr
este Save... a continuacin, el commit automtico.

281

Business Components
Resumen

Objetivo:
Reutilizarlalgicadelnegociodefinidaenlastransacciones.Usarel
poderdelastransacciones(sinsusforms)desdeotrosobjetosGeneXus:
Procedimientos,WebPanels...
desdeotraTransaccin(aligualqueunavariablepodallenarse
interactivamenteinsertndolaenelForm,tambinunBC)

Beneficios:
ActualizacinalaBDgarantizandointegridaddelosdatosyejecucinde
lasreglasdelnegocio.
Reutilizacindecdigo(nonecesidaddeduplicarreglasdenegocio)
VariosobjetosGeneXus puedenactualizarlaBD.

282

Business Components
Reglas y Eventos

Reglas:sonejecutadastodaslasreglasdelatransaccinexcepto
(sonignoradasporelespecificador):
lasqueincluyenuser interface (Ej:Customer.call(),
lasquenoaplican:parm,prompt,NoPrompt,Default_mode,etc

Eventos:todosloseventosdelatransaccinsonignorados,
exceptoloseventosStart yAfter TRN(ysistosincluyen
referenciasaobjetosconuser interface,seignoran).
Nota: cuando decimos se ignora nos referimos en el contexto de la
actualizacin utilizando BC, no cuando la actualizacin se realiza a travs
de la propia transaccin.

Si existe una regla que invoca a un objeto que tiene interfaz, es decir, form, esa regla no se incluye en el
BC. Existe una forma de especificar que una regla declarada en la transaccin no aplique cuando se
ejecuta la transaccin, sino solo cuando se ejecuta el Business Component asociado: es calificando la
regla con [BC].
Ejemplo:
[BC] Default( BillDate, &today);
Si se quiere calificar de una sola vez un conjunto de reglas:
[BC]
{
regla1;
regla2;
...
reglan;
}
Lo mismo vale para eventos.
Anlogamente, existen calificadores para indicar que una regla solo se ejecute si se est corriendo la
transaccin con su form web: [WEB].

283

Actualizacin no
interactiva directa
Procedimientos

284

Procedimientos
Update

Nohayuncomandoespecficoparamodificarunregistro:se
realizaenformaimplcitadentrodelcomandoFor each.
Ejemplo:
parm( in: CustomerId, in: &StartDate, in: &EndDate);

La modificacin de datos de la base de datos se realiza en forma implcita: 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.
Se pueden actualizar varios atributos dentro del mismo For each, pudiendo stos pertenecer
tanto a la propia tabla base como a la tabla extendida.
El ejemplo que presentamos completa el que habamos iniciado respecto al proceso de
facturacin.
Obsrvese que aqu se est recorriendo la tabla INVOICE, filtrando por InvoiceDate, por
InvoicePendingFlag, as como por CustomerId (en el listado de navegacin se observar que si
bien no se ha especificado order, al recibir en el atributo CustomerId, que es foreign key, se
ordena por este atributo para optimizar). Dentro del for each, para cada factura que cumple las
condiciones, se actualiza el valor del atributo InvoicePendingFlag. Aqu podran actualizarse no
solo ese atributo, sino cualquiera de la propia tabla INVOICE, o de su extendida, con las
excepciones que se indican a continuacin.

285

Procedimientos
Update

Atributosactualizables:losdelatablaextendida delFor each.


Salvo:
losqueformanpartedelaclaveprimariadelatablabase.
losqueformanpartedelndiceporelqueseest accediendoalatabla.

LaactualizacinserealizaenelEndfor.
No secontrolaintegridadreferencial.
SiseactualizaunatributoqueesFK nosecontrolaexistencia.

Sloserealizacontroldeduplicados:
Si dentro de for each se intenta actualizar un atributo
para el que hay definido ndice unique, y existe
duplicado el valor, no se actualiza... de existir
clusula when duplicate se ejecuta su cdigo.

For each ...


bloque1
[when duplicate
bloque2...]
Endfor

Supongamos que tenemos el siguiente diagrama de Bachman genrico:


A*
B
C
D

B*
E
F

Y en el Source de un procedimiento hacemos:


For each
C = &C
E = &E
D = &D
Endfor
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?
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.
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.

286

Procedimientos
Update

Eficiencia:

Si hay un milln de registros a actualizar?

for each
where InvoiceDate >= &StartDate
where InvoiceDate <= &EndDate
InvoicePendingFlag = False
endfor

Por cada uno se enva comando UPDATE


al servidor de BD (que no tiene por qu
estar en la misma mquina que el Web
Server) eficiencia?

Actualizacinmasiva:clusulaBlocking reducenmerode
accesosalaBD.
for each
where InvoiceDate >= &StartDate
where InvoiceDate <= &EndDate
Blocking 1000
InvoicePendingFlag = False
endfor

Hasta la N-sima (1000) iteracin, el Update


se realiza en un buffer.
Con la N-sima se enva comando:
Update masivo a la BD y se actualizan los
datos del buffer.

Realizar un blocking a las operaciones de actualizacin de la BD significa almacenarlas en


memoria y enviarlas en grupo al DBMS. En lugar de interactuar con el DBMS en cada
operacin de actualizacin, la interaccin tiene lugar solamente cada N operaciones de
actualizacin, donde N es el nmero que se establece en la clusula Blocking.
No ser el caso de nuestro ejemplo, pero qu sucedera si se est haciendo una actualizacin
masiva que incluye algn atributo clave candidata de la tabla, y se encuentran duplicados para
algunos de los registros del grupo de 1000 que se est procesando?
En ese caso, una vez llenado el buffer con las 1000 actualizaciones, al enviar a la BD el
comando UPDATE del grupo, saltar el error de duplicados y se iterar sobre el grupo,
realizando un comando UPDATE individual de BD, uno por uno.

287

Procedimientos
Delete

Paraeliminarregistrosdeunatabla:ComandoDelete.
DebeirdentrodeunFor each.
Eliminaelregistrodelatablabaseenelqueseest posicionado.
Seejecutanibienseencuentraelcomando(ynoenelEndfor).
Nocontrolaintegridadreferencial.
Ejemplo:
For each
defined by InvoiceDate
Blocking 1000
Delete
Endfor

Elimina todos los registros de la tabla


base: INVOICE, eliminndolos en
grupos de a 1000 (para hacerlo ms
eficientemente).
Las lneas quedarn colgadas

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 InvoiceDetailQuantity
DELETE

//se eliminan las lneas

Endfor
DELETE //luego de eliminar las lneas se elimina el cabezal
Endfor
Para mayor eficiencia en la eliminacin, dependiendo del nmero de registros de la base de
datos, convendr agregar clusula Blocking con un factor de bloqueo, N, adecuado. Por
ejemplo, si se agrega Blocking 1000 la eliminacin fsica no se realizar en cada iteracin,
sino que cada 1000 veces que se llegue al Endfor, se eliminarn el grupo de 1000 registros en
un nico acceso a la Base de Datos (en lugar de 1000).

288

Procedimientos
Insert

ComandoNew:permiteinsertarunregistroenunatabla.
Procedimiento NewPrice
New
ProductId = &ProductId
ProductPriceListDate = &today
ProductPriceListPrice = &price
endnew

Nocontrolaintegridadreferencial.
Realizaelcontroldeduplicados:
Si ya existe registro para el producto
y fecha? actualizar el precio:
clusula when duplicate.

New
ProductId = &ProductId
ProductPriceListDate = &today
ProductPriceListPrice = &price
when duplicate
for each
ProductPriceListPrice = &price
endfor
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. Este debe crear un nuevo registro en la tabla PRODUCTPRICELIST, que est
compuesta por los atributos ProductId, ProductPriceListDate y ProductPriceListPrice, siendo su
clave primaria una compuesta, conformada por ProductId y ProductPriceListDate.
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.
Cada vez que GeneXus encuentra un new, debe determinar la tabla en la que se realizar la
insercin (tabla base del new). Es determinada a partir de los atributos que aparecen dentro
del comando new, del lado izquierdo en una asignacin.
El nico control que realiza, es el de duplicados. En nuestro caso, si existiera un registro con
los valores de ProductId y ProductPriceListDate, no se realizar la insercin (pero en cambio si
lo que no existiera fuera un producto en la tabla PRODUCT con el ProductId, all s se
insertar, pues no controla integridad referencial). Si se programa la clusula when duplicate,
se actualizar el registro encontrado.
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.
Si se quisiera insertar un registro para el cual existiera clave candidata duplicada, tambin se
controlar y no se realizar la insercin. En caso de existir clusula when duplicate, se
ejecutar.

289

Procedimientos
Insert

Ejemplo:siquisiramosrealizarlageneracinderecibos
directamenteenunprocedimiento(noatravsdeBC).
For each using ActiveCustomers()
New
Blocking 1000
BillDate = &Today
BillInvoicePeriodStartDate = &start
BillInvoicePeriodEndDate = &end
BillAmount = sum( InvoiceAmount, InvoiceDate >= &start and
InvoiceDate <= &end and
InvoicePendingFlag )
Endnew
endfor

En el for each se
recorren los
clientes activos
y el new inserta
en la tabla BILL
un nuevo recibo
para ese cliente
(por qu
CustomerId no
aparece
asignado?).

Si los clientes son miles, puede optimizarse la insercin y hacerse en bloques.

El caso ms comn ser tener el comando new dentro de un for each, dado que en general se
quieren insertar registros en base a clculos efectuados en funcin de otros.
El mismo proceso de generacin de recibos que habamos resuelto anteriormente utilizando
Data Provider y Business Component, podramos realizarlo con un procedimiento que utilice el
comando new de insercin. Cul alternativa elegira usted? Recuerde que con los comandos
de actualizacin dentro de procedimientos, el nico control que se realiza es el de duplicados.
Si las inserciones son muchas, as como vimos para el caso de las actualizaciones,
disponemos de la clusula blocking para ir guardando en un buffer y luego hacer la insercin
de todos esos registros a la vez.
En nuestro caso no fallar la insercin, debido a que la clave primaria es autonumber, y que no
tenemos claves candidatas (va ndices unique) en la tabla de recibos (BILL).
Pero si no fuera el caso, como las inserciones se van realizando en el buffer hasta llegar a la
1000, no es posible hasta completar el buffer saber si alguna operacin fallar. Cuando se
ejecuta el INSERT masivo de base de datos, all s puede fallar alguna insercin. En ese caso,
se itera en los elementos del buffer, ejecutando el INSERT simple, uno por uno. Si existe
clusula When duplicate en el New, entonces por los registros que fallen, se ejecutar la
clusula.

290

Procedimientos
Insert

Sintaxis delnew
new
[ Defined by att1,, attN ]
[ Blocking NumericExpression ]
bloque_asignaciones1
[ when duplicate
For each
bloque_asignaciones2
Endfor ]
endnew

att1,, attN
attx1 = ...
...
attxm = ...

deben
pertenecer a
una tabla fsica
tabla base

Nota: No es necesario asignar valor a todos y cada uno de los atributos de la tabla.
Algunos vienen instanciados por el contexto del new (ej: si est dentro de un for each)
y no es necesario asignarles valor para el registro a insertar (toman el del contexto).

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,
as como anidarse otro comando new).
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.
La tabla base del new se obtiene de los atributos del Defined By y los que aparezcan del lado
izquierdo de asignaciones dentro del bloque_asignaciones1. Aqu no se utiliza la tabla
extendida.
En el caso de que el comando new est dentro de una clusula repetitiva (ej. For each), es
posible reducir el nmero de accesos a la base de datos usando la clusula blocking.
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.
291

Actualizacin BD
BC versus Proc

Actualizacin va BusinessComponent:
Serealizan controles deintegridad referencial.
Secontrolan duplicados.
Sedisparan las reglas delnegocio.

Actualizacin va comandos enprocedimientos:


Noserealiza controldeintegridad referencial.
+
Elnico controlqueserealiza es eldeduplicados.
Notiene ninguna relacin contransaccin aqu nohayreglas.

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 (ergo, en un Business Component).
Queda claro de la enumeracin mostrada arriba que los Business Components ofrecen todas
las garantas y constituirn la forma de actualizacin privilegiada.
Cabe preguntarse entonces: cundo actualizar utilizando estos comandos? La respuesta es:
cuando la performance sea un problema.
Un ejemplo discutible es el que utilizamos para cambiar el valor del atributo
InvoicePendingFlag a False. No haba ninguna regla que lo implicara, no involucraba integridad
referencial, ni duplicados y poda involucrar millones de registros. Cul hubiese sido la
alternativa? Prender la propiedad Business Component de la transaccin Invoice, y en el
procedimiento MarkInvoiceAsNotPending definir variable &invoice con ese tipo de datos y
luego:
for each
where InvoiceDate >= &startDate
where InvoiceDate <= &endDate
where InvoicePendingFlag
&invoice.Load ( InvoiceId )
&invoice.InvoicePendingFlag = False
&invoice.Save()
endfor
Pero esta solucin ser ms ineficiente que la actualizacin directa utilizando blocking factor,
sabiendo que se debern actualizar millones de facturas.

292

Uso de Subtipos

293

Definicin de subtipos
LasrelacionesentreatributosGeneXusseestablecenatravsde
susnombres.
Mediantesubtipossepuedeestablecerquedosatributosquese
llamandiferente correspondenalmismoconcepto.
Casosdesubtipos:
A.Mltiplesreferencias
B.Especializacindeunnivel(relacin11)
C.Subtiposrecursivos

294

A. Mltiples referencias
Atributosconceptualmenteigualesquecumplenrolesdiferentes
(ej.:reservasdepasajes).
Reservation

City

PROBLEMA
Atributos con
el mismo
nombre

ReservationId*
CityId
origen
CityId
destino

{
CityId *
CityName

SOLUCION
}

Reservation
{
ReservationId*
ReservationCityFromId
ReservationCityToId

Desaparece
el problema!

City
subtipo
subtipo

{
CityId *
CityName
}

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 ciudad origen
CityId ciudad destino (mismo nombre que la PK de CITY)
Opcin 2) CityId ciudad origen (mismo nombre que la PK de CITY)
ReservationCityToId ciudad destino
Opcin 3) ReservationCityFromId ciudad origen
ReservationCityToId ciudad destino
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

295

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.

296

A. Mltiples referencias
Conladefinicindelossubtiposantesmencionados:
Seestablecenlassiguientesrelaciones:
ReservationCityFromId

RESERVATION

ReservationCityToId

CITY

Se hacen adems automticamente los controles de Integridad


Referencial (IR) entre ambas tablas cuando se utilizan sus
correspondientestransacciones.

LosatributossecundariosdeCITY:
Pertenecen a la tabla extendida de RESERVATION, pero al existir doble
referencia no se pueden utilizar directamente desde RESERVATION
(ambigedaddecaminosyconvaloresdeciudades diferentes).

Solucin definirtambinsubtiposparalosatributossecundariosde
CITY,eincluirlosenc/udelosgruposdesubtipos.

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.

297

A. Mltiples referencias
Nombre de
cada grupo
de subtipos.

Transaccin Reservation

Tabla Reservation

{
ReservationId*
ReservationCityFromId
ReservationCityFromName
ReservationCityToId
ReservationCityToName

ReservationId*
ReservationCityFromId
ReservationCityToId

Inferido
Inferido

FK
FK

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.
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.

298

A. Mltiples referencias a 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
COUNTRY

SALE
SELLER
Source:

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!

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.

299

A. Mltiples referencias a la tabla extendida

Solucin

Cuando queremos el pas del cliente de la venta: SaleCustomerCountryName

SALE

eC
Sal

o
ust

rId
me

CUSTOMER
COUNTRY

Sal
eSe
ller
Id

SELLER
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!

300

A. Mltiples referencias a 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.

301

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

PERSON

TEACHER

datos comunes a profesores


y estudiantes

STUDENT

datos propios de
los profesores

datos propios de
los estudiantes
Sistema
Teachers

Sistema
Students

Caso de subtipos Especializacin de atributos:


Cuando se est 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.
302

B. Especializacin de atributos
Person
{

Teacher
{

PersonId*
PersonName
PersonAddress

Student
{

TeacherId*
TeacherName
TeacherAddress
TeacherSalary

}
}

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).

303

C. Subtipos recursivos
Ejemplo:EmployeeManager

Tabla
EMPLOYEE
{
EmployeeId*
EmployeeName
EmployeeIsManagerFlag
EmployeeManagerId
Error(Debe ingresar un gerente para el empleado)
if not EmployeeIsManagerFlag and
EmployeeManagerId.isnull();

FK

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
recursin).
- 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.

304

C. Subtipos recursivos
Listadodenavegacindetallado:

305

Consideraciones
Cuandosedefineunsubtiposte"hereda"ladefinicindel
supertipo.
Al menos uno de los supertipos del grupo (o conjunto de
supertipos del grupo) debe(n) corresponder a la PK de una
tabladelmodelo.

306

Patterns

307

Patterns: Escenario

Filtro sobre los


datos

Paginacin

Teniendo la transaccin Country y la transaccin Customer, queremos lograr hacer la aplicacin ms


vistosa, con consultas con vistas ms completas y con algn aumento de funcionalidad.
Por ejemplo, trabajar con los pases de una forma ms vistosa y amigable que la que brinda la sola
transaccin. Visualizar en un grid los pases existentes, con la posibilidad de filtrar por nombre de pas,
y fijando paginado al grid, de forma tal que muestre un nmero fijo de registros por pgina...

308

Patterns: Escenario

New Country

Update Country

Delete Country

T
r
a
n
s
a
c
t
i
o
n

...as como poder ingresar un nuevo pas (mediante la transaccin Country), o seleccionar uno de los
mostrados en el grid, para poder modificarlo o eliminarlo...

309

Patterns: Escenario

...o incluso ver la informacin completa de ese pas, incluyendo los clientes asociados...

310

Patterns
Generalidades
Definicin
Patrones que se pueden aplicar a una KB para
implementar automticamente cierta funcionalidad.
Patrones disponibles:

Work With
Category

Selectores dentro de
las Transacciones

Una vez aplicado el patrn, todos los objetos generados quedan como
parte de la Base de Conocimiento.

Es natural al desarrollar aplicaciones, tener que resolver partes muy similares pero no exactamente
iguales.
Por ejemplo, si en una Base de Conocimiento se tienen modelados los objetos de la realidad Customers
y Countries, a pesar de ser dichos objetos bien diferentes, los Work With Customers y Work With
Countries respectivamente, tienen muchas cosas en comn: un grid en el form, un conjunto de
variables para utilizar en filtros, opciones de ordenamiento de la consulta, invocaciones a la transaccin
correspondiente para actualizar la base de datos, etc..
Surgen entonces los Patterns, que ofrecen la posibilidad de aplicar un patrn (pattern) a las instancias
que se deseen de una Base de Conocimiento, y generar todos los objetos GeneXus necesarios para
implementar cierta funcionalidad, teniendo en cuenta sus datos especficos.
Siguiendo con el ejemplo mencionado inicialmente, es posible aplicar el patrn Work With a la Base de
Conocimiento, de forma tal que partiendo de las transacciones Customer y Country, se obtenga todo
el desarrollo correspondiente al Work With Customers y Work With Countries para ambiente web
(pantallas vistosas que implementan las consultas, con ordenamientos, filtros, invocaciones a las
transacciones correspondientes, y ms).

311

Patterns
Work With
Genera a partir de una Transaccin:
Pantalla Work With: consulta interactiva, mltiples ordenamientos,
filtros, invocacin a la transaccin, etc.
Pantalla View: Registro seleccionado, con la informacin asociada.

WorkWith

Transaccin
View

La pantalla Work With ofrece:


Consulta interactiva
Mltiples ordenamientos
Filtros
Invocacin a la Transaccin en los diferentes modos (insert, update, delete, display)
Posibilidad de incluir invocadores propios a objetos
Link en cada lnea de la grilla a la pantalla View
La pantalla View muestra:
La informacin del registro seleccionado en la grilla Work With
Un tab control con:
Un tab con la informacin del registro
Un tab por cada tabla subordinada a la tabla base del registro en la grilla Work With.:

312

Patterns
Aplicacin

Abrir la Transaccin.
Seleccionar el patrn a aplicar
(aparecer la instancia por
defecto).
Marcar la opcin Apply this
pattern on save.
Grabar la Transaccin.

Para aplicar el pattern sin demoras, alcanzar con editar la instancia (selector Work With de la
transaccin), marcar el check box y grabar. Listo! Con eso se crearn automticamente los objetos
GeneXus que implementan el pattern (en particular la pantalla de seleccin y filtro y la pantalla de View
que mostramos antes). Asimismo se modificar la transaccin para que ahora reciba por parmetro el
modo (Insert, Update, Delete, Display) y el pas.

313

Patterns
Work With: objetos generados
Consecuencia: Se generan en la KB los objetos que ya vimos en ejecucin.
Dnde? En el Folder View, bajo la propia transaccin:

Una vez grabada la instancia, en el folder view, bajo el nombre de la transaccin, aparecer el nombre
del pattern aplicado a la misma (en nuestro ejemplo WorkWithCountry) y todos los objetos que GeneXus
debe crear para implementarlo.
En nuestro caso se crearn 2 objetos de tipo Web Component, y 2 objetos de tipo Web Panel. Son muy
similiares. La diferencia es que un Web Component puede incluirse dentro de otro objeto. No
entraremos en detalles en este momento.

314

Patterns
Ejemplo
Aplicacin del pattern Work With a la transaccin Country.

Al aplicar el pattern Work With a la transaccin Country, se crear:


Pantalla Work With:
Tendr una grilla con los atributos de la transaccin: CountryId y CountryName.
Se podr ordenar y filtrar por CountryName, por ser CountryName el atributo descriptor.
Se podr invocar a la transaccin en los diferentes modos (Insert, Update, Delete).
Pantalla View: Mostrar dos tabs. El primer tab tendr la informacin del pas seleccionado, y el
segundo tendr la informacin de los clientes pertenecientes a dicho pas (puesto que existe una
relacin 1-N entre las tablas Country y Customer asociadas a las transacciones de igual nombre).

315

Patterns
Comenzando a asociar... pantalla Work With

Se sita en el pas
indicado, o muestra
todos los pases.

Son muchas las propiedades que se ofrecen en las instancias correspondientes al patrn Work With,
para personalizar el comportamiento de los objetos que se generarn. A continuacin describimos
algunas de ellas.
El nodo Selection ofrece las propiedades relacionadas a la pantalla Work With que se generar para la
instancia. Sus sub-nodos son:
Modes (Ins, Upd, Del, Dis)
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
En la instancia aparece <default> al lado de cada una de las propiedades anteriores. Dnde se
configura este valor por defecto? Lo veremos unas pginas ms adelante.
Para cada 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).

316

Patterns
Personalizacin... pantalla Work With

Agregar,eliminar,ocultar atributos ovariables delgrid.


Especificar losmodos deinvocacin alatransaccin.
Definir rdenes yfiltros.
Agregar,eliminar,modificar Acciones.

Posicionarse en el nodo correspondiente


y presionar el botn derecho del mouse.

Attributes
Este nodo permite definir cules atributos se desean mostrar en el grid (y para cada atributo, se pueden
personalizar sus propiedades). Por defecto muestra todos los atributos de la estructura de la
transaccin.
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 uno de ellos si se desea orden ascendente o descendente). Se presentar
un combobox en la pantalla Work With 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. Sin embargo, el
control grid ya presenta la posibilidad de ordenar en ejecucin, simplemente cliqueando sobre la
columna por la que se desean tener ordenados los datos. Pero hay que tener en cuenta que esa
funcionalidad solo permite ordenar en ejecucin los datos de la pgina del grid que se est mostrando.
Filter
Este nodo permite definir condiciones de filtro, para que en el grid se muestren solo los registros que
cumplan con las mismas.
Actions
El nodo Actions permite incorporar acciones propias a la pantalla Work With. Es decir, permite agregar
botones (dentro o fuera del grid) que invoquen a los objetos que se indiquen, con sus correspondientes
parmetros. Si bien el nodo Actions no est visible por defecto, estando posicionado en el nodo
Selection y presionando el botn derecho del mouse, se ofrecer la opcin Add Actions que lo
agregar. Una vez agregado este nodo, estando posicionado sobre el mismo y presionando el botn
derecho del mouse, se ofrecer la opcin Add Action que permitir agregar una accin con su nombre
de accin, caption, objeto invocado, etc.

317

Patterns
Personalizacin - Ejemplos
1) Ocultar atributo CountryId del grid.

F4

Por qu ocultarlo en lugar de eliminarlo?

El atributo CountryId, a diferencia del CountryName, no puede ser eliminado del grid, debido a que es el
atributo que se enva a la transaccin Country cuando el usuario desea modificar o eliminar el pas
mostrado en una lnea del grid del Work With.

318

Patterns
Personalizacin - Ejemplos
2) Eliminar modo Delete desde el grid.

F4

Al editar las propiedades estando posicionados en el nodo de la instancia que se muestra, podemos
observar que cada uno de los modos en que se puede invocar una transaccin (para insertar, modificar,
eliminar o incluso deplegar) estn listados como propiedades.
Podemos ver tambin que aparece una propiedad Export que permite exportar los datos a una planilla
excel.
Otra vez aqu podemos apreciar que cada una de las propiedades tiene el valor <default> que an no
sabemos de dnde es tomado. Pero si queremos fijar un valor independiente de cul sea el default,
podemos editar el combo box que presentar tres valores: <default>, true, o false.
Hemos fijado el valor de la propiedad Delete en false. Podemos ver en ejecucin la repercusin. Ya no
aparece en el grid la primera columna que contena la imagen que permita eliminar el pas. Ahora no se
podr desde esta pantalla eliminar pases.
Obsrvese tambin cmo ha desaparecido del grid el atributo CountryId. Lo habamos ocultado en la
pgina anterior.

319

Patterns
Personalizacin - Ejemplos
3) Agregar una Accin a la pantalla Work With Countries que
invoque al proceso de facturacin: BillingProcess.
a) Clic con el botn derecho
sobre el nodo Selection

b) Clic con botn derecho sobre


el nodo Actions que apareci
al final.

320

Patterns
Personalizacin - Ejemplos
c) Definir la Accin editando sus
propiedades (F4).

Nombre de la accin y
objeto que se invoca.

Botn fuera del grid.

d) Finalmente en ejecucin, se
observa el botn fuera del grid.

Ya habamos definido el objeto BillingProcess para realizar la facturacin del mes a todos los clientes.
Aqu estamos agregando un botn fuera del grid, que al presionarlo llama a este otro objeto GeneXus
que habamos creado antes.

321

Patterns
Asociando... pantalla View

El nodo View por su parte, ofrece las propiedades relacionadas a la pantalla View que se generar para
la instancia. Muestra toda la informacin de un registro, que fue seleccionado en el grid del Work With
(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).

322

Patterns
Personalizacin - Ejemplos
1) Quitar atributos CustomerGender y CustomerStatus del tab
Customer de la pantalla View Country.

a) Posicionarse sobre el atributo


y borrarlo con la tecla de
eliminacin del teclado o
botn derecho/Delete.

En este caso si no queremos que los atributos CustomerGender y CustomerStatus se vean en el grid en
ejecucin, no necesitamos ocultarlos. Podemos directamente eliminarlos.

323

Patterns
Personalizacin - Ejemplos
2) Agregar un filtro por CustomerName en el tab Customer.

a) Click con el botn derecho


sobre el tab Customer

b) Indicar el atributo sobre el cual filtrar,


editando las propiedades (F4).

Una vez que ejecuta el paso a) y elige Filter aparecer un nuevo nodo Filter inmediatamente despus
del nodo Attributes, con 2 subnodos: Attributes y Conditions.
Luego, en el paso b), deber posicionarse en el subnodo Attributes y hacer botn derecho, donde se le
ofrecer la posibilidad de agregar un atributo de filtro. Al editar las propiedades, usted deber presionar
el combo box que le desplegar una ventana donde ingresar el atributo (en nuestro caso,
CustomerName). Con esto se crear automticamente una variable de igual nombre que el atributo
&CustomerName, que ser el control que aparecer en ejecucin para que el usuario digite all el filtro.
Veamos el paso siguiente...

324

Patterns
Personalizacin - Ejemplos
(Continuacin)
c) Definir la condicin correspondiente.

325

Patterns
Valores por defecto para las propiedades
Propiedades (F4)

El patrn Work With adems de generar objetos nuevos, tambin modifica las transacciones, para que
sean invocadas por los objetos generados por el pattern, agregndoles regla parm, etc.
Relacionado a esto, cada instancia contiene la propiedad UpdateTransaction, que ofrece los siguientes
valores:
Do not update: La transaccin no ser modificada (web form, reglas y eventos sern mantenidos).
Only rules and events: Solo las reglas y eventos se modificarn, no se modifica el web form.
Apply WW Style: La primera vez que se aplique el patrn, el comportamiento ser el mismo que si se
hubiese seleccionado el valor Create Default. A partir de la segunda vez que se aplique el patrn, no se
modificar la data area del form de la transaccin (por si se personaliz y se desea mantener), y s se
modificar el style area, as como los eventos y reglas.
Create default: Reglas, eventos y form de la transaccin (tanto data area como style area) sern
modificados. En lo que respecta al form, ser como seleccionar la opcin Apply default (Web Form).
El valor por defecto para esta propiedad es Only rules and events.
En cuanto a las propiedades AfterInsert, AfterUpdate y AfterDelete, permiten definir el
comportamiento luego de que se inserta, modifica o elimina un registro.
Los valores posibles para cada una de ellas son:
<default>
Return to caller
Go to View
Go to Selection
Otra vez el valor <default>. Lleg el momento de ver dnde se configuran todos estos valores por
defecto que hemos ido encontrando en la instancia...

326

Patterns
Pattern Settings
Configuracin de propiedades generales (para todas las instancias).

En este lugar estn centralizados los <default> para toda instancia. Podemos ver que en el nodo
Template se ofrecen algunas de las propiedades que mencionamos en la pgina anterior.
El tamao de pgina de los grids del work with, que en las imgenes anteriores era de 3 (se mostraban
3 lneas por pgina del grid) se configura en el nodo Grid. El valor por defecto de esta propiedad es
Page.Rows. Es decir, el valor del dominio enumerado Pages creado por GeneXus automticamente al
aplicar el pattern por primera vez. El valor que tiene Page es 10. Nosotros lo habamos cambiado a 3
para que nos entraran las imgenes completas en estas slides.

327

Patterns
Dinamismo entre la Transaccin y Patterns
TodoslosobjetosgeneradosporPatterns estnbasadosenelesquemade
Defaults deGeneXus.CadapartedeunobjetoesgeneradacomoDefault..

LaimplementacinbasadaenDefaults permitetenerdinamismoentrela
Transaccinyelpatrn.
No es necesario reaplicar el patrn, los cambios se ven al abrir
nuevamente el objeto

Eldinamismosemantieneparatodaslaspartesdefault delobjeto
OpcinEdit /Apply Default delMen paravolveraldefault deunaparteode
todaslaspartes(All parts)
Ejemplo:siagregamosatributoCountryFlag alaestructuradeCountry,qu
pasar conelgrid delWork With Countries?SisteconservaelDefaul,ser
agregadaautomticamentecolumnaCountryFlag algrid.

El dinamismo mencionado se mantiene para todas las partes default de los objetos.
Todos los objetos generados por Patterns estn basados en el esquema de Defaults de GeneXus.
Cada parte (Form, Reglas, Eventos) de cada objeto es generado como Default. Si se modifica alguna
parte del objeto, sta deja de ser Default.
Por ejemplo, si se modifica el web form de un WW (no queda como default), y se agrega un nuevo
atributo a la transaccin, no se va a actualizar automticamente el grid del WW con ese atributo (o sea,
no se agregar dicho atributo).
La implementacin basada en Defaults permite tener dinamismo entre la Transaccin y el patrn
Cambiar propiedades en la definicin del patrn (Pattern setting)
Cambios en la instancia (agregar un nuevo filtro)
Cambios en la Transaccin (agregar un nuevo atributo)
Si se quiere volver al dinamismo, se deber tener nuevamente las partes como default.
Para esto, se debe seleccionar desde el Men Edit / Apply Default (la parte donde se tiene abierto el
objeto) o Apply Default (All parts), lo cual vuelve a default todas las partes que se haban modificado.

328

Patterns
Cmo borrar los objetos generados por Patterns
Seleccionar la instancia en el Folder View, presionar botn derecho /
opcin Delete o presionar la tecla DEL. Aparecer el mensaje:

Al confirmar el mensaje:

Se borrarn todos los objetos generados por Patterns asociados a


la Transaccin.
Se borrarn todos las reglas y eventos agregados por Patterns en
la Transaccin.
Se desmarcar la opcin Apply this pattern on save de la
Transaccin.

329

Objeto Web Panel

330

Web Panels
Generalidades
Definicin Objetos GeneXus que permiten al usuario realizar
consultas interactivas a la base de datos a travs de una pantalla
en tiempo de ejecucin.
Son flexibles, por lo que se prestan para mltiples usos.
Algunos web panels conocidos:
Work With Countries.
View Country.
Elementos que los componen:

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.
Rules: Las reglas de un web panel permiten definir ciertos comportamientos puntuales de dicho objeto.
Por ejemplo, declarar qu parmetros recibe.
Events: 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. Aqu tambin pueden programarse
subrutinas a ser invocadas por varios eventos.
Conditions: Es para definir las condiciones (globales) que deben cumplir los datos a ser recuperados
(filtros). Anlogo a la solapa de igual nombre del objeto Procedure.
Variables: aqu se declaran las variables que sern utilizadas dentro del objeto. Recordar que son
locales.
Help: Permite la inclusin de texto de ayuda, que los usuarios podrn consultar en tiempo de ejecucin
del web panel.
Documentation: Permite la inclusin de texto tcnico en formato tipo wiki, como documentacin para el
equipo involucrado en el desarrollo de la aplicacin.
Propiedades: Son caractersticas a ser configuradas para definir ciertos detalles referentes al
comportamiento general del web panel. Recordar que se acceden con F4.

331

Web Panels

Para el ingreso de datos

Event Enter

En el ejemplo, el web panel contiene dos variables &startDate y &endDate como se muestra arriba. En
tiempo de ejecucin, el usuario podr ingresar valores en las variables dado que en los web panels las
variables son por defecto de entrada (salvo las incluidas en grids, como veremos).
En el evento Enter del web panel (asociado al botn Billing Generation), se obtienen para cada cliente
las facturas cuyas fechas se encuentren en el rango especificado y se genera recibo para el cliente
(invocando al Data Provider que devuelve la coleccin de Business Components que ya hemos visto
oportunamente cuando estudiamos esos temas).
De modo que este web panel tiene como finalidad permitir al usuario ingresar un rango de fechas, y
presionando el botn Billing Generation, ejecutar el procesamiento de las facturas.

332

Web Panels

Para exhibir datos de un registro


Customer
{
CustomerId*
CustomerName
CountryId
CountryName
CustomerAddress
CustomerGender
CustomerStatus

blob

CustomerPhoto
}

Tabla base: CUSTOMER

parm(in: CustomerId );

Se muestran los
datos del cliente

El web panel mostrado arriba ha sido creado para exhibir los datos de un cliente. Se necesita invocarlo desde otro
objeto (como ya veremos), pasndole por parmetro el cdigo del cliente del cual se quiere mostrar la informacin.
Un web panel es un objeto tpicamente utilizado para mostrar informacin. Entonces, cuando GeneXus encuentra
atributos en el form, qu intencin adjudicar al programador que los puso all? Pues, que le est pidiendo
implcitamente que vaya a buscar los datos correspondientes a la base de datos para desplegarlos.
En definitiva, con el web panel anterior, GeneXus ir a la tabla CUSTOMER y filtrando por el atributo recibido por
parmetro, CustomerId, mostrar la informacin del registro encontrado. Qu informacin? La que reside en los
atributos que figuran en el form. Pero el atributo CountryName no se encuentra en la tabla CUSTOMER. Pues
sucede lo mismo que con un for each, un grupo de Data Providers, etc., es decir, desde el registro de la tabla base,
se accede al registro relacionado de la tabla extendida que se necesite, para obtener el valor del atributo requerido
(en nuestro caso accede a la tabla COUNTRY para recuperar el valor de CountryName).
Las inferencias que GeneXus realiza son las siguientes:
Al tratarse de un web panel, los atributos que figuren sern de consulta1. Entonces GeneXus deber acceder a la
base de datos para recuperar sus valores. A qu tablas? Depender de si el Web panel tiene grids o no:
Web panel plano (sin grid): estn los atributos sueltos en el form, como en el caso que estamos mostrando. Si
esto sucede, es porque el analista necesita acceder a informacin de un registro de una tabla (y eventualmente de
los registros relacionados por tabla extendida), como es el caso del ejemplo. En este caso, el web panel estar bien
programado si adems se agrega un filtro que determine ese registro a mostrar. En nuestro caso, tenemos la regla
parm que al recibir en atributo PK de la tabla slo recuperar un registro. En definitiva, GeneXus determina una
tabla base del web panel, as como lo haca para un for each. Cmo? Buscando la mnima tabla extendida que
contenga a los atributos...
Web panel con uno o ms grids: lo veremos en lo que sigue, pero ya podemos intuirlo... qu sentido tendr
colocar un grid? Mostrar informacin repetitiva. En el caso general: cada grid mostrar muchos registros de una
tabla (y su informacin asociada).
-------------------------------------------------------------------------------------------------------------------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).

333

Web Panels

Para exhibir mltiples registros: Grid (con tabla base)...


Ejemplo: Mostrar todos los clientes

Grid: Carga lneas de


informacin en un
archivo temporal.

CUSTOMER

COUNTRY

Tabla base: CUSTOMER

Este web panel, a diferencia del anterior no es plano.


Cuando se incluye un grid en un form, se est indicando que se va a mostrar una cantidad indefinida de
datos (en este caso, clientes).
Dado que en este web panel hay involucrados atributos, GeneXus infiere que se desea acceder a la
base de datos. Simplemente dicindole qu atributos se desean desplegar, sin necesidad de ms
informacin, ya sabr qu hacer. Existe un grid, hay atributos, entonces, necesariamente habr tabla
base, esto es, la tabla de la base de datos que se navegar en busca de la informacin requerida.
Si en lugar de mostrar esta informacin en pantalla, la quisiramos en un listado, crearamos un
procedimiento con un print block customer con los atributos CustomerName y CountryName y en el
source programaramos:
for each
print customer
endfor
Esto es anlogo, solo que el for each est implcito, no hay que especificarlo. Cada lnea del grid que se
carga, es como el print que se ejecuta en cada iteracin del for each del listado.
De las tablas CUSTOMER y COUNTRY y de la relacin entre ambas es Na1, GeneXus determina la
tabla base de este web panel (aquella tal que su tabla extendida sea la mnima que cumple que
contiene a todos los atributos referidos). Obsrvese que este ejemplo solo difiere del anterior, en que los
atributos aparecen en un grid, y por tanto, no habr que filtrar quedndose con un solo registro de
CUSTOMER. En este web panel no hay regla parm que establezca filtro alguno.
Tambin conseguiremos ms adelante que este web panel no solamente se remita a mostrar los
clientes de la base de datos en el grid, sino que adems permita filtrar los clientes que se deseen ver en
cada oportunidad, ya sea por nombre de cliente, por pas del cliente, o por ambos. Por eso las variables
que aparecen en el form.

334

Web Panels

... Load automtico


Customer table
CustomerId

CountryId

CustomerName
Susan Jones

Richard Smith

Martina Rodrguez

Hugo Romero

...

...

...

Country table
CountryId

CountryName

Uruguay

United States

Italy

Venezuela

...

...

Base de datos

load
load
load
load

For each implcito:


para c/customer buscar nombre de
pas asociado y Load se carga
lnea en el grid.

Cuando GeneXus puede determinar automticamente una tabla a recorrer para cargar las lneas del
grid, lo hace, y en ese caso no habr necesidad de brindarle esa informacin. Es por ello que decimos
que en ese caso hay un for each implcito. Luego veremos casos en los que esto no ocurre (grids sin
tabla base).
Obsrvese en el ejemplo, que si en la tabla base existen 4 registros, se cargarn uno a uno los cuatro.
Si ahora queremos que el usuario pueda filtrar los clientes que desea ver... ah entran en juego las
variables que hemos definido en la parte fija del form, como veremos en la pgina siguiente.

335

Web Panels

...filtrando

Ejemplo: Mostrar los clientes que cumplen condiciones:

Por defecto
de entrada

Obsrvese cmo en la ventana de propiedades del control Grid, aparece una de nombre Conditions.
Cliqueando en el combo se abrir un editor para especificar las condiciones booleanas que debern
cumplir los registros para ser cargados como lneas del grid.
Es por esa razn que se han agregado las variables &CustomerName y &CountryName al form del web
panel, de manera tal que el usuario pueda ingresar all valores que operen como filtros sobre los datos a
mostrar. En nuestro caso, hemos establecido filtros con el operador like. Las variables en la parte plana
del form de web panels son por defecto de entrada. Luego veremos que en principio si estn en grids
sern por defecto de salida.
Obsrvese que las condiciones (separadas con ;) equivalen a las que aparecan en las clusulas
where de un for each (o grupo repetitivo de data provider).
De la misma manera, por cuestiones de optimizacin, puede determinarse, al igual que se haca en un
for each, criterio de ordenamiento de la tabla a recorrerse, como se muestra arriba en el ejemplo.
Nota: Asimismo, igual que en un procedimiento, no slo pueden establecerse condiciones locales al grid
(for each), sino tambin generales, mediante el selector Conditions. Esto tendr sentido cuando se
tenga ms de un grid (for each), para no tener que repetir la misma condicin cada vez.

336

Client

Web Panels

...con refresh automtico


Re
fre

sh

Server

Eventos del sistema:


Refresh y Load...
Load
Load
...
DB

La propiedad Automatic Refresh que se encuentra a nivel del Web Panel puede tomar los siguientes valores:
When variables in conditions change (valor por defecto): luego de provocarse automticamente el refresh, se
dispara el evento Load cargndose el grid segn los nuevos valores de las variables.
No
Dependiendo del tipo de datos del filtro, y del control web utilizado para filtrar, la condicin ser aplicada cuando se
est digitando o al abandonar el campo.
En el caso de filtros en controles edit, para tipo de datos Character, son aplicados cuando el usuario los va
digitando. Para tipo de datos Date, DateTime y Numeric, las condiciones se evalan cuando se abandona el campo.
En el caso de filtros combo boxes o dynamic combos, las condiciones son evaluadas cuando se abandona el
campo. Para Check boxes y Radio buttons, las condiciones son evaluadas cuando el valor es cambiado.
Ejecucin: qu sucede en el cliente y en el servidor al tener la propiedad por defecto y un grid con tabla base?
1 ejecucin (variables vacas):
For each CUSTOMER
guardar en memoria CustomerName
acceder a registro de COUNTRY relacionado
guardar en memoria CountryName
cargar (load) lnea en el grid con ambos valores

N-sima ejecucin (cambia valor de variable de las conditions):


Automticamente en el browser del cliente se detecta cambio refesh en el servidor para volver a cargar el grid
con los registros que cumplan las condiciones (con los nuevos valores de las variables) load por cada lnea.
Conclusin: Existen dos eventos del sistema que ocurren en el momento de carga del form (Refresh) y de carga de
cada lnea del grid (Load). Como veremos, a estos eventos puede asocirseles cdigo para que se ejecute en esos
momentos especficos...

337

Web Panels

... programando el evento Load


Agregamos al grid atributo CustomerStatus y
variable &select booleana...

Intencin: para aquellos clientes con estado On Hold poder activarlos marcando
check box y presionando botn Activate. Antes queremos:
1. Solo habilitar check box para los On Hold:
Cuando se carga cada lnea del grid, si el valor del atributo CustomerStatus de la tabla
CUSTOMER a ser cargado es On Hold, habilitar check box...

Ampliaremos la funcionalidad de nuestro web panel, permitiendo ver el estado de cada cliente, y para
aquellos que estn On Hold, brindando la posibilidad de pasarlos al estado Active.
Para hacer esto, agregaremos al grid el atributo CustomerStatus que muestra el estado, y una variable
booleana &Select, que permitir al usuario seleccionar aquellos clientes que desea activar. Adems un
botn para efectivamente activar todos los clientes marcados. Pero esto lo haremos en un segundo
paso.
Obsrvese que al ser el tipo de datos de la variable &select booleano, por defecto aparece en el grid
como un check box. Para asegurar que el usuario solamente intente activar clientes On Hold,
deseamos que solamente aparezca habilitado este check box cuando corresponde... para ello
necesitaremos programar la carga de cada lnea, esto es, el evento Load...

338

Web Panels

... programando el evento Load

Customer table
CustomerId

CustomerStatus

...

CustomerName
Susan Jones

...

Richard Smith

...

Martina Rodrguez

...

Hugo Romero

...

...

...

...

Se dispara una vez por cada


registro de la tabla base a ser
cargado... (tenga cdigo
programado o no)

En la seccin Events del web panel, programamos el evento Load del grid que vemos arriba. En el
ejemplo, customerGrid es el nombre que hemos dado al control grid en el form.
Al tratarse de un web panel con un nico grid, tambin podramos haber programado el evento Load a
secas:
Event Load
if CustomerStatus = Status.OnHold
&select.Enabled = 1
else
&select.Enabled = 0
endif
endevent
Es decir, en el caso de un web panel con un nico grid, no es necesario calificar el evento con el
nombre del grid. Igualmente recomendamos hacerlo, anticipndonos a la posibilidad futura de agregar
otro grid al form del web panel.
El evento Load se disparar por cada lnea que haya de cargarse en el grid, se encuentre ste
programado o no. Lo que hacemos en el ejemplo es aprovechar ese momento inmediatamente anterior
a la carga, para efectuar una accin. Y ese es el cdigo que incluimos en el evento.
Ahora s, estamos en condiciones de implementar la activacin, para lo que necesitaremos asociar al
botn un evento, que podr ser el evento Enter o uno de usuario...

339

Web Panels

... evento Enter


2. Activar los clientes On Hold seleccionados:

Comando For each line...


Recorre lneas de un grid

For each line in customerGrid


if &select
&customer.Load( CustomerId )
&customer.CustomerStatus = Status.Active
&customer.Save()
Commit
endif
endfor

&customer BC Customer

En el ejemplo, cuando el usuario presiona el botn Confirm, necesitamos recorrer todas las lneas del
grid, y para cada una de ellas, si el check box de la variable booleana &Select fue marcado por el
usuario, entonces debemos cambiar el estado del cliente correspondiente, de On Hold a Active.
Al insertar el botn en el form del web panel, y editar sus propiedades, podr observarse que por
defecto, el botn est asociado al evento Enter (ver propiedad OnClickEvent).
El Enter ser un evento del sistema, que se ejecuta tanto cuando el usuario hace clic sobre el control
asociado, como cuando presiona la tecla Enter.
En este ejemplo veremos a la vez:
Posibilidad de definir eventos de usuario y asocirselos a controles o de utilizar el evento Enter del
sistema.
Comando For each line, para recorrer las lneas ya cargadas en un grid.
Variables en un grid pasan de ser Read only (de salida) por defecto, a ser de entrada, cuando se
utiliza comando for each line en ese grid (tambin cuando se programan eventos OnClickEvent, Click,
etc., sobre alguna columna del grid).
Obsrvese que el comando For each line slo tiene en comn con el comando For each estudiado
antes, el hecho de representar una estructura repetitiva. La diferencia ms importante: mientras el for
each recorre registros de una tabla (base) de la base de datos, el for each line recorre las lneas de un
grid.
En nuestro ejemplo hemos definido una variable &customer, Business Component Customer, mediante
la cul cambiaremos a estado Active todas las lneas del grid marcadas por el usuario. Para ello
recorremos el grid con el comando for each line.

340

Web Panels

... o evento de usuario


2. Activar los clientes On Hold seleccionados:

For each line in customerGrid


if &select
&customer.Load( CustomerId )
&customer.CustomerStatus = Status.Active
&customer.Save()
Commit
endif
endfor

Otra posibilidad, en lugar de utilizar el evento del sistema Enter, es definir un evento de usuario. Ello se
consigue siguiendo los pasos que pueden verse arriba.
Como puede apreciarse, la mayora de los controles presentes en un form tienen la propiedad
OnClickEvent asociada. Esa propiedad permite especificar un evento a dispararse cuando el usuario
haga clic sobre el control. Podr ser un evento del sistema (Refresh, Enter) o uno definido por el
usuario.

341

Web Panels

... variables de grid


Por defecto todas las variables de un grid son Read-Only
For each
columnas
valor por
entrada.

line [in grid] o cualquier evento sobre las lneas o


(OnClickEvent, Click, DblClick, IsValid, etc): modifica
defecto y todas las variables del grid pasan a ser de
Para que algunas sean de salida:

Propiedad: Read Only

No as las de la parte fija del web panel. Esas son por defecto de entrada, como ya hemos visto antes
para las variables que utilizamos para filtrar los customers mostrados en el grid.
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 a travs de la propiedad ReadOnly.
2. Si dentro de la fila hay algn control con un evento click, dblClick, etc.. asociado ( evento de usuario
especificado en la propiedad OnClickEvent), suceder lo mismo.

342

Web Panels

...ocultar atributos del grid y permitir seleccin de una lnea

Event Select customer


CustomerView.Call( CustomerId )
endevent

Seguimos ampliando nuestro ejemplo; ahora queremos que el usuario pueda seleccionar una lnea del
grid (un cliente) y presionando botn Select customer poder invocar al web panel que habamos
implementado antes.
En este ejemplo vemos dos funcionalidades en juego:
La necesidad de colocar una columna en el grid oculta (no visible).
Permitir que el usuario seleccione una lnea del grid para hacer algo con ella.
Por qu colocar la columna correspondiente a CustomerId y ocultarla, en lugar de no agregarla en
absoluto? Reflexione sobre lo siguiente: el atributo CustomerId enviado por parmetro al ejecutarse el
evento Select customer, de dnde es extrado? De la base de datos? No, es el que est cargado en
el grid. Ms especficamente, por cada grid existir un archivo temporal que contendr tantas columnas
como las del grid, visibles y ocultas. Cuando el usuario selecciona en el grid la segunda lnea, y
presiona el botn Select customer, se est posicionado en ese archivo temporal, correspondiente a esa
lnea (y nunca en la base de datos!). Es por esta razn que de no colocar la columna correspondiente a
CustomerId en el grid, no estaramos pasando valor alguno a CustomerView.
Para permitir al usuario seleccionar una lnea del grid, alcanza con prender la propiedad
AllowSelection del grid.

343

Web Panels

Puesta a punto: determinacin tabla base


1. Atributos sueltos en el form
+
2. Grid:
atributos de las columnas
(visibles+invisibles)

propiedad Order
propiedad Conditions
propiedad Data Selector
Event Activate
For each line in customerGrid
if &select
&customer.Load( CustomerId )
&customer.CustomerStatus = Status.Active
&customer.Save()
Commit
endif
endfor
endevent

Event Select customer


CustomerView.Call( CustomerId )
endevent
Event customerGrid.Load
if CustomerStatus = Status.OnHold
&select.Enabled = 1
else &select.Enabled = 0
endif
endevent

+
3. Eventos:
atributos sueltos
(fuera de for eachs)

Cmo determina GeneXus una tabla base a recorrer automticamente para cargar el grid del web
panel?
De existir algn atributo en por lo menos uno de los 3 lugares mencionados, GeneXus podr encontrar
tabla base. Para determinarla extrae los atributos encontrados all (parte fija del Form, en el Grid, tanto
en sus columnas como en las propiedades Order, Conditions o using Data Selector, y en los eventos
programados en el selector de Eventos, solamente considerando los atributos que estn sueltos dentro
del evento, es decir, no dentro de un comando for each de acceso a la base de datos), y determina la
mnima tabla extendida que los contiene. La tabla base de esa extendida, ser la recorrida
automticamente y cargada con el Load.
Observemos que solamente hemos programado el evento Load para tomar la decisin para cada lnea a
ser cargada en el grid, acerca de si se habilitar o no para la misma la variable &select que permitir al
usuario marcar el check box.
Importante: La forma de determinacin de la tabla base de un grid depender de si existe otro grid en el
web panel o es el nico. El resumen presentado aqu corresponde a un nico grid. En este caso se dice
que el propio Web panel tiene tabla base. Es la del grid. Cuando existan ms de un grid en el web
panel, esto ya no tendr sentido, y cada grid pasar a tener o no tabla base. Veremos la forma de
determinacin de las tablas bases en ese caso, cuando tratemos el caso de mltiples grids en un web
panel.

344

Web Panels

Para exhibir mltiples registros: Grid (sin tabla base)...

Mostrar el total de facturas por da


(pudiendo filtrarse entre dos fechas dadas)
Cada lnea del grid no corresponde a cada
registro de la tabla INVOICE, sino que agrupa
todas las facturas de una fecha y las suma...si
fuera un pdf, lo implementaramos:
For each order InvoiceDate
where ...
&InvoiceDate = InvoiceDate
&Amount = 0
for each defined by InvoiceDate
&Amount += InvoiceAmount
endfor
print InvoiceInfo
endfor

Aqu presentamos otro ejemplo, para observar un caso en el que surge naturalmente la necesidad de
implementar un grid sin tabla base.
El caso natural de implementacin de un grid con tabla base, es cuando se quiere cargar por cada
registro de una tabla, una lnea del grid (1 registro 1 lnea). Cuando el caso es que se quiere cargar
una lnea del grid como producto de recorrer varios registros de la base de datos (N registros 1 lnea),
como productos de clculos, etc., suele ser ms natural implementar el grid sin tabla base.
Este es el caso del ejemplo: no queremos cargar por cada factura una lnea, sino que queremos agrupar
facturas por fecha, y por cada grupo, cargar una lnea que sumariza sus Amount. Estamos hablando de
un corte de control. Si tuviramos que implementar un listado PDF en lugar de un web panel, sabramos
bien cmo programarlo (como lo hacemos arriba). Veamos cmo implementarlo con un web panel...

345

Web Panels

Para exhibir mltiples registros: Grid (sin tabla base)...


No hay atributos (en ninguno de los 3 puntos
anteriores) no hay tabla base
GeneXus no puede inferir carga automtica:
hay que programarla
evento Load ocurre 1 sola vez

Orden de carga de una lnea en


el grid (con los valores que en ese
momento asuman las variables)

El objetivo del comando LOAD es agregar una lnea en un grid. Es necesario cuando el grid no tiene
tabla base, dado a que en ese caso no se agregar automticamente lnea alguna. El evento Load
ocurrir una vez, y si ste no se programa, el grid resultar vaco. Por tanto en este caso es
indispensable programarlo, de acuerdo a la lgica que corresponda. Una vez que se haya asignado
valor a cada variable, y se desee agregar una 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.
Obsrvese que este caso es el que deja ms a cargo del analista la implementacin. Frente al caso de
grid con tabla base, en este GeneXus realiza muchas menos inferencias.

346

Web Panels

Para exhibir mltiples registros: Grid (sin tabla base)...

Refresh no es automtico!

Agregamos botn asociado a evento


Enter o de usuario, sin cdigo, o
directamente al Refresh.

En el caso de un grid sin tabla base, los filtros sobre los datos a mostrar son programados dentro del
cdigo que implementa la carga (el del Load). Aqu no habr refresh automtico. Esto es, cuando el
usuario modifique los valores de las variables que intervienen en los filtros, GeneXus no detectar que
debe volver a cargar el grid.
Para ello deber, por ejemplo, agregarse un botn asociado al evento Enter, o a un evento de usuario,
sin cdigo, debido a que solo lo necesitamos para que se produzca un Refresh, es decir para que se
vuelva al servidor a cargar el web panel.
Sobre los eventos disponibles y el orden en que se disparan, entraremos en lo que sigue.

347

Web Panels
Programacin dirigida por Eventos

Evento Start
Evento Refresh
Evento Load
Evento Enter
Eventos de Usuario
Evento TrackContext (no lo veremos en el curso)

Asociados a controles del form (dependiendo del tipo de control):


Evento Click, DblClick, RightClick, IsValid, Drag, Drop, etc.

Nota:
Refresh, Enter, de Usuario:
pueden asociarse a controles del form
a travs de propiedad OnClickEvent

En todo Web panel existen eventos del sistema que pueden programarse. Algunos ocurrirn siempre,
en cada ejecucin del web panel (como el Start, Refresh, Load), otros si se los declara y el usuario
realiza las acciones necesarias para provocarlos (Enter, definidos por el usuario, TrackContext).
Asimismo, 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 (F4), y definiendo un evento de usuario en la propiedad
OnClickEvent, o asocindole el evento Enter o el Refresh.
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. Lo mismo ocurre con los eventos DblClick,
RightClick, IsValid... (para cuando se hace doble clic, botn derecho, etc.).
Sobre los eventos asociados a las acciones sobre los controles (click, dblclick, drag, drop, etc.) no nos
explayaremos en el presente curso. En nuestro wiki encontrar informacin detallada, as como en el
Help de GeneXus.
Sobre el evento TrackContext solo mencionaremos que ser posible detectar cambios en el valor dado
a un control (grid, variable, etc.) y en ese caso disparar este evento para en base al valor modificado,
tomar una accin.

348

Web Panels
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

349

Web Panels
Evento Refresh Evento Load
Eventos del sistema, codificables, asociados a la carga del Web
Panel. Se ejecuta primero el Refresh y a continuacin siempre
el Load.
Si el grid tiene tabla base
Load se ejecuta N veces:
una por cada lnea

Si el grid no tiene tabla base


Load se ejecuta 1 sola vez:
Dentro del evento habr que
programar la carga de cada lnea
del grid. Para cargarla, comando
Load.

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 en el
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. Dentro de ese evento habr que codificar la carga, que podr requerir acceder a la base
de datos (ej: comando for each) o no (supngase que se desea cargar el grid con informacin obtenida
de recorrer un SDT collection, tras efectuar alguna transformacin sobre sus items... o cargar lneas en
el grid producto de clculos). El control de la carga del grid, queda aqu en manos del analista, utilizando
el comando Load. Este comando solo es vlido dentro del evento de igual nombre. Obsrvese cmo en
el caso de grid con tabla base, este comando se torna innecesario.

350

Web Panels
Refresh automtico
Solo vlido para Grid con tabla base

Para Grid sin tabla base


necesariamente hay que asociar evento

Estudiemos con ms detalle la propiedad Automatic Refresh que se encuentra a nivel del Web Panel
puede tomar los siguientes valores:
When variables in conditions change (valor por defecto): luego de provocarse automticamente el
refresh, se dispara el evento Load cargndose el grid segn los nuevos valores de las variables.
No: para que el contenido del grid se refresque luego de cambiar los filtros, el usuario debe realizar
una accin:
Si el grid es con tabla base:

Los cambios en las variables de los filtros se detectan automticamente.

Al presionar la tecla Enter, se dispara el Refresh de la pgina (no el cdigo del evento
Enter, aunque est programado).

Al hacer click en un botn o en una imagen asociados a un evento de usuario,


inmediatamente despus de cambiar el valor de una variable de las conditions del grid, se
ejecuta este evento e inmediatamente a continuacin el Refresh de la pgina. Si el
evento fuera el Enter, este evento NO se ejecuta.

Si el grid es sin tabla base:

Los cambios en las variables de los filtros NO se detectan automticamente

El usuario debe hacer clic en un botn o en una imagen asociados a un evento


Refresh o a un evento de usuario que invoque a un Refresh.

351

Web Panels
Eventos Orden de disparo
GET: Cuando el Web Panel se abre.

Start
Refresh
Load

POST: Resto de las ejecuciones del web panel.

Start
Lectura de variables en pantalla
Evento enter o de usuario (click,
dblclick, etc., que produjo post)
Refresh
Load

Los eventos que se disparan y su orden depende de si se est abriendo el web panel (Get) o si ya
estaba abierto y se est efectuando una accin posterior, como presionar un botn (Post).
Arriba mostramos con ejemplos el caso general.
1a. vez: Start + Refresh + Load
N-sima vez: Start + Lectura de variables de pantalla + Evento que produjo el Post + Refresh + Load.
Este es el caso general... existe una excepcin...

352

Web Panels
Eventos Orden de disparo
Excepcin:
Algunos eventos de usuario deben ejecutarse en el Server pero para
otros no existe necesidad se ejecutarn solamente en el Cliente (sin
ejecutarse todos los otros eventos del server: Start, Refesh y Load).
Evitando roundtrips innecesarios al servidor, y reduciendo la cantidad de
datos que viajan de un lado a otro.
Ejemplo: un evento que cambia el estado de un control, no necesita
ejecutarse en el server.
Event UserEvent
&CustomerId.Visible = 0
endevent

GeneXus tiene la inteligencia para determinarlos. Es transparente para el


programador.

Internamente GeneXus determina las entradas y salidas de cada evento. Si en sus entradas, se
requiere de acciones ejecutadas en el Server, entonces el evento se ejecutar en el Server. Por
ejemplo, si entre las entradas de un evento de usuario se encuentra alguna de las salidas del evento
Start (del server), entonces el evento de usuario se ejecutar en el Server.
Si el cdigo del evento no requiere que se ejecute en el servidor, entonces por performance, se
ejecutar en el cliente, como cdigo javascript.
De todas maneras el analista GeneXus no deber preocuparse de estos asuntos, dado que en todo
caso ser GeneXus quien tendr la inteligencia de resolver dnde ejecutar el evento.

353

Web Panels
Mltiples grids Grids paralelos

filtrar facturas
por da del
cliente

Aqu presentamos un ejemplo que rene los dos casos que venamos estudiando: el web panel
mostrado en ejecucin tiene dos grids paralelos: uno que muestra informacin de los clientes del
sistema, y otro que muestra facturas, totalizadas por da.
En nuestro caso, querremos adems relacionar los datos, de manera tal que si el usuario selecciona un
cliente, se le muestren solo las facturas de ese cliente. Incluso al establecer filtros de fechas, tambin
querremos que valgan para el cliente seleccionado (y no para todos los clientes).
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,
una advertencia informando 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).

354

Web Panels
Mltiples grids Grids paralelos
Event Start
&Customer.Visible = 0
endevent

Event Select customer


&CustomerId = CustomerId
endevent

GeneXus no relaciona las cargas


Event inoicesGrid.Load
for each order InvoiceDate
where InvoiceDate >= &startDate when...
where InvoiceDate <= &endDate when...
where CustomerId = &customerId when
not &customerId.IsEmpty()
...
endevent

Este web panel podra haberse implementado de varias maneras distintas, dando por resultado la
misma ejecucin.
La implementacin ms natural es la que podemos ver arriba: el primer grid tiene tabla base y el
segundo no. Pero podra haberse implementado al revs, con variables en el primer grid y teniendo que
realizar la carga de los clientes a mano en el Load, y atributos en el segundo grid, y algunas cosas ms
para lograr el corte de control, siendo un grid con tabla base. O cualquiera de las otras dos
combinaciones (ambos grids con tabla base, o ninguno con tabla base).
Lo importante es, una vez elegida la implementacin ms natural al caso, realizarla correctamente.
En cualquiera de los casos, aunque la informacin a cargar en un par de grids se encuentre relacionada
en la base de datos, GeneXus no asumir ninguna relacin entre los datos a la hora de cargar un grid y
el otro. Es anlogo al caso de un par de for eachs paralelos en el Source de un procedimiento.
Como puede verse arriba, al web panel en el que tenamos el grid con los clientes, le hemos agregado
la parte de visualizacin de facturas por fecha que habamos implementado en web panel aparte. Pero
no alcanza con simplemente unir ambos web panels... para poder relacionar las cargas de los grids,
deberemos agregar cierta lgica. En nuestro caso deseamos que una vez que se seleccione un cliente
del primer grid, las facturas que se carguen en el segundo no sean las de todos los clientes, sino las del
seleccionado.
Para ello debimos hacer dos cosas: agregar una variable &CustomerId para almacenar el id del cliente
seleccionado al presionar Select customer, y luego agregar un filtro por el valor de esa variable cuando
se carga el grid de Invoices. Asimismo tuvimos necesariamente que colocar esa variable en el form para
que todo funcione como esperamos... y la razn la encontraremos en el anlisis que sigue.

355

Web Panels
Mltiples grids Grids paralelos
1. ejecucin
Start oculta &customerId
Refresh
customerGrid.Refresh
customerGrid.Load
customerGrid.Load
....

invoicesGrid.Refresh
invoicesGrid.Load

Analicemos lo que sucede cuando se ejecuta este web panel por primera vez.
Primero se ejecuta el evento Start, que en nuestro caso oculta la variable &CustomerId.
Luego, como puede apreciarse en la imagen, se produce un evento Refresh genrico, luego del cul se
producirn las cargas de todos y cada uno de los grids que se encuentren en el web panel, de izquierda
a derecha de arriba a abajo.
Por cada uno ocurrir un evento Refresh propio y el evento Load (N veces si el grid tiene tabla base, 1
sola si no la tiene).
Obsrvese que en nuestro caso, el grid de clientes tiene condiciones para cargarse, por las variables de
filtro &customerName y &countryName, pero al estar vacas no aplican (dado que ambas clusulas
condicionales tienen when not &var.IsEmpty())
El segundo grid es sin tabla base, pero como ya vimos, el evento Load ejecutaba un for each con
clusulas where, por tanto se cargarn solo aquellas lneas para las que se cumplan sus condiciones.
Estas son tres:
where InvoiceDate >= &startDate when not &startDate.IsEmpty()
where InvoiceDate <= &endDate when not &endDate.IsEmpty()
where CustomerId = &customerId when not &customerId.IsEmpty()
Obsrvese que en esta primera ejecucin &customerId estar vaco, por lo que no se aplicar este filtro
y se cargarn todas las facturas por da, de todos los clientes.

356

Web Panels
Mltiples grids Grids paralelos
2. ejecucin Seleccionar un cliente:
Start oculta &customerId
Lectura de variables de pantalla
Evento que produjo post
Event Select customer
&CustomerId = CustomerId
endevent

Refresh
customerGrid.Refresh
customerGrid.Load
customerGrid.Load
....
invoicesGrid.Refresh
invoicesGrid.Load

Luego el usuario selecciona del grid el cliente correspondiente a la segunda lnea y presiona el botn
Select customer.
Se detecta una accin, y se realiza un post al servidor, quien ejecuta el Start (ocultando la variable),
luego lee las variables en pantalla (&customerId por ahora est vaca, pero no slo son consideradas
variables de pantalla las variables definidas, sino, por ejemplo, la informacin completa de la lnea
seleccionada por el usuario con el mouse, entre ella, el valor de CustomerId, columna del grid), luego
ejecuta el cdigo del evento que produjo el post, en nuestro caso, Select customer. Aqu la variable
&customerId toma el valor del CustomerId de la lnea elegida. Luego se produce el Refresh general que
dispara el Refresh y Load de cada grid.
Por tanto, cada grid se carga ejecutando las conditions. El primero se carga igual que antes, porque
ninguna de sus conditions ha variado. El segundo, ahora s tiene un valor para &customerId, por lo que
se mostrarn solamente las facturas del cliente.
Uno podra preguntarse por qu se tuvo la necesidad de colocar la variable oculta en el form. Por qu
simplemente no poda usrsela como variable dentro del programa, sin necesidad de colocarla y hacerla
invisible. Con esta segunda ejecucin todava no podemos contestar la pregunta. De hecho, si se
analiza, puede verse fcilmente que hubisemos obtenido el mismo comportamiento si slo le
asignbamos valor a la variable en el Select Customer sin colocarla en el form.
La razn surgir claramente con la siguiente ejecucin...

357

Web Panels
Mltiples grids Grids paralelos
3. ejecucin Filtrar facturas para el
cliente seleccionado
Start
Lectura de variables de pantalla
&customerId invisible

Evento que produjo post (vaco)


Refresh
customerGrid.Refresh
customerGrid.Load
customerGrid.Load
....
invoicesGrid.Refresh
invoicesGrid.Load

Ahora el usuario ya tiene seleccionado el segundo cliente, y lo que desea es filtrar sus facturas por
fecha (no quiere visualizarlas todas).
Para ello especifica los filtros de fecha, y presiona el botn Search, que producir un post al servidor.
Entonces se ejecutar el Start con su cdigo, luego se leern las variables de pantalla: aqu est la
razn de haber colocado &customerId en el form. Se leer entonces el valor de &customerId, que
permanecer incambiado hasta tanto el usuario no vuelva a seleccionar otro cliente del grid y presionar
el botn Select customer... esta variable presente en el form, es la forma de mantener la memoria entre
ejecuciones.
Recurdese que cada vez que se hace un post al servidor, es una nueva ejecucin del web panel, por lo
que las variables comienzan nuevamente vacas. Es por ello que el segundo paso: Lectura de variables
de pantalla es fundamental.
Ahora s, siguiendo con el ejemplo, se lee de pantalla la variable &customerId invisible, junto con las
variables visibles &startDate y &endDate.
Y luego, como siempre, se ejecuta la carga (Refresh genrico + Refresh y Load de cada grid).
Han cambiado las condiciones del for each que carga el segundo grid, por lo que ahora aparecern
solamente las facturas del segundo cliente, entre las fechas estipuladas por el usuario.
Si ahora el usuario quiere cambiar de cliente, para ver sus facturas, lo seleccionar del grid de clientes y
presionando Select Customer, el proceso volver a empezar como vimos en la 2da. ejecucin.
Y cmo se vuelve a trabajar con las facturas de todos los clientes y no con las de uno dado?
Piense qu pasar si el usuario no selecciona ningn cliente del grid con el mouse, pero presiona
Select Customer. El valor de la variable &CustomerId quedar vaco, pues CustomerId no tendr valor.
Por este motivo, al botn Select Customer podramos haberle llamado Select/Unselect.

358

Web Panels
Grid - Propiedades
Paginado automtico: GeneXus realiza un paginado automtico si
la propiedad Rows tiene un valor distinto de 0.

Inserta automticamente los botones de paginado.

Los botones que se insertan dependen de la cantidad de registros a mostrar y la cantidad de lneas del
grid.

359

Web Panels
Grid Ordenamiento automtico de las columnas
Las columnas pueden ser ordenadas sin necesidad de programar ningn
cdigo adicional: clic sobre el ttulo de la columna.

Esta funcionalidad
es vlida para grids
en transacciones y
en web panels.

Se ordena la pgina del grid cargada, por lo que no compite con el


Order programado a nivel del grid.

360

Web Panels
Tipos de grids
Grid estndar: Datos repetitivos en
formato fijo (filas y columnas)

Grid Free Style: Datos repetitivos en formato libre.


Tabla con registros repetitivos
No posee ttulos para las
columnas
Permite tener ms de un tipo
de control en una misma celda

Se dispone de dos tipos de grids:


Grid estndar: el que vimos hasta ahora, en transacciones y web panels
Grid Free Style
Estos grids agregan potencia al diseo de aplicaciones web, permitiendo al desarrollador mayor libertad
a la hora del diseo.
El grid Free Style permite al usuario definir el formato de los datos a desplegar de una forma menos
estructurada que el grid estndar.
El grid Free style 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. 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 pases. El atributo
CountryFlag se ha incluido en la transaccin Country para almacenar la foto de la bandera de cada
pas (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 pas.
El comportamiento de las variables dentro de un grid Free Style es anlogo al que presentan dentro de
un grid estndar, por lo tanto tambin quedan de ingreso si existe un For each line dentro de algn
evento, o si se asocia un evento a cualquier control de la fila. Nuevamente este comportamiento puede
modificarse, cambiando la propiedad Read Only.

361

Web Panels
Mltiples grids Grids anidados
Ejemplo: Desplegar todos los pases con sus respectivos clientes, y cantidad de
clientes.
Trn Country

Grid1: Free Style.

{
CountryId*
CountryName
CountryFlag

Grid2: estndar

Trn Customer
Tabla base Grid1:
COUNTRY

{
CustomerId*
CustomerName

Tabla base Grid2:


CUSTOMER

CustomerAddress
CountryId
CountryName
}

Este caso de grids anidados es como el de for eachs anidados en el caso de un procedimiento: esto es,
aqu s se relacionan las cargas, y se cargarn por tanto en el Grid2, todos los clientes pertenecientes al
pas cargado en el Grid1 en cada oportunidad.
De hecho, el orden de ejecucin de los eventos estar anidado:
Refresh (genrico)
Grid1.Refresh
Grid1.Load carga de un pas
Grid2.Refresh
Grid2.Load carga de cliente del pas
Grid2.Load carga de cliente del pas
Grid2.Load carga de cliente del pas
Grid1.Load carga del siguiente pas
Grid2.Refresh
Grid2.Load carga de cliente del pas
Grid2.Load carga de cliente del pas
Grid2.Load carga de cliente del pas
.....

362

Web Panels
Grid Free Style
(Ejemplo: Continuacin)

Propiedades
Grid Free Style

363

Web Panels
Tipos
Tipos de Web panels
Component
Web Page
Master 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
transaccin o web panel)
Web Page (es decir, el objeto ser una transaccin web panel tal como hemos trabajado hasta el
momento)
Master Page
A continuacin introduciremos el Web Panel tipo: Component y luego volveremos sobre el Master
Page pero no lo veremos en profundidad en este curso.

364

Web Panel
Web Component
Ya tenamos programado un
web panel CustomerView
que mostraba los datos del
cliente Reutilicmoslo

Un component es un
web panel pero que se va
a ejecutar dentro de otro.

365

Web Panels
Web Component

366

Web Panels
Web Components
Ejemplo: Crear un nuevo tab en la instancia de Pattern Work With Countries,
mostrando los clientes por cada pas.

1) Definir el Web Panel CustomersPerCountry como


Component

2) Definir el nuevo tab CustomersPerCountry en la


instancia de Pattern Work With Countries

El Web Panel CustomersPerCountry


recibe CountryId como parmetro.

367

Web Panels
Web Components

368

Web Panels
Master Pages
El otro tipo de Web Panel que ya vimos es la Master Page, que
centraliza layout y comportamiento comn, en un solo objeto y
permite reutilizarlo en todo otro objeto sin tener que programar.

control dentro
del que se
cargarn las
pginas

Creadas automticamente
con la KB

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 toma
gran tiempo de programacin.
Al crear una base de conocimiento, GeneXus X crear tambin dos objetos de tipo Master Page:
ApplMasterPage: Para la aplicacin.
PromptMasterPage: Para los prompts.
Se crear un web panel, ApplMasterPage 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). Corresponde al control especial
ContentPlaceholder. 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), y se asocian a la Master Page
(a travs de la propiedad de igual nombre), de manera que cada vez que se ejecuten, se carguen con ese
contexto. Abra cualquier objeto GeneXus con form (transaccin o web panel) creado en una KB, y vea el valor
de la propiedad Master Page.
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!.
En una misma base de conocimiento se pueden definir tantas Master Pages como se desee.

369

Gxflow

370

GXFLOW

Breve introduccin terica

Qu es unworkflow?
Unsetdetareas ordenadas enuna secuencia determinada,que defineun
proceso enelcual las situaciones sonresueltas obien manualmente o
automticamente.

Ejemplo

En el ejemplo se est mostrando un workflow que se sigue en una empresa que vende mercadera al
por mayor.
Se pueden observar claramente las tareas consecutivas que se siguen para llevar a cabo el proceso de
venta.

371

GXFLOW

Breve introduccin terica


Por qu recomendamos incluir tecnologa de workflow
dentro de nuestras soluciones GX?
Porque todo sistema que querramos construir para una empresa, en el
99% tendr procesos de negocios para modelar, gestionar y hacerles
seguimiento
- conjuntos de tareas ordenadas
- responsables
- cronogramas, alertas, tiempos mximos ...
y el manejo y seguimiento de todo esto est hecho: Lo provee Gxflow

372

GXFLOW

Breve introduccin terica

Gxflow es una herramienta integrada aGeneXus que nos permite ybrinda:


Modelar losprocesos delaempresa
Definirseguridad
Definircalendarios,alertas,deadlines
EtapasdeModeladoyDesarrollodeaplicacinoperativaintegradas
Etapadeejecucinquebrindaproactividad
Auditora
Claridadparacapacitarnuevosmiembrosyparamostraraclientes

Gxflow es una herramienta integrada a GeneXus que nos permite y brinda:


1) Modelar los procesos de la empresa: Diagramar los procesos nos da la ventaja de poder cambiar
el orden de sus tareas, quitar o incluir tareas nuevas y/o cambiar las condiciones de su ejecucin, sin
tocar el cdigo de los objetos mismos.
2) Definir seguridad: Se definen roles y cules pueden ejecutar qu tareas. Esto evita tener que incluir
cdigo para la seguridad en los objetos.
3) Definir calendarios, alertas, deadlines
4) Etapas de Modelado y Desarrollo de aplicacin operativa integradas: En GeneXus X es muy
prctico y sencillo relacionar los objetos GeneXus desarrollados que implementan la aplicacin
operativa con los diagramas que modelan los procesos. Veremos como se arrastran los objetos a los
diagramas y lo prctico que resulta tener el modelado de los procesos integrado con el desarrollo de la
aplicacin operativa.
5) Etapa de ejecucin que brinda proactividad: Cada usuario al ejecutar, de primera ver las tareas
que tenga para hacer (no tendr que buscar en la aplicacin el trabajo pendiente).
6) Auditora: GXflow permite ver en qu est cada usuario, cunto tiempo le lleva cada tarea, etc.
7) Mejor entendimiento: para un nuevo miembro del equipo trabajo, y tambin para hacer muestras a
los clientes.

373

GXFLOW

Breve introduccin terica

Pasos aseguir para trabajar conGXflow:


Crear objetos GeneXus que describen realidad y procesos
INTERCALADOS

Crear diagramas de procesos de negocios para modelar los procesos


Asociar objetos GeneXus a diagramas de procesos de negocios
Ejecutar proceso

374

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Cmo crear undiagrama deproceso denegocio?


CreandounobjetoenlaKBdetipoBusinessProcess Diagram

Cuntos diagramas deprocesos denegocios definiremos en


nuestra KB?
Tantos como procesos setengan enlaempresa

375

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin paso apaso..(1)

376

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin paso apaso..(2)

TAREA / ACTIVIDAD
INTERACTIVA

ARRASTRANDO ESTOS
SMBOLOS SE
CONFECCIONA
DIAGRAMA

TAMBIN SE PUEDE
ARRASTRAR AL DIAGRAMA
TAREA / ACTIVIDAD
INTERACTIVA DESDE
FOLDER VIEW

Si desde Folder View se arrastra un objeto transaccin o web panel al diagrama, se estar agregando
una tarea / actividad interactiva al flujo, y la misma ya quedar con dicho objeto asociado para la
etapa de ejecucin. Tambin dicha tarea / actividad interactiva agregada al diagrama, quedar
automticamente nominada con el mismo nombre que la transaccin o web panel que fue arrastrado.
Si en cambio se agrega una tarea/actividad interactiva al diagrama arrastrando el smbolo
correspondiente desde la toolbox disponible para confeccionar diagramas de procesos de negocios,
luego ser necesario asociar a dicha tarea un objeto transaccin o web panel definido en la KB.
Para ello, simplemente despus de haber agregado la tarea en el diagrama y tenindola seleccionada,
habr que editar sus propiedades (F4 para abrir el dilogo de propiedades) y completar la propiedad
Web Application con el objeto que corresponda, as como la propiedad Name con el nombre que se le
quiera dar a la tarea/actividad interactiva.

377

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Descripcin desmbolos

INICIO DE PROCESO
ACTIVIDAD/TAREA INTERACTIVA
ACTIVIDAD/TAREA BATCH
EN ESTE PROCESO QUE SE EST MODELANDO,
OTRO PROCESO ES REUTILIZABLE COMO
SUBRPROCESO
CONDICIN PARA EVALUAR Y SEGN
RESULTADO, SE SEGUIR UNA RUTA U OTRA
VIENEN VARIAS RUTAS HASTA ESTE SMBOLO Y RECIN
AL LLEGAR TODAS A ESTE PUNTO, EL FLUJO CONTINA
FIN DE PROCESO

No se describirn todos los smbolos disponibles en la toolbox de workflow, sino los smbolos bsicos
que debemos conocer en un principio.
Smbolo: Condicin
Cuando se est modelando un diagrama de proceso y en determinada parte del flujo de actividades se
necesita evaluar una condicin para que dependiendo de si se cumple o no, se siga con cierto flujo de
actividades u otro, es que contamos con el smbolo de condicin.

378

Bastar con agregar un smbolo de condicin (rombo verde) al diagrama (conectado desde la
actividad previa) y a partir del rombo podrn salir N rutas (que sern de color verde tambin).
Cada una de estas rutas verdes que salgan desde un rombo de condicin, deber tener
asociada una condicin a ser evaluada (haciendo doble clic en cada ruta verde, se abrir un
editor para ingresar su condicin asociada); y en tiempo de ejecucin del diagrama, como
veremos ms adelante, cuando se llegue a la condicin en la ejecucin del proceso,
dependiendo de cul de las evaluaciones resulte verdadera se continuar con la ejecucin de
una ruta y su flujo de actividades que le sigue, u otra.
En breve veremos ejemplos de definicin de condiciones (sintaxis y posibilidades).

Smbolo: Batch Activity


Permite agregar a un diagrama de proceso de negocio, un proceso batch (por ejemplo un
proceso masivo) que se ejecutar en el servidor.
Si se agrega arrastrando el smbolo correspondiente desde la toolbox, luego ser necesario
asociarle a dicho proceso batch un objeto procedimiento definido en la KB. Para ello,
simplemente despus de haber agregado el smbolo de proceso batch en el diagrama y
tenindolo seleccionado, habr que editar sus propiedades (F4 para abrir el dilogo de
propiedades) y completar en la propiedad Procedure el nombre del procedimiento que
corresponda. Asimismo habra que asignarle un nombre en su propiedad Name.
Si en cambio desde Folder View se arrastra un procedimiento determinado, se estar
agregando al diagrama como proceso batch que ejecutar en el servidor; y el mismo ya
quedar con dicho procedimiento y nombre asociado para la etapa de ejecucin.

379

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin paso apaso..(3)


Se va confeccionando diagrama de
proceso de negocio, arrastrando
smbolos de Toolbox y objetos de
Folder View .
QU INFORMACIN
PODEMOS INVOLUCRAR
EN LAS CONDICIONES?

Aqu vemos que hemos ido confeccionando el diagrama de proceso que creamos. Le hemos agregado
tareas interactivas y una condicin.
Vemos que con doble clic en las rutas verdes que salen de la condicin, se abre el editor de condiciones
para editar cada condicin (as en caso de cumplirse una u otra se seguir con cierto flujo de
actividades u otro).
En lo que sigue veremos el concepto de Datos Relevantes que es fundamental para comprender qu
informacin podemos involucrar en las condiciones.

380

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Concepto fundamental:Datos Relevantes


Elconcepto deDatos Relevantes seutiliza para mantener unrea globalde
datos enunproceso
Esteconcepto permite administrar elpasaje deinformacin entrelas tareas yque
lainformacin seaconocida entodo elflujo
Sepuede ver como que sonvariablesglobales enunproceso

TODO DIAGRAMA DE PROCESO DE NEGOCIO TIENE UN TAB


PARA LA DEFINICIN DE SUS DATOS RELEVANTES

381

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Concepto fundamental:Datos Relevantes (Cont.)

Cuando se arrastra desde Folder View una transaccin a un


diagrama de proceso, automticamente se crea un dato relevante
con el mismo nombre e igual tipo de dato que la clave primaria de la
transaccin:
NUESTRO OBJETO DE TIPO BUSINESS PROCESS MODEL

AL ARRASTRAR LA TRANSACCIN INVOICE AL DIAGRAMA,


AUTOMTICAMENTE SE CRE ESTE DATO RELEVANTE

Tambin definiremos
veremos...

datos

relevantes

explcitamente,

como

Para los datos relevantes que se definen automticamente con igual nombre y tipo que las claves
primarias de las transacciones (como en este ejemplo: InvoiceId), hay una correspondencia automtica
entre el dato relevante y el atributo PK.
Esto es, cuando modelamos el diagrama el dato relevante es el dato global conocido en ese contexto y
en los objetos GeneXus que desarrollamos asociados a las actividades del diagrama recibimos en
parm al atributo PK (tratndose de la misma informacin o bien en el contexto del diagrama, o en el
contexto del desarrollo de la funcionalidad respectivamente). En otras palabras hay un mapeo
automtico entre el dato relevante de igual nombre y tipo al de un atributo clave primaria y dicho atributo
clave primaria.
Si bien la mayora de Datos Relevantes en un diagrama de proceso suelen corresponderse con claves
primarias, tambin hay casos en los que surge la necesidad de definir explcitamente otros datos
relevantes. A continuacin veremos ejemplos.

382

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios
InvoiceId = Dato Relevante
en el diagrama

Cundo surge la necesidad de definir datos relevantes?


Trn Invoice

thor
l Au
Pane
b
e
W

n
izatio

Parm(InvoiceId);

CMO CARGO UN VALOR U OTRO EN ESTOS EVENTOS Y QUE EL VALOR CARGADO


SE VEA EN EL DIAGRAMA PARA EVALUAR CONDICIN POSTERIOR?

Inicialmente hemos explicado que cuando trabajamos en GeneXus con workflow, realizamos los
siguientes pasos bsicamente:
Crear objetos GeneXus
Crear diagramas de procesos de negocios
Asociar objetos GeneXus a diagramas de procesos de negocios
Ejecutar proceso
As es que venimos confeccionando un diagrama de proceso en nuestra KB; tenamos previamente
definidos algunos objetos GeneXus que hemos arrastrado al diagrama, y vamos desarrollando otros
objetos e incorporndolos al diagrama tambin. Ms adelante veremos como asignar roles a las
diferentes actividades del diagrama. Por ahora la idea es que contamos en la KB con una transaccin
Invoice, la cual fue arrastrada al diagrama como primer actividad interactiva del proceso y ms
adelante definiremos que esta tarea interactiva podr ser ejecutada por las vendedoras de la empresa.
Cuando una vendedora ingrese una venta (a travs de la transaccin Invoice), entrar el cliente, la
mercadera solicitada, las cantidades, la forma de pago solicitada por el cliente, grabar la venta con un
nmero interno (no el nro de factura formal) y ah terminar la primer actividad. Luego esa venta deber
ser evaluada por un supervisor (quien evaluar de qu cliente se trata, el monto, la forma de pago), y el
supervisor deber aceptar o denegar la venta. Esta segunda actividad interactiva del proceso fue
agregada al diagrama arrastrando el web panel Authorization.
Entonces, a nivel del diagrama de proceso contamos con el dato relevante InvoiceId (de igual nombre y
tipo de dato que el atributo InvoiceId), lo cual significa que dicho dato se conoce a lo largo de todo el
flujo de actividades. Y en lo que se refiere a los objetos GeneXus relacionados al diagrama, el web
panel Authorization implementa la 2da actividad del proceso y recibe por parmetro al atributo
InvoiceId. En el form del web panel Authorization se visualizarn los datos de la factura, el lmite de
crdito y saldo de lmite de crdito del cliente y estar la posibilidad de ver la historia de facturas
anteriores del cliente. Este web panel ofrecer al supervisor 2 botones: Authorize y Refuse.

383

Vale explicar que cuando trabajamos con workflow en GeneXus, en el cdigo de los objetos ya no
pondremos invocaciones de un objeto a otro. En cambio, en los diagramas de procesos que
confeccionamos ya quedan implcitas las invocaciones entre actividades consecutivas.
Ms adelante veremos que en la etapa de ejecucin, procederemos a ejecutar una aplicacin que nos
ofrecer crear instancias de los procesos que hemos definido (por ejemplo se podrn crear N instancias
del proceso de venta definido). Al crear una nueva instancia de proceso, comenzar la ejecucin de la
primer actividad (se presentar la trn Invoice para ello, y si definimos roles, se validar que en particular
sea una vendedora quien realice esta actividad). Una vez finalizada la primer actividad, seguir la
segunda actividad (para ser efectuada por el rol que corresponda, que en nuestro ejemplo es un
supervisor) y as sucesivamente se irn finalizando actividades de la instancia del proceso y ejecutando
las siguientes actividades hasta concluir dicha instancia de proceso.
De modo que no codificamos ms calls en los objetos GeneXus, y de necesitar cambiar el orden de
precedencias de las actividades en un proceso, o agregar o quitar actividades, as como cambiar las
condiciones de ejecucin de las actividades, lo reflejamos en el diagrama de proceso sin tocar el cdigo
de los objetos.
Algo a hacer notar es que si bien no definimos calls en el cdigo mismo de los objetos, s definimos regla
parm en los objetos GeneXus que participan en un diagrama de proceso. Esto es porque los objetos son
invocados -si bien con otro esquema de trabajo del que conocamos- y necesitan pasarse la informacin
necesaria as es que suelen recibir por parmetro los atributos claves primarias que son anlogas a los
datos relevantes en el diagrama de proceso (y que hay una correspondencia entre estos conceptos).
Una vez hechas estas explicaciones, seguiremos estudiando paso a paso la implementacin de la
segunda actividad del proceso que venimos confeccionando. El web panel Authorization recibe por
parmetro al atributo InvoiceId, muestra en su form informacin para la toma de desicin de la
autorizacin o denegacin y para ello contiene 2 botones Authorize y Refuse respectivamente.
Si nuestro objetivo es cargar una variable con valor 1 en el evento Authorize y con valor 0 en el evento
Refuse, y queremos que el valor asignado se vea en el diagrama de proceso, bastar con realizar lo
siguiente:
1) En el tab Relevant Data del diagrama de proceso, habr que crear un dato relevante (por ejemplo de
nombre: InvoiceAuthorized) de tipo Numeric.
2) En el web panel "Authorization habr que leer el dato relevante y cargarlo en cada evento del web
panel, as:

Siendo:
&wfAuthoriz: una variable definida en el web panel, de tipo de datos es: WorkflowApplicationData
&wfProcessInstance: una variable definida en el web panel, de tipo de datos: WorkflowProcessInstance
384

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin paso apaso..(4)


Creacin explcita de Dato Relevante en Diagrama de Proceso
y cmo trabajar con el mismo en objetos

1)

2)

En wbp Authorization
defimos 2 variables
de tipos de datos
WorkflowApplicationData
y WorkflowProcessInstance
para leer y cargar dato
relevante

De modo que hemos definido un dato relevante en el diagrama de proceso (de nombre
InvoiceAuthorized) y luego en el web panel Authorization se lee el dato relevante en variable
&wfAuthoriz de tipo WorkflowApplicationData. El tipo de datos WorkflowApplicationData viene a
significar dato relevante.
Tambin hemos definido en el web panel una segunda variable de tipo WorkflowProcessInstance. El
tipo de datos WorkflowProcessInstance viene a significar instancia de proceso. O sea que si
analizamos la primer lnea codificada en cualquiera de los 2 eventos, estamos recuperando en la
variable &wfAuthoriz (de tipo dato relevante) el valor del dato relevante de nombre InvoiceAuthorized
(entre comillas va el nombre del dato relevante tal como se ha definido en el diagrama de proceso)
perteneciente a la instancia del proceso que se est ejecutando.
Luego en la segunda lnea codificada en ambos eventos, se est asignando a la variable &wfAuthoriz
(de tipo dato relevante) el valor 0 o 1 segn corresponda (utilizando la propiedad Numeric del tipo
de dato WorkflowApplicationData, por estar asignando un valor nmerico).
Por ltimo en cada evento se hace return, porque ya se ha recuperado el valor del dato relevante, se le
ha cargado el valor deseado y se desea culminar con la ejecucin de esta actividad.
De esta manera entonces leemos y cargamos datos relevantes en los objetos GeneXus asociados a las
actividades de un diagrama de proceso, empleando tipos de datos workflow, propiedades y mtodos.
Sin embargo para datos relevantes con igual nombre y tipo que las claves primarias, esto no es
necesario (sino que se reciben por parm los atributos primarios directamente y ya hay mapeo
automtico con el dato relevante correspondiente).

385

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin paso a paso.. (5)


Evaluacin de Dato Relevante en condicin de Diagrama de Proceso
En todo el diagrama contamos con el
Dato Relevante &InvoiceAuthorized...
En rutas que salen de la condicin
evaluamos valor de Dato Relevante
&InvoiceAuthorized

Observe que en cada ruta verde que sale del rombo de condicin, se evala el valor del dato relevante
&InvoiceAuthorized.
Si bien cuando definimos el nombre del dato relevante no incluimos el & (amperson), el dilogo de
definicin de datos relevantes muestra claramente un cono &, dando la pauta de que se trata de
variables:

De modo que para referirnos a un dato relevante en el flujo, lo referenciamos con & como se puede
observar en las 2 imgenes capturadas correspondientes al editor de condiciones. Sin embargo para
datos relevantes con igual nombre y tipo que las claves primarias, es posible referenciar tanto el dato
relevante (con &) como el atributo clave primaria directamente.

386

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Otra solucin posible para resolverpasos (4)y(5)


1)

Se quiere definir atributo InvoiceAuthorized en trn Invoice y grabar en cada invoice si fue
autorizada o no..

2)

En web panel Authorization se invoca proc en cada evento, que graba 1 o 0 en atributo
InvoiceAuthorized

3)

En Diagrama de Proceso el atributo InvoiceAuthorized puede inferirse (a travs de InvoiceId) y


evaluamos directamente dicho atributo en rutas que salen de la condicin

EVALUAMOS ATRIBUTO
(NO DATO RELEVANTE)

Con esta solucin, no tenemos necesidad de definir Dato Relevante InvoiceAuthorized , ya que tenemos
en un atributo la informacin de si la invoice fue autorizada / denegada y en el flujo se pueden inferir
atributos a travs de claves primarias, y evaluar directamente atributos.

387

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Definicin deroles

1)

DEFINICIN
DE ROLES EN
LA KB

2)

ASIGNACIN
DE ROLES
A ACTIVIDADES
EN DIAGRAMA

La definicin de roles se realiza a nivel de la KB en la seccin de Preferences.


Luego seleccionando cada actividad del diagrama y presionando F4, en la propiedad Roles se podr
asignar la lista de roles que podrn ejecutar dicha actividad.

388

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Diagrama deProceso completo correspondiente alproceso que


venimos confeccionando:

Si el supervisor autoriza una venta, la siguiente actividad modelada en el diagrama es


InvoiceToBePrepared. Esta actividad interactiva tiene un web panel asociado que recibe por parmetro
al atributo InvoiceId, muestra la informacin de la venta autorizada y tiene un botn para que la persona
de empaque lo presione cuando haya terminado de preparar la mercadera. El evento asociado a ese
botn, invocar a un procedimiento que grabar en un atributo de la invoice, un valor indicador (flag) de
que el empaque ya se ha realizado.
La siguiente actividad tambin es interactiva y tiene un web panel asociado que recibe por parmetro al
atributo InvoiceId, muestra la informacin de la venta preparada y tiene un botn para emitir la factura.
Cuando una vendedora presione este botn, el evento asociado al botn invocar a un procedimiento
que grabar en la invoice el nmero de factua formal y emitir la impresin.
La ltima actividad de este flujo que venimos explicando, corresponde a la distribucin de la mercadera.
Esta actividad tambin tiene un web panel asociado que muestra los datos de la venta y presionando un
botn, un proc grabar que la misma ha sido entregada.
Las fechas / horarios de efectuadas cada una de las actividades, quedarn registradas durante la
ejecucin del workflow.

389

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Pasosparaejecutar:

Save All
Build All
(Se solicitarn datos de Enviroment)
Run del Diagrama de Proceso

390

GXFLOW

Conceptos bsicos para crear


diagramas de procesos de negocios

Ejecucin:

Hay 2 modalidades de ejecucin:


Prototyper
Full Client
En la seccin de Preferences se puede configurar cul se desea:

Lgicamente la modalidad Prototyper est orientada a la etapa de prototipacin. Y la modalidad FullClient a etapa de produccin.
En etapa de prototipacin no nos interesa probar la seguridad, motivo por el cual al ejecutar la
aplicacin en modalidad Prototyper inicialmente se limpian todas las instancias de pruebas anteriores y
se permiten ejecutar todas las actividades sin controlar roles.
Al ejecutar la aplicacin en modalidad Full-Client en cambio, no se aborta nada inicialmente y se
requiere crear usuarios (para login) cada uno de ellos con la lista de roles que le corresponda, ya que en
este caso s la seguridad se controlar.

391

Manejo de versiones

392

Manejo de Versiones
Eldesarrollodesoftwareesuntrabajoenequipoyciertogrado de
confusinesinevitable.
Qu pas con el
arreglo de la
semana pasada?

No puedo
reproducir el
error en esta
versin!

La aplicacin en
ejecucin no es
compatible con
el cdigo fuente

Realmente
estamos
trabajando en
la ltima
versin?

Este
programa
ayer
funcionaba!

393

Manejo de Versiones
Conclusin:
Elciclodedesarrolloesunprocesodinmicoquerequiere
controldeloscambiosrealizadosalosobjetosdelproyecto.
Senecesita:
Marcarhitoseneldesarrollodelaaplicacin
Tenerlneasdedesarrolloparalelas
Administrarelciclodevidadelaaplicacin(SCM)

. . .
KB

Versin 1

Versin 2

Versin N

Durante el proceso de construccin de la aplicacin, es necesario marcar hitos en el desarrollo de la


misma, entendiendo como hitos la congelacin del desarrollo en un determinado momento especial en
el proceso. Esto se puede dar por ejemplo para liberar una versin a produccin, congelar una versin
entregada a un cliente, la necesidad de congelar un determinado estado especial de la aplicacin, etc.
Adems tambin vamos a querer tener distintas lneas de desarrollo de la aplicacin, algo muy comn
por ejemplo cuando se quiere hacer variaciones del proyecto para un cliente o cuando se requiere que
dos grupos de trabajo lo hagan en paralelo y necesitamos poder realizar una administracin de todos
estos elementos.
Lo que necesitamos bsicamente es administrar el ciclo de vida de la aplicacin durante el desarrollo.
Varias de estas funcionalidades entran en lo que en el mundo del software se conoce como SCM
(Software Configuracin Management)

394

Manejo de Versiones
Solucin:Manejodeversionesdelaaplicacin

1.1.1

APP
APP

1.0

Nodo raz del rbol


de versiones

1.1

1.2

1.0.1

1.1.2

2.0

1.0.2

2.1

1.0.3

Se comienza el desarrollo siguiendo una lnea principal de desarrollo (lnea del medio Trunk), lugar donde se
agregan las funcionalidades requeridas y se utilizan prototipos para probarlas .
En determinados momentos de este ciclo surge la necesidad de establecer un checkpoint en el proceso, ya sea por la
liberacin de una versin, la entrega de una versin a un cliente, la necesidad de congelar un determinado estado de
una aplicacin, etc. Entonces lo que hacemos es congelar el producto en ese momento creando por ejemplo la
versin 1.0 que se la entregamos a un cliente y se contina el proceso de desarrollo principal.
En determinado momento surge la necesidad de realizar correcciones sobre la versin entregada al cliente (1.0) por
lo que es necesario abrir una nueva lnea de desarrollo para incluir estas correcciones sobre lo que era la versin 1.0
sin afectar la lnea de desarrollo principal que sigui creciendo desde el momento de la congelacin de la versin 1.0.
Entonces se crea lo que se conoce como Developmen Version o branch, que es simplemente una nueva lnea de
desarrollo paralela a la principal.
Luego durante el transcurso del proyecto vuelven a aparecer requerimientos de este tipo, ya sea de determinacin de
checkpoints como la necesidad de abrir nuevas lneas de desarrollo, entonces por ejemplo creamos la versin 1.1, o
la 1.0.1 que vendra a ser un congelado de la lnea de desarrollo abierta a partir de la versin 1.0 y as sucesivamente
hasta tener por ejemplo la situacin planteada en el diagrama.
Estas situaciones forman parte de la operativa normal en el desarrollo de una aplicacin y es necesario administrar
fcilmente este proceso.
Para ello se introduce el concepto de Manejo de Versiones. Las versiones se clasifican en:
Development Versions, representan las lneas de desarrollo de la aplicacin las cuales son independientes entre si,
existe una lnea principal y varias paralelas, la principal vendra a ser lo que se conoce como Trunk y las dems
seran lo que en SCM se conoce como Branches
Frozen Versions (tambin conocidas como Labels en SCM), representan los congelados creados en determinados
momentos del proceso sobre las DV para determinar ciertos checkpoints (liberacin de versin, entrega a cliente,
congelar estado, etc.)

395

Manejo de Versiones
Solucin:Manejodeversionesdelaaplicacin
Development Version
1.1.1

APP
APP

1.0

1.1

1.2

1.1.2

2.0

2.1

Development Version (Trunk)


Nodo raz del rbol
de versiones

1.0.1

1.0.2

1.0.3

Development Version
Frozen Versions

Se comienza el desarrollo siguiendo una lnea principal de desarrollo (lnea del medio Trunk), lugar donde se
agregan las funcionalidades requeridas y se utilizan prototipos para probarlas .
En determinados momentos de este ciclo surge la necesidad de establecer un checkpoint en el proceso, ya sea por la
liberacin de una versin, la entrega de una versin a un cliente, la necesidad de congelar un determinado estado de
una aplicacin, etc. Entonces lo que hacemos es congelar el producto en ese momento creando por ejemplo la
versin 1.0 que se la entregamos a un cliente y se contina el proceso de desarrollo principal.
En determinado momento surge la necesidad de realizar correcciones sobre la versin entregada al cliente (1.0) por
lo que es necesario abrir una nueva lnea de desarrollo para incluir estas correcciones sobre lo que era la versin 1.0
sin afectar la lnea de desarrollo principal que sigui creciendo desde el momento de la congelacin de la versin 1.0.
Entonces se crea lo que se conoce como Developmen Version o branch, que es simplemente una nueva lnea de
desarrollo paralela a la principal.
Luego durante el transcurso del proyecto vuelven a aparecer requerimientos de este tipo, ya sea de determinacin de
checkpoints como la necesidad de abrir nuevas lneas de desarrollo, entonces por ejemplo creamos la versin 1.1, o
la 1.0.1 que vendra a ser un congelado de la lnea de desarrollo abierta a partir de la versin 1.0 y as sucesivamente
hasta tener por ejemplo la situacin planteada en el diagrama.
Estas situaciones forman parte de la operativa normal en el desarrollo de una aplicacin y es necesario administrar
fcilmente este proceso.
Para ello se introduce el concepto de Manejo de Versiones. Las versiones se clasifican en:
Development Versions, representan las lneas de desarrollo de la aplicacin las cuales son independientes entre si,
existe una lnea principal y varias paralelas, la principal vendra a ser lo que se conoce como Trunk y las dems
seran lo que en SCM se conoce como Branches
Frozen Versions (tambin conocidas como Labels en SCM), representan los congelados creados en determinados
momentos del proceso sobre las DV para determinar ciertos checkpoints (liberacin de versin, entrega a cliente,
congelar estado, etc.)

396

Manejo de Versiones
Development Version:(Branch)Lneadedesarrollodela
aplicacin.Puedenhabervariaslneasquetranscurranparalelas.
Development Version

APP
APP

1.0

1.1.1

1.1

1.2

1.1.2

2.0

2.1

Development Version principal (Trunk)


1.0.1

Nodo raz del rbol de


versiones = nodo raz del Trunk

1.0.2

1.0.3

Development Version

Las development version son las lneas de desarrollo de la aplicacin, es decir el lugar donde
efectivamente creamos y modificamos la aplicacin.
En el ciclo de vida de una aplicacin participa una lnea de desarrollo principal, es decir, donde
comienza el proceso de desarrollo de la aplicacin y en la cual normalmente se van a estar haciendo las
modificaciones requeridas en el avance del proyecto. En SCM esta lnea de desarrollo se conoce con el
nombre de Trunk.
Adems de esta lnea principal podrn existir una o varias lneas de desarrollo secundarias, totalmente
independientes de la lnea principal e independientes entre si. En SCM estas lneas de desarrollo
secundarias se conocen como Branches y son usadas en general para realizar correcciones o
pequeos agregados sobre versiones congeladas o liberadas de la aplicacin, o para liberar una versin
especial para un cliente.
El desarrollo en cada una de estas development version es independiente, teniendo cada versin sus
propios objetos, su propia base de datos, ambientes para generar la aplicacin, etc.
Una Development Version, es entonces, una copia de la KB editable e independiente.

397

Manejo de Versiones
Frozen Version:Versinnomodificable,esunafoto dela
aplicacinenunmomentodado.
1.1.1

APP
APP

1.0

1.1

1.2

1.0.1

1.1.2

2.0

1.0.2

2.1

1.0.3

Frozen Versions

Una Frozen Version permite almacenar en forma esttica momentos especiales de la KB. Es el
elemento que utilizamos para marcar distintos hitos en el proceso, como por ejemplo el cierre de una
versin para liberarla a los clientes.
Se obtiene a partir de una versin en desarrollo (development version), congelndola para obtener una
foto en un determinado momento.
La versin obtenida es Read Only, es decir que objetos de la misma no podrn ser modificados, ni
tampoco sus propiedades. S ser posible realizar acciones relacionadas con la generacin de la
aplicacin, como por ejemplo la creacin de la base de datos o la regeneracin de los programas.
Cuando congelamos una versin es porque determinamos que la misma est en un estado consistente
y sera conveniente guardar dicho estado. Por ejemplo, congelamos una version X para drsela a los
clientes, en determinado momento, mientras se contina con el proceso de desarrollo, un nuevo cliente
requiere de la aplicacin, entonces lo que hacemos es generar la misma en la version X, que sabemos
tiene un estado correcto y se la instalamos al nuevo cliente.
Los objetos si bien no pueden ser modificados, pueden ser abiertos para distintas consultas o para
realizar comparaciones con otras versiones de la aplicacin.

398

Manejo de Versiones
Ejemplodeversionado:Implementacinpasoapaso
Variaciones debido a arreglos o cambios en
requerimientos

APP
APP

..

Ciclo de desarrollo principal - Prototipado

Development
Version
principal
(Trunk)

Partimos del nodo raz del rbol de versiones, el cual se crea al crear la KB.
La aplicacin va sufriendo cambios a medida que transcurre el ciclo de desarrollo. La lnea de desarrollo
principal es donde se implementan las funcionalidades requeridas y donde se hace el prototipado.
Esta lnea de desarrollo generalmente coincide con el Trunk, o sea con la rama principal del rbol de
versionado. Es una Development Version creada por defecto al crearse la KB.
A medida que se van haciendo modificaciones a la aplicacin, la misma va cambiando a lo largo del
tiempo.

399

Manejo de Versiones
Paraverelrboldeversiones,abrimoslaventanaKnowledge Base
Versions (View/Versions):

Nodo raz del rbol de


versiones = nodo raz del
Trunk

400

Manejo de Versiones
Surgelanecesidaddecongelar versiones,parafijarhitosenel
proyecto.ParaesocreamosFrozen Versions (copiadeslo
lecturadelaaplicacin).
..

APP
APP

1.0
1.0

Development Version
principal (Trunk)

Frozen
Version 1.0

Las Frozen Version sirven para:


Analizar (no modificar) objetos, propiedades, environments, etc.
Como fuente de un Reporte de Anlisis de Impacto de la base de datos
Para crear la base de datos
Para regenerar todos los programas

401

Manejo de Versiones
Cmocongelamos unaDevelopment Version,paracrearuna
Frozen Version?

Damos botn derecho sobre el


nodo raz y seleccionamos
Freeze

402

Manejo de Versiones
AhoraqueremosponerlaaplicacinenProduccin.Paraesopartir
deunaFrozen Version 1.1creamosunaDevelopment Version
Release 1.
..

APP
APP

1.0
1.0

Development Version
principal (Trunk)

1.1
1.1

Release1
Release1

Development
Version para
Produccin

En la versin de Produccin se van produciendo variaciones debido a arreglos, pero no se agrega


funcionalidades nuevas. Las mismas son agregadas en la lnea de desarrollo principal.
Las Development Version sirven para:
Trabajar en una lnea de desarrollo paralela a la principal
Como fuente o destino de una operation de Revert desde una Frozen Version de Backup

403

Manejo de Versiones
CreamoslaFrozen Version 1.1comovimosanteriormente

Botn derecho sobre el nodo


raz y click en Freeze

Frozen
Version
1.1

Ntese que las Frozen Version ms nuevas, se muestran ms arriba en el rbol de versiones.

404

Manejo de Versiones
DamosbotnderechosobrelaFrozen Version 1.1yseleccionamos
New Version paracrearlaDevelopment Version Release 1.

Development
Version
Release1

El tiempo que se demora en crear una nueva Development Version es proporcional al tamao de la KB.

405

Manejo de Versiones
TambinpodemoscrearnuevasFrozen Versions tantoenlarama
deldesarrolloprincipalcomoenlaramadeProduccin.
..

KB1
KB1

1.0
1.0

Produccin

1.1
1.1

1.2
1.2

Trunk

2.0
2.0

2.1
2.1

Release1
Release1

1.1.1
1.1.1

1.1.2
1.1.2

Frozen Versions
de Produccin

Como las lneas de desarrollo del Trunk (Desarrollo) y de Relase 1 (Produccin) son paralelas, los
cambios en una no afecta a la otra.
Ambas versiones son entonces totalmente independientes y podemos requerir congelarlas por
diferentes motivos. Por ejemplo, en el caso de la rama de Produccin, para fijar un estado luego de
ciertos arreglos que tuvimos que hacer.
De acuerdo a la metodologa adoptada, en el ciclo de desarrollo principal, es donde se agregan nuevas
funcionalidades, arreglos, cambios importantes a la aplicacin, prototipado y testing. Es ms frecuente
que se necesita fotos en esa etapa viva del desarrollo de la aplicacin.
En la rama del Release1, los cambios son menores, ms bien arreglos circunstanciales que no agregan
funcionalidad. En este caso, es menos frecuente la necesidad de crear Frozen Versions, pero puede ser
igualmente necesario.

406

Manejo de Versiones
NtesequelasFrozen Versions msnuevas,semuestranms
arribaenelrboldeversiones

407

Manejo de Versiones
LuegodeciertosarreglosenProduccin,nosinteresagenerarla
aplicacin.ParaesomarcamoslaDVRelease 1comoactiva.

Damos botn derecho


sobre el nodo Release1
y elegimos Set Active

GeneXus genera automticamente los programas y las estructuras de la BD, partiendo de la versin que
est activa.
Se puede marcar como activa una versin en desarrollo o una versin congelada. En ste ltimo caso,
no podremos hacer ninguna modificacin a la misma, solamente utilizarla para generar la aplicacin o
para realizar un impacto a la base de datos, o para comparar versiones.
Solamente puede haber una versin activa a la vez.

408

Manejo de Versiones
LaDevelopment Version queest activa,ser laqueseutilizar
paragenerarlaaplicacinalhacerunBuild (F5)
GeneXus nos indica
cul es la rama
activa

409

" #

$
! !
%&

"

'

" #

, %-. /
,)

'

!" #
!
#

!
/

&
%&

"
,

2
'

,3
/
)
#

# 01)

!
4 #

2
, $ !! . " #
,0

5 !" #

, 6/ 7 8 '9
,"

%&

"
$ !!
/

" #
#
"
!
!

"
#

#
!

"
$ !!
/

" #
#

#
0

"
!" #

#
!

4
! ;
!

1
!

$% & ' (
6/ 7 8 '9
!

4 !

)
#

!!

"

8 #!
!

10

10
255

25

905

145

550

210

150

300

890

230

2510

1340

320

1090
2510

1100

Como columna

Como pgina

Anlogo a un corte
de control que corta
primero por
CountryName, luego
por CustomerName
y luego por
InvoiceDate, y para
los registros de este
ltimo grupo,
sumariza
InvoiceAmount.

Observacin: se busca tabla extendida que contenga CountryName, CustomerName, InvoiceDate e


InvoiceAmount.

For each order CountryName


Defined by InvoiceDate
print Country
For each order CustomerName
print Customer
For each order InvoiceDate
&sum = 0
For each
&sum += InvoiceAmount
endfor
Print DateWithSum
endfor
endfor
endfor

Pero el usuario no tiene la


libertad de cortar la
informacin pivoteando
(en distinto orden), ni de
mostrarla de diferentes
formas
En cambio con un objeto
Query

Conditions: CustomerName in [Julia, Diego, Mary]


CountryName = Uruguay

" #

!
Manipulable:

Prototipacin

Qu puede
especificarse dentro
del nodo Attributes?

Atributos
Funciones de agregacin
Expresiones

Los atributos (simples,


agregados o en expresiones)
que compongan la consulta
que desea realizarse.

Simples (Sum, Count, Average)


Condicionadas

Lectura opcional

Sin agregacin. Ej: descripciones,


fechas, numricos sin decimales.

Con agregacin. Ej: numricos con


decimales,Sum, Count, y Average

! "#

"
$
Lectura opcional

"

"

Suma de las ventas del cliente


Cantidad de facturas
del cliente

Promedio diario de facturacin por cliente

% Average(Count(InvoiceId)
Lectura opcional

Los resultados de cualquier funcin de agregacin


pueden mostrarse como porcentaje.

Nota: Se est filtrando por Uruguay, por eso es el


100%

Lectura opcional

Cantidad de clientes por pas.

Cantidad de clientes que compraron, por


pas.
El count avanzado cuenta las ocurrencias
distintas del atributo involucrado. Por esta
razn colocamos CustomerId y no
CustomerName.
Estamos pidiendo que cuente los distintos
CustomerId que tienen facturas.

Lectura opcional

Monto promedio de lo que gasta cada vez


que compra

Monto promedio de lo que gasta diariamente

Lectura opcional

Se pueden condicionar los datos a consultar.

Pueden definirse filtros de los mismos


tipos que los del nodo Filters (general)

Lectura opcional

Se puede realizar el filtro antes o


despus de la agregacin
Se suman nicamente las facturas (del
pas) cuyo InvoiceAmount supera los U$S
500.
Se muestra el pas en la salida, solamente si
la suma de los InvoiceAmount de todas sus
facturas, supera los U$S 1000.

Lectura opcional

&

'

&

#
!

Lectura opcional

Rango con valores


constantes

Lista de valores
constantes

Operador Like

Rango o Lista de valores no


constantes (subconsulta)

Lectura opcional

( )
& +,

'

Sus elementos se unen con OR

Sus elementos se unen con OR

Luego se aplica el AND


Lectura opcional

Lectura opcional

!
Ejemplo: Se resuelve con 2 consultas select de las que luego se hace full join:

Tabla base: Invoice


Tabla base: Bill

Lectura opcional

! "#

#$

$!

& '

& '
. +

& '
-/ +

{Ascending, Descending, Custom}


{Row, Column, Page, Data, NotShow}
{DataProvider, Query}
{PivotTable, Table, Chart, Default}

& '
. +

& '

Desarrollo de Aplicaciones con tecnologa GeneXus

Curso 2013

Prctico 1 Diseo de Transacciones


Se quiere implementar un sistema para administrar el funcionamiento de un Cambio.
Se busca registrar la cotizacin de las monedas respecto al Peso Uruguayo. De la moneda se
conoce su descripcin, su smbolo y el histrico de cotizaciones incluyendo compra y venta. El
histrico busca registrar un valor de cotizacin y la fecha desde la que tiene vigencia.
1) Disear la transaccin Moneda teniendo en cuenta adems que:
- El smbolo se debe ingresar obligatoriamente
La pizarra electrnica que se coloca en la entrada del cambio toma el valor desde nuestro
sistema. Cada pizarra se identifica por la fecha en la que se presenta, tambin muestra la
fecha en texto (p.e 23 de Abril de 2013). Luego en forma de rengln muestra una moneda y la
cotizacin vigente para la fecha de la pizarra.
2) Disear la transaccin pizarra teniendo en cuanta adems que:
- Al ingresar una nueva pizarra debe sugerir como fecha, la fecha de hoy
Las boletas de cambio registran una operacin hecha en alguna sucursal. De la boleta se
conoce la fecha, la sucursal, el tipo de operacin (COMPRA o VENTA), la moneda, la cotizacin
vigente a la fecha de hoy, el importe de la operacin y el importe resultado de la operacin. De
las sucursales se conoce su direccin, el telfono y la cantidad de operaciones realizadas.
3) Disear la transaccin Sucursal y Boleta teniendo en cuenta que:
- Al ingresar una boleta, las sucursales deben salir listadas en un combo box para
que el usuario del sistema pueda seleccionarla.
- Crear un dominio para los tipos que representan importes
Verificar como GeneXus respeta la integridad referencial

Forma de entrega
El trabajo debe realizarse en forma individual y la entrega consiste en un archivo xpz de
nombre <Cedula>_<NombreApellido>.xpz con la resolucin de los ejercicios.
El xpz debe enviarse a la casilla ernestolopezmoreira@gmail.com antes del da 30 de Abril
(inclusive).

Desarrollo de Aplicaciones con tecnologa GeneXus

Curso 2011

Laboratorio Desarrollo de aplicaciones GeneXus 2011


Una empresa multinacional de alquiler de autos decide ofrecer sus servicios de renta y
consultas a travs de un sistema Web. Se busca que cualquier cliente registrado pueda
consultar la flota de automviles que ofrece la empresa, y de quererlo realizar la
reserva del coche. Entonces se quiere un sistema que requiera autenticacin, en caso
de que el cliente no est registrado se le dar la opcin de hacerlo. Si el usuario no se
autentica entonces no podr acceder a ninguna funcionalidad del sistema y este lo
redirigir automticamente a la pantalla de login.
Clientes:
Al registrarse, el usuario deber elegir un Nick el cual debe ser nico. Deber empezar
con una letra, no podr contener espacios y solo puede estar formado por letras,
nmeros y guin bajo. Adems deber ingresar obligatoriamente nombres, apellidos,
pas, ciudad, direccin e email de contacto. Tambin ingresa la contrasea y una casilla
extra para repetir la contrasea as se puede verificar que fue escrita correctamente.
Al ingresar el Pas mediante un ComboBox automticamente se muestran solo las
ciudades de ese pas en el comboBox de ciudades.
Luego de realizado el login se muestra una pantalla en la que se muestra algn
promocin de la empresa. La promocin consta de algn modelo de la flota y una
descripcin de Marketing. En todo momento debe visualizarse el usuario conectado y
el rol (por ejemplo en la Master Page).
Vehculos:
Los vehculos sern rentados por la empresa a los clientes. Se cuenta con varios
vehculos de cada modelo. Cada Modelo est identificado por la marca y el nombre del
modelo (p.e Ford, Escort). Deber existir una pantalla para administrar las marcas. De
cada modelo se conoce una foto, una descripcin breve del modelo, cilindrada, tipo de
motor (gasoil o nafta), el costo de alquiler por da, si tiene direccin hidrulica, si tiene
aire acondicionado y capacidad. Tambin se desea visualizar la cantidad de vehculos
en la flota que son de ese modelo,
Un vehculo est identificado por la matrcula y se conoce su modelo. Adems es
necesario registrar la cantidad de kilmetros que tiene, color, si est en renta o no, y si
est en el taller o no.
Renta:
Cuando un cliente desea rentar un auto realiza una bsqueda de modelos de autos.
Debe poder realizar bsquedas pudiendo filtrar por al menos marca, modelo,
capacidad y precio. De los modelos que cumplan las condiciones de bsqueda se debe
mostrar foto del modelo, nombre del modelo, marca, una descripcin breve del
modelo, cilindrada, tipo de motor (gasoil o nafta), el costo de alquiler por da, si tiene

Pgina 1

Desarrollo de Aplicaciones con tecnologa GeneXus

Curso 2011

direccin hidrulica, si tiene aire acondicionado y capacidad. Para esto utilizar una Free
Style grid. Junto a cada modelo debe aparecer la opcin de rentar.
Al seleccionar la opcin se redirige a una pantalla en la cual se muestran otra vez los
datos del modelo seleccionado y se pide al usuario que ingrese la fecha desde la cual
quiere alquilar y la cantidad de das. A travs de un botn se muestra una grilla con los
vehculos disponibles del modelo seleccionado y el costo total de la renta. El usuario
elige un vehculo y se emite un listado pdf que funciona como comprobante en el que
se muestra los datos del cliente, la fecha de la reserva, la cantidad de das, el total a
pagar y los datos del vehculo.
Al momento de confirmar se ingresa la reserva del vehculo. Una reserva est
identificada por el vehculo, y la fecha de la reserva (no es posible reservar un vehculo
ms de una vez en un da). La reserva tiene adems la cantidad de das que se alquil,
el kilometraje que se hizo durante el alquiler, el cliente que hizo la reserva y el estado
(abierta, cerrada). Al ingresar la reserva, esta queda abierta
Luego, cuando el cliente retorna con el vehculo un usuario administrador ingresa los
kilmetros realizados y marca la reserva como cerrada.

Objetivo:
Implementar la seguridad requerida para los clientes. Esto incluye mostrar solo las
opciones de men que corresponden.
Implementar para el cliente las funcionalidades de:
- Buscar Modelo
- Rentar auto
- Ver las reservas realizadas.
Implementar para el administrador las funcionalidades de:
- Reporte de estado de vehculos (permitir filtros por modelo)
- Ver reservas pendientes
- Reporte de historial de reservas de un vehculo.
- Reporte de reservas por rango de fechas. Agrupar por fecha los totales de
las reservas de cada modelo (solo los modelos que efectivamente tuvieron
reservas en el rango de fecha)

Consideraciones:
1) Instalar el User control MultiLevelMenu que viene en el archivo
MultiLevelMenu.zip:
http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Default+Installation+Instructions
+for+User+Controls,

Pgina 2

Desarrollo de Aplicaciones con tecnologa GeneXus

Curso 2011

2) Luego, y solo luego de instalar el user control, cargar el XPZ laboratorioGX2011.xpz


que contiene la masterPage y el tema a utilizar para el laboratorio.
Deber modificarse el data provider dataProviderMLM para cargar las opciones del men
de la aplicacin y establecer como MasterPage y tema por defecto los del XPZ (el tema
es K2b3).

3) Para el manejo de la seguridad utilizar el tipo de dato WebSession. Este tipo de dato
permite almacenar pares {etiqueta, valor} a lo largo de la sesin del usuario. Por
ejemplo para la seguridad se puede utilizar la etiqueta userid para mantener el id del
usuario, entonces al momento de hacer el login guardamos este valor utilizando el
mtodo set del tipo de dato webSession:
&Session.set(userid, <NombreDeUsuario>)
Luego en el evento Start de la masterPage verificamos que este valor exista de lo
contrario redirigimos al usuario a, por ejemplo, la pantalla de login:
&Usuario = &Session.get(userid)
If

&usuario.isEmpty()
Login.call()

http://wiki.gxtechnical.com/commwiki/servlet/hwiki?WebSession,

Inscripcin:
El laboratorio se realizar en grupos de hasta 3 personas. Enviar correo a
ernestolopezmoreira@gmail.com con los nombres de los integrantes antes del 30 de
octubre.

Pgina 3

Desarrollo de Aplicaciones con tecnologa GeneXus

Curso 2011

Fechas de entrega y evaluacin:


Enviar a ernestolopezmoreira@gmail.com un archivo comprimido de nombre
labGXGr_XX.zip (donde XX es el nmero de grupo), conteniendo un XPZ de nombre
labGXGrXX.XPZ con la solucin del laboratorio y un documento de nombre
labGXGrXX.doc con una descripcin breve de la solucin implementada. No est
permitido intercambiar objetos GeneXus entre los grupos y aquellos casos en los que
se detecten objetos copiados sern pasibles de sanciones.
La entrega debe realizarse hasta las 23:59 del da 23 de noviembre.

Referencias:
Search de GeneXus: http://www.gxtechnical.com/gxsearch
Wiki de GeneXus: http://www.gxtechnical.com/wiki/
Grupo google del curso: http://groups.google.com.uy/group/desarrollo-deaplicaciones-con-genexus-tecnologo/

Pgina 4

Prctico 1 Diseo de transacciones Curso Desarrollo de aplicaciones basadas en tecnologa GeneXus

Ejercicio 1
Se desea modelar un sistema para la administracin de las salas de la emergencia de un hospital. Al
ingresar un paciente a la emergencia se lo registra en el sistema. Cada paciente es identificado por el
nmero de paciente el cual es asignado en forma automtica por el sistema. Tambin se ingresan los
dos nombres y los dos apellidos (debiendo ingresar en forma obligatoria primer nombre y primer
apellido), cdula de identidad (nica para cada paciente) y fecha de nacimiento. El sistema registra la
fecha en la que se ingres al paciente y la fecha en que utiliz por ltima vez a la emergencia.
Lugo el paciente describe los sntomas que presenta y el usuario del sistema ingresa la descripcin en los
datos del paciente. nicamente se podr ingresar una descripcin por da para cada cliente. De esta
forma al momento de consultar los datos del paciente se vern las distintas visitas a la emergencia.
Finalmente hay que asignar al paciente una cama del hospital. Cada cama ser parte de una sala. Las
salas estn identificadas por una letra, se conoce la ubicacin dentro del Hospital (SUR, NORTE, ESTE,
OESTE), la cantidad total de camas, la cantidad de camas libres, fecha del ltimo mantenimiento. Luego
se ven las camas, cada una identificada por un nmero nico dentro de la sala. Se registra tambin la
fecha en la que fue ingresada en la sala, el estado, que puede ser OCUPADA o LIBRE. En caso de estar
ocupada se conoce tambin el paciente (y la descripcin de los sntomas) asignado a la cama.
Entonces, al ingresar un paciente, se toman los datos personales y de los sntomas presentados, se pasa
a la pantalla de mantenimiento de Salas y camas y se asigna una cama al paciente para que sea tratado
por los sntomas descriptos en el ingreso.

Crear un modelo Web en GeneXus


Realizar el diseo de las transacciones para el problema descripto, incluyendo las reglas,
formulas y eventos que considere necesarios.
Ejecutar la aplicacin con las reorganizaciones necesarias y verificar que el comportamiento es
el deseado.

Forma de entrega
El trabajo debe realizarse en forma individual y la entrega consiste en un archivo xpz de nombre
<Cedula>_<NombreApellido>.xpz con la resolucin del ejercicio 1.
El xpz debe enviarse a la casilla ernestolopezmoreira@gmail.com antes del da 15 de setiembre
(inclusive).

1) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles


Se ensamblan distintas marcas de autos (marca). Un Auto tiene una Marca. A su vez pueden haber muchos
autos de una marca
Determine el diseo de transacciones que considere correcto para representar dicha realidad.

a)

c)

Marca
{
MarcaId*
MarcaDescripcion
Auto
{
AutoId*
AutoDescripcion
}
}
Auto
{
AutoId *
AutoDescripcion
}

b)

Auto
{
AutoId *
AutoDescripcion
MarcaId
MarcaDescripcion
}

Marca
{
MarcaId *
MarcaDescripcion
AutoId
AutoDescripcion
}

Marca
{
MarcaId *
MarcaDescripcion
}

d) Ninguna de las anteriores

2) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles


Un Auto est compuesto por varios tipos de Piezas (PiezaTipo). Un tipo de pieza puede ser parte de muchos
autos.
Determine el diseo de transacciones que considere correcto para representar dicha realidad.

a)

c)

Auto
{
AutoId *
AutoDescripcion
PiezaTipoId
PiezaTipoDesc
}

PiezaTipo
{
PiezaTipoId *
PiezaTipoDesc
}

Auto
{
AutoId *
AutoDescripcion
}

PiezaTipo
{
PiezaTipoId *
AutoId*
PiezaTipoDesc
}

b)

Auto
{
AutoId*
AutoDescripcion
PiezaTipo
{
PiezaTipoId*
PiezaTipoDesc
}
}

PiezaTipo
{
PiezaTipoId *
PiezaTipoDesc
}

d) Ninguna de las anteriores

3) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles


Un Auto est compuesto por varias Piezas (Pieza). Ests piezas son utilizadas nicamente para esos Autos por lo
que no puede haber una Pieza que no est asociada a un Auto.
Determine el diseo de transacciones que considere correcto para representar dicha realidad.
Auto
{
AutoId *
AutoDescripcion
PiezaId
PiezaNombre
}

a)

c)

Pieza
{
PiezaId *
PiezaNombre
}

Auto
{
AutoId*
AutoDescripcion
Pieza
{
PiezaId*
PiezaNombre
}
}

b)

d)

Auto
{
AutoId*
AutoDescripcion
Pieza
{
PiezaId*
PiezaNombre
}
}

Pieza
{
PiezaId *
PiezaNombre
}

Pieza
{
PiezaId *
PiezaNombre
Auto
{
AutoId *
AutoDescripcion
}
}

Auto
{
AutoId *
AutoDescripcion
}

4) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


A partir del siguiente diseo de transacciones, determine la estructura fsica de las tablas que GeneXus crear.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

a)

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Fx EnvioTotal
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

Envio
EnvioId *
EnvioFecha
EnvioTotal

Sum(AutoPrecio)

EnvioAuto
EnvioId *
AutoId *
AutoDescripcion
AutoPrecio

b)

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
EnvioId *
EnvioFecha
AutomotoraId

c)

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
EnvioId *
EnvioFecha
AutomotoraId
AutomotoraNom

EnvioAuto
EnvioId *
AutoId *

EnvioAuto
EnvioId *
AutoId *

d) Ninguna de las anteriores


5) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
Dado el siguiente diseo de transacciones, determine la tabla extendida de la tabla Envo.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a)
b)
c)
d)

No posee tabla extendida


{Envo, EnvioAuto}
{Envo, Automotora}
{Envo, Automotora, EnvioAuto,Auto }

6) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


Dado el siguiente diagrama de Bachman, determine la tabla extendida de EnvioAuto.

Envo
Automotora
EnvioAuto

Auto

a)
b)
c)
d)

No posee tabla extendida


{Envo, EnvioAuto}
{Envo, Automotora}
{Envo, Automotora, EnvioAuto,Auto }

7) 2 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Auto para registrar los automviles que son ensamblados. De los autos es
necesario registrar el pas de origen del constructor y el pas de origen de los repuestos.
Determine el diseo de transacciones que considere correcto.

a)

Auto
{
AutoId*
AutoDescripcion
ContructorPaisId
ContructorPaisNombre
RepuestoPaisId
RepuestoPaisNombre
}

Pais
{
PaisId*
PaisNombre
}

Subtype group: ConstructorPaisId


ContructorPaisId subtype or PaisId
Subtype group: ConstructorPaisNombre
ContructorPaisNombre subtype of PaisNombre
Subtype group: RepuestoPaisId
RepuestoPaisId subtype or PaisId
Subtype group: RepuestoPaisNombre
RepuestoPaisNombre subtype of PaisNombre

b)

Auto
{
AutoId*
AutoDescripcion
ContructorPaisId
ContructorPaisNombre
RepuestoPaisId
RepuestoPaisNombre
}
Auto
{
AutoId*
AutoDescripcion
PaisId
PaisNombre
RepuestoPaisId
RepuestoPaisNombre
}

Pais
{
PaisId*
PaisNombre
}

Subtype group: ConstructorPais


ContructorPaisId subtype or PaisId
ContructorPaisNombre subtype of PaisNombre

c)

d)

Subtype group: RepuestoPais


RepuestoPaisId subtype or PaisId
RepuestoPaisNombre subtype of PaisNombre

Pais
{
PaisId*
PaisNombre
}

Ninguna de las anteriores

8) 4 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


Dado el siguiente diseo de transacciones. Suponga que existe un nico Pas ingresado en la base con PaisId = 4.
Indique que sucede si se intenta ingresar una nueva Marca con PaisId = 9.
Marca
{
MarcaId *
MarcaDescripcion
PaisId
PaisNombre
}

Pais
{
PaisId *
PaisNombre
}

a) Se ingresa la nueva marca y


automticamente crea el pas 9 con Nombre
de pas vaco.
b) GeneXus verifica que exista el pas 9 en la
tabla Pas. Como no existe emite un
mensaje de error y no se ingresa la nueva
marca.
c) Se ingresa la nueva marca sin un pas
asociado.
d) Ninguna de las anteriores

9) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. La hora del
envo (EnvoHora) debe asignarse en el momento exacto en el que se ingresa el envo. Se declara entonces la
siguiente regla en la transaccin Envo, determine la opcin correcta:
EnvioHora = now() if insert on BeforeComplete
Envio
{
EnvioId*
EnvioFecha
EnvioHora
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a) La regla est bien declarada porque al ejecutarse antes del


COMMIT y solo en modo INSERT la hora se guarda con el valor
deseado.
b) La regla est mal declarada porque si bien se ejecuta antes de
COMMIT el registro del cabezal ya fue grabado en la base de
datos.
c) La regla est mal declarada porque se ejecuta una vez para cada
registro del segundo nivel.
d) Ninguna de las anteriores.

10) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Se quiere
que al trabajar con cada lnea del detalle del envo (EnvioAuto), ya sea alta, baja o modificacin, se ejecute el
procedimiento logEnvio que recibe como parmetro el identificador del envo.
Envio
{
EnvioId*
EnvioFecha
EnvioHora
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a) logEnvio.call(EnvioId) ;
b) logEnvio.call(EnvioId) on AfterComplete;
c) logEnvio.call(EnvioId) on AfterValidate;
.
d) logEnvio.call(EnvioId) on AfterValidate level AutoId;

11) 7 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Se necesita
emitir un listado de los envos por automotora. Se listaran solo aquellas automotoras para lasque hayan envos.
Determine cual es la implementacin correcta.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

c)

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

For each
Print --- (AutomotoraId, AutomotoraNom)
For each AutomotoraId
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

a)

For each
Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

b)

For each order AutomotoraId


Defined by EnvioFecha
Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

d)

For each order AutomotoraId


Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

12) 7 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Dado el
siguiente diseo de transacciones determine las tablas bases de los for each que aparecen a continuacin.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

a)
b)
c)
d)

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

For each
Print --- (EnvioId, EnvioFecha)
For each
Print --- (AutoId, AutoDescripcion)
Endfor
Endfor

For each Externo {ENVIO}, for each interno {ENVIOAUTO}


For each Externo {ENVIO}, for each interno {AUTO}
For each Externo {ENVIOAUTO}, for each interno {ENVIOAUTO}
For each Externo {ENVIO }, for each interno {ENVIO}

13) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Dado el
siguiente diseo de transacciones determine qu tipo de for each es el siguiente:
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

For each
Print --- (EnvioId, EnvioFecha)
For each
Print --- (AutomotoraId, AutomotoraNom)
Endfor
Endfor

a)
b)
c)
d)

JOIN
Producto cartesiano
Corte de control
Ninguna de las anteriores

14) 3 pts. Determine cul de las siguientes afirmaciones sobre Data Providers es correcta.

a) El Data Provider es un objeto que me permite procesar datos para obtener informacin en forma
estructurada (SDTs, bussines component, ext.).
b) El Data Provider es un objeto utilizado para actualizar la base de datos.
c) Ninguna de las anteriores es correcta.

15) 3 pts. Determine cul de las siguientes afirmaciones sobre Business component (BC) es correcta

a) Un objeto BC permite invocar una transaccin desde cdigo GeneXus como si esta estuviese
siendo ejecutada desde su Web Form.
b) A travs de un BC se puede actualizar la base de datos desde un Web Panel
c) Al llamar un BC, este no hace COMMIT sobre la base de datos y queda a cargo del programador
la confirmacin de los datos en la base de datos.
d) Todas las anteriores son correctas.

16) 6 pts. Se tiene un Web Panel SIN TABLA BASE con una grilla para listar todos los Autos que existen en el sistema.
Si se sabe que en la tabla autos existen 50 autos ingresados. Cuntas veces se ejecuta el evento load de la
grilla?

a)
b)
c)
d)

1 vez
50 veces
Ninguna vez
10 Veces

17) 8 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles. La misma cuenta con la
transaccin Envo para registrar los envos despachados a las automotoras. La transaccin Automotora, que se
utiliza para mantener las automotoras a las cuales la ensambladora realiza los envos, tiene el atributo
AutomotoraEsPref para identificar aquellas que son clientes preferenciales de la ensambladora. Se quiere
construir un Web Panel que liste todos los envos del sistema mostrando en una columna el texto
PREFERENCIAL para aquellos envos a automotoras que son clientes preferenciales y el texto CLIENTE COMUN
para aquellas que no. Determine la opcin de implementacin que considere correcta.
Automotora
{
AutomotoraId *
AutomotoraNom
AutomotoraEsPref
}

a)

b)

c)

d) Ninguna de las anteriores

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
AutomotoraEsPref
}

1) 2 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Auto para registrar los automviles que son ensamblados. De los autos es
necesario registrar el pas de origen del constructor y el pas de origen de los repuestos.
Determine el diseo de transacciones que considere correcto.

a)

Auto
{
AutoId*
AutoDescripcion
ContructorPaisId
ContructorPaisNombre
RepuestoPaisId
RepuestoPaisNombre
}

Pais
{
PaisId*
PaisNombre
}

b)

Auto
{
AutoId*
AutoDescripcion
PaisId
PaisNombre
RepuestoPaisId
RepuestoPaisNombre
}

Pais
{
PaisId*
PaisNombre
}

c)

Auto
{
AutoId*
AutoDescripcion
ContructorPaisId
ContructorPaisNombre
RepuestoPaisId
RepuestoPaisNombre
}

Pais
{
PaisId*
PaisNombre
}

d)

Subtype group: ConstructorPaisId


ContructorPaisId subtype or PaisId
Subtype group: ConstructorPaisNombre
ContructorPaisNombre subtype of PaisNombre
Subtype group: RepuestoPaisId
RepuestoPaisId subtype or PaisId
Subtype group: RepuestoPaisNombre
RepuestoPaisNombre subtype of PaisNombre

Subtype group: ConstructorPais


ContructorPaisId subtype or PaisId
ContructorPaisNombre subtype of PaisNombre
Subtype group: RepuestoPais
RepuestoPaisId subtype or PaisId
RepuestoPaisNombre subtype of PaisNombre

Ninguna de las anteriores

2) 4 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


Dado el siguiente diseo de transacciones. Suponga que existe un nico Pas ingresado en la base con PaisId = 4.
Indique que sucede si se intenta ingresar una nueva Marca con PaisId = 9.
Marca
{
MarcaId *
MarcaDescripcion
PaisId
PaisNombre
}

Pais
{
PaisId *
PaisNombre
}

a) GeneXus verifica que exista el pas 9 en la


tabla Pas. Como no existe emite un
mensaje de error y no se ingresa la nueva
marca.
b) Se ingresa la nueva marca sin un pas
asociado.
c) Se ingresa la nueva marca y
automticamente crea el pas 9 con Nombre
de pas vaco.
d) Ninguna de las anteriores

3) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. La hora del
envo (EnvoHora) debe asignarse en el momento exacto en el que se ingresa el envo. Se declara entonces la
siguiente regla en la transaccin Envo, determine la opcin correcta:
EnvioHora = now() if insert on BeforeComplete
Envio
{
EnvioId*
EnvioFecha
EnvioHora
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a) La regla est bien declarada porque al ejecutarse antes del


COMMIT y solo en modo INSERT la hora se guarda con el valor
deseado.
b) La regla est mal declarada porque se ejecuta una vez para cada
registro del segundo nivel.
c) La regla est mal declarada porque si bien se ejecuta antes de
COMMIT el registro del cabezal ya fue grabado en la base de
datos.
d) Ninguna de las anteriores.

4) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Se quiere
que al trabajar con cada lnea del detalle del envo (EnvioAuto), ya sea alta, baja o modificacin, se ejecute el
procedimiento logEnvio que recibe como parmetro el identificador del envo.
Envio
{
EnvioId*
EnvioFecha
EnvioHora
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a) logEnvio.call(EnvioId) ;
b) logEnvio.call(EnvioId) on AfterValidate;
c) logEnvio.call(EnvioId) on AfterComplete;
d) logEnvio.call(EnvioId) on AfterValidate level AutoId;

5) 7 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Se necesita
emitir un listado de los envos por automotora. Se listaran solo aquellas automotoras para lasque hayan envos.
Determine cual es la implementacin correcta.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

c)

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

For each order AutomotoraId


Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

a)

b)

d)

For each order AutomotoraId


Defined by EnvioFecha
Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

For each
Print --- (AutomotoraId, AutomotoraNom)
For each
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

For each
Print --- (AutomotoraId, AutomotoraNom)
For each AutomotoraId
Print --- (EnvioId, EnvioFecha)
Endfor
Endfor

6) 7 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Dado el
siguiente diseo de transacciones determine las tablas bases de los for each que aparecen a continuacin.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

a)
b)
c)
d)

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

For each
Print --- (EnvioId, EnvioFecha)
For each
Print --- (AutoId, AutoDescripcion)
Endfor
Endfor

For each Externo {ENVIO}, for each interno {AUTO}


For each Externo {ENVIO}, for each interno {ENVIOAUTO}
For each Externo {ENVIO}, for each interno {ENVIO}
For each Externo {ENVIOAUTO }, for each interno {ENVIOAUTO}

7) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.


La misma cuenta con la transaccin Envo para registrar los envos despachados a las automotoras. Dado el
siguiente diseo de transacciones determine qu tipo de for each es el siguiente:
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

For each
Print --- (EnvioId, EnvioFecha)
For each
Print --- (AutomotoraId, AutomotoraNom)
Endfor
Endfor

a)
b)
c)
d)

Producto cartesiano
Corte de control
JOIN
Ninguna de las anteriores

8) 3 pts. Determine cul de las siguientes afirmaciones sobre Data Providers es correcta.

a) El Data Provider es un objeto que me permite procesar datos para obtener informacin en forma
estructurada (SDTs, bussines component, ext.).
b) El Data Provider es un objeto utilizado para actualizar la base de datos.
c) Ninguna de las anteriores es correcta.

9) 3 pts. Determine cul de las siguientes afirmaciones sobre Business component (BC) es correcta

a) Un objeto BC permite invocar una transaccin desde cdigo GeneXus como si esta estuviese
siendo ejecutada desde su Web Form.
b) A travs de un BC se puede actualizar la base de datos desde un Web Panel
c) Al llamar un BC, este no hace COMMIT sobre la base de datos y queda a cargo del programador
la confirmacin de los datos en la base de datos.
d) Todas las anteriores son correctas.

10) 6 pts. Se tiene un Web Panel SIN TABLA BASE con una grilla para listar todos los Autos que existen en el sistema.
Si se sabe que en la tabla autos existen 50 autos ingresados. Cuntas veces se ejecuta el evento load de la
grilla?

a)
b)
c)
d)

1 vez
10 Veces
50 veces
Ninguna vez

11) 8 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles. La misma cuenta con la
transaccin Envo para registrar los envos despachados a las automotoras. La transaccin Automotora, que se
utiliza para mantener las automotoras a las cuales la ensambladora realiza los envos, tiene el atributo
AutomotoraEsPref para identificar aquellas que son clientes preferenciales de la ensambladora. Se quiere
construir un Web Panel que liste todos los envos del sistema mostrando en una columna el texto
PREFERENCIAL para aquellos envos a automotoras que son clientes preferenciales y el texto CLIENTE COMUN
para aquellas que no. Determine la opcin de implementacin que considere correcta.
Automotora
{
AutomotoraId *
AutomotoraNom
AutomotoraEsPref
}

a)

b)

c)

d) Ninguna de las anteriores

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
AutomotoraEsPref
}

12) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles
Se ensamblan distintas marcas de autos (marca). Un Auto tiene una Marca. A su vez pueden haber muchos
autos de una marca
Determine el diseo de transacciones que considere correcto para representar dicha realidad.

a)

c)

Marca
{
MarcaId*
MarcaDescripcion
Auto
{
AutoId*
AutoDescripcion
}
}
Auto
{
AutoId *
AutoDescripcion
MarcaId
MarcaDescripcion
}

b)

Auto
{
AutoId *
AutoDescripcion
}

Marca
{
MarcaId *
MarcaDescripcion
}

Marca
{
MarcaId *
MarcaDescripcion
AutoId
AutoDescripcion
}

d) Ninguna de las anteriores

13) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles
Un Auto est compuesto por varios tipos de Piezas (PiezaTipo). Un tipo de pieza puede ser parte de muchos
autos.
Determine el diseo de transacciones que considere correcto para representar dicha realidad.

a)

c)

Auto
{
AutoId *
AutoDescripcion
}

PiezaTipo
{
PiezaTipoId *
AutoId*
PiezaTipoDesc
}

Auto
{
AutoId *
AutoDescripcion
PiezaTipoId
PiezaTipoDesc
}

PiezaTipo
{
PiezaTipoId *
PiezaTipoDesc
}

b)

Auto
{
AutoId*
AutoDescripcion
PiezaTipo
{
PiezaTipoId*
PiezaTipoDesc
}
}

PiezaTipo
{
PiezaTipoId *
PiezaTipoDesc
}

d) Ninguna de las anteriores

14) 10 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles
Un Auto est compuesto por varias Piezas (Pieza). Ests piezas son utilizadas nicamente para esos Autos por lo
que no puede haber una Pieza que no est asociada a un Auto.
Determine el diseo de transacciones que considere correcto para representar dicha realidad.
Auto
{
AutoId *
AutoDescripcion
PiezaId
PiezaNombre
}

a)

c)

Pieza
{
PiezaId *
PiezaNombre
}

Auto
{
AutoId*
AutoDescripcion
Pieza
{
PiezaId*
PiezaNombre
}
}

Pieza
{
PiezaId *
PiezaNombre
}

b)

Pieza
{
PiezaId *
PiezaNombre
Auto
{
AutoId *
AutoDescripcion
}
}

d)

Auto
{
AutoId *
AutoDescripcion
}

Auto
{
AutoId*
AutoDescripcion
Pieza
{
PiezaId*
PiezaNombre
}
}

15) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
A partir del siguiente diseo de transacciones, determine la estructura fsica de las tablas que GeneXus crear.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

a)

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Fx EnvioTotal
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

Envio
EnvioId *
EnvioFecha
EnvioTotal

Sum(AutoPrecio)

EnvioAuto
EnvioId *
AutoId *
AutoDescripcion
AutoPrecio

b)

c)

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
EnvioId *
EnvioFecha
AutomotoraId
AutomotoraNom

Automotora
AutomotoraId *
AutomotoraNom

Auto
AutoId *
AutoDescripcion
AutoPrecio

Envio
EnvioId *
EnvioFecha
AutomotoraId

EnvioAuto
EnvioId *
AutoId *

EnvioAuto
EnvioId *
AutoId *

d) Ninguna de las anteriores


16) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
Dado el siguiente diseo de transacciones, determine la tabla extendida de la tabla Envo.
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}

Automotora
{
AutomotoraId*
AutomotoraNom
}

Envio
{
EnvioId*
EnvioFecha
AutomotoraId
AutomotoraNom
Auto
{
AutoId *
AutoDescripcion
AutoPrecio
}
}

a)
b)
c)
d)

No posee tabla extendida


{Envo, EnvioAuto}
{ Envo, Automotora, EnvioAuto,Auto }
{ Envo, Automotora}

17) 5 pts. Se tiene una aplicacin GeneXus para una ensambladora de Automviles.
Dado el siguiente diagrama de Bachman, determine la tabla extendida de EnvioAuto.

Envo
Automotora
EnvioAuto

Auto

a)
b)
c)
d)

No posee tabla extendida


{ Envo, Automotora, EnvioAuto,Auto }
{Envo, Automotora}
{ Envo, EnvioAuto}