Está en la página 1de 177

2

GeneXus X Episodio Uno


Cecilia Fernndez Daniel Mrquez Lisboa
Diseo de tapa: Fiorella Franzini
Aporte artstico: Mara Ins Carriquiry

Prlogo a la 2da. Edicin


Todo el equipo de Artech ha trabajado mucho en la versin X de GeneXus.
sta no es, simplemente, una versin ms: representa un gran salto adelante en
muchos aspectos y, muy especialmente, en su capacidad de integracin y de
extensin, ya sea por Artech o por la propia Comunidad GeneXus.
La Comunidad GeneXus ha participado entusiastamente en las pruebas de
las versiones CTP y est adoptando la primera versin liberada del producto,
utilizndolo y, en muchos casos, construyendo extensiones. En el XIX
Encuentro esperamos la exposicin de muchas experiencias importantes.
En el ao 2007 hemos encomendado a Daniel Mrquez Lisboa (autor de
GeneXus, Desarrollo Basado en el Conocimiento Gua Prctica editado por
Magr en el 2006) y a Cecilia Fernndez, con una muy buena experiencia como
instructora en nuestros cursos, un libro introductorio sobre la Versin Rocha de
GeneXus. Ahora que la versin X es una importante realidad, hemos pedido a
Daniel y Cecilia una segunda edicin del libro, actualizando aquella historia,
contada sobre la marcha del desarrollo de la versin, a la realidad actual donde
la versin X est en plena produccin.
Deca entonces: No niego que, en una primera instancia, me sorprendi el
tono informal del libro. Luego de leerlo cuidadosamente, veo que el tono
informal es un acierto ms de los mltiples que han tenido los autores: dos
aos despus ratifico aquellas palabras.
Espero una muy buena acogida de esta segunda edicin del libro que,
acompasndose con los tiempos y la tecnologa, se puede obtener libremente en
www.genexus.com/genexus/libroepisodio1ed2 y, desde ya, felicito a los
autores por su trabajo y les deseo el mayor de los xitos.

Ing. Breogn Gonda


Presidente de Artech
4

Estimado lector
Para el XVII Evento Internacional de Usuarios GeneXus, realizado en
setiembre de 2007, nos pidieron escribir un libro de gil y amena lectura sobre
la versin de GeneXus que se encontraba en plena gestacin: la entonces
denominada versin Rocha, hoy la X, una verdadera refundacin del producto.
Desde ese entonces la X ha crecido mejorando funcionalidades e
incorporando algunas otras. Por esa razn, sentimos la necesidad de adaptar
aquella primera edicin de nuestro libro GeneXus Rocha Episodio Uno
para que siga cumpliendo con su objetivo inicial: mostrar GeneXus a quien,
nuevo en esta herramienta, tenga inquietud o deseos de descubrirla, as como a
quien, conocedor de versiones anteriores, quiera redescubrirla en esta nueva y
fundamental etapa que inicia.
He aqu entonces la segunda edicin actualizada de aquel libro. Fue
elaborada con GeneXus X, upgrade 4. Actualmente, Artech se encuentra
trabajando para liberar en unos meses ms GeneXus X Evolution 1, que incluye
nuevas e importantes funcionalidades, como el permitir generar, adems de
aplicaciones Web, aplicaciones Win.
Esperamos que pueda ir siguiendo las pginas de este libro con el mismo
entusiasmo que nos llev a escribirlas, y que pueda adaptar la lectura a sus
ganas y necesidades. Hay captulos ms tcnicos que otros, en especial el 3 que
trata sobre Patterns. No pudimos ceder ante la tentacin de mostrar toda su
potencia, lo que nos llev a desnudar cada vez un poquito ms. Quien quiera
mucho, lo leer todo, quien no, lo leer ms superficialmente. Tmese esa
libertad, que fue la que nos permiti dar rienda suelta a nuestras ganas de
contar. Los ltimos captulos probablemente sean los ms giles y disfrutables.
Para entender ms cabalmente lo explicado, sugerimos ir realizando con la
versin Trial de GeneXus, de distribucin gratuita (www.genexus.com/trial), la
aplicacin que nuestros personajes irn desarrollando a lo largo del libro. Si
bien podr elegir el generador y DBMS que prefiera, si es usted nuevo en
GeneXus, le recomendamos elegir los default que son lo que utilizarn nuestros

personajes en el libro. Encontrar en nuestro Download Center,


www.gxtechnical.com/genexus/libroepisodio1ed2/zip para ser descargado en
forma gratuita, un zip con el contenido final del proyecto desarrollado. Podr
crearse otro proyecto (KB) e importarlo. Le servir para comparar lo que va
haciendo, con la aplicacin ya implementada.
Encontrar repetidamente en este texto citas a un whitepaper de Breogn
Gonda y Nicols Jodal, Desarrollo basado en conocimiento. Filosofa y
fundamentos tericos de GeneXus, publicado en mayo de 2007.
Por ltimo, volvemos a agradecer a todos los compaeros que en
oportunidad de la primera edicin estuvieron de un modo u otro aportando a
este trabajo. A todos: gracias!
Mary, Diego, Mike y Julia, esperan ansiosos entrar en escena
Buena lectura!

Los autores.
Montevideo, Mayo de 2009.

Sinopsis
Captulo 1: El encuentro. Diego y Mary se reencuentran luego de aos sin
verse, dando inicio a esta historia de encuentroscon GeneXus.
Captulo 2: rase una vezun Proyecto. Julia, Mike y Diego definen e
inician el anlisis y desarrollo del sistema para una agencia de viajes, a la vez
que Diego acompaa a Mary, caf mediante, en su primera experiencia de
acercamiento al IDE y a la creacin de los primeros objetos del proyecto.
Captulo 3: Hecho a mquina, configurado a mano. Mientras Julia va
haciendo uso de lo mximo en capacidad de productividad gracias a los
patterns, Diego da rienda suelta a su creatividad poniendo de manifiesto que
los deseos de los clientes no siempre deben ser un duro escollo a sortear.
Captulo 4: Vuelo al mundo de los Subtipos. A velocidad match 3, Diego
ensea a Mary, esta vez en su oficina y no en el bar, por qu los subtipos son la
solucin ideal al problema de las ambigedades que se pueden presentar en un
modelo de datos, mientras pone el punto final a las ltimas transacciones.
Captulo 5: Cuando el qu no alcanza. El inters de Mary pareca ir in
crescendo. Encuentros frecuentes en la oficina o en el bar. Preguntas todava
sin respuesta. Las transacciones permiten declarar, pero qu pasa con los
procesos batch? Procedimientos GeneXus. Despus, ms declaraciones:
Business Components. Y cmo realizar reportes pdf? Atracciones que invitan.
Invitaciones que atraen. Una cena en ciernes Y las consultas dinmicas por
ejemplo?
Captulo 6: Ms declaraciones. Data Providers para permitir cargar y
devolver una salida estructurada, sin programar, sino declarando intenciones.
Diego declara sus intenciones. Debe enviar un xml a la aerolnea.
Captulo 7: Soplan nuevos vientos. Su casa (la de ella), vino, msica, su
nerviosismo (el de l) y ms GeneXus. Sabemos que todo tiene un final, pero lo
que Diego apenas sospechaba, era que esto poda llegar a ser el principio de
algo ms.

Captulo 1

El encuentro
Alguien cuenta que esperando por fin ser atendido en un banco, escuch
casualmente una conversacin entre un hombre y una mujer, que tambin
esperaban. Segn pareca, se reencontraban luego de aos sin verse; antiguos
compaeros de estudio?
Cmo ests Mary? Cmo van tus cosas? Sigues trabajando donde
siempre?dijo el hombre con voz profunda, impostada, mirada fija, aire
seductor.
Bueno Diego, luego de tantos aos trabajando en la empresa, logr
ascender y ahora soy Developer Team Manager desde hace ya dos aos dijo
la mujer de rostro sensiblemente cansado.
Supongo que debo felicitarte, pero por qu esa cara? tienes
problemas en el departamento? He escuchado que los sistemas de ustedes,
adems de ser de gran porte, son fiables
Lo son, pero no sabes lo que cuesta su mantenimiento. Me estoy
enfermando, Diego, no duermo bien; muchas responsabilidades, grandes cargas
horarias, poco descanso. Siento en el pecho
una presin complet Diego Entiendo, Mary dijo al tiempo
que depositaba su mano derecha sobre el brazo izquierdo de ella-. Cmo estn
trabajando? Qu herramientas estn usando?
Y de todo un poco, lo usual al final todo es lo mismo contest
Mary ajena a esa cercana- Tengo un equipo importante de personas trabajando
en los desarrollos y mantenimientos, pero an as no damos abasto.
Bueno, no todo es lo mismo Qu te parece si terminamos este
trmite aqu y vamos a tomar un caf y me sigues contando? pregunt Diego a
la vez contento y turbado.

GeneXus?
Ya en el bar, caf mediante, Diego escuchaba atentamente a una Mary
angustiada. Recordaba su antigua firmeza, su empuje. Senta un egosta dejo de
alegra de poder ser ahora l quien la ayudara.
En cuntos proyectos estn? pregunt Diego para instaurar un
clima confesional.
Ahora en uno solo. Pero es ms que nada en tareas de mantenimiento.
Nuestros clientes nos estn solicitando cosas nuevas todo el tiempo, pero nos
est siendo imposible satisfacer nuevos requerimientos. Adems, esta tarea de
mantenimiento es realmente costosa, y ya no puedo justificar a la Direccin la
incorporacin de ms recursos humanos; nos saldramos del punto de
equilibrio.
No ser que los sistemas estn un poco anticuados, tecnolgicamente
hablando? No les convendra hacer una reingeniera de todo a nuevo?
pregunt Diego con liviandad.
S, eso quisiera, y eso he propuesto. Pero los tiempos realmente no nos
dan, y como te dije, puede que estemos ya pasados de costos. No s qu voy a
hacer estoy agotada Diego, me siento en un callejn sin salida.
Mary, no desesperes, sabes cuntos estn como t? Tu caso es uno
ms entre muchos. Las aplicaciones son cada vez ms complejas, y con las
herramientas manuales de las que disponamos, se est tornando imposible
desarrollar y peor an, mantener esos sistemas, pues se estn volviendo
inmanejables. Pero no todo es negro, Mary. Hoy en da hay soluciones. La
alternativa es delegar en procesos automticos el trabajo que hacemos los
humanos, de manera que podamos dedicarnos a las nuevas complejidades y no
a tareas como la codificacin que pueden ser efectuadas por un programa.
Nosotros, sin ir ms lejos, estamos llevando adelante varios proyectos
importantes en simultneo, y no tenemos demasiados inconvenientes. Conoces
algo de GeneXus?
Ah, GeneXus. S, algo he escuchado, pero no he tenido tiempo de
interiorizarme demasiado Ustedes trabajan con esa herramienta? He odo
10

que cada vez ms gente no tcnica puede usarla, lo que me despierta cierta
curiosidad.
Mira Mary, no s si GeneXus sea la panacea, pero s s que cura
varias de las dolencias que tienen empresas como la tuya. Es un programa que
hace programas. Automatiza la construccin y mantenimiento de tus
aplicaciones y de tu base de datos. Obviamente est en un nivel de abstraccin
superior a otras herramientas, comprendes? Contstame a esta pregunta: si t
pudieras disponer de un software que te permitiera lograr hacer esto
automticamente, lo usaras?
Absolutamente... Se incorpor en su silla. S, justamente se es
nuestro problema. Tenemos que hacer casi todo a mano
La gran dificultad de la empresa de Mary, pens Diego, era el de tantas
otras: imposibilidad de enfrentar nuevos proyectos porque los tiempos de
mantenimiento de los sistemas actuales, fundamentados en metodologas
tradicionales, lo impedan. Y eso, para una empresa que vive del desarrollo, es
una luz roja de peligro.
Bueno, no lo diga en voz alta, pero usted, estimado lector, se estar
preguntando: Cmo?
Cmo? pregunt ya ms vital.
No te parece razonable pensar que dado un conjunto de visiones de
datos, - se interrumpi Diego con cierta malicia - exista un nico modelo
relacional mnimo que lo satisfaga?
Hmmm puede ser, no estoy segura. Pero qu tiene esto que ver con
mis problemas de mantenimiento?
Y si eso es cierto continu Diego, ignorando la vacilacin de su
compaera- no te parece posible encontrar un procedimiento de ingeniera
inversa que partiendo de ese conjunto de visiones d como resultado el
esquema de esa base de datos relacional mnima? Bueno, si me vas a decir ver
para creer, con gusto acepto una apuesta, como en los viejos tiempos; pero
desde ya te adelanto: vas a perder.

11

Una Apuesta
El objetivo de GeneXus es (a travs de la descripcin de las visiones de los
usuarios) conseguir un muy buen tratamiento automtico del conocimiento de los
sistemas de negocios..
Breogn Gonda & Nicols Jodal

GeneXus es una herramienta que parte de las visiones de los usuarios;


captura su conocimiento y lo sistematiza en una base de conocimiento. A
partir de esta ltima, GeneXus es capaz de disear, generar y mantener de
manera totalmente automtica la estructura de la base de datos y los programas
de la aplicacin, es decir, los programas necesarios para que los usuarios
puedan operar con sus visiones.

GeneXus trabaja con conocimiento puro, cuya validez es totalmente independiente


de las tecnologas de moda.

Mary, GeneXus almacena en una Knowledge Base todos los


elementos necesarios para construir la aplicacin, y luego la utiliza para el
desarrollo del sistema, construyendo automticamente el modelo de datos en
12

forma normalizada, y tambin utilizando el lenguaje de programacin y base de


datos que se le indique. As que te permite obtener un proyecto con el
conocimiento de la empresa
Ah! Entonces eso
S le interrumpi Diego completando la idea-, te permite ganar algo
muy importante: la portabilidad futura de la aplicacin. Todo ese conocimiento
-reglas de negocio, dilogos, controles, listados- que hoy estn en un lenguaje
de programacin determinado, pueden ser convertidos a otros lenguajes sin
necesidad de arrancar de cero. O sea que se reutiliza el conocimiento porque la
Knowledge Base es conocimiento independiente de la plataforma.
Mary parpade rpidamente un par de veces y, sin mediar palabra alguna,
pidi otra ronda de caf.

Base de Conocimiento y Modelos Externo y Relacional


Nuestros personajes continuaron su conversacin en el caf. A esas alturas,
Mary ya se mostraba particularmente interesada en esa herramienta, y Diego
en...
Bueno, por un lado est el Modelo Relacional, que como bien sabes,
est orientado a obtener una buena representacin de los datos en una Base de
Datos, obedeciendo a algunas condicionantes muy deseables.
Cierto asegur ella . Eliminar las redundancias e introducir un
pequeo conjunto de reglas para evitar las mayores fuentes de inconsistencia de
los datos
Eso mismo, reglas que chequean la unicidad y la integridad referencial
y adems tambin proveen de un conjunto de operadores para poder manipular
los datos a buen nivel acot Diego, alegre por el clima de complicidad
generado.
S, claro, por eso todo el mundo las usa. GeneXus no las usa?
Bueno, s, ya voy a llegar a eso. Te acuerdas tambin del Modelo
Externo, aquel donde se representaban las visiones externas? Bueno, GeneXus

13

pone el nfasis en este modelo, porque es donde realmente est el conocimiento


genuino, es el realmente importante para los usuarios y los desarrolladores. En
l se recoge el conocimiento exterior y todo lo dems, como otros modelos
auxiliares que pudieran ayudar, puede inferirse automticamente a partir de ese
Modelo Externo.
Ahel Modelo Externono puede contener ningn elemento fsico o
interno como archivos, tablas, entidades, relaciones entre entidades, ndices
verdad?
Exacto! O cualquier otro que se pueda inferir automticamente
exclam Diego animado, recuperando el entusiasmo que siempre le provocaron
las conversaciones con Mary El Modelo Externo ser utilizado para obtener y
almacenar el conocimiento. Pretende la representacin ms directa y objetiva
posible de la realidad.
Claro, y con eso te independizas de la implementacin, porque tienes
una descripcin del sistema en alto nivel, descripcin que slo cambiar si
cambian las visiones sobre el mismo; voy bien?
Perfecto! Por
ello tomamos las visiones
de
los
diferentes
usuarios Visiones que
son almacenadas en el
modelo. Luego se captura
todo el conocimiento
contenido en ellas y se lo
sistematiza para maximizar las capacidades de inferencia
Eso es lo que no termino de creer. Me suena a pura teora t
intentas decirme que es posible slo describir y que un programa, con slo un
par de pases de varita mgica te haga realidad la aplicacin? pregunt Mary
intentando ser convencida por los razonamientos apasionados de Diego.
Bueno, yo no dira que es magia. Es un software al fin de cuentas. Y
no digo que no tengas que programar algo, pero s digo que casi nada, lo

14

menos posible. En GeneXus vas a tener algn cdigo que ser procedural, pero
el lenguaje en que lo escribes, no es el lenguaje al que ests acostumbrada en
l tampoco tienes que nombrar tablas, ni ndices, ni nada de lo fsico de una
base de datos.
Pero no entiendo entonces dnde entra el Modelo Relacional
pregunt Mary confundida.
Es el que se utiliza para representar y manipular los datos: es el
modelo interno o fsico, pero no ser creado por ti, ser inferido por GeneXus
con su procedimiento de ingeniera inversa. Mi apuesta fue tramposa.
Y cmo describes las visiones de los usuarios, el Modelo Externo, de
manera que pueda aplicarse ingeniera inversa sobre ellas y obtener todo eso
que dices? Porque tiene que ser lo bastante formal y rigurosa esa descripcin
como para que no haya ambigedades y que un programa pueda inferir todo
eso que los programadores hacemos todava a mano.
S, lo es. Las descripciones se realizan a travs de determinados
objetos-tipo de GeneXus que indican el qu. A travs de ellos, GeneXus
encuentra el cmo. Por lo que, para aprender a usar GeneXus, tienes que
aprender a describir, a usar esos objetos-tipo. No necesitas grandes
conocimientos tcnicos; cada vez menos.
Diego continuaba hablando, llenando el reducido silencio que su
interlocutora haba dejado. A pesar de tantos aos sin verse, conoca bien a
Mary, conoca esa expresin de ojos pensativos, y saba que su silencio lo
invitaba a proseguir. No poda tener mejor suerte - Bendito GeneXus! - pens,
y continu en tono confidente, manejando las pausas, seguro de lograr los
efectos buscados.

15

Para lograr todo esto,


GeneXus tiene una base de
conocimiento,
que
inicialmente tiene asociado un
conjunto de mecanismos de
inferencia y algunas reglas de
aplicacin general, como las
que aseguran la consistencia
(las de integridad referencial, por ejemplo). Luego, cuando el analista GeneXus
comienza a describir la realidad creando objetos, estas descripciones (el
Modelo Externo) son sistematizadas automticamente y pasan a estar
contenidas en la base de conocimiento Adems, sobre ese conocimiento,
obtiene un conjunto de resultados que le ayudan a mejorar la eficiencia de las
inferencias posteriores.
Es una mquina de inferencias! exclam Mary.
Nada ms cierto. Por ejemplo, dada una visin de los datos, puede
inferir automticamente el programa necesario para manipularla.

GeneXus trabaja permanentemente sobre la Knowledge Base. Todo el


conocimiento de la Knowledge Base es equivalente al contenido del Modelo Externo
(subconjunto de ella), ya que consiste en el propio Modelo Externo ms reglas y
mecanismos de inferencia independientes de l y un conjunto de otros elementos que
son automticamente inferidos a partir del mismo.
El desarrollador puede alterar, modificando objetos de la realidad del usuario, el
Modelo Externo y las modificaciones se propagarn automticamente a todos los
elementos que lo necesiten: otros elementos de la Knowledge Base, Base de Datos y
programas de la aplicacin. De la misma manera, el desarrollador no puede alterar
directamente ningn elemento que no pertenezca al Modelo Externo
TODO el conocimiento est contenido en el Modelo Externo y, por ello, maana
podramos soportar la Knowledge Base de una manera totalmente diferente y el
conocimiento de nuestros clientes seguira siendo utilizable sin problema alguno.
Breogn Gonda & Nicols Jodal

16

Diego, debo irme, pero quiero saber ms. Me has dejado con la cabeza
confusa. Es muy grande el cambio de mentalidad, quisiera palpar esto ms de
cerca, verlo funcionando. Te parece de encontrarnos la semana prxima,
misma hora, mismo lugar?
Ciertamente expres Diego en tono pretendidamente sereno.

17

18

Captulo 2

rase una vez un Proyecto


Travel Agency & Co. es una novel compaa de venta de tickets de viajes y
turismo que ha contratado a la software house ACME Business Software
Solutions a fin de que le sea desarrollado un sitio en Internet que permita a sus
clientes realizar bsquedas de destinos, de vuelos existentes, de servicios
brindados, reservar tickets y obtener pasajes y servicios tursticos (front-end).
Incluir tambin todo el sistema para el mantenimiento de la informacin
relacionada (back-end).
ACME, que viene trabajando con GeneXus en sus sucesivas versiones
desde hace un tiempo, est integrada por varios tcnicos; entre todos ellos,
Julia, Mike y Diego fueron los seleccionados para llevar adelante este
desarrollo. Diego y Mike son Analistas GeneXus y los que normalmente se
encargan de la implementacin que les toque en suerte. En particular, Mike se
encarga casi siempre de la tarea de testear las aplicaciones, mientras que Diego
se encarga del desarrollo. Julia, en cambio, no es tcnica en GeneXus, si bien
ha trabajado en muchos proyectos relevando requerimientos; su especialidad es
documentar y moderar las charlas entre los integrantes del equipo a medida que
se van produciendo los avances. El hecho es que los tres conforman un equipo
donde todos tienen voz y voto.
Las primeras tareas recaen sobre los hombros de Julia y Diego mientras
Mike realiza los testings de las otras aplicaciones de ACME en curso para los
desarrollos en otros clientes.
Desde siempre, Julia documentaba en procesadores de texto, y en proyectos
de envergadura le resultaba extremadamente engorroso el mantener decenas de
carpetas con cientos de archivos, conjugarlos entre los desarrolladores,
coordinar las discusiones del equipo (cuando lograba hacerlo), entre otras
tareas. Usted comprender el impacto que sinti luego de enterarse que
GeneXus X contena, en forma embebida, un perfil de documentacin muy
particular que facilitara su vida de ahora en ms.

19

El tiempo es tirano
Un breve tiempo atrs, los directores y el equipo de desarrollo se pusieron
de acuerdo en el objetivo de un proyecto a corto plazo, tres semanas o algo
as. El hecho de que iban a trabajar con GeneXus X, a sabiendas del gran
aumento de usabilidad y productividad que sta traa incorporado, les haba
permitido reducir a la mitad los plazos que normalmente pactaban con sus
clientes.

Es necesario un dramtico aumento de productividad (en el desarrollo de


sistemas) pero la productividad de los lenguajes de programacin ha llegado
hace ya bastante tiempo a una estabilizacin Cmo lograr, entonces, el
aumento de productividad que se necesita? Haciendo desarrollo basado en
conocimiento y no en programacin: la solucin es describir en vez de
programar!.
Breogn Gonda & Nicols Jodal

Afortunadamente, Travel Agency & Co. ya tena su esquema interno de


funcionamiento bastante slido, con abundante documentacin y esto ya era
una ventaja para el equipo de desarrollo. Julia, Diego y Mike acordaron que
deban tener reuniones en forma paralela con los involucrados de cada sector
e ir recogiendo sus visiones.

Cada usuario tiene una o mltiples visiones de los datos que utiliza
cotidianamente. Entre estas visiones, podemos pensar en un primer tipo: el
que agrupa aquellas que se utilizan para manipular los datos (introducirlos,
modificarlos, eliminarlos y visualizarlos en forma limitada), a estas visiones de
usuarios les hemos llamado Transacciones y constituyen el primer objeto-tipo
de GeneXus.
Breogn Gonda & Nicols Jodal

Queran rpidamente comenzar a representar la realidad de la empresa;


entre otras cosas, detectaron que Travel Agency & Co. apuntaba
fundamentalmente al turismo de diversin y esparcimiento con destinos muy

20

variados en el mundo. Qu les deca esto? Antes que nada, que si los
destinos eran puntos tursticos de ciudades distribuidas a lo largo y ancho del
mundo, deban disponer de un almacenamiento para ello.
Es as que el equipo completo se reuni y luego de intercambiar notas e
impresiones, concordaron en que Julia comenzara a describir las primeras
pautas obtenidas, mientras el resto, en especial Diego, comenzara a
representar en GeneXus aquellas visiones de los usuarios ms claramente
descriptas.

El IDE a primera vista


Ahora intentemos adentrarnos un poco en el ambiente de desarrollo de
GeneXus X. Si usted lo desea podr seguir los pasos de Julia para tomar
contacto con los elementos que componen este ambiente. As, crear la base de
conocimiento del proyecto y el primer objeto de tipo Transaccin.
Generalmente conocido por sus siglas (IDE, Integrated Development
Environment), en realidad este ambiente de desarrollo supera largamente el
verdadero significado de las siglas en su acepcin ms general.
Por qu? Porque el concepto ms elemental de IDE es el de un ambiente
que ofrece una buena dosis de comodidad, de ventanas en donde seleccionar
elementos, de ventanas donde codificar, de cajas de herramientas y de fuentes,
y alguna cosa ms.
Sin embargo, el IDE de GeneXus X no slo satisface las mnimas
especificaciones, sino que pone al alcance del usuario mecanismos de
operatividad integral que van ms all.
Julia inici la sesin en una computadora con GeneXus X recin instalado,
y apareci ante su vista una imagen semejante a la que se ilustra a
continuacin.

21

Panels

Inicialmente, podemos notar dos reas contenedoras claramente definidas.


A la izquierda, tenemos el contenedor Knowledge Base Navigator; su objetivo
es ofrecer distintas vistas. Est compuesto por una zona (ahora en blanco) que
contendr, en forma de rbol, los elementos que integren la base de
conocimiento en uso, y un grupo de paneles horizontales rotulados con
descripciones inherentes a otras vistas.
La ventana de la derecha, que podramos considerar la principal (la mayor
parte de nuestra actividad se realizar en ella y as la llamaremos de ahora en
adelante), es en principio otro contenedor de mltiples funciones.
Note que en su esquina superior izquierda se encuentra un tab (o solapa)
rotulado Start Page. Es el primer contenedor abierto dentro de la ventana
principal. A medida que usted vaya trabajando, la presencia de nuevos tabs
indicar la disposicin de nuevos espacios conteniendo elementos del proyecto
tales como listados de navegacin, diagramas, estructuras de transacciones, etc.
Ahora veamos el contenido del nico tab que tenemos. Observe que incluye
otros contenedores con informacin. Por ejemplo, Recent Knowledge Bases nos

22

ofrece los nombres de las ltimas bases de conocimiento que han sido abiertas,
con sus fechas de ltima modificacin; note que tambin estn presentes links
que permiten abrir o crear una nueva base de conocimiento.
Debajo, un contenedor Extensions presenta herramientas desarrolladas por
Artech o terceros, que pueden ser instaladas y utilizadas libremente, y permiten
extender en todas direcciones la potencia de la herramienta.
El sector rotulado GeneXus Community, contiene sindicaciones de
contenidos de sitios Web vinculados a la Comunidad que se actualizan con
frecuencia (RSS). Note que debajo de cada noticia aparece More como link al
documento propuesto.
A su vez observe la celda Address que le permitir navegar por la Web o
por su sistema de archivos sin salir del IDE.

Proyecto nuevo, Base de Conocimiento nueva


La primera tarea cuando se comienza a desarrollar una aplicacin con
GeneXus es crear la base de conocimiento.
En el siguiente encuentro que mantuvieron en el caf, Mary, con ojos an
graves, pregunt:
Me contaste que GeneXus automatiza la creacin de base de datos y
programas, pero cmo sabe en qu ambiente, en qu lenguaje debe codificar
esos programas? Por ejemplo, si tuvieras que desarrollar una aplicacin en Java
y suponte, otra, o la misma, en .Net, o en
Bueno, cuando te creas la Knowledge Base (le solemos llamar KB,
para abreviar) le puedes decir que quieres generar el proyecto en un ambiente
Java. Como ya te coment, la KB es independiente de la plataforma de
ejecucin: si t generaste la aplicacin Java, ms adelante, con el mismo
conocimiento, puedes generarla para .Net, y no tienes que volver a describir los
objetos de la realidad que ya habas descrito. Simplemente tienes que indicarle
que ahora necesitas asociarle otro ambiente. Cuando le asocias un ambiente,
tiene por ah un lugar donde especificar todo lo referido al mismo. Por ejemplo,

23

en Java tendrs que indicar cosas tales como dnde estarn las clases en la
webapp, algo que en .Net no tiene sentido. Es decir, en base al ambiente que
hayas elegido, te muestra propiedades necesarias para configurarlo, para que
GeneXus pueda luego decirte: sus deseos son rdenes y te implemente la
aplicacin como se lo pediste.
Casualmente, mientras Diego y Mary intercambiaban palabras y miradas en
el caf, Julia realizaba esos mismos pasos que lo invitamos a seguir a usted
tambin.
1. Seleccione File/New/Knowledge Base (o el link New Knowledge Base de la
Start Page). A continuacin ver en la pantalla el siguiente dilogo:

TravelAgency

Observe cmo desde aqu se asocia un ambiente de implementacin al


proyecto. Dejamos la opcin por defecto, C# Environment. Tambin
observe que por defecto se asocia el lenguaje English para la aplicacin a
ser generada. Todos los mensajes, botones, etc., estarn por defecto en
ingls. Pero luego ser posible generar la misma aplicacin en otro idioma,
tanto en forma esttica como dinmica (el usuario, en tiempo de ejecucin,
elige el idioma en que desea utilizar la aplicacin) a un costo mnimo.

24

Observe adems que la KB ser almacenada en una base de datos que por
defecto recibir el nombre GX_KB_nombre en la instalacin del
SQLServer local que usted tenga. Si no tiene una local, podr utilizar una
de la red. Presionando el botn [Advanced] podr modificar estos valores.
2. Pulse [Create]. GeneXus crear una base de conocimiento vaca, y usted
debera ver una imagen semejante a la que se observa a continuacin.

Observe que han cambiado algunos contenidos. En el panel Folder View ha


aparecido un rbol cuya raz es la propia base de conocimiento (con el
nombre que usted le ha dado) y sus ramas los distintos elementos que la
componen: Domains, Objects, Tables, Customization, Documentation, etc.
Tambin note que se ha agregado un nuevo sector dentro de la Start Page
rotulado Knowledge Navigator conteniendo atajos a las tareas ms comunes
que probablemente usted querr ejecutar luego de haber creado o abierto
una base de conocimiento.
25

Sobre esta base de conocimiento trabajarn los dems integrantes del


equipo; Julia est ahora lista para comenzar a documentar.

Documentando desde dentro


Documentos, notas, listas de tareas, son slo ejemplos de la documentacin
que rodea a cualquier proceso de desarrollo de software. La documentacin es
una parte importante de cualquier aplicacin si se encuentra actualizada y es
fcilmente accesible.
Esta es la razn por la cul GeneXus contiene funcionalidades de
documentacin integradas a la KB.
Documentos, archivos, diagramas, objetos pueden estar todos
interrelacionados mediante links, fcilmente accesibles por cualquier miembro
del equipo. Por tal razn decimos que la documentacin es activa e integrada,
constituyendo un verdadero wiki.

Files
Julia haba recibido por e-mail varios archivos de documento de los jefes de
seccin de cada departamento con requerimientos para el sistema, donde
listaban las prioridades y caractersticas de sus sectores, algunos flujos de
procesos, etc.

26

Como estos documentos ya estaban hechos por terceros, decidi que sera
importante incorporarlos en su estado original dentro de la base de
conocimiento, de forma tal que siempre estuvieran disponibles para su consulta.
Eran importantes las palabras de los usuarios expuestas por ellos mismos.
As, expandi el nodo Documentation del rbol y seleccion Files
abrindolo con doble clic. Como resultado, un nuevo tab apareci dentro de la
ventana principal, rotulado Files. All presion Add New File y se le abri una
ventana que le permiti explorar su sistema de archivos, y elegir cada archivo a
ser insertado en la KB. As qued el tab Files luego de esto.

Images
Tambin le haban enviado por e-mail el logo de la empresa, por lo que
accedi al nodo Customization del rbol del Folder View, abri haciendo doble
clic sobre Images el tab correspondiente e import, almacenndolo en la KB, el
archivo Logo.bmp que sera utilizado en el encabezado de las pginas de la
aplicacin. En ese mismo e-mail recibi decenas de archivos con imgenes
sobre atracciones tursticas que luego necesitaran almacenar en la base de
datos, por lo que momentneamente las guard tambin aqu, para tenerlas
centralizadas en la KB.

27

Main Document
Ahora Julia se apresta a empezar a escribir la pgina principal del wiki de la
KB: observe que bajo el nodo Documentation del rbol aparece un objeto Main
Document. Cada equipo de desarrollo tiene metodologas diferentes respecto a
la documentacin. En ACME utilizan esta pgina principal para describir las
generalidades del sistema bajo desarrollo, y para acceder desde aqu a los
distintos elementos de documentacin.
Tambin podra elaborarse aqu mismo el Plan Director del proyecto, en vez
de insertarlo como archivo. Pero usted y su equipo de desarrollo utilizar esta
pgina como mejor le parezca.
Julia abre Main Document y un nuevo tab aparece en la ventana principal,
rotulado Document:Main. Dado que lo que desea es comenzar a escribir, pulsa
el selector Edit que se encuentra al pie de la ventana y redacta (dndole
formato) lo que se observa en la siguiente imagen. Luego pulsa el selector
Preview y tiene la vista normalizada de lo que escribi. Guarda los cambios
(Preview se transforma en Browse).

Note que le ha dado algn formato al texto. Para ello se vali de la toolbar
formatting:

28

Julia ha cambiado el tipo de letra, su tamao, e incluso


puso en negrita el tpico sobre el cual se comenta.
Pero adems, y bien importante para lograr una
documentacin integrada, Julia necesitaba agregar links
hacia los documentos recibidos e insertados en la KB
instantes antes. Para ello se vali de la toolbox1, seleccion
Table de la misma, arrastrndola a la pgina y luego de
insertada la tabla, en cada fila escribi:

Queriendo tener una vista previa, presion el selector


Preview y, satisfecha, grab, luego de lo cual se le mostr
lo que aparece en la siguiente figura:

El IDE de GeneXus ofrece varios paneles con utilidades que se pueden acoplar en cualquier parte de la ventana y tambin se
pueden ocultar automticamente cuando pierden el foco para que no ocupen sitio en la ventana principal. Usted puede activarlas
mediante View/Other Tool Windows.

29

Observe que como consecuencia de los smbolos que emple en la segunda


columna de la tabla, los documentos se encuentran subrayados: son links a los
archivos almacenados. Esto aporta un gran dinamismo a la documentacin, y la
integra en forma activa en el proyecto a travs de la KB.
El editor de documentacin de GeneXus utiliza dos parntesis rectos de
apertura ([[) y dos de cierre (]]) en el texto para crear links.
Si usted est siguiendo el ejemplo en forma prctica, habr notado que,
apenas pulsado el segundo parntesis de apertura, el editor le propuso una lista
de objetos vlidos para seleccionar, tal como mostramos en esta imagen:

30

Julia seleccion File y al digitar . se abri la lista de los archivos


disponibles (tambin podra haber arrastrado desde la toolbox el objeto File y
habra obtenido igual resultado que al escribir [[File.).

Entonces seleccion el deseado en cada momento, puls <Enter> y el texto


qued rematado con los dos parntesis finales.

Creando la primera Transaccin: Attraction


Diego piensa, mientras conversa con Mary (la mirada perdida en el caf
humeante), que ya debe dar inicio al volcado de las primeras visiones obtenidas
a travs de los usuarios que entrevist en el Departamento de Informaciones
Tursticas de Travel Agency & Co. Este departamento tiene a cargo la
bsqueda de informacin que permite agregar o suprimir los destinos e
itinerarios que ofrece la empresa a sus clientes. Piensa que ni bien vuelva al
trabajo, deber crear la transaccin Attraction, cuando Mary interrumpe su
interno discurrir:
Sabes Diego? No comprendo muy bien cmo puedes describir
rigurosamente las visiones de los usuarios como para que no haya
ambigedades y se pueda inferir todo automticamente.
Bueno. Recuerdas que te coment que estamos trabajando en un
proyecto nuevo? Bien, pues me he estado reuniendo con los usuarios quienes
me contaron que manejan atracciones tursticas de cada pas y ciudad, para
poder ofrecer a los viajeros. Manejan el nombre de la atraccin, como podra
ser Centenario Stadium o Roman Colisseum o Disney World; manejan el
nombre de pas y ciudad al que pertenece la atraccin, una imagen de la misma.
Tambin me contaron que las atracciones estn categorizadas. Por ejemplo,
31

Centenario Stadium pertenece a la categora Great Monuments o algo as, y


Disney World a Entertainment. Estas son sus visiones de los datos
Aj. Y cmo describes esas visiones objetivamente?
Mediante atributos y objetos de tipo Transaccin. Djame explicarte
un poco. Los atributos son el marco de referencia sobre el cul hacer las dems
descripciones. No es exactamente lo mismo que un atributo en un modelo
relacional. El atributo es el elemento semntico fundamental. El significado del
mismo vendr dado por su nombre, por lo que los nombres de los atributos
pasan a ser esenciales en GeneXus.
Diego tom una servilleta de papel de la mesa del bar y garabate algunos
nombres: AttractionName, CountryName, CityName, AttractionImage,
AttractionCategoryDescription. Y prosigui:
Estos atributos tienen un contenido semntico claro, que cualquier
persona podr entender sin necesidad de contexto alguno. No son slo Name
o Description. Existe una fuerte relacin entre el nombre del atributo y su
significado. Ese nombre, a su vez, es una secuencia de caracteres, algo
sintctico, nico, con lo que cualquier programa puede trabajar, sin
ambigedad. Si yo coloco AttractionCategoryDescription en algn lado, t y
yo sabemos que estamos hablando de la descripcin de la categora de la
atraccin. GeneXus lo reconoce, por su sintaxis.
Aj, entonces interrumpi Mary claramente no puedes usar el
mismo nombre de atributo cuando quieras referirte a otro dato, pues ah s
habra confusin y ambigedad.
Exacto. Un atributo deber tener el mismo nombre en todos los
lugares donde aparezca y no podr haber dos atributos diferentes, con
significado diferente, que compartan el mismo nombre. En eso se basa. Hay
una excepcin, pero no te quiero confundir ahora. Estas visiones que me
expresaron los usuarios, corresponden a aquellas que se utilizan para manipular
los datos (ingresarlos, modificarlos, eliminarlos, visualizarlos), y son las que se
representan en GeneXus mediante el objeto de tipo Transaccin. Cada
transaccin tiene un conjunto de elementos: una estructura, reglas, frmulas,

32

elementos de presentacin. Es decir, en un mismo objeto, se matan varios


pjaros de un tiro: al tiempo que dices con qu informacin se va a trabajar,
tambin diseas la pantalla que se desplegar al usuario final para hacerlo,
declaras el comportamiento que debern tener esos datos cuando se vayan
ingresando, y dems.
Diego volvi a tomar la servilleta que haba dejado sobre la mesa, y esta vez
escribi (y luego dijo):
-

Los datos se presentan de acuerdo a una estructura que debe recogerse


con todo rigor. Esta sera la estructura de la transaccin Attraction. El asterisco
que sigue a AttractionId significa que para cada atraccin, existe un nico
AttractionId, es decir, es lo que le da unicidad a la atraccin: un identificador.
Toda informacin debe poder identificarse. Una atraccin debe identificarse
mediante algn o algunos de sus atributos.
Espera, Diego. Me surgen algunas dudas en definitiva me ests
hablando del concepto de clave primaria de una tabla en un modelo relacional?
Esos atributos que listas no sern las columnas de una tabla fsica que
almacenar esa informacin? En definitiva, con la transaccin, no ests
diseando una tabla?

33

S, indirectamente. Y no: yo no me preocup de disear una tabla


fsica del modelo relacional. Solamente me limit a especificar los atributos con
los que el usuario final interactuar al ingresar atracciones al sistema.
Especifiqu una vista de usuario, no una tabla. Aqu entra lo de la ingeniera
inversa y el Modelo Relacional inferido por GeneXus. Si no hubiesen ms
transacciones que sta en la base de conocimiento, entonces GeneXus
inferira una tabla fsica compuesta exactamente por los atributos listados.
Pero la cosa cambia si existen otras transacciones compartiendo algunos de los
atributos mencionados. All habr que normalizar. Pero no me quiero apurar,
espera un poco que ya te contar de esa parte.
Creo que te voy entendiendo, Diego. Pero me llama la atencin que
pusiste en la estructura de la transaccin atributos que no dijiste que hubieran
mencionado los usuarios. Todos los que terminan con Id Por otro lado, por
qu no utilizaste el nombre de la atraccin como identificador?
Y si el nombre de la atraccin pudiera repetirse para atracciones de
distintos pases y ciudades? Suponte: Disney World que existe en Pars,
Miami, Las Vegas, Orlando. En este caso, necesitamos un atributo que d
unicidad al conjunto de elementos de informacin que constituyen una
atraccin. Toda estructura de transaccin debe tener un atributo o atributos que
identifiquen a cada instancia. En principio, en esta transaccin, coincidir
exactamente con la clave primaria de la tabla inferida. Pero no siempre ser
as, como vers cuando te muestre un ejemplo de transaccin con niveles. No te
preocupes ahora. En nuestro caso, podremos decirle a GeneXus que
AttractionId ser numrico y que queremos que se numere automticamente.
Y qu me dices de los atributos AttractionCategoryId, CountryId,
CityId? Ms identificadores?
S, sern identificadores en otras transacciones. Me explico:
evidentemente los pases y ciudades, as como las categoras de atracciones,
corresponden en s mismas a entidades independientes de la atraccin turstica.
Por ejemplo, no hemos entrado a ver eso an con este cliente, pero
evidentemente los vuelos areos tambin tendrn pas y ciudad (de origen y de

34

destino). Es decir, resulta evidente que deberemos crear una transaccin para
representar e ingresar la informacin de pases y sus ciudades, as como de las
categoras de atracciones existentes. Esos identificadores de los que me
preguntabas, sern, casualmente, los que identifiquen cada dato (instancia) de
estos.
A ver si entiendo: una vez que definas esas otras transacciones,
GeneXus inferir tablas para almacenar los datos que manipulan, y a partir de
all, se dar cuenta que esos atributos que colocaste en la estructura de la
transaccin Attraction, (AttractionCategoryId, CountryId y CityId) son los que
se traduciran en claves forneas en la tabla relacional asociada.
Sigues siendo la misma luz de siempre, Mary! exclam Diego con
ojos iluminados.
Pero entonces, qu hacen en esa estructura CountryName, CityName,
AttractionCategoryDescription? En un modelo relacional normalizado nunca
podran estar en esa tabla.
Es que no lo estarn. Por eso te deca que la estructura de una
transaccin no se corresponde exactamente con la de la tabla fsica asociada.
Ya te lo explicar, no quiero abrumarte con detalles. Traer mi notebook al
prximo encuentro porque lo habr, no? inquiri Diego vacilante, y
prosigui sin esperar respuesta, y te mostrar
Ahora el lector ver los pasos que sigui Diego en la creacin de la
transaccin mediante el IDE de GeneXus al da siguiente en su trabajo.
Primero que nada, seleccion el link New Object de la Start Page y
apareci a su vista la ventana cuyo dilogo permite la creacin de un objeto
dentro de la KB. De la caja Select a Type, con la lista de objetos GeneXus
disponibles, seleccion Transaction y luego, en la celda Name escribi el
nombre Attraction, quedando una imagen semejante a la que se muestra a
continuacin.

35

A continuacin, puls [Create], tras lo cual la transaccin se abri.


Obsrvese en la imagen siguiente que aparece un nuevo tab en la ventana
principal con el nombre de la transaccin. Qu se est editando? Una parte de
la transaccin: su estructura.

Los objetos que se abren en la ventana principal del IDE aparecen como tabs,
donde uno solo, el activo, se presenta en la ventana central. El objeto abierto
puede tener varios elementos o partes, en cuyo caso ser uno el activo en cada
oportunidad. En el tope inferior de la ventana aparece una barra de acceso que
permite, mediante Selectores, seleccionar otra de las partes del objeto activo.

La ventana de edicin de la estructura contiene una serie de columnas que el


desarrollador utiliza para crear un atributo; es decir, darle un nombre, un tipo
de dato, una descripcin, etc.

36

Selectors

Corresponde en GeneXus, a la estructura dibujada por Diego en una


servilleta de papel. Diego asign nombres a los atributos utilizando lo que se
conoce como nomenclatura GIK (GeneXus Incremental Knowledge), un
estndar creado por Artech y adoptado por la Comunidad, cuyo fin es dotar a
un atributo de un nombre nico que transmita lo ms claramente posible su
concepto, su semntica.
Usted habr deducido correctamente que la columna Type pretende dotar al
atributo con alguno de los tipos de datos soportados por GeneXus.

37

El tipo de datos Blob posibilita el almacenar una gran diversidad de tipos de


informacin (videos, planillas, documentos de todo tipo, archivos de msica,
imgenes digitalizadas, etc.) en la propia base de datos. La idea del atributo
AttractionImage es justamente almacenar una imagen de la atraccin, que
podr ser un archivo bmp, jpg, etc.
La columna Description pretende que se asigne una descripcin ampliada
del atributo. Por ahora dejaremos las sugerencias de GeneXus a partir del
nombre del atributo.
Para continuar agregando atributos, simplemente pulse <Enter> luego de
terminada una definicin y repita el mecanismo.
Atributos Clave. Como puede usted apreciar, el atributo clave que Diego
indicaba con un asterisco en la servilleta, se indica en GeneXus por el cono de
una llave.
Cuando Diego estaba asignando el tipo de datos en la columna Type para el
atributo AttractionName, consider oportuno crear un dominio Name para
todos los atributos que fueran nombres de algo, as como uno Id para todos
los que tuvieran la caracterstica de ser identificadores numricos.
Usted estar ya acostumbrado a trabajar con Dominios. Si no es as, lea el
siguiente prrafo que le aclarar la cuestin.
Dominios? Es comn en las aplicaciones tener atributos que comparten las
mismas definiciones de tipo de dato, tamao y algunas otras caractersticas. Por
ejemplo, en la transaccin Attraction hay varios atributos que son Id
(AttractionId, AttractionCategoryId, CityId, y CountryId). Diego ha creado un
dominio al que llam Id, con todas las caractersticas propias de los
identificadores y se lo aplicar a todos aquellos atributos que tengan la
funcionalidad de representar un valor inexistente en la realidad pero necesario
para lograr la unicidad.

38

Cada dominio es un conjunto de caractersticas nicas que pueden ser


compartidas por varios atributos. Esto proporciona consistencia y facilita el
mantenimiento, ya que cambiando alguna de las caractersticas de un
dominio se provocar la propagacin del cambio a todos los atributos
basados en l.

Definicin de Dominios
Diego hizo doble clic sobre el nodo Domains en el rbol del Folder View
tras lo cual se abri en la ventana principal el tab que muestra y permite editar
dominios. Ingres as los dominios Id y Name. El mecanismo es semejante al
de crear atributos en una transaccin.

Existen algunos dominios que son creados automticamente por GeneXus


cuando se crea la KB.
Teniendo los primeros dominios definidos, Diego volvi a la transaccin,
sustituy por estos dominios y en ese momento se percat de que le faltaba
definir un dominio Description para AttractionCategoryDescription. En vez de
volver a la ventana Domains, se posicion en la columna Type del atributo y
escribi Description=Character(20)2. Al abandonar el campo, ese dominio se
crea automticamente. Luego grab y pudo ver:

2
En general en GeneXus existen varios caminos que le permiten realizar lo mismo, para que el efectuar su tarea le resulte
siempre cmodo.

39

Observe que el asterisco que segua al nombre de la transaccin en el tab


desapareci (el asterisco indica que los cambios que se han realizado an no se
han grabado) y que el selector Structure cambi de color.
Atributo Descriptor. Ahora tambin apareci un cono con la imagen de una
lupa, precediendo al atributo AttractionName. Es una forma de indicar que si
uno tuviera que quedarse con uno solo de todos los atributos, de forma tal que
sea el que mejor describa a la entidad, se ser el elegido (el de mayor carga
semntica). Ahora no nos preocuparemos de esto, servir a herramientas que
automaticen.
La Tabla ATTRACTION
Por defecto, cuando GeneXus disea las tablas les asigna como nombre el
mismo que el de la transaccin en la que estn basadas3. En todo momento
puede verse el diseo de la tabla (su estructura, ndices, etc.) abriendo el nodo
Tables del rbol que se encuentra en el panel Folder View y haciendo doble clic
sobre el nombre de la tabla. Para ATTRACTION se ver:

3
En lo que sigue en este material, para diferenciar los nombres de las tablas de los de las transacciones usted ver a las tablas
escritas en maysculas.

40

Dada la estructura de la transaccin, GeneXus disear tambin un form


para la misma, que ser la pantalla a travs de la cul el usuario ingresar
atracciones cuando la transaccin sea convertida en programa ejecutable. Puede
verse escogiendo el selector WebForm4 de la barra de acceso:

4
Con GeneXus X usted podr generar exclusivamente aplicaciones Web 2.0. Para generar una aplicacin Win, podr utilizar
GeneXus X Evolution 1. All la transaccin presentar tambin un WinForm.

41

Este form podr ser personalizado, moviendo de lugar, insertando,


modificando, eliminando controles, cambiando su aspecto, etc.
Conforme con el resultado, Diego record que no haba documentado nada
sobre la transaccin. Es norma de los integrantes de ACME el ir documentando
a medida que se producen los avances, sobre todo en lo que respecta a las
entidades, tal como la transaccin Attraction.
As que abri Main Document, insert una nueva tabla, esta vez titulada
Objects y agreg en la primera fila un link hacia la transaccin recin creada
(del mismo modo en que lo hizo Julia varias pginas atrs, al incluir los links a
los documentos), junto con una breve descripcin.

42

Podemos ver Attraction como link. Qu suceder cuando Diego haga clic
sobre el mismo? Se abrir un nuevo tab de documentacin, esta vez de la
transaccin, donde podr editarla, e incluso abrir la propia transaccin:

Supngase que necesita abrir la transaccin para mirar su estructura antes


de documentar. Pues siguiendo el link Open Transaction: Attraction, podr
43

hacerlo, y luego para efectivamente ir a la ventana de edicin de la


documentacin, podr directamente elegir el selector Documentation. Como
podr constatar usted mismo, estimado lector, en GeneXus tambin se aplica
aquello de que varios caminos conducen a Roma.

Creando la segunda Transaccin: Country


Luego Diego se aboc a crear la transaccin que contendra la informacin
inherente a los pases y ciudades. Tena dibujada la estructura en la servilleta de
papel que guard en su bolsillo cuando se despidi de Mary en el encuentro
anterior:

44

Con Main Document abierto en edicin, agreg un nuevo link en la tabla,


ahora a la transaccin Country. Pero todava no la haba creado! Observe que
aparece un link, s, pero sobre un smbolo ?:

45

Cuando Diego haga clic sobre ? automticamente se crear la transaccin


que aparecer abierta en la estructura, lista para que l comience a ingresar los
atributos, y el link quedar ahora definido en Main Document. (Sin nimo de
ser reiterativos: cmo era aquello de los caminos a Roma?).

Country: una Transaccin de dos niveles


Como todos sabemos, los pases contienen ciudades, es decir, la realidad
dictamina que se tienen n cantidad de ciudades por pas. GeneXus dispone de
una forma muy sencilla y prctica de representar esta realidad, y lo hace a
travs de transacciones de dos niveles.
La transaccin Country consta entonces de dos niveles: el primer nivel,
tambin conocido como prlogo o simplemente cabezal, queda de hecho
implcito, por lo que no es necesario identificarlo. En este caso, los atributos del
prlogo implican que habr una sola instancia para cada pas.
Sin embargo, como existen varias ciudades para un mismo pas, se recurre a
una representacin (en el papel: se recurre a un juego de llaves antecedidas de
un nombre para el nivel) que determina un grupo de atributos que son
repetitivos para el prlogo: se lo conoce como cuerpo o segundo nivel.
Ahora, note usted que ambos niveles (cabezal y cuerpo) tienen
identificadores propios: el atributo CountryId es el identificador del primer
nivel, y el atributo CityId es el identificador del segundo nivel, lo que significa
que para un pas dado (CountryId) no puede repetirse la misma ciudad (CityId).
A partir de esta estructura, GeneXus determina que debe crear dos tablas: la
tabla COUNTRY y la tabla COUNTRYCITY. En la primera, la clave primaria
es CountryId, mientras en que la segunda, la clave primaria est compuesta por
CountryId y CityId.
La siguiente imagen muestra cmo qued la estructura luego de que Diego
la ingresara5.
5

Obsrvese que aparecen nuevos dominios. Es de suponer que Diego los cre, o bien antes o bien en el mismo momento de
ingresar estos atributos, por ejemplo, al ingresar CountryFullName, en la columna Type pudo haber digitado: LongName =
Character(50) con el mismo resultado. Suponiendo que Diego ya tuviera definido un dominio Details como VarChar(500,200),

46

Como CountryId y CityId ya existen en la KB (recuerde que fueron creados


al grabar la transaccin Attraction) al comenzar a digitar las primeras letras de
cada uno, GeneXus le abrir una lista conteniendo los atributos de la KB que
empiezan igual, de modo tal que usted pueda seleccionar el que corresponda y
evitar seguir digitando el nombre completo. dem con CityId y CityName.
Para insertar un segundo nivel en una transaccin, sitese en el atributo
anterior y pulse <Ctrl+L> (en este caso, sitese sobre el atributo CountryFlag).
Luego prosiga con el resto de los atributos segn el mecanismo natural.
Tambin lo logra haciendo botn derecho sobre el atributo, donde se le
desplegar un men contextual para, por ejemplo, insertar un nuevo nivel,
mover el atributo de lugar, etc.

Normalizacin de la Base de Datos


Al definir la transaccin Country se produjeron algunos cambios
importantes. En particular, la tabla ATTRACTION ha variado en su
composicin por la sencilla razn de que GeneXus la ha normalizado en virtud
de las nuevas dependencias funcionales que se introducen. Vea las
composiciones de las tablas ahora.
tambin es interesante destacar que cuando inserte el atributo CountryDetails, GeneXus ya inferir como su tipo de datos, el
dominio Details (ya que lo contiene como ltima parte de su nombre).

47

Recuerde que una dependencia funcional XY es una restriccin entre dos


conjuntos de atributos de la base de datos, que establece que si para 2 registros
coinciden los valores de X, entonces tambin tienen que coincidir los valores
de Y. Esto significa que los valores de los atributos en Y en cualquier registro,
dependen de los valores de los atributos en X, o estn determinados por ellos.

Percibe los cambios? Al crear la transaccin Country, y al designar a los


atributos CountryId y CityId como identificadores de sus respectivos niveles, se
est diciendo que:
1. Todo pas se identificar (de manera nica) por el valor de CountryId y que
este valor tendr asociado (determinar) un CountryName (y slo uno),
CountryFullName, etc. (establece esas dependencias funcionales). En un
Modelo Relacional normalizado, esto deriva en una tabla fsica con clave
primaria CountryId para almacenar esta informacin respetando esta
unicidad establecida.

48

2. Toda ciudad se identificar para un pas dado (CountryId), por el valor de


CityId, y que por tanto, este par (CountryId, CityId) determinar un
CityName y CityInformation. De esto se desprende que deber existir una
tabla fsica con clave primaria {CountryId, CityId} para almacenar la
informacin de cada ciudad6.
Pero entonces: qu hace GeneXus con los atributos de igual nombre en
diferentes transacciones? Teniendo presentes los dos enunciados mandatarios
en la filosofa GeneXus:
Conceptos iguales deben tener el mismo nombre de atributo, y
Conceptos diferentes no deben tener el mismo nombre de atributo.
encontrar atributos de igual nombre en distintas transacciones slo puede
querer decir una cosa: son lo mismo!. Entonces qu puede hacer GeneXus
para mantener la base de datos inferida normalizada? Transformar en la tabla
ATTRACTION los atributos CountryId y CityId en claves forneas, y quitar,
por tanto, a los atributos CountryName y CityName de dicha tabla (pasan a
poder inferirse a travs de los anteriores; si se dejaran se tendra informacin
redundante)

Atributos: almacenados e inferidos


Aqu viene a cuenta la pregunta que Mary le hiciera a Diego sobre la
confusa presencia de los atributos CountryName y CityName referenciados en
la estructura de la transaccin Attraction, dado que no van a estar presentes en
la tabla fsica asociada para qu Diego los coloc en Attraction entonces?
Si el lector revisa unas pginas atrs (pgina 34) y observa el form de la
transaccin, podr constatar que aparecen esos atributos. Para qu?
La transaccin se va a convertir en un programa ejecutndose. El usuario
final va a acceder a la transaccin mediante su Browser, y a travs de una
6

Observe que GeneXus nombra la tabla concatenando el nombre de la transaccin al nombre del
nivel: COUNTRYCITY

49

pantalla cuyo diseo ser el del WebForm, podr, por ejemplo, ingresar una
nueva atraccin (nuevo registro en la tabla ATTRACTION subyacente). Sera
deseable que cuando el usuario final colocara un identificador de pas en el
campo correspondiente a CountryId, y uno de ciudad en CityId pudiera
visualizar automticamente el nombre de dicho pas, CountryName y de dicha
ciudad, CityName. Es decir, que CountryName y CityName sean trados en
ejecucin de las tablas COUNTRY y COUNTRYCITY a travs de la clave
fornea {CountryId, CityId}. Para poder colocar en el form atributos a los que
se llega a travs de claves forneas, es necesario que estn presentes, inferidos,
en la estructura.
Qu sucedera si el usuario digitara para CountryId, CityId un par de
valores inexistentes? Y si mediante la transaccin Country se quisiera eliminar
una ciudad para la que existieran atracciones? Si se nos permitieran hacer estas
operaciones, se estara violando una de las condiciones ms importantes de los
modelos relacionales para mantener la consistencia de los datos: la integridad
referencial. De hecho GeneXus agregar automticamente en las transacciones
el cdigo necesario para realizar estos controles sin que el desarrollador se
moleste en hacerlo.

Integridad Referencial
Diego comunic a Julia que ya haba definido las dos primeras
transacciones. A los efectos de comprobar que el modelo reflejara la realidad,
ella hizo un Diagrama de Bachman (diagrama de relaciones entre tablas) sobre
las tablas inferidas por GeneXus a partir de las transacciones.
Para ello expandi el nodo Tables del contenedor Folder View, luego,
posicionada sobre cualquier tabla, puls el botn derecho para abrir el men
contextual y escogi New/Object, tras lo cual se abri la ventana Create New
Object donde seleccion el objeto Diagram para finalmente pulsar [Create].
Seleccion las tres tablas simultneamente y las arrastr hacia la hoja en
blanco, obteniendo el siguiente resultado.

50

En este tipo de diagrama, la punta simple de la flecha representa la


existencia de una instancia de la tabla apuntada para cada instancia de la otra;
es decir: para cada ciudad existe slo un pas; para cada atraccin turstica
existe una sola ciudad. Recprocamente, la punta doble representa la ocurrencia
de varias instancias de la tabla apuntada para cada instancia de la otra, es decir:
para cada pas existen muchas ciudades relacionadas; para cada ciudad muchas
atracciones.
Esto permite determinar las relaciones entre ellas. Por ejemplo, la relacin
entre COUNTRY y COUNTRYCITY es de 1 a N (1 a muchos) y viceversa es
N a 1 (muchos a 1). La de COUNTRYCITY con ATTRACTION tambin es 1
a N.
Para asegurar la integridad referencial, deber entonces controlarse que
cuando se inserte o modifique un registro en la tabla ATTRACTION, exista el
registro relacionado en la tabla COUNTRYCITY. Y cuando se elimine un
registro de la tabla COUNTRYCITY, no existan registros en la tabla
ATTRACTION relacionados. GeneXus resuelve esto automticamente,
agregando esta lgica a las transacciones Attraction y Country, en forma
transparente para el desarrollador. Anlogas consideraciones pueden hacerse

51

respecto a los controles sobre las tablas relacionadas COUNTRY y


COUNTRYCITY.

Concepto de Tabla Base y Tabla Extendida


Mientras Julia comprobaba que estuviera todo bien, al recuerdo de Diego
vinieron fragmentos de la ltima conversacin en el bar:
Mira, Mary, por una cuestin prctica, le llamamos tabla base, en el
contexto que sea, a la tabla en la que ests parada en un momento dado, la
que sea foco de tu atencin en ese momento, en el que ests queriendo hacer
algo con sus registros. As es que en la transaccin Attraction, decimos que su
tabla base es la del mismo nombre, porque siempre que trabajes con la
transaccin, vas a trabajar con un registro de esa tabla, ya sea para insertarlo,
modificarlo, o eliminarlo. Y luego vas a seguir por otro, y por otro y por otro.
Pero adems, cuando ests trabajando con un registro individual de una tabla
base, podras acceder tambin a la informacin que est unvocamente
relacionada con l, de otras tablas.
Aj, siguiendo las relaciones N a 1, desde el registro de la dijiste
tabla base? en la que estemos parados, hasta llegar al registro que tiene la
informacin que queremos. S, no hay nada nuevo en eso.
Es verdad. Solo la terminologa: le llamaremos tabla extendida de
una tabla base dada, al conjunto de las tablas a las que se llega partiendo de la
tabla base, a travs de relaciones N a 1.
A ver si entiendo Si no fuera por la necesidad de tener la
informacin desperdigada en varias tablas para evitar redundancias, la tendras
toda en una misma tabla fsica. En el caso de las atracciones, tendras una sola
gran tabla con todos los atributos de ATTRACTION, ms los atributos de
COUNTRYCITY, ms los de COUNTRY. No puedes, por lo de las posibles
inconsistencias que provienen de hacer los datos redundantes, pero de todas
formas le das un nombre a la tabla que tendras si s pudieras: y ese es el

52

concepto de tabla extendida. Una tabla que fsicamente no existe, pero que te la
imaginas.
Absolutamente cierto. Vers que utilizamos el concepto a lo largo y
ancho de GeneXus y por eso se le ha puesto un nombre.
Mientras Diego permaneca absorto en sus recuerdos, Julia comprob que
se cumplan correctamente las necesidades de acceso a la informacin entre las
tablas.
Mirando un Diagrama de Bachman es fcil determinar cul es la tabla extendida
de cada tabla (base). Todas las tablas a las cuales se pueda llegar siguiendo las
flechas de punta simple (relaciones N-1) desde la tabla base, formarn parte de
su tabla extendida. La tabla extendida no tiene existencia fsica, sino slo
conceptual. Nos permitir referirnos a la informacin unvocamente relacionada
con el registro en el que estemos posicionados.

Comenzando a Prototipar
Para poder dejarle paso a Mike, y que ste pueda comenzar a jugar su papel
de tester del proyecto, Diego puls <F5> para dar comienzo a la prototipacin.

Con GeneXus no hay diferencia entre prototipar e implementar el sistema. La


prototipacin no es ni ms ni menos que la aplicacin generada en una
plataforma determinada: lo mismo que la aplicacin final! La diferencia entre
una cosa y otra es solamente el uso que se le da.

Recuerde que ya se haba seleccionado el ambiente cuando se cre la KB,


de modo que varias propiedades ya aparecan configuradas7, entre ellas el
DBMS Default (SQLServer). Pero an falta algo para poder implementar el
sistema Un asistente (wizard) le pedir a Diego la informacin del servidor
de base de datos (DBMS), y la base de datos, por esta nica vez.
7

Si desea modificar alguna de ellas, alcanza con seleccionar el panel Preferences del contenedor Knowledge Base Navigator y
all buscar la preferencia a configurar, por ejemplo el DBMS asociado, o el lenguaje de implementacin, etc. y con <F4> sus
propiedades (en la ventana que se abre).

53

Su DBMS es Microsoft SQL Server 2005 Express y se encuentra instalado


en el servidor DevelopeSrv de la red. El nombre que Diego dar a la base de
datos es TravelAgencyTest:

Si la base de datos an no existe, podr crearla presionando [Edit conection]


y luego el link Create database. Tambin puede posponerlo y GeneXus lo har
automticamente unos pocos pasos ms adelante.
Luego GeneXus proceder a la generacin y ejecucin del Developer
Menu8, a fin de que los desarrolladores puedan testar inmediatamente las
aplicaciones. Una vez que el ambiente est completamente configurado, cada
vez que se presione <F5> GeneXus proceder a efectuar todos los pasos
pendientes, necesarios para ejecutar la aplicacin. Diego esperaba ver lo que se
observa en la siguiente imagen: el primer Anlisis de Impacto de esta base de
conocimiento.

8
Un sencillo men de prototipacin creado por GeneXus (es un xml conteniendo links a los distintos objetos GeneXus creados,
para poder invocarlos en forma fcil y rpida como se ver en breve).

54

El Impact Analysis Report (IAR) que estaba observando le deca que se


iban a crear las tablas que se mostraban a la izquierda, y cuyas estructuras y
dems informacin como ndices, etc. 9, podan verse a la derecha.
Qu es el Impact Analysis Report? GeneXus disea a partir de la base de
conocimiento la base de datos. En todo momento pueden hacerse
modificaciones a los objetos existentes, o pueden crearse nuevos objetos,
modificndose la KB. El IAR es el resultado de un anlisis que realiza
GeneXus del impacto causado por las definiciones nuevas o cambios del
modelo de desarrollo en una KB sobre la base de datos fsica asociada. Por
tanto, este anlisis tiene por finalidad informar al desarrollador sobre los
9

Obsrvese que abajo se muestran las sentencias SQL que se utilizarn para reorganizar (en este caso crear) esa tabla.

55

cambios estructurales que GeneXus deber llevar a cabo sobre la base de datos
para dejarla en el nuevo estado, consistente con la KB.
De conformidad con el IAR, Diego puls [Create] dando paso a la
reorganizacin de la base de datos10. Como en este primer paso sta no exista,
se va a crear. Ser en sucesivos cambios que ser reorganizada, en tanto
reestructurada. Ahora bien, cundo se generan los programas?
Inmediatamente, listos para ser probados! Desde que Diego presion <F5> e
ingres la informacin que le faltaba a la plataforma (nombre de BD y
servidor), hasta que se le abri una ventana del Browser con el Developer
Menu listo para ejecutar, no pas ms de un minuto. Diego estudi
detenidamente unos listados desplegados por GeneXus antes, que le
permitieron ver que iba por buen camino pero no se apure, estimado lector,
que sobre este punto volveremos ms adelante y Mike est un poco ansioso por
entrar en escena.

Mike 007 con licencia para matar


Era su turno. Deba destrozarlas. A las transacciones, claro.
Con su vista fija en el Developer Menu (desplegado en el Browser tras el
<F5>) conteniendo links a las transacciones, entrecruz sus dedos, los hizo
sonar, y tras una breve pausa, se dijo all vamos.

10

El trmino reorganizar refiere a efectuar cambios fsicos.

56

La idea era comenzar cuanto antes a probar, cargando informacin en la


base de datos recin creada por GeneXus y verificar el comportamiento de las
transacciones.
Puls sobre Country y apareci ante su vista una imagen semejante a la que
se observa a continuacin.

Esta es la transaccin Country en plena ejecucin.

57

Inmediatamente se percat de que el atributo CountryId debera ser


autonumerado, es decir, que el usuario no debera preocuparse por asignarle un
valor especfico ya que CountryId no representa nada de la realidad, es slo un
nmero que otorga unicidad al registro a ser insertado.
Asimismo, cuando Mike se enfrent a CountryWorldRegion, atributo
numrico de apenas un dgito, no supo qu valor numrico representaba cada
regin del mundo (cmo indicar que se trata de un pas africano,
norteamericano, europeo, etc.?) Hay que mostrarle al usuario final los
nombres de las regiones y continentes para que escoja el apropiado!, se dijo.
As que decidi iniciar con Diego una conversacin sobre el tema, de forma
tal que todos estuvieran de acuerdo sobre lo que propona. Volvi a la KB,
seleccion Country y luego ingres a su seccin de documentacin.

Agregando conversacin
Entre los selectores que se presentan al abrir la documentacin, aparece
uno: Talk, que tiene por finalidad permitirnos crear un espacio donde establecer
un dilogo con otros usuarios sobre el objeto en cuestin.

Note que el texto indicador superior est declarando un documento Talk


para la transaccin y que finaliza con un signo de interrogacin. Este signo
indica que an no existe una pgina Talk para este objeto, y antes de comenzar
58

a escribir, sta debe ser creada. Cuando Mike salve este espacio de memoria, se
generar una pgina con su contenido.
Al cliquear sobre el signo de interrogacin, cambi al estado de edicin e
ingres el texto, grab, y pudo ver:

Determinando un Atributo Identificador como Autonumber


Rato despus, en cuanto Diego ley lo que haba escrito Mike, contest
positivamente en el Talk de la transaccin Country y se dispuso a realizar los
cambios.
Quera que se numerara en forma automtica el atributo CountryId,
identificador numrico, utilizando la funcionalidad Autonumber de los DBMSs
que la soportan.
Todos los objetos de GeneXus contienen propiedades que afectan tanto su
apariencia como su comportamiento.

Las propiedades de todo objeto, atributo, etc. pueden editarse en cualquier


momento con <F4> y se abrirn en una ventana flotante.

59

Por lo que Diego se posicion sobre el atributo CountryId y en la estructura


de la transaccin Country puls <F4>11.

Primeramente, asign el valor True a la propiedad Autonumber, y


configur las propiedades como mostramos en la figura.

11

Sin necesidad de entrar a la transaccin, tambin puede buscarse el atributo para editar sus propiedades con <F4>, a travs de
la ventana Attributes, que se accede mediante View/Work With Attributes. Las propiedades que se modifiquen de cualquiera de
las dos maneras aplican al atributo en general, no al atributo en una determinada transaccin en particular.

60

Ciruga esttica para un atributo


Para completar el siguiente pedido de Mike en el Talk, Diego se situ en el
WebForm de la transaccin, se posicion sobre el control atributo
CountryWorldRegion y puls <F4> (Diego tiene la ventana de propiedades con
Auto Hide, as que ahora la ventana Properties se desplaz hacia afuera). Ya en
la ventana de propiedades del control, en la propiedad ControlType seleccion
Combo Box; a continuacin, seleccion la propiedad Values para abrir la
ventana Values Editor y carg los valores para el atributo. Eso fue todo.

61

Si en lugar de haber hecho esto especficamente en las propiedades del


control CountryWorldRegion del form lo hubiese hecho en las propiedades del
atributo CountryWorldRegion en la estructura, habra hincado el bistur ms
a fondo: significara que en todos los forms donde se colocase ese atributo, por
defecto se mostrase como Combo Box, con la definicin indicada y no como
control Edit. Cuando se percata de su distraccin, Diego decide hacer esa
definicin a nivel de la estructura. Aqu queda claro cmo es que el
conocimiento se infiere en la base de conocimiento, y es reutilizado.
Pero all reconoce que lo ms conveniente, sin embargo, ser crear un
dominio enumerado para ser utilizado por cualquier atributo que quiera
representar regiones del mundo, en particular, CountryWorldRegion. Edita
entonces los dominios y crea uno nuevo, WorldRegion de tipo Numeric(1.0), y
en la ventana de propiedades (<F4>) se posiciona en la propiedad Enum values
y pulsando sobre el botn
abre la ventana para ingresar los valores que
tomar el dominio enumerado:

62

De esta manera evitar en la aplicacin tener que recordar que el valor 8


corresponda en su sistema a South America, y a partir de all, cuando se quiera
referir a ese valor, escribir WorldRegion.SouthA, que ser sin duda ms fcil
de recordar que 8.
Por tanto edita las propiedades del atributo CountryWorldRegion (por
ejemplo, posicionndose en ese atributo en la estructura de Country y pulsando
<F4>) y modificar su tipo de datos para que ahora sea del dominio
WorldRegion.

63

Observar inmediatamente que el valor de la propiedad ControlType del


atributo automticamente pasa a ser Combo box, y sus valores los del
enumerado.

Reorganizando (reorg)
Diego cambi propiedades de dos atributos de la transaccin Country, esto
indirectamente disparar algn cambio en la tabla fsica? Veamos el siguiente
Impact Analysis Report que se observa luego de que pulsara <F5>:

64

S, GeneXus encontr que debe realizar una reorganizacin de la tabla.


Note que ahora aparece el texto Autonumber a la derecha del tipo de datos en
el atributo CountryId. La reorganizacin deber encender esa propiedad a
nivel del DBMS. Pero, qu pas con el otro cambio, con el de
CountryWorldRegion? Nada! No se trata de un cambio a efectuar sobre la base
de datos, sino que solamente vale a nivel de la KB: el dominio WorldRegion
sigue siendo de tipo Numeric(1.0) por lo que el atributo CountryWorldRegion
no cambia su tipo a nivel de la base de datos. El cambio principal ser esttico:
en todos los forms donde se presente ese atributo como control, lo har como
Combo Box con los valores del dominio enumerado.
Aqu se evidencia que no todos los cambios que se efecten en un objeto
GeneXus necesariamente provocarn una reorganizacin. Veremos otro
ejemplo de ello a continuacin cuando hablemos de las reglas de una
transaccin.

65

Diego puede decidir pedirle a GeneXus que haga efectivamente los cambios
informados ([Reorganize]) o cancelar la reorganizacin, con lo cual la prxima
vez que se presione <F5> volver a realizarse el IAR. Elige reorganizar.
Al releer lo charlado en el Talk, con intenciones de contestar que todo fue
hecho, encuentra que Mike propona que por defecto todos los Ids de
transacciones fueran autonumerados. (Su confusin vino a raz de que Mike, en
lugar de haber documentado esto en el Talk del Main Document, lo hizo en el
de la transaccin Country). Pero entonces, para implementar lo sugerido,
tendra que ir una por una a cambiar la propiedad Autonumber de esos
atributos? No!, pronto record que todos ellos estaban basados en el dominio
Id. Alcanzaba con editar el dominio, sus propiedades y all, de igual manera
que se hizo para el atributo CountryId, encender la propiedad Autonumber a
nivel del dominio. Todos los atributos basados en el presente y en el futuro en
ese dominio, automticamente heredarn la propiedad!
Pero#@!#!@...!, maldijo en voz alta. CityId no es clave primaria
simple. Para dotar a un atributo con la caracterstica de autonumerado, ste
debe ser clave primaria simple. CityId es parte de la clave primaria de
COUNTRYCITY12.
Cmo hacer, entonces, para que este atributo no tome la propiedad
Autonumber como True dada a su dominio Id?13 Sencillo. Se editan las
propiedades del atributo CityId (como antes se hiciera con CountryId) y se
modifica la Autonumber, llevndola a False. Se est cambiando, pues, el
comportamiento por defecto dado por el dominio.
Lo mismo puede decirse del atributo AttractionCategoryId que por el
momento es de Attraction y no es clave primaria, aunque pronto lo ser cuando
Diego cree la nueva transaccin AttractionCategory, unos pasos ms adelante.
Por esta razn, decidi dejar la modificacin en la definicin del dominio Id
12
Para dar valores consecutivos a este atributo, habr, pues, que apelar a una regla: Serial. Le proponemos la investigue luego
de ver algunas reglas, en la seccin siguiente.
13
De todas formas, como GeneXus sabe de esta restriccin, si Diego no se hubiera percatado del problema, GeneXus
igualmente hubiera actuado con inteligencia y no hubiera definido el atributo en la base de datos con autonumber. A efectos
didcticos preferimos hacer trabajar a Diego.

66

(para encender la Autonumber) para ms adelante, cuando cree la nueva


transaccin (dejando este To-Do Diego que, creado seleccionando el objecto
Document desde la ventana New Object, al guardarlo qued colgado en Orphan
Documents).

Transacciones: no slo una cara bonita, tambin personalidad


Diego decidi incorporar a las transacciones el comportamiento que los
usuarios haban descrito respecto a la manipulacin de los datos.
Nunca debe ingresarse al sistema una atraccin a la que no se le haya
dado un nombre. Abri, por tanto, la transaccin Attraction, puls sobre el
selector Rules y escribi lo siguiente:
Error('Attraction must have a name')
if AttractionName.IsEmpty();

En ejecucin, si el usuario dejara vaco el campo Attraction Name, le


aparecer el mensaje indicado y el control quedar en el mismo campo sin
dejarle continuar. Tampoco se le permitir grabar el registro en la tabla
correspondiente.
Nunca debe ingresarse al sistema un pas sin nombre y nombre completo
S se permite no ingresar detalles del pas, pero en este caso se le quiere dar
un mensaje al usuario, advirtindole por si lo dej vaco por distraccin.
Seleccion, pues, el selector Rules de la transaccin Country y escribi las
siguientes tres reglas en un orden cualquiera:
Error('Country must have a name')
if CountryName.IsEmpty();
Error('Country must be in full')
if CountryFullName.IsEmpty();
Msg('No country datails were provided. Do you want to continue?')
if CountryDetails.IsEmpty();

67

La tercera regla tambin emite un mensaje, pero a diferencia de la Error, no


traba el paso del usuario hacia el campo siguiente, y permite grabar el registro.
Existen muchas ms reglas, que permiten programar el comportamiento
especfico que tendr la transaccin. Obsrvese que se escriben siguiendo un
estilo declarativo: salvo excepciones no importa el orden. En nuestro caso, se
dispararn de acuerdo al orden en que se encuentren los atributos
CountryName, CountryFullName y CountryDetails en el form.
En una transaccin de dos niveles, se estn manipulando registros de dos
tablas. Por tanto, cuando el usuario ingresa un nuevo pas y sus n ciudades
mediante el form de la transaccin Country, se estarn insertando n+1 registros:
1 en la tabla COUNTRY y n en la tabla COUNTRYCITY. Se insertarn en el
orden en que se hayan ingresado en el form. Puede querer dispararse una regla
inmediatamente antes o inmediatamente despus que una grabacin de estas se
efecte. Para ello las reglas pueden condicionarse no slo con clusulas if como
las mostradas, sino tambin con eventos de disparo como son el BeforeInsert o
el AfterInsert.
Luego de grabarse los n+1 registros de la transaccin (cabezal y sus n
lneas) se realiza automticamente un Commit. Puede ser deshabilitado por el
desarrollador mediante una propiedad de la transaccin. Tambin existen
eventos de disparo de reglas, que capturan el momento inmediatamente
anterior a realizarse el Commit, o el inmediatamente posterior. Por ejemplo, si
quisiera realizarse un listado del pas recin ingresado con sus respectivas
ciudades, podra invocarse a otro objeto GeneXus de otro tipo: Procedimiento,
asegurndose de invocarlo luego de haberse insertado los n+1 registros,
envindole por parmetro el identificador de pas recin ingresado y si se
quiere que sea antes del Commit se escribir en la seccin de reglas:
PrintCountry.call( CountryId ) on BeforeComplete;14
14

Obsrvese que se est utilizando un mtodo de invocacin corriente en GeneXus: el Call, que est apareciendo aqu como una
regla. Tambin obsrvese que lo que precede al call es el nombre del objeto invocado, en nuestro caso ser otro objeto GeneXus
de tipo Procedimiento, y por ltimo, obsrvese que los eventos de disparo aparecen identificados en la sintaxis de una regla:
Rule if condition on Event

68

Y si se quiere que sea luego del Commit se escribir:


PrintCountry.call( CountryId ) on AfterComplete;

Diego deja documentadas las modificaciones efectuadas. Piense cules


fueron los cambios en la KB desde el <F5> anterior.

Lo que se esconde tras el <F5>


1. Lo primero que hace GeneXus tras un <F5> es un anlisis del impacto que
tendr los cambios efectuados en la KB, sobre la base de datos. En caso de que
haya impacto, desplegar el Impact Analysis Report que puede ser confirmado,
en cuyo caso se reorganizar fsicamente la base de datos, o cancelado, como ya
vimos.

Sabiendo que lo nico que modific desde el anterior <F5> fue agregar
reglas a ambas transacciones, anticipa que cuando ahora vuelva a pulsar <F5>
no habr reorganizacin, pero s los pasos que siguen.
2. GeneXus da paso a la etapa de especificacin, que es un anlisis de todo lo
definido en cada uno de los elementos que componen los objetos que usted haya
cambiado, como por ejemplo, las estructuras, los forms, las reglas incorporadas, y
ms. Esta tarea da por resultado un listado de navegacin en el cual GeneXus
informa de la lgica que ha interpretado para cada objeto que haya sufrido
cambios desde el <F5> anterior, junto con advertencias y errores (en caso de
haberlos).

En el caso de nuestros amigos, dos objetos han cambiado: Country y


Attraction, por lo que esto ser lo que Diego ver tras su <F5>:

donde condition es una condicin booleana y Event es uno de los eventos de disparo vlidos, que invitamos al lector
interesado a buscar en las distintas fuentes de documentacin del producto. Listamos algunos: AfterValidate, BeforeInsert,
BeforeUpdate, BeforeDelete, AfterInsert, AfterUpdate, AfterDelete, BeforeComplete, AfterComplete, etc.

69

No hubo advertencias ni errores. Observe el lector cmo al elegir Country a


la izquierda, le informa las tablas en las que realizarn las grabaciones y la
integridad referencial que controlar cuando se pretenda eliminar un pas, o una
ciudad a travs de esta transaccin.
3. Luego de especificar, se pasa a la etapa de generar el o los objetos que
GeneXus entienda necesarios para que la ejecucin pueda realizarse en forma

70

completa (si hay objetos que no han variado, y fueron generados en un <F5>
anterior, para qu hacerlo nuevamente?). La generacin implica la escritura de
lneas de cdigo que implementen la programacin de los objetos en el lenguaje
elegido por usted para el ambiente de desarrollo (por cada una de las dos
transacciones de Diego, se generar entre otras cosas un archivo .cs. No olvide
que l eligi C# como su lenguaje de desarrollo). Adems mientras el
desarrollador no cree su propio objeto principal, se crear un xml: el Developer
Menu, que contendr links a todos los programas (objetos) generados.
4.

Por ltimo, GeneXus compila los programas y ejecuta (hasta que no se cree un
objeto principal de la ejecucin) el Developer Menu en el Browser instalado en
esa mquina.

Todo este proceso es enteramente automtico. Usted nunca tendr que


especificar y/o generar un objeto en forma explcita, pues GeneXus es lo
suficientemente inteligente como para determinar qu acciones disparar en cada
momento.
As fue que, avisado por Diego, previo paso por el Developer Menu, Mike
ejecut Country, ingres unos cuantos registros, modific algunos, elimin
otros, y document los resultados en la Documentation de la transaccin
otorgndole el status de okay.
Observe lo que sucedi cuando accidentalmente, teniendo al pas 1,
Argentina, en edicin, borr su nombre y sali del campo. Recuerda que
Diego program una regla Error con exactamente ese mensaje un poco antes?

71

Le faltaba an probar Attraction (habiendo encontrado cosas a modificar en


Country, haba decidido esperar un poco), cuando vio en el Talk de la misma
que Diego le indicaba que postergara la prueba hasta que l creara la siguiente
transaccin relacionada.

Creando la Transaccin AttractionCategory


En la transaccin Attraction, Diego nombr al par de atributos como
AttractionCategoryId y AttractionCategoryDescription sabiendo que ms tarde
creara una transaccin AttractionCategory, que los contendra.

72

La finalidad de esta transaccin es categorizar los variados puntos de


atracciones de una ciudad. Ejemplos de esto pueden ser las categoras
Buildings/Structures, Nightlife, Relaxation, Adventure, Safaris,
Gastronomy, Business, etc.
Con las estructuras de las transacciones Attraction y AttractionCategory
estamos diciendo implcitamente que: una atraccin pertenecer a una y solo
una categora, mientras que una categora podr contener n atracciones.
El siguiente Diagrama muestra la nueva relacin existente ahora entre las
tablas involucradas hasta el momento en el proyecto.

GeneXus deber reorganizar la base de datos en el prximo <F5>, creando


la nueva tabla ATTRACTIONCATEGORY y quitando de ATTRACTION al
atributo AttractionCategoryDescription, que pasar ahora a ser inferido, a partir
de la nueva clave fornea, AttractionCategoryId.
Antes de dar <F5>, Diego record modificar el dominio Id para que fuera
Autonumber (como haba dejado anotado en la documentacin para hacer
cuando creara la transaccin AttractionCategory).
Ahora s, <F5>. Analiz los Impact Analysis Report correspondientes:

73

Observe cmo informa sobre los cambios habidos en Attraction. Y para


AttractionCategory informa que la tabla es nueva, deber ser creada. Adems
presenta una advertencia15:

15

Y si Mike hubiese testado anteriormente la transaccin Attraction y hubiese insertado registros antes de esta reorganizacin?
Supngase que hubiera ingresado una atraccin con Id de categora 1 y descripcin Nightlife qu pasara entonces en la
reorganizacin, cuando se cree la tabla ATTRACTIONCATEGORY y AttractionCategoryId pase a ser clave fornea en
ATTRACTION y AttractionCategoryDescription inferido? Qu pasar con el registro pre-existente en ATTRACTION? Para
que la base de datos quede en estado consistente, tendr que crearse un registro en ATTRACTIONCATEGORY, con Id 1 y
con descripcin Nightlife. Esto lo har el propio programa de reorganizacin. Qu pasar si existan dos o ms atracciones
con el mismo Id de categora y distinta descripcin? Es lo que informa la advertencia. Investguelo.

74

Tras el [Reorganize] confirmado por Diego, obtuvo la nueva base de datos y


los nuevos programas generados. Cerr el Browser (pues la tarea de testar todo
era de Mike) y finalmente document la nueva transaccin y los cambios de
Autonumber.
Mike ley lo escrito por Diego y se dispuso a prototipar todas las
transacciones. <F5> nuevamente

Para que el usuario final no tenga que recordar cdigos para las claves forneas,
GeneXus crea objetos automticamente que se conocen como Prompts y que se
invocan mediante la imagen que aparece en ejecucin al lado de todo campo
clave fornea. Se trata de listas de seleccin que muestran toda la informacin de
la tabla referida, para que el usuario seleccione la deseada.

As, cuando Mike prob la transaccin Attraction, al momento de ingresar


la categora de la atraccin Tour Eiffel, no recordaba el cdigo que
corresponda a Buildings/Structures que deba asociarle. Entonces presion
en la imagen que sucede al campo para ingresar el Id de la categora, , y se le
abri la lista de seleccin de categoras creada automticamente por GeneXus,
como aparece en la siguiente imagen:

75

Con esa lista abierta, Mike elegir la primera opcin,


Buildings/Structures, y el control volver a la transaccin Attraction, donde
aparecer en el campo AttractionCategoryId el valor 1, correspondiente; el foco
estar all, y el usuario podr pasar a ingresar el siguiente campo (en nuestro
caso, el Id de pas, para lo que el procedimiento podra repetirse).
Tambin prob que estuvieran funcionando bien los controles de integridad
referencial, por lo que coloc en AttractionCategoryId un valor inexistente de
categora, y vio cmo en ejecucin apareca un mensaje de error
indicndoselo16.
16
Segundos ms tarde, probara intentar eliminar en la transaccin AttractionCategory una categora con atracciones asociadas,
esperando ver que fallara la eliminacin, asegurndose as la integridad referencial. Amigo lector: pruebe y ver.

76

Para que el usuario final no tenga que estar abriendo estas listas de
seleccin cada vez que tenga que ingresar el valor de una clave fornea,
GeneXus provee de la facilidad de disfrazar en ejecucin un atributo por
otro. Mike propuso esto ltimo; Diego lo realiz cambiando dos propiedades
del atributo AttractionCategoryId, y como resultado, ahora para ingresar la
categora Buildings/Structures Mike slo debe recordar con qu letras
empieza, digitarlas y tendr autocomplete:

El atributo en el que el usuario final estar ingresando la descripcin, es en


realidad la clave fornea AttractionCategoryId, que est disfrazada de
AttractionCategoryDescription, de manera que el usuario final ingresa
descripciones, pero lo que en realidad queda almacenado es ni ms ni menos
que el Id correspondiente, que se fue a buscar a la tabla, en forma transparente.

77

Ahora quedaba mejorar un poco la usabilidad y la apariencia de lo que iba


del proyecto, y dejaron por escrito que habra que comenzar a hacer uso de
algunas de las otras herramientas de GeneXus, como los GXpatterns. Y tal vez
ya podran reunirse todos para discutir si poner en produccin alguna parte de
la aplicacin en el sector Tourism de la agencia, de tal forma que pudieran ir
probando, cargando pases y ciudades y enviando de retorno las sugerencias
que encontraran.

La prototipacin es un gran recurso, y utilizndola adecuadamente, se evita


una exagerada dependencia de la prueba final o, an, de la puesta en marcha (el
Da D, donde todo ocurre y donde la ley de Murphy se aplica especialmente).
Breogn Gonda & Nicols Jodal

Por las caractersticas de GeneXus, todo se puede probar en cualquier


momento y, en particular, se puede prototipar cada objeto en el momento en
que se considere oportuno hacerlo. Esta posibilidad es siempre muy importante
y es consecuencia directa de la teora de GeneXus y, en particular, de su
propagacin automtica de los cambios.

78

Captulo 3

Hecho a mquina, terminado a mano


Planes Inmediatos
El proyecto de Travel Agency & Co. ya ha avanzado lo suficiente como
para que varias de sus partes sean puestas en preproduccin. Es momento de
pruebas por parte de los usuarios y a la vez de seguir incrementando el sistema.

El problema: pobreza de la aplicacin


Julia asiste con los usuarios finales para tener un feedback temprano y
corregir posibles desvos. Cuando stos comienzan a probar el ingreso de datos
mediante las transacciones, manifiestan estar satisfechos respecto a los
controles y la forma de ingresar los datos individuales, pero quieren consultas
con vistas ms completas y con algn aumento de funcionalidad. Por ejemplo,
quieren poder trabajar con los pases de una forma ms vistosa y amigable.
Quieren poder visualizar en un grid todos los pases existentes, seleccionar uno
de ellos para poder modificarlo o eliminarlo, o incluso ver la informacin
completa de ese pas, incluyendo sus ciudades y toda otra informacin que
pueda tener relacionada.

La solucin: aplicacin vistosa en slo tres clics


Sin titubeos Julia se dijo Patterns, all vamos Con la transaccin
Country en edicin, tres clics y un <F5>, pregunt a los usuarios finales Es
esto lo que desean?.
Los usuarios finales ven en el Developer Menu un nuevo link, Work With
Country, que al ser cliqueado abre un nuevo objeto en el browser, WWCountry,
que no slo muestra en un grid los pases existentes en el sistema, ordenados

79

por su atributo ms significativo, el nombre17, sino que adems permite filtrar


en ese grid tambin por nombre (a medida que el usuario final va digitando en
la variable de filtro, automticamente se va filtrando en el grid), as como
pagina automticamente el grid18:

Filtro sobre el grid

Para
desplazamiento
entre las pginas
del grid

17

Ver pgina 32. Cuando se ingresan los atributos en la estructura de una transaccin, el primero de tipo Character o VarChar
ingresado, se marca como el descriptor. Se puede cambiar de descriptor posicionndose en la estructura sobre el nuevo atributo
descriptor, y va botn derecho- eligindolo mediante Toogle description attribute en el men contextual desplegado.
Aunque como veremos apenas ms adelante, Julia tendr otra alternativa para hacerlo
18
El valor por defecto es de 10 registros por pgina (es decir, carga 10 lneas del grid). Lo hemos modificado a 3 en un lugar
centralizado del Pattern Work With del que luego hablaremos.

80

Y no slo eso, tambin permite realizar acciones tales como:

insertar un nuevo pas, cliqueando en la imagen que aparece arriba y a


la derecha del grid, , lo que llamar a la transaccin Country en
modo Insert19 (para insertar un pas y sus ciudades) y retornar.

modificar informacin de uno de los pases, cliqueando en la imagen


que aparece en la lnea del grid correspondiente a ese pas (lo que
tambin llamar a la transaccin Country pero en modo Update, para
actualizar ese pas y retornar).

eliminar un pas del sistema (cliqueando ahora la imagen ) lo que


tambin llamar a la transaccin, en modo Delete y luego retornar.

visualizar toda la informacin de un pas determinado: observar el link


que aparece sobre el nombre del pas; cliqueando aqu se abrir un
nuevo objeto (creado automticamente), ViewCountry, que mostrar
toda la informacin relacionada con el pas (en tabs):

19

El objeto Transaccin tiene una variable predefinida, &Mode, que identifica el modo en que se encuentra en un momento
dado (modo Insert, modo Update, modo Delete o modo Display) de acuerdo a la operacin que se vaya a realizar. Si se le enva
por parmetro el modo y se recibe en esta variable, entonces la transaccin sabr qu operacin se quiere realizar.

81

Es decir, se cre un verdadero Trabajar con Pases (Work With


Countries). Lo mismo podran pedir los usuarios para trabajar con las otras
entidades: atracciones y categoras de las atracciones.

Patrones?
En lneas generales usted ya sabe de qu se habla cuando se dice patrn:
conocimiento comn que puede ser aplicado a situaciones distintas. Un pattern
en GeneXus es muy potente; evita que usted deba crear manualmente objetos
de gran versatilidad funcional; permite el reuso del conocimiento; y es un
utilitario abierto: llegado el caso, usted mismo puede crear sus propios
patrones. Introducen un alto nivel de productividad y generan aplicaciones de
calidad, con interfaces ms uniformes, y una lgica consistente. Es un
generador de conocimiento a partir de conocimiento.
82

Todo lo que Julia hizo fue aplicar el patrn Work With (uno de los
existentes) a la transaccin Country, obteniendo un trozo de aplicacin que
implementa todo lo necesario para poder Trabajar con la informacin
asociada, en nuestro caso: pases.
Podemos pensar al patrn Work With (as como muchos otros) como una
mquina, cuya entrada es una transaccin (y la KB) y cuya salida es un
conjunto de nuevos objetos GeneXus (algunos de los cuales mostramos antes
en ejecucin), ms cambios en algunas propiedades de la KB, ms la propia
transaccin modificada20

Personalizacin: siempre hay un pero


Los usuarios respondieron a la pregunta de Julia: S, es esto lo que
deseamos, pero
1. En el grid slo queremos ver el nombre del pas y la regin del mundo (el
resto de la informacin no nos interesa).
2. Adems quisiramos poder ordenar los pases mostrados no slo por
nombre de pas, sino tambin por regin del mundo, as como tambin por
el par {regin del mundo-nombre de pas}, y por ltimo queremos poder
20
En particular la transaccin deber declarar que recibe parmetros, dado que ahora se la quiere poder invocar desde el objeto
Work With Countries (WWCountry).

83

3. filtrar el grid por regin del mundo (adems de por nombre).


Todo lo que Julia haba hecho para aplicar el pattern
Work With fue abrir la transaccin Country, pulsar sobre el
selector Work With que se halla al pie (1er. clic), marcar el
check box Apply this pattern on save (2do. clic) como
podr observar en la imagen de abajo y grabar (3er. clic).
Luego <F5> (tras lo cual los usuarios pudieron ver la
aplicacin funcionando). Observe los nuevos objetos
creados y desplegados en el listado de navegacin:
Sin embargo, en la siguiente imagen usted apreciar que el selector Work
With no slo permite marcar el check box, sino que edita una estructura arbrea
que Julia ni mir al realizar los pasos anteriores. Aqu es donde tendr que
trabajar ahora para realizar las modificaciones pedidas.

84

Configura el
web panel
WWCountry:

Configura el
web panel
ViewCountry

Esta imagen muestra una instancia del pattern Work With, la instancia
para Country, que permite personalizarlo21. Se puede observar una estructura
jerrquica conteniendo nodos y un conjunto de propiedades cuyos valores
determinarn la apariencia y el comportamiento de lo generado por el pattern
para esta instancia.
El pattern Work With generar, entre otras cosas, dos nuevos objetos
GeneXus, que pudimos ver en ejecucin, y que hemos incluido para usted sobre
la imagen de la instancia, de un tipo del que an no habamos hablado: Web

21
No hemos definido instancia. Puede pensarse como la declaracin de cmo se aplicar el patrn al caso particular de este
objeto.

85

Panel. Permite, grosso modo, hacer consultas interactivas a la base de datos, de


modo amigable22.
En la imagen hemos indicado qu nodos de la instancia del pattern
permiten configurar las caractersticas de qu web panel. Los usuarios le han
pedido a Julia modificaciones sobre el primer web panel. Nada han dicho por el
momento del segundo (pero tal vez lo hagan).
Observe el lector lo primero que aparece bajo el nodo Level (Country).
Recuerde que CountryName era el atributo descriptor
de la transaccin (el
de mayor carga semntica). Qu repercusin tiene el atributo descriptor en lo
generado por el pattern? Mucha. Por ejemplo, define cul ser el atributo del
grid del WWCountry que contendr un link hacia el web panel ViewCountry
creado automticamente para ver la informacin de ese pas. Pero este es slo
un ejemplo, como veremos, se utiliza en varios lugares. No obstante, el atributo
descriptor, que es heredado de la transaccin, si bien puede ser cambiado por
otro en el rbol, no implicar que sea tambin cambiado en la estructura; es
slo el descriptor para el pattern.

Web panel WWCountry:


nodo Selection (Work With Countries)
Obsrvese que el nodo Selection contiene como subnodos: Attributes,
Orders y Filter (adems de acciones: Ins, Upd, Del, Dis).
El subnodo Attributes muestra por defecto todos los atributos del primer
nivel de la transaccin Country, y son los listados (casualmente?) en el grid
del web panel WWCountry (Work With Country)23 generado
Los usuarios pidieron a Julia solamente mostrar CountryName y
CountryWorldRegion, por lo que lo nico que sta debe hacer es eliminar de
22

En un caso tenemos un web panel que nos permite entre otras cosas listar los pases, filtrando por nombre, y en el otro
tenemos un web panel que nos muestra toda la informacin de un pas determinado y sus ciudades (stas en un grid dentro de
un tab).
23
Este web panel, WWCountry tiene su descripcin en singular Work With Country, sin embargo, en su pantalla se presenta
como Work With Countries. Por lo que para referirnos al mismo, utilizaremos indistintamente el singular y el plural, de
acuerdo a lo ms natural al contexto en el que lo estemos referenciando.

86

ese nodo, con <Supr>, el resto de los atributos, con la excepcin de CountryId.
Este ltimo no puede ser eliminado tan alegremente. Aunque no se le muestre
al usuario final en el grid, deber estar presente, invisible, como justificaremos
en breve. Por lo tanto, lo que har Julia en ese caso ser posicionarse sobre el
atributo en ese nodo, y, editando sus propiedades con <F4>, modificar la
propiedad Visible pasndola a False.
As quedar la instancia; vea la repercusin en ejecucin.

Requerimiento 1 listo!
El subnodo Orders indica el orden por el que en forma predeterminada se
desean recuperar los datos que se cargarn en el grid. El orden elegido por
defecto es (casualmente?) el de CountryName, el atributo descriptor. Los
usuarios pidieron poder elegir entre ese orden y uno por CountryWorldRegion,
as como uno compuesto por ambos.
Cmo puede el usuario decidir en ejecucin por cul criterio quiere
ordenar la informacin a recuperar? Mediante un combo box que le muestre las
posibilidades. Julia necesitar agregar los nuevos ordenamientos pedidos bajo
el subnodo Orders, a los que les dar un nombre (World Region, Both) que
87

sern las opciones que el usuario final ver en ejecucin en el combo insertado
automticamente por el pattern.
As quedar la instancia y luego el web panel generado (en ejecucin):

Observe un detalle: puede tambin ordenar en ejecucin lo que haya


cargado en el grid en un momento dado, por alguna de sus columnas,
simplemente cliqueando sobre la misma. Pero cuidado! Si est trabajando con
paginado, aqu estar ordenando slo la pgina actualmente cargada.
Requerimiento 2 listo! Slo queda el 3.
Los usuarios quieren tambin poder filtrar los pases a cargar en el grid por
regin del mundo. Evidentemente: subnodo Filter de la instancia. Obsrvese lo
que aparece en forma predefinida bajo este nodo (vea pgina 77). Otra vez,
casualmente CountryName? Tmese un tiempo, estimado lector, para deducir
qu significan los dos subnodos Attributes y Conditions, mirando el web panel

88

WWCountry que GeneXus implement y la instancia en la pgina 77. Y si


ahora le mostramos lo que hizo Julia en la instancia y la repercusin que esto
tuvo en el web panel?

Al agregar el atributo CountryWorldRegion bajo el subnodo Attributes, se


crear
automticamente
una
variable
del
mismo
nombre,
24
&CountryWorldRegion , que se colocar sobre el grid del web panel y que
permitir que el usuario final seleccione una regin del mundo para que en el
grid se le muestren slo los pases de esa regin (por qu aparece como combo
box25
?). Cmo sabe que debe hacer ese filtro?
Pues por lo que Julia escribi bajo el subnodo Conditions. Observe algunos
detalles: hay dos filtros definidos (por nombre de pas y regin). Cul aplica?
Ambos, a menos que alguno no deba ser aplicado (observe las clusulas
when de cada filtro. Por ejemplo, cuando &CountryWorldRegion tenga el
valor del dominio correspondiente a None. En tal caso, no aplicar ese filtro).
Requerimiento 3 listo!
Obsrvese un hecho interesante y nada casual: cuando Julia mostr en
ejecucin a los usuarios cmo modificar un pas o eliminarlo, se abri la
24
Ya habr deducido que las variables aparecen identificadas en todo el cdigo GeneXus por un & que es colocado como
prefijo del nombre de la variable.
25
Recuerde que el atributo CountryWorldRegion est basado en el dominio WorldRegion de tipo enumerado. De ese modo
cuando se presenta como control en un form, ser un combo box. Aqu se trata de una variable que se basa en este atributo y
observe cmo hereda el mismo comportamiento, sin tener que decirle nada.

89

transaccin Country, editndose el pas seleccionado del grid. Para ello el


pattern WorkWith tuvo que modificar las reglas de la transaccin, agregando
algunas que se suman a las que ya habamos declarado. Para qu? Para poder
instanciar, editar el pas, recibirlo por parmetro. Echemos un vistazo:

La forma que tiene todo objeto GeneXus de declarar los parmetros que recibe y
devuelve, es mediante la regla Parm.

Cuando desde el Work With Countries se elija un pas del grid para
modificarlo, se invocar a esta transaccin envindole el modo UPD que es
recibido en la variable &Mode y se enviar adems el CountryId
correspondiente (es por este motivo que tuvimos que dejarlo en el grid, oculto).
Cuando se quiere insertar, se enva INS y el valor vaco como segundo
parmetro, y as

90

Web panel ViewCountry:


Nodo View (Country Information)
Cuando hacemos clic en ejecucin sobre el nombre del pas, se abre el web
panel ViewCountry que nos muestra la informacin del pas correspondiente
(ver pgina 74). Observemos qu datos nos muestra: el nombre del pas
recibido por parmetro (otra vez casualmente CountryName?) y luego en un
tab General todos los atributos del primer nivel de la transaccin Country para
ese pas, y dos botones para poder llamar a la transaccin pasndole ese pas
por parmetro (para modificar el pas y eliminarlo respectivamente) y en un tab
City, nos muestra en un grid todas las ciudades del pas.
Observe detenidamente el nodo View
(Country Information) de la instancia del
Work With de Country. Si el usuario pidiera que
adems del nombre del pas, apareciera el
nombre completo en la parte fija, luego en el tab
General slo se mostraran los atributos
CountryWorldRegion,
CountryDetails
y
CountryFlag, y si adems quisiera que en el tab
City, en el grid de las ciudades slo se mostrara
el nombre de las mismas, qu cambios debera
hacer sobre estos nodos para lograrlo? Y si no
se deseara el tab City en absoluto?
En la instancia aparecer un Tab por cada
26
tabla subordinada (muchos a 1) pero Julia podra agregar otros Tabs con
otras cosas No nos apuremos

26

COUNTRY slo tiene a COUNTRYCITY en esta relacin (muchas ciudades por cada pas) y por ello slo aparece un Tab.
Obsrvese que el nombre que eligi GeneXus para nombrarlo fue la descripcin del nivel 2 de la transaccin Country (la
descripcin de las lneas, que era City).

91

Concluyendo: Cuando Julia marca Apply this


pattern on save en el selector Work With de
Country, al grabar, se generarn objetos GeneXus
como los que estuvimos viendo en ejecucin,
pudiendo acceder a ellos en el Folder View, bajo la
transaccin. Asimismo, cada vez que modifique la instancia, al grabar, se
regenerarn los objetos que corresponda, en forma automtica.

Ms?
Los usuarios, que por momentos parecen tener como especial misin en el
mundo encontrar las flaquezas de los desarrolladores y volver sus vidas
miserables, pidieron a Julia que luego de modificar un pas, no se volviera al
llamador, WWCountry, sino que les mostrara toda la informacin del pas
recin modificado (es decir, ir al View Country).

Julia, inmutable, se posicion en el nodo raz de la instancia y cambi el


valor de la propiedad AfterUpdate para Go to View
Obsrvese que inicialmente toma un valor <default>. En algn lado tiene
que decir cul es este (y los dems) <default>. Este valor especifica cul es el
comportamiento predeterminado para todas las instancias (aqu tenemos la de
Country, pero tambin podramos querer un Work With Attractions y un Work

92

With AttractionCategories). Si en la mayora o todos los Work With de la


aplicacin queremos que el comportamiento por defecto sea que luego de
modificar se vaya al View, entonces en lugar de cambiar a mano una por una
esta propiedad en la instancia de cada transaccin, podemos cambiar en un
lugar centralizado el <default>.
Cul es este lugar centralizado?
Se encuentra bajo el grupo Preferences de la ventana Knowledge Base
Navigator: nodo Patterns. Observe en la imagen que sigue que al momento
slo se encuentran los patterns Work With y Category. Pero ya habr otros de
usted, de Artech y de terceros
(Extensibilidad integrabilidad piezas claves en la ideologa X)

Obsrvese que aqu aparecen todos los comportamientos predeterminados


que heredarn las instancias particulares del Work With para cada transaccin.
Por ejemplo, si queremos cambiar para todos los Work With la cantidad de

93

registros por pgina de los grids (cosa que ya habamos hecho sin mostrarle,
pasndola a 3), tenemos el nodo Grid27. Invitamos al lector interesado a
investigar sobre las configuraciones generales que puede realizar desde aqu.
Por ejemplo, puede cambiar el aspecto general de las pginas, los nombres de
las mismas, las imgenes para las acciones de Insert, Update, Delete y mucho
ms.
Reflexione el lector sobre lo que significa trabajar con. Qu otras cosas
podra pedir el infame usuario? (perdn lector, es que tambin somos
humanos). Pregntele a Julia y ella le podr contar que en esa misma reunin,
se le ocurri a esa especie particular de homo sapiens que quera:
A. Exportar la informacin de los pases con los que estaba trabajando, a una
planilla Excel. Puede usted creer? Adems dijeron que no queran:
B. Que se pudiera eliminar pases desde el Work With Countries. Y por si esto
no fuera poco, que queran:
y
C. Agregar otra accin ms sobre los pases (adems de las de Insert
Update ), cuyo efecto fuera mostrar en otra pantalla cada pas con sus
ciudades, todos juntos!, y en un formato ms agradable a la vista. (Un
poco ambiguo para nuestro gusto y el de Julia)
Julia disfrut con sorna: ante cada requerimiento que el usuario peda con
ojos maliciosos, haca un par de clics y listo. Salvo para el ltimo, donde el
usuario logr su aparente objetivo: complicarle la vida. Pero ni tanto. No
olvidemos que Julia no es tcnica, luego en la oficina pedira ayuda a Diego.

27

Si observa en su KB la propiedad Page del nodo Grid, encontrar que tiene el valor Page.Rows. Qu es Page? Pues un
dominio enumerado creado automticamente, que contiene un solo valor, Rows, cuyo valor por defecto es 10 y que nosotros
hemos cambiado a 3.

94

Acciones en el Work With Countries

Aqu se muestran las acciones que el


pattern Work With tiene disponibles para
implementar sobre los datos del WWCountry
Exportacin
con los que trabaja. En particular obsrvese
que existe la opcin Export. Otra vez los
valores default! Otra vez, s, estos estarn
configurados en el objeto WorkWith que
vimos antes que centraliza todo esto. En
nuestro caso, los valores default para Delete
y para Export, eran true y false,
respectivamente. Para deshabilitar la accin de eliminacin de un pas y
habilitar la accin de exportacin, Julia slo tuvo que modificar los combos que
mostramos, pasndolos a false y true respectivamente. Requerimientos A
y B listos!
Ahora queda el ltimo requerimiento, el C: agregar una accin que no es
una de las predefinidas. Pero el objeto al que hay que invocar como resultado
de la accin, no es creado por el pattern Work With; se quiere hacer a
medida, para estos datos en particular. Se aparta de lo que es comn a

95

cualquier trabajar con. Aqu es donde deber intervenir Diego,


implementando en GeneXus ese objeto. Julia escribe en el selector
Documentation del WorkWithCountry que esto queda pendiente (qu selector
Documentation? Observe el tab que se abre cuando usted presiona doble clic
sobre el nodo WorkWithCountry del Folder View, bajo la transaccin Country
-vea pgina 84 y la siguiente pgina- todos los caminos conducen). Lo
hizo bajo un ttulo To-Do Diego para que sea implementado por l cuando
ponga manos a la obra28.

Los insaciables de siempre: quiero ms!


Tras volver de la reunin con los usuarios, Julia se encuentra con un e-mail
de los usuarios!... solicitndole que en la lista de pases del Trabajar con
se pudiera ver aunque ms no fuere un trozo de los detalles del pas,
CountryDetails, cuestin de poder comentar a sus clientes algo muy breve de
cada uno. Tambin queran poder ver para cada pas su cantidad de atracciones.
Necesitaba agregar dos nuevas columnas al grid del Work With Countries.
Una para la descripcin corta, y otra para la cantidad de atracciones. Pero no
saba cmo lograrlo, ya que esa informacin no estaba almacenada en atributos
de la base de datos, sino que se tena que obtener mediante algn
procesamiento. Ya tena en mente llamar a Diego para que le enseara cmo
implementar el requerimiento que haba quedado pendiente, el C, por lo que
tom el telfono inmediatamente.
Diego cre el dominio ShortDetails
de tipo Character(70). Luego abri el
Work With Pattern Instance de Country
y mediante el comando Add agreg una variable al grid.

28

Como ver un poco ms adelante, a Diego no le resultar nada complicado ubicar esta nota de Julia entre toda la
documentacin que se supone desperdigada entre tantos objetos de la KB, y ser gracias a las Categoras Dinmicas, de las
que l mismo hablar en el captulo 6.

96

Obsrvese que en el dilogo de propiedades se le debe necesariamente dar


un nombre y asignar un dominio a la variable que se est insertando (es lo que
). Diego le asigna como nombre ShortDetails y como
indica el cono
dominio el recin creado de igual nombre. Solamente resta decirle el valor que
deber tomar para cada lnea del grid.
Como bien intuyes, Julia, cuando ponas los atributos bajo este nodo
no era preciso decir ms: GeneXus recorrera la tabla COUNTRY, y para cada
registro que cumpliera con las condiciones de los filtros especificados (en este
caso veo que son por CountryName y CountryWorldRegion), cargara una lnea
nueva en el grid del Trabajar con con los valores de esos atributos en cada
columna. Si los usuarios quisieran la descripcin completa del pas, bastara
con incluir el atributo CountryDetails, pero lo que quieren es acortar la
descripcin a 70 caracteres. Por lo que, lo nico que tendremos que hacer es
especificar en la propiedad LoadCode de la variable que ingresamos, el valor
que tomar para cada lnea: ser la operacin de quedarnos con los primeros 70
caracteres del string29, es decir: &ShortDetails = Substr(CountryDetails,1,70).
S, CountryDetails es el atributo. As de sencillo. Ya puedes hacerlo sola.
Entiendo, y entonces para el otro requerimiento, el de mostrar el
nmero de atracciones que tiene cada pas
29
GeneXus cuenta con mltiples funciones para trabajar con los distintos tipos de datos. En particular, tiene la funcin substr,
que permite recuperar un substring de un string dado.

97

Bueno, en principio ah el procesamiento que debes hacer para cargar


la variable que contendr esa informacin es un poco ms complejo. Slo en
principio. Fjate que para el pas que se est cargando en una lnea del grid en
cada oportunidad, se debern recorrer todas sus atracciones para contarlas.
Tienes tres caminos: uno es programar ese cdigo que te permite recorrer
informacin30, otra vez en el LoadCode; otro, es agregar un atributo a la
transaccin Country, que contenga esa informacin, suponte un
CountryTotalAttractions. De esta manera slo tienes que agregar este atributo
al nodo Attributes de la instancia, y listo!
Pero, espera, no entiendo En ese caso, cuando el usuario ingrese la
informacin de un pas mediante la transaccin, va a digitar el nmero de
atracciones que contendr? Y si despus resulta que no coincide con las
atracciones reales que ingres? Eso no les va a gustar a los usuarios.
Julia, en cualquier momento me dejas en la calle! Exactamente, no
tiene sentido que el usuario tenga que digitar una cantidad que es resultado de
un clculo entre valores que estn en la base de datos. Este atributo,
CountryTotalAttractions ser de un tipo especial, que en GeneXus se denomina
frmula. Vers, ingresar ese atributo nuevo en la estructura de la transaccin
Country, y le dir a GeneXus que tengo ms informacin, que s cmo debe
calcularlo, y que por tanto no lo almacene en la base de datos, sino que siempre
que se le pida su valor, la calcule como yo le digo:

30

Ser el comando For Each, del que hablaremos ms adelante, en el Captulo 5.

98

Count(AttractionName)? Aj, con eso le dices a GeneXus que


quieres que para ese pas cuente la cantidad de valores de AttractionName
asociados31, no? Ahora, cmo sabe que tiene que contar las atracciones de
ese pas y no de todos los pases?
Bueno, recuerda que GeneXus conoce las relaciones entre los datos y
sabe que una atraccin pertenece a un pas y ciudad determinado. Y cada pasciudad pertenece en particular a un pas. Con eso basta.
Y qu ventaja tiene esta solucin para nosotros, frente a la otra, la de
agregar una variable en la instancia del pattern y decirle cmo hacer el clculo
con ese comando for each que dijiste -cosa que, por otra parte, no s hacer-?
Pues que aqu has implementado una solucin general. Si en otros
lados, en otros objetos, cuando recuperas un pas necesitas saber su cantidad de
atracciones, slo con nombrar el atributo frmula ya se dispara el clculo, y no
tienes que programarlo a mano. Ahora slo tienes que agregar al nodo
Attributes de la instancia este atributo frmula. Ya estn listos los dos
requerimientos del e-mail!
31
Para usted que s es informtico: para cada pas contar la cantidad de registros asociados de la tabla donde se encuentra
AttractionName, que en este momento es ATTRACTION.

99

Pero espera habas dicho que tenamos tres caminos posibles para
implementar esto ltimo y slo me has explicado dos.
Qu suerte, Julia. Estaba esperando que te dieras cuenta. De hecho, el
tercer camino es el que yo hubiera utilizado desde un principio en este caso. Si
no lo hice fue para aprovechar a explicarte esto de las frmulas globales. Lo
que hicimos sera lo ms recomendable si creyramos que muchas veces, y en
lugares distintos, vamos a tener que realizar esa misma cuenta de las
atracciones. Pero si por el contrario, ser en pocos lugares, tal vez lo mejor
hubiese sido directamente definir la variable como antes en el nodo Attributes
de la instancia del Work With, por ejemplo &CountryTotalAttractions, y en la
propiedad LoadCode de la variable, especificar &CountryTotalAttractions =
count( AttractionName ).
Pero no es la misma frmula que antes?
S y no. Aqu no has definido un atributo frmula, sino que ests
utilizando la frmula localmente, como si fuera una funcin. Por el contexto en
el que est especificada -en nuestro caso estar en un grid que recorre la tabla
de pases- sabr que deber contar solamente las atracciones del pas que se
est cargando en cada caso.

Existen diversos tipos de frmulas en GeneXus (para sumar, contar, buscar,


maximizar, minimizar, sacar promedios). Es importante destacar que se pueden
definir tanto en forma global, como atributos, as como localmente donde se
necesite. Cuando se definen globales sern atributos virtuales: no estarn
almacenados en la base de datos.

As mostr a Julia, tras el <F5> cmo luce ahora el trabajar con pases:

100

Quod Pattern non dat, GeneXus praestat32


En lo que Julia demor en ir a servirse un caf, saludar a un compaero y
volver con la taza humeante, Diego ya haba implementado el ltimo
requerimiento (el C pendiente). Como no estaban seguros si implementaba lo
que deseaban los clientes, capturaron la siguiente pantalla y se la enviaron por
e-mail:

32
N. de A. Frase latina, Quod Natura non dat, Salamantica non praestat para referir a que si la naturaleza no da inteligencia,
ni la prestigiosa Universidad de Salamanca puede darla.

101

Cmo lo hiciste tan rpido, Diego? Me enseas? No puede ser


complicado.
No lo es; lo que hice fue crear un nuevo objeto en GeneXus, de tipo
Web Panel. Es el que ests viendo en la pantalla en ejecucin. Fjate que lo
que deseas es mostrar informacin de pases y de ciudades (las suyas). Olvdate
por un momento de los pases, y supn que slo quieres listar informacin de
las ciudades, en un grid. Lo nico que debes hacer es insertar un control de este
tipo en el form del web panel y decir qu atributos compondrn sus columnas.
Slo con hacer esto, cuando presiones <F5> vers en ejecucin listadas todas
las ciudades existentes. GeneXus observa los atributos presentes y de ellos
infiere la tabla que deseas navegar (le llama tabla base). Fjate cre un web

102

panel Cities en un segundo, insert el grid mediante la toolbox que ofrece


todos los controles que pueden insertarse en un form, eligi el atributo
CityName, y qued el form del objeto como puede ver a continuacin- en
nuestro caso: los atributos que colocamos en el grid (CityName) son de la tabla
COUNTRYCITY y esa ser la que navegar GeneXus.

La grilla que hemos insertado se conoce como Grid, a secas, grid


estndar, ya que permite mostrar la informacin de un registro de una tabla
-y de su extendida-, con un elemento de informacin por columna -observa
que nuestro grid tiene una sola columna, corresponde al atributo CityName,
pero si tuviramos otro, lo colocara en otra columna-. Ahora olvdate por un
instante de las ciudades, y piensa que algo muy parecido quieres hacer con
los pases, slo que quieres mostrar la informacin de cada pas no en
columnas rgidas, sino de forma ms flexible, como puedes ver en la pantalla
que le enviamos a los clientes. Observa el web panel que hice mientras ibas
por tu taza de caf:
-

103

- Observa que ahora aparece el grid de ciudades, junto con los atributos
CountryFlag y CountryName dentro de un rectngulo. Qu es? Otro tipo de
grid, uno llamado Free Style, pues como ves, la informacin del pas que
quieres listar se muestra no por columna, sino toda junta, con el diseo que t
decidas. Pero tambin es un grid. Mostrar por tanto, tantos pases como
existan en la tabla de pases. Observa que en sus propiedades aparece una
Columns, a la que modifiqu el valor de 1 a 3, y es por ello que puedes
ver en la imagen que le enviamos a los usuarios tres pases por fila. Rows 0
significa que no realice paginado, sino que muestre todos los pases
existentes. Luego observa que dentro del Free Style, podemos colocar
cualquier control, incluyendo otro grid. Y al hacerlo, GeneXus encuentra las

104

relaciones entre las tablas, y es por esta razn que est listando por cada pas,
sus ciudades en el grid, sin tener que indicarle nada, lo hace solo. Si no te
convence, mralo t misma en el listado de navegacin que aparece luego de
la especificacin, tras el <F5>. A ver si lo entiendes

El pas que se est


cargando en el
id

- Lo que s entiendo es por qu lo implementaste tan rpido no es que


Natura te dio, es que GeneXus te prest. No tuviste que hacer casi
nada!, Diego Cambia esa cara, estaba bromeando. No vendr tu amiga
hoy a verte?
- adems podramos hacer otro web panel, invocado va un Tab del
View de pases, que dado el pas muestre las imgenes de las atracciones de

105

ese pas, como una galera de imgenes que se deslizan. Quisiera hacer algo
que impresione qued pensativo.
- A los usuarios? Bueno, Diego, veo que hoy no ests para bromas.
Antes de que sigas, qued pendiente poder llamar desde el Work With
Countries a este web panel que acabas de implementar.
- Es verdad, pero eso sabes hacerlo. Simplemente debes agregar una
nueva accin a las ya predeterminadas (insert, update, etc.) en la instancia
del Work With de Country: la asociaremos a un botn fuera del grid y le
indicaremos que en esa accin queremos invocar al web panel
CitiesPerCountry que acabo de crear.
Sobre el nodo Selection (Work With Countries), con botn derecho,
seleccionar Add actions y luego posicionarse sobre el nuevo nodo Action y
otra vez repetir la operacin. Vea lo que hicieron nuestros amigos, y la
repercusin en ejecucin:

106

el web panel creado


Botn dentro del grid?

Se quiere imagen para la


accin en lugar de botn?

Requerimiento C listo!

Nuevo Tab en el View Country


Diego quera impresionar a alguien, no sabemos a quin (quizs a usted,
estimado lector) con un nuevo requerimiento: en el ViewCountry, agregar un
nuevo control Tab que muestre en una galera de imgenes las atracciones de
ese pas. Es decir, algo que en ejecucin se ver:

107

En todo momento se mostrarn 3 imgenes, siendo la del centro la activa.


Cuando se pulsa sobre la de la derecha, la del medio pasa a la izquierda, la de la
derecha al centro (pasa a ser la activa) y aparece una nueva a la derecha.
Para lograr esto, Diego agrega un nodo Tab en la instancia del pattern Work
With correspondiente al View, que se cargar con el contenido de otro objeto
GeneXus que luego deber programar. Podra ser un web panel, pero en
realidad tiene que ser un objeto que se pueda ejecutar dentro de otro (en nuestro
caso del ViewCountry). Se tratar de un Web Component. A los dems efectos
ser igual que un web panel. Le llamar CountryAttractions, y deber indicar
en el nuevo Tab que se cargar con el mismo:

108

Se le deber pasar el CountryId como


parmetro al Web Component que
implementa la galera de imgenes.

Cmo se implementa? Otra cara de la extensibilidad: User controls


Adems de los controles estndares que usted suele insertar en sus paneles
(attribute, grid, text block, etc.), GeneXus X le permite crear sus propios
controles personalizados: user controls. Una vez que un control de usuario es
instalado, puede ser utilizado como cualquier control estndar. GeneXus X
viene con algunos controles de usuario ya instalados (vea la toolbox en el IDE;
ellos se encuentran agrupados bajo el rtulo User Constrols): uno de ellos es el
ImageGallery. Observemos en la foto composicin que sigue que Diego insert
un control de ese tipo en el form del web component, y luego lo nico que tuvo
que hacer fue configurarle sus propiedades. Al insertar este control en el form,
se crea automticamente un tipo de datos estructurado, ImagesData, ms
conocido como SDT por su sigla en ingls, que en forma flexible permite
construir listas de largo variable de records. En este caso, una lista de
elementos en el que cada uno tendr la informacin de la atraccin a mostrar;
esto es: su id, el lugar donde se encuentra la imagen (en general se almacena la

109

imagen en tamao grande, y la misma imagen en tamao pequeo) y la


descripcin de la misma. Junto con el SDT se crea automticamente la variable
&imagesData basada en el mismo, justamente para cargar las imgenes a
mostrar.
Por tanto, lo nico que Diego debi hacer fue programar la carga de esa
variable. Cmo lo hizo? En el evento Start del Web Component escribi la
invocacin a un objeto que cre inmediatamente, que justamente tiene por
objeto cargar estructuras jerrquicas de datos, como SDTs. Ese objeto es de un
tipo que veremos ms adelante (el Data Provider). No importa que ahora no
entienda este cdigo. Slo queramos mostrarle lo fcil que es lograr este
requerimiento.

110

Look & Feel consistente, sin transpirar?


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 ley
Julia en voz alta de una revista tcnica que estaba sobre la mesa del escritorio
de Diego.

111

No con las Master Pages acot Diego-. Como te cont, un web


panel puede implementar una pgina web comn y corriente, como la que
hicimos, CitiesPerCountry -con los grids Free Style y estndar-, es decir, una
pgina web independiente que ser invocada por otra -en nuestro caso por
WWCountry-; o puede implementar una pgina web que ser parte
componente de otra, como la de la galera de imgenes que era un Web
Component parte del ViewCountry; o por ltimo, puede ser una pgina
maestra, es decir, una pgina que contiene centralizado all lo que ser comn a
todas las pginas del sitio,
como el encabezado y el pie
de pgina que has visto por
todos
lados
repetido;
incluso suelen tener un
men vertical a la izquierda, de manera tal que slo est en un lugar, y que si se
quiere modificar, se lo haga en un solo sitio.
Con razn! Cuando empezamos con el proyecto vi a Mike ejecutando
las transacciones y no entenda cmo era que todas salan con el mismo
encabezado y pie de pgina (que tambin veo ahora que tienen el Work With
Countries, y el View Country) siendo que en el form de esos objetos esas partes
no aparecan. Existe una master page que programa ese look comn, verdad?
Efectivamente. Mira esto- dijo
Diego a la vez que seleccionaba la
transaccin Country y acceda a sus
propiedades-. Vers lo mismo en cada
transaccin y en los web panels creados por
patterns: AppMasterPage es una master
page creada automticamente con la KB
-observa el contenido de la carpeta
GeneralWeb- que es la que contiene ese
encabezado y pie de pgina que se repite por

112

doquier. Si abrimos este web panel, mira sus propiedades. Qu te dice esto?

Y aqu no slo se programa el form comn: tambin se le puede programar el


comportamiento comn. Es ms que habitual que las pginas sean restringidas
a usuarios autorizados, que debern loguearse al sistema antes de comenzar a
navegar por las distintas pginas del sitio. Antiguamente la validacin de que el
usuario estuviera autorizado deba repetirse en cada pgina web a la que se
accediera. Sin embargo, con las master pages, alcanza con escribir el cdigo de
validacin solamente una vez, aqu, y listo! Nos aseguramos que todas las
pginas asociadas realizarn esa validacin, y su cdigo no estar desperdigado
por todos lados.
Qu bueno! Digo, para ustedes, que tienen que trabajar menos para
que les quede todo consistente. Me voy a almorzar y luego a impactar el
pattern al resto de las transacciones que tenemos Ya almorzaste?

113

114

Captulo 4

Vuelo al mundo de los subtipos


El proyecto avanzaba segn los tiempos estipulados. Cada uno en lo suyo.
Dada la filosofa incremental de GeneXus, no teman a los cambios ni a lo
nuevo. El modelo amparaba todo lo necesario. Slo lo necesario.

Restantes Transacciones al vuelo


Diego no haba almorzado, no tena apetito. Deba comenzar a crear el resto
de las transacciones, pero decidi esperar un rato. Quera lucirse frente a Mary,
a quien haba ofrecido mostrar ms de GeneXus. En lugar de llevar su notebook
al bar, le haba propuesto encontrarse, esa misma tarde, en su oficina en
ACME.
Mary, te ves bien. Cmo ests?
Mejor. Te agradezco que me hubieras invitado a vernos de nuevo, an
cuando estemos en empresas competidoras. Es un lindo gesto de tu parte.
- Mmm bueno, no es tan as dijo pensativo, mientras en la pizarra a
sus espaldas escriba: la Comunidad . No, por favor, no me malinterpretes,
no quise decir Me refera a esto de la rivalidad, de la competencia. Mira,
entre los miles de desarrolladores GeneXus existe en forma etrea algo que
se conoce como la Comunidad. Es muy estimulante. Sinrgico,
escuchars decir. T me preguntars si es un club; pues no desde el punto de
vista de actividades sociales o deportivas, al menos por ahora agreg
sonriendo, intentando disimular el temblor en la voz , pero s respecto a la
interaccin. Es como un tejido del que todos formamos parte, compartiendo
conocimiento y soluciones a travs de GeneXus y de las dems herramientas
que se han desarrollado alrededor. Existen muchas extensiones creadas por la
Comunidad para satisfacer distintas necesidades. Hay muchos sitios Web de
donde descargarlas, y a donde subirlas tambin. La Comunidad es muy
activa. Existen decenas de foros donde se intercambian soluciones de todo
115

tipo. Yo estoy en las listas de varios de ellos, y me considero un miembro


activo.
Suena lindo. Pero, funciona? O sea, te dan una mano desinteresada
cuando la necesitas, o es puro cuento?
Es que es hoy por m y maana por ti. Todos necesitamos una mano
de vez en cuando. Si en vez de vernos como competidores nos sentimos
cooperadores, trabajamos mejor, ms animados, llegamos a mejores soluciones,
para todos. Tiramos para un mismo lado: hacer crecer a la Comunidad, en
beneficio de todos. Puede resultarte un poco ingenuo, pero la prueba est a la
vista: funciona. Como evidencia de ello, el propio GeneXus est compuesto por
extensiones de GeneXus. Es decir, la Comunidad puede seguir haciendo crecer
a GeneXus con sus propias extensiones. De hecho, GeneXus puede
considerarse en s mismo una extensin.
Tras reparar en esa luz antigua, conocida, que adquira su mirada, continu
ms seguro:
Mira invit Diego al tiempo que abra la ventana Extensions
Manager a travs de la opcin Tools del men de GeneXus . Esta es la lista de
extensiones que componen GeneXus X en este momento. La mayora han sido
desarrolladas por Artech y las otras por personas de la Comunidad que las
publican para que diferentes miembros puedan hacer uso de ellas.
Veo que en la Start Page aparece una seccin que dice Extensions,
con un abstract escrito por el autor, y un link para instalarla.
S, y si te fijas, aparecen
unas cuantas que no dicen By
Artech. Son extensiones realizadas
por terceros, miembros de la
Comunidad.
En cuanto al proyecto en s y al
punto en que haban llegado, la realidad reclamaba otras transacciones. Tras
una breve ojeada a lo ya hecho, Diego pas a crear Airline. Su finalidad:

116

almacenar el nombre de las compaas areas involucradas con Travel Agency


& Co.

Transaccin Flight: vuelo al mundo de los Subtipos


En cuanto Diego mir sus papeles, agradeci por la complejidad asociada a
la prxima transaccin. A Mary solan gustarle los desafos.
Mary, vamos a crear la siguiente transaccin, pero va a hacer falta un
poco de concentracin de tu parte advirti tratando de predisponerla Mira
este caso. La transaccin contendr informacin relativa a los vuelos; cosas
tales como la descripcin, la aerolnea, la hora de despegue, la cantidad
mxima de pasajeros, fciles de entender y de inferir; y por otro lado,
tendremos la ciudad de donde se sale y la ciudad a donde se llega33,
informacin que debemos conocer y almacenar porque est comprendida en la
realidad. Recuerdas que te coment en el bar que dos atributos con igual
concepto deben tener el mismo nombre?
S, fue cuando me explicaste cmo crear la transaccin Country.
Recuerdo perfectamente que mencionaste que haba una excepcin
Lleg la hora de aclarar eso. Hay momentos en los que no hay ms
remedio que llamar distinto a dos atributos que son bsicamente lo mismo.
Mira, en la transaccin Flight se nos presenta el problema que da lugar a la
excepcin que lo resuelve: en cada vuelo existen dos pases y dos ciudades
involucradas, que cumplen roles diferentes: un pas y una ciudad son de partida
y otro pas y ciudad son de destino. Es decir, tenemos dos referencias a una
misma tabla, COUNTRYCITY. Observa, si slo escribiramos esto que dibujo
en el papel:

33

Recuerde que estamos simplificando la realidad: supondremos que no habr nunca ms de un aeropuerto por ciudad.

117

podramos
decir
que
los
atributos CountryId
y CityId en la
transaccin Flight
representan
una
ciudad de un pas,
pues se llaman igual que los identificadores de la transaccin Country. Es decir,
sern una clave fornea a la tabla COUNTRYCITY. Hasta all nada nuevo bajo
el sol, pero ahora debemos agregar otra ciudad34, en otro rol, el de ciudad de
destino. Es decir, tiene que aparecer una doble referencia a una ciudad: en un
caso en un rol de ciudad origen, y en el otro de ciudad destino. Cmo hacemos
esto? GeneXus no nos permitir agregar la misma pareja de atributos en la
misma transaccin, eso es obvio porque cmo se discriminara entre un
atributo y otro?! Pero podramos hacer algo as tom el lpiz y escribi dos
atributos nuevos, luego de lo cual antecedi a los dos primeros con la D de
departure y a los dos ltimos con A de arrival.
Hmm pero si GeneXus entiende que si se llaman distinto son otra
cosa ya no habra conexin entre vuelos y ciudades, verdad?...
Verdad. Solucin? Poder decirle a GeneXus que si bien se les ha
cambiado el nombre a los
atributos, por la necesidad
de diferenciarlos, de todos
modos corresponden al
mismo concepto. Es decir,
que no se confunda: que
por ms que el atributo
DCountryId no se llame
34

Cuando hablamos de ciudad, nos referimos a una ciudad real, como Pars. Para identificar una ciudad, necesariamente
debemos dar el par {CountryId, CityId}. Est sobreentendido. Por el diseo de las transacciones, una ciudad no tiene existencia
independiente del pas al que pertenece. As, existe ciudad Rosario de Argentina y ciudad Rosario de Uruguay. Pero no existe
Rosario, independiente del pas del que se trate.

118

CountryId, a todos los efectos es como si se llamase as, de modo que siga
estableciendo las relaciones de integridad referencial igual que antes. Decirle
esto a GeneXus es decirle que DCountryId es un subtipo de CountryId35. La
solucin completa, por tanto, es agrupar estas parejas en dos grupos de
subtipos, ves? inquira mientras rearmaba el croquis.
- Ah, comprendo! Gracias
a ello, DCountryId y
DCityId sern una clave
fornea en FLIGHT a la
tabla COUNTRYCITY, al
igual que ACountryId y
ACityId, verdad? Tienes dos claves forneas a la misma tabla.
As es, y se deben realizar todos
los controles de integridad referencial
automticamente contest al tiempo que
descubra un entusiasmo nuevo en Mary.
Podra luego quitarla del teclado?
De todos modos el problema no
se termin aqu continu Diego . En esta transaccin, adems de representar
que un vuelo tiene un pas-ciudad de origen y uno de destino, cosa que ya
hicimos, queremos poder inferir el nombre de cada pas y ciudad, para verlos
en el form. Es decir, queremos inferir para mostrar atributos que pertenecen a la
tabla extendida de FLIGHT, pero cmo los inferimos si tenemos una doble
referencia a la tabla?, es decir, no podemos poner directamente CityName,
porque de cul se tratara? Del atributo que se debe inferir de la clave fornea
{DCountryId, DCityId}, o del que se debe inferir de la otra clave fornea
{ACountryId, ACityId}? Hay una ambigedad!
Y bueno, le tendrs que cambiar el nombre tambin a esos atributos que
necesitas inferir (CountryName, CityName) y colocarlos en el grupo de
35

Recprocamente, decimos que CountryId es supertipo de DCountryId

119

subtipos adecuado pens Mary, pero no emiti palabra . Mustrame cmo


se definen estos grupos en GeneXus, anda; as lo termino de entender.
Diego seleccion el icono Subtype Group de la ventana New Object, y le
asign por nombre Departure. Mary mantena un silencio cmplice

Te haba dicho grupos, y realmente es as. Creas uno, le das un


nombre y le incluyes los nuevos atributos36 apuntando a sus respectivos
supertipos. Entonces, expresado as, GeneXus sabr que el atributo
FlightDepartureCountryName ser inferido a travs del atributo
FlightDepartureCountryId y no otro. Por pertenecer ambos al mismo grupo,
Departure. Comprendes la conexin?
Comprendo respondi
ella. Esto quiere decir que
cuando el usuario digite un
valor sobre la clave fornea
{FlightDepartureCountryId,
FlightDepartureCityId} no slo
se va a disparar el control de
integridad referencial sobre
COUNTRYCITY sino que se va a inferir en el atributo
FlightDepartureCityName el nombre correspondiente a ese cdigo de pasciudad y tambin, por tabla extendida, se inferir el CountryName de ese pas
36

Obsrvese cmo Diego ha establecido el nombre de los subtipos respetando la nomenclatura GIK y comienzan con Flight,
el nombre de la transaccin, y continan con el nombre del grupo, Departure. De esta manera se asegura una semntica clara,
estableciendo el rol que juegan en la transaccin.

120

en FlightDepartureCountryName. Ahora habra que crear el otro grupo de


subtipos, el de los arribos, verdad?
Bueno, no necesariamente, pues ya estn claramente identificados los
dos grupos; uno es el explcito, el que acabo de crear. Y el otro est implcito
si yo coloco los atributos CountryId, CityId en la estructura de la transaccin37.
Pero por claridad, solemos en casos de este tipo mantener todas las ocurrencias
en grupos, porque si no uno de los roles, en este caso el de ciudad de arribo, no
quedara claramente identificado. Te invito a que t sola armes el otro grupo,
te animas? pregunt Diego, sealando con su mano el laptop.
Bueno, veamos dijo ella controlando su impulso de abalanzarse
sobre el teclado. Tipe, tipe y tipe, hasta que

Perfecto! Diego ya tena todo para crear la transaccin Flight en GeneXus.


Esta transaccin ser de dos niveles dado que para cada vuelo existen tres
clases (Business, Standard y Executive) con tres precios diferentes, lo
que en realidad la transforma en una lista de precios (relacin 1-N). Todos los
vuelos tienen hasta tres tarifas, no ms.
Otra cosa importante: el identificador de vuelo no deber numerarse
automticamente, dado que ese nmero lo determina un estndar internacional,
que considera ruta y hora. Por ejemplo, el vuelo 0174, Montevideo-Buenos
37

Slo con cambiarle el nombre a una de las dos ocurrencias de CountryId y de CityId alcanzara para eliminar la ambigedad.

121

Aires, corresponde a un vuelo de la aerolnea Pluna de los sbados de maana.


Si ese vuelo cambiara para la tarde, tambin cambiara su nmero de vuelo.
La siguiente imagen muestra la estructura final. Observe usted el cono
que indica que el atributo es un subtipo y adems parte de clave fornea; y el
cono que indica que es un subtipo, por un lado, e inferido, por el otro.

Capacidad mxima de pasajeros en el vuelo

Viendo que el atributo FlightClassType slo puede tener hasta tres posibles
valores fijos: Business, Standard y Executive, Diego cre un dominio
enumerado para l.
El atributo FlightDepartureTime almacena la hora del vuelo (no nos interesa la
fecha). Obsrvese su tipo de datos DateTime. De l, slo se utilizar la parte que
representa Time, por lo que en sus propiedades, modificaremos bajo el grupo
Picture la de nombre Date format. La pasaremos a None.

Antes y despus
Para mostrarle a Mary en ejecucin la nueva transaccin, hizo <F5> tras lo
cual tuvo que reorganizar la base de datos (tres nuevas tablas sern creadas).

122

Mary no pudo ocultar su cara de


decepcin.
Diego,
que
estaba
pendiente de todas sus reacciones y
que tambin percibi un form un poco
pesado
de
ver,
agreg
inmediatamente: vamos a arreglar
este form que est muy poco
amigable.
Para hacer el ingreso de pas de
partida y ciudad de partida ms
amigable para el usuario, podra
utilizar combo boxes dinmicos, o
disfrazar al Id del Nombre (recuerde
lo que hizo en la pgina 69) y lo
mismo con el pas y ciudad de
llegada, as como con la aerolnea.

Comencemos con los pases y las ciudades;


podra editar las propiedades del atributo
FlightDepartureCountryId en la estructura y
modificar su propiedad ControlType (y hacer
lo mismo para los dems) a Dynamic Combo
Box.
Aj -se apur Mary-,y en la propiedad
ItemDescriptions tendras que poner FlightDepartureCountryName, que es
donde quieres inferir el nombre del pas, as saldrn como descripciones en el
combo, los nombres de los pases de la tabla COUNTRY

123

Bueno, s, eso es lo que quieres, pero por eso mismo, all debers
colocar el atributo CountryName y no el subtipo, porque en verdad es as como
se llama el atributo en la tabla COUNTRY y no FlightDepartureCountryName.
As, Diego escribi CountryName en
la propiedad ItemDescriptions y
tambin modific el valor de la
propiedad ContextualTitle del atributo
FlightDepartureCountryName que ahora
dice Departure country. Hizo anlogas
acciones para FlightDepartureCityId,
para FlightArrivalCountryId y para
FlightArrivalCityId. Observe cmo luce
ahora el form, sin que Diego tocara nada
en l.
Hizo lo mismo para Airline, y
adems edit las propiedades del grid en
el form, modificando el valor de Rows,
pasndolo de 5 a 0. El valor de esta
propiedad especifica la cantidad de
lneas vacas que se presentan en
ejecucin para que el usuario ingrese los
datos all. Obsrvese que no es necesario
tener ninguna lnea vaca, dado que
abajo del grid aparece [New Row] para
agregar una lnea vaca al grid y poder llenarla.
Nuestro amigo hizo <F5> para mostrarle a Mary en ejecucin el despus:

124

...cuando sta sorpresivamente anunci que


deba irse.
Mil gracias, Diego. Ahora
disclpame pero debo irme, te llamo
en estos das.

Un vuelo real: transaccin FlightInstance


La transaccin Flight pretende manejar datos generales de un vuelo, por
ejemplo, el 0174 de la aerolnea Pluna, Montevideo-Buenos Aires, que sale
todos los das a las 11:15 AM. Pero por cada vuelo 0174, tendremos un avin
real, que realizar en un da determinado, ese viaje, con determinados
pasajeros.
Lo que consigue la siguiente transaccin es representar el vuelo real, con
informacin como la fecha y hora de partida, la cantidad de pasajeros, sus

125

reservas con sus nombres y nmeros de asiento. Aqu el identificador s ser


numrico y autonumerado.

count(FlightInstancePassengerSeatNumber)

Con este diseo, FlightNumber ser una clave fornea. Cuntos FlightInstance
podrn haber para el mismo vuelo, FlightNumber? Corresponde a lo deseado?

Existen algunos atributos aqu que merecen especial atencin. Por ejemplo,
FlightDepartureTime38 es la hora de partida estipulada del vuelo (es inferido de
FlightNumber), mientras que FlightInstanceDate y FlightInstanceTime son la
fecha y hora reales, del vuelo real. La hora del vuelo real, se inicializa en forma
predeterminada con el valor de FlightDepartureTime, pudiendo ser cambiada
por el usuario, para lo que Diego declar en las Rules:
default(FlightInstanceTime, FlightDepartureTime);

Esta regla slo se ejecuta cuando el modo es Insert. Por otro lado, observe
la otra regla que ha agregado Diego:
error('Number of passengers exceeded')
if FlightInstanceNumberOfPassengers > FlightTotalCapacity;

38

Si bien los atributos FlightDepartureTime y FlightInstanceTime son de tipo DateTime (permiten almacenar una fecha+hora),
slo nos interesa la representacin de la hora.

126

El atributo FlightTotalCapacity es inferido a travs de FlightNumber. Y


FlightInstanceNumberOfPassengers? Es una frmula que cuenta la cantidad de
lneas que se han ingresado en el subnivel. Cada vez que se agregue un nuevo
pasajero en el grid del form (que no hemos mostrado pero que usted imaginar
sin problemas), se estar agregando un nuevo nmero de asiento para ese vuelo
real, FlightInstancePassengerSeatNumber, por lo que la frmula se actualizar,
sumando 1, y si con ese pasajero se ha superado la capacidad, se disparar el
error que impedir que se inserte en la base de datos el pasajero para ese vuelo.
Por ltimo, Diego declara la regla:
error('The flight departure cannot be advanced')
if update and (FlightInstanceDate < FlightInstanceDate.GetOldValue()
or (FlightInstanceDate = FlightInstanceDate.GetOldValue() and
FlightInstanceTime < FlightInstanceTime.GetOldValue()));

Es decir, si se est actualizando un vuelo real, slo se permitir modificar su


da y/u hora de partida, siempre y cuando no se lo adelante. Obsrvese que se
utiliza el mtodo GetOldValue() de un atributo, que devuelve el valor que est
almacenado en la base de datos, mientras que el atributo tiene ahora en
memoria el valor que el usuario coloc en el form en este momento (an no se
ha grabado).
Por supuesto, se necesitar almacenar informacin de los pasajeros, por lo
que Diego crear la ltima transaccin de esta etapa y el atributo PassengerId
pasar a ser clave fornea en FlightInstance, as como PassengerName inferido.

De carne y hueso: Transaccin Passenger

127

El siguiente Diagrama representa las relaciones entre las nuevas tablas y las
viejas.

Diego puls <F5>. Todo pareca bien, as que reorganiz la base de datos.
Luego accedi al Wiki, document la terminacin de esta etapa y dej a Mike
la tarea de probar lo hecho y a Julia la tarea de aplicar los Work With al resto de
las transacciones.

128

Captulo 5

Cuando el qu no alcanza
Slo declarar?... y las descripciones procedurales?
Fue lo que Mary cuestion un par de citas despus, en el bar de siempre. Se
haban estado viendo con mayor frecuencia, en su oficina o en el bar, lo que
haba dado oportunidad a intercambiar sobre varios asuntos, como patterns,
web panels y dems. Lleg a este nuevo encuentro, reflexiva. Deca entender
que las transacciones permiten de manera declarativa describir las visiones de
datos de los usuarios. Pero, es esto suficiente? Qu pasa con los procesos
batch o similares, que en toda aplicacin se necesitan? Estos procesos no se
pueden inferir a partir del conocimiento aportado por las visiones de datos.
Entonces?
S, faltara un lenguaje procedural, estamos de acuerdo ratific
Diego-. Si piensas en la filosofa de GeneXus, evidentemente deber ser un
lenguaje de muy alto nivel. Ms an: deber ser un lenguaje que no utilice
jams referencias al Modelo Relacional, sino slo al Externo. Te mostrar un
ejemplo tonto: suponte que necesitas, por la razn que fuere, por ejemplo por
malas condiciones en la pista de un determinado aeropuerto en un determinado
momento de un determinado da, posponer la hora de partida prevista de todos
los vuelos grandes (que sobrepasan determinada capacidad de pasajeros).
Suponte que debern atrasarse. En definitiva, debers acceder a todos los
registros de FLIGHTINSTANCE, tales que el valor de FlightInstanceDate y
FlightInstanceTime coincidan con la fecha y hora en la que no deben despegar
los aviones, y tales que correspondan a un vuelo que parta del pas y ciudad
determinado (aeropuerto) y que tenga una capacidad de pasajeros mayor que un
valor determinado. Para esos registros debes modificar el valor de
FlightInstanceTime, y eventualmente tambin el de FlightInstanceDate por los
nuevos. Podras hacerlo filtrando en el Work With FlightInstance por esos

129

valores, y para cada lnea (un


vuelo real) desplegada en el grid,
llamar
a
la
transaccin
FlightInstance en modo Update y
modificar
los
valores
manualmente, lo que seguramente
ser inaceptable para el usuario
final. La otra alternativa: desde
algn web panel en variables
pedirle al usuario los valores de
fecha y hora a modificar, pas y
ciudad, y capacidad, y el valor de
la nueva fecha y hora de esos
vuelos, y luego llamar mediante una accin (botn o imagen)
a un procedimiento que recorra los registros y realice el cambio al tiempo que
lo deca, abra su notebook e implementaba el web panel.
Un procedimiento comn y corriente?
S, ser un nuevo tipo de objeto GeneXus. Queremos que cuando el
usuario presione sobre el botn Change flights, que est asociado al evento
Enter del web panel, se invoque a este nuevo objeto.
Event Enter
ChangeDepartureTime.Call( &FlightDate, &FlightTime,
&DepartureCountry,&DepartureCity, &NewDate, &NewTime, &capacity
)
EndEvent

Vamos a crearlo entonces.

Segundos despus, Diego tena creado el procedimiento que implementaba


la lgica anterior:

130

donde las variables que aparecen fueron declaradas por Diego como
parmetros de entrada del procedimiento, en el selector Rules:
parm( in: &CurrentInstanceDate, in: &CurrentInstanceTime,
in: &CountryId, in: &CityId, in: &NewFlightInstanceDate,
in: &NewFlightInstanceTime, in: &FlightTotalCapacity);

Espera, Diego, que me he perdido. Deduzco que el For each es un


comando que permite acceder a la base de datos recorriendo una tabla. Pero,
dnde le dices que es FLIGHTINSTANCE la tabla que debe recorrer?
Adems ests utilizando atributos de otra tabla tambin. No deberas recorrer
primero FLIGHT, y para los registros que cumplan con las condiciones, hacer
un join con la tabla FLIGHTINSTANCE?
No es necesario observ Diego-. Para empezar, la tabla no se la
dices directamente. Ah est la gracia. Mira lo que le ests diciendo con el For
each que hemos escrito:39 para cada registro de la tabla donde se encuentren
FlightInstanceDate,
FlightInstanceTime,
FlightDepartureCountryId,
FlightDepartureCityId, y FlightTotalCapacity mencionados, tales que los
39

Respire profundo, amigo lector, no se nos vaya a quedar sin aire a la mitad

131

valores de los primeros cuatro coincidan con los de las variables recibidas por
parmetro, y el valor de FlightTotalCapacity sea mayor o igual que el de la
variable tambin recibida por parmetro, cmbiale el valor que contengan
FlightInstanceDate y a FlightInstanceTime por los indicados.
Sigo sin entender. Esos atributos estn en tablas distintas.
FlightInstanceDate y FlightInstanceTime estn en FLIGHTINSTANCE, s,
pero los dems estn todos en FLIGHT No deberas recorrer?
Cierto interrumpi Diego sin dejarla terminar-. Pero FLIGHT est
en la tabla extendida de FLIGHTINSTANCE. Es decir, por cada vuelo real,
tienes un FlightNumber (clave fornea) que corresponde a un y solo un registro
de
FLIGHT,
que
tiene
un
FlightDepartureCountryId,
un
FlightDepartureCityId, y un FlightTotalCapacity. Hay una relacin N a 1 entre
FLIGHTINSTANCE y FLIGHT. Con eso no necesita ms: sabr que debe
recorrer la tabla FLIGHTINSTANCE, accediendo para cada registro a su
correspondiente en FLIGHT, es decir, haciendo un join automtico para saber
el valor de los atributos FlightDepartureCountryId, FlightDepartureCityId y
FlightTotalCapacity y con eso decidir si se queda o no con el registro para
procesarlo (por supuesto, siempre y cuando el propio registro de
FLIGHTINSTANCE cumpla con ser del da y hora indicados por las variables
&CurrentInstanceDate y &CurrentInstanceTime). La condicin que impone
sobre un registro para quedarse con l y procesarlo, es la concatenacin con
And de todas las condiciones lgicas que ves en las clusulas Where del For
each. Como antes hablamos de tabla base, aqu tambin: para el For each es la
tabla que recorre. Observa, entonces, cmo conociendo las relaciones entre las
tablas y dnde estn los atributos en el momento del anlisis, GeneXus puede
inferir el acceso a los datos sin que le tengas que nombrar tabla alguna. Esto
tiene una consecuencia importante: permite que se puedan cambiar de tabla
esos atributos, sin que la descripcin del procedimiento pierda validez40.

40
Por supuesto: siempre y cuando los atributos pertenezcan a una misma tabla extendida. En caso contrario GeneXus arrojar
un error, informando que no fue posible relacionar los atributos.

132

Por qu? Hmmm parece un poco mgico, no me sentira segura


programando as.
No Mary, creme, nada es mgico. Miremos el listado de navegacin
para aclarar tus dudas (y las mas; siempre antes de ejecutar un procedimiento
para probarlo, el primer test ya est hecho: es el listado de navegacin, que
informa sobre gran parte de lo que te da inseguridad. Por eso, nunca ejecuto sin
antes mirar ese listado. Bueno, est bien, a ti no te voy a mentir. A veces no lo
miro, de apurado noms, pero luego me arrepiento). Mirmoslo juntos (si
slo quiere verse el listado de navegacin, en lugar de hacer <F5> que adems
construir todos los programas, se puede hacer botn derecho sobre el tab del
procedimiento, y elegir la opcin View Navigation)

Tabla base

Ves? Te informa la tabla base del For each, el orden por el que
procesar la informacin41 y el ndice que propone para satisfacer ese orden (si
es que existe). Adems te informa los filtros de navegacin, es decir, desde
dnde empezar a recorrer la tabla y hasta dnde (en nuestro caso, recorrer
41

El orden puede indicarse mediante la clusula Order del comando For each. Como no se ha indicado, y no existe ningn
ndice en la base de datos que permita optimizar la bsqueda de los registros que cumplan estas condiciones, asume clave
primaria de la tabla a recorrer.

133

toda la tabla42). Luego se observan las Constraints (filtros sobre los registros a
recorrer). Ms abajo te informa que por cada registro de FLIGHTINSTANCE
deber hacerse un join con la tabla FLIGHT de su extendida (para realizar los
filtros
por
FlightDepartureCountryId,
FlightDepartureCityId
y
FlightTotalCapacity) y que se actualizarn de la tabla FLIGHTINSTANCE los
atributos FlightInstanceDate y FlightInstanceTime. S franca, Mary, y dime
cunto ms te costar implementar esto mismo utilizando las herramientas que
usas. Habras implementado t misma este join. Lo mejor de todo, en verdad,
es el hecho de seguir hablando en alto nivel. Piensa qu pasara en tu
implementacin, que seguramente requerir nombrar las tablas, si mueves por
ejemplo, el atributo FlightTotalCapacity de FLIGHT a FLIGHTINSTANCE.
Aqu no tendrs que tocar absolutamente nada. Simplemente volver a generar el
objeto, para que GeneXus infiera la nueva navegacin y listo!
S, comprendo. Y cmo insertas y eliminas registros de la base de
datos?
Bueno, el comando For each te permite recorrer una tabla de la base
de datos, y acceder a su extendida, tanto para consultar solamente, como para
actualizar atributos. Por este motivo, es un comando importantsimo, que podr
ser utilizado no slo en procedimientos sino en todo objeto GeneXus donde se
admita cdigo procedural (como los eventos de transacciones y web panels, por
ejemplo). Para las inserciones y eliminaciones se han creado dos comandos
especficos: New y Delete43.

42

Si existiera un ndice compuesto por {FlightInstanceDate, FlightInstanceTime, FlightDepartureCountryId,


FlightDepartureCityId, FlightTotalCapacity}, lo propondra sin dudar, optimizando la consulta, de modo que ya no tendra que
recorrer toda la tabla y esto lo informara en los Navigation filters del listado de Navegacin. Aun si no existiera este ndice,
pero s uno compuesto por un subconjunto de esos atributos, lo propondra. Es decir, siempre que exista un ndice que le
permita optimizar la consulta, lo propondr. (No lo dijimos antes, pero en cualquier momento usted puede pedirle a GeneXus la
creacin de un ndice de usuario) Por qu decimos lo propondr? Pues para los generadores SQL si bien esta informacin es
til e influyente, en realidad es el propio DBMS quien resuelve el plan de acceso ms apropiado. Para los no SQL (RPG,
COBOL, VB-Access, VFP-DBF) en cambio, es vital. Existe mucho para conversar sobre este tema, estimado lector, pero no
viene a cuento en esta historia.
43
En ninguno de los casos se hacen controles de integridad referencial, permitiendo as insertar registros que apuntan a un
registro inexistente, o eliminar registros que son apuntados por otros, dejando a estos ltimos hurfanos. El nico control que se
realiza es el de unicidad. Hablamos de controles programticos, ya que en GeneXus se puede indicar si se desea activar la
integridad referencial a nivel del DBMS, en cuyo caso siempre se controlar.

134

Ahora que pienso, no ests controlando en el procedimiento lo que s


controlas en la transaccin FlightInstance: que no intenten cambiar la fecha y
hora del vuelo, adelantndolo. Si mal no recuerdo, all tenas una regla de error
que controlaba eso.
Tienes razn! -. Pensativo, Diego rumiaba algo. Mary lo miraba
entusiasmada. Tras unos segundos de meditacin, rompi el silencio-. Tendra
que hacer ese control en el procedimiento, preguntando con un comando If
antes de apresurarme a actualizar as sin ms. Toda vez que quiera modificar
fecha y/u hora de un vuelo real, en cualquier objeto, tendr que volver a hacer
el mismo control que haca mediante la regla en la transaccin. Repitiendo el
cdigo. Una y otra, y otra vez. Quizs en alguna me olvido. o me equivoco.

A lo seguro y sin transpirar: el qu de los Business Components


Ya que sabemos continu con una renovada vitalidad- que las
transacciones son uno de los objetos ms importantes, porque en ellas se
recogen las visiones de los usuarios, las reglas del negocio, las frmulas, y se
ejecutan los controles de unicidad y de integridad referencial, qu me dices
sobre reutilizarlas desde cualquier otro objeto GeneXus?
Ehh?! la expresin de su rostro provoc una sonrisa en nuestro
amigo.
S, reutilizarlas, aprovechando todo ese conocimiento que ya tienen
incorporado. Por ejemplo, si yo tuviera una forma de encapsular toda la lgica
de la transaccin FlightInstance, dejando de lado la interfaz es decir, si
pudiera tener algn buffer o parecido, alguna estructura temporal, por ejemplo
una variable compuesta, estructurada, donde cargar los datos de un vuelo real
(cabezal y lneas) podra ingresarlo en la base de datos desde cualquier
objeto Si realmente tuviera encapsulada la lgica de la transaccin de esa
forma, entonces se permitir la insercin solamente si se cumple todo lo que se
debe cumplir para ingresar esa misma informacin va la transaccin Quiero
decir: si quisiera insertar una instancia de vuelo asocindole un vuelo

135

(FlightNumber) inexistente, o pretendiendo agregar algn pasajero inexistente,


fallar y no me dejar hacer la insercin, tal como ocurre con la transaccin. O,
por ejemplo, si quiero agregar un pasajero existente pero con el que se excede
la capacidad del vuelo, no me dejar realizar esa insercin, tal como sucede
cuando quiero hacerlo va la transaccin, dado que tengo una regla de error en
ella que lo impide . Diego abri la transaccin FlightInstance y mostr a Mary
la seccin Rules. Usted, estimado lector, puede buscarla en el captulo
anterior-. Encapsular la lgica de la transaccin, quedndose con la estructura
pero dejando de lado el form es posible: se llama Business Component. Es un
tipo de datos generado por GeneXus a partir de una transaccin44.
Y cmo haces para encapsular todo eso? y cmo lo usas?
A la transaccin que quieres utilizar de esta otra forma silenciosa,
alcanza con cambiarle el valor de su propiedad Business Component a True.
A partir del momento en que guardas este cambio, GeneXus crear un nuevo
tipo de datos Business Component, cuyo nombre ser el de la transaccin45.
Y cmo lo utilizas? volvi a preguntar, intrigada.
A travs de variables basadas en ese tipo de datos. Siempre que
quieras actualizar, insertar o eliminar una
instancia de vuelo, en vez de utilizar For each,
New y Delete, podrs utilizar toda la potencia de
la transaccin FlightInstance a travs de las
propiedades y los mtodos de una variable basada
en el tipo de datos FlightInstance, business
component, que GeneXus gener. Modifiquemos
el procedimiento anterior para hacer la
actualizacin mediante un Business Component
prosigui Diego su monlogo; Mary observaba
expectante sin hablar-. Necesitamos una variable,
&FlightInstance de este tipo de datos (generado
44

Los Business Components se obtienen de objetos transaccin, pero pueden ser utilizados desde cualquier otro objeto
GeneXus, para hacer inserciones, eliminaciones y modificaciones en sus tablas.
45
Si la transaccin tiene 2 niveles, crear un business component por nivel.

136

cuando pasamos a True la propiedad Business Component de la transaccin).


En ella alojaremos todo el contenido de la instancia de vuelo a cambiar. Esta
variable ser, lgicamente, estructurada, ser el buffer donde temporalmente
tener los datos del vuelo que queremos manipular en un momento dado. El
cdigo nos quedara ms o menos as- y sustituy en el objeto las dos
asignaciones directas por las cuatro sentencias que se pueden observar en la
siguiente imagen-. Observa que aqu slo utilizamos el For each para recorrer
la tabla base y filtrar, pero no actualizamos directamente:

Ves? Lo primero que hago aqu es cargar desde la base de datos la


instancia de vuelo a modificar, dentro de la variable &FlightInstance, segn
el valor de FlightInstanceId que corresponde al registro que cumpli las
condiciones de filtro dentro del For each (es el registro de esa iteracin).
Luego cambio solamente los datos que debemos modificar, y luego grabo,
con el mtodo Save. Observa la analoga: para editar un vuelo mediante la
transaccin, hubieses colocado el identificador en el campo
FlightInstanceId del form, y salido del campo. Para hacer eso con el
Business Component, utilizamos el mtodo Load. En la transaccin
hubieses cambiado en el form los valores de los campos FlightInstanceDate

137

y FlightInstanceTime y luego hubieras presionado [Confirm]. Y aqu?


Cambias lo valores en la variable, y luego ejecutas el mtodo Save. Lo que
pasar como consecuencia de esas acciones, es prcticamente lo mismo.
Quiero decir, qu pasara si en la transaccin modificaras fecha y hora de
forma tal que adelantaras el vuelo?
Se disparara el error ese que habas programado como regla, y no nos
dejara grabar, o sea, no se realizara ese cambio en el registro. Lo dejara como
estaba antes.
Exactamente. Y qu piensas que suceder aqu, en el procedimiento?
Lo mismo? pregunt y afirm al mismo tiempo-.
Lo mismo! Disparar la regla, y como su condicin se satisfar, no te
dejar grabar el cambio.
Y cmo me entero?
Bueno, en el caso de la transaccin, como es un objeto interactivo, all
no hay duda, te despliega mensaje. Sin embargo, un Business Component no lo
es, razn por la cul los posibles mensajes y errores producto del
procesamiento (ejecucin de mtodos Load, Save o tambin Delete, el utilizado
para eliminar) deben quedarte almacenados en algn lado. GeneXus los inserta
en una coleccin (lista) de mensajes asociados a la variable Business
Component de que se trate, y la puedes recuperar con un mtodo
(GetMessages). Luego tienes la posibilidad de recorrer esa lista de mensajes
Pero si slo te interesa saber si se produjo algn error, tienes el mtodo Fail
que te devuelve True en caso de error: as, en nuestro caso, programaras if
&FlightInstance.Fail()
Entiendo. Y qu otros errores podran producirse cuando manipulas
la informacin con el Business Component?
Los mismos que cuando intentas insertar mediante la transaccin
FlightInstance. Es decir: los de integridad referencial (si quisieras cambiar por
ejemplo el vuelo, FlightNumber, que es clave fornea, por uno inexistente), el
de unicidad (por ejemplo, si quisieras insertar una instancia de vuelo nueva, y
le asignas un FlightInstanceId que ya existe para otro registro), las validaciones

138

de tipos de datos, las reglas de error declaradas en la transaccin, y cuyas


condiciones de disparo se satisficieranObserva cmo en ese sentido es ms
seguro hacer un procedimiento utilizando Business Component donde sabes
que se van a disparar todas las reglas del negocio, sin tener que repetirlas.
Todas? Si no te quedas con la interfaz visual, qu ocurre si en la
transaccin hubiera una regla que disparara una llamada a un web panel, por
ejemplo?
Bueno, no todas GeneXus ignora en el Business Component las
reglas que hacen uso de interfaces de usuario. Esa no ser incluida.
Interesante -dijo pensativa.

A dnde quieres llegar? Atracciones que invitan en pdf


El lector observador habr notado lo que Mary en su momento (y que
prefiri dejar en el tintero esperando la oportunidad propicia):
Entre los selectores del objeto de tipo Procedimiento aparece uno
Layout. Para qu? Acaso un procedimiento te permite efectuar una salida
visual?
Pues s. Casualmente los usuarios nos han pedido como requerimiento
que el sitio de la agencia de viajes tenga una pgina que muestre las atracciones
por ciudad, y un link del estilo Ver como pdf. Para implementar esto ltimo,
cre un procedimiento al que llam AttractionsPerCity. Mira dijo Diego
mientras mostraba el objeto en su notebook, seleccionando Layout-:

139

Le tendr que decir a este procedimiento que tendr una salida como pdf.
La idea del Layout es declarar qu es lo que quiero mostrar en la salida.
Como resultado de la ejecucin, quiero mostrar para cada ciudad, todas sus
atracciones. Evidentemente, el usuario final tendr que tener Acrobat
Reader instalado para que desde el Browser se pueda abrir correctamente el
archivo pdf generado. Para indicar qu es lo que se quiere mostrar en la
salida y su formato, el Layout contiene reas de impresin, que son
controles llamados printblock. Coloreados en la imagen, puedes ver donde
empiezan dos de esos controles: City_Block y Attraction_Block. Esos
nombres se los di yo luego de insertar cada control. Dentro de cada
printblock insertas la informacin (atributos, variables, imgenes, lneas,
recuadros, etc.) que deseas desplegar en esa rea de datos, cuando sea
invocada desde el cdigo. Por ejemplo, observa que dentro de City_Block
he insertado los controles atributo CityId y CityName, porque esa es la
informacin de cada ciudad que querr mostrar en el listado.
Y slo con eso GeneXus ya sabe qu listar y cmo?
Mary, espera. El amigo no es mago, slo es inteligente. Con eso solo
no puede saber cmo quieres listar la informacin. Falta el cdigo dijo
enarcando las cejas, con expresin risuea, viendo aparecer un rubor...

140

Bueno, lo presentas como tan maravilloso bien podra adivinar tus


intenciones, no? sonrieron ambos.
T las adivinas? avanz Diego.
Y si las explicitas? contest Mary sin retroceder, mirndolo
fijamente a los ojos, con una expresin que a l se le antoj encantadora.
Sus deseos son rdenes!.... Y tras un breve silencio que a ambos
pareci eterno, l continu-. Quiero recorrer las ciudades, y para cada ciudad,
sus atracciones. Esto implica la utilizacin de dos For eachs anidados.
Mary aproxim su silla a la de l, tom el mouse sin preguntar, siempre
sonriendo, y se posicion en el selector Source. La ventana se transform,
mostrando el siguiente cdigo:

Diego continu:
Observa que no necesitas establecer el filtro por ciudad para el
segundo For each: es que existe una relacin 1-N directa entre las tablas que se
recorren, siendo uno de los casos ms comunes de For eachs anidados. La tabla
base del For each externo es COUNTRYCITY, y la del interno es
ATTRACTION (por los atributos de los printblocks involucrados), y como
GeneXus conoce las relaciones entre las tablas, l implcitamente aplica la

141

restriccin sobre los registros a recuperar. Pero es ms potente que eso,


encuentra tambin relaciones 1-N indirectas. Por ejemplo, si quisieras listar
para cada aerolnea, la cantidad de instancias de vuelo46.
Mary, muda, no emita palabra. Miraba la pantalla. Una sonrisa segua
estampada en su rostro. Posicion el mouse sobre el Tab del procedimiento
donde se encontraba su nombre, y con botn derecho seleccion View
Navigation del men contextual. Diego la miraba. Apareci un nuevo Tab en
la pantalla, conteniendo la siguiente ventana:

Ves lo que digo? Est restringiendo la bsqueda- explic a esta


mujer que tena tan cerca y que slo observaba y sonrea-. Te lo indican los
filtros en la navegacin de la tabla ATTRACTION en el segundo For each.
Observa el @. Est indicando que toma esos valores del contexto. Cules
son @CountryId y @CityId? Los del registro del primer For each con el que se
encuentra trabajando en esa iteracin. Esas intenciones GeneXus s las
descubre.
Diego continu, llenando el silencio que Mary no llenaba:
Para convertir este listado en ejecutable, debers cambiar 2
propiedades: Main Program = True, Call Protocol = HTTP para que se
46
Entre las tablas AIRLINE y FLIGHTINSTANCE hay una relacin 1-N indirecta (est la tabla FLIGHT de intermediara).
GeneXus encuentra en muchos otros casos relacin 1-N indirecta y hace el join.

142

ejecute en el Browser. Adems debers incluir una regla en el selector Rules


output_file("AttractionsPerCity", "pdf"); que es donde le dices que
la salida ser un archivo pdf, con el nombre que especifiques. Tambin puedes
decirle que quieres que enve la salida a alguna impresora de las que estn bajo
el alcance de la computadora desde la que se est ejecutando el navegador con
la aplicacin.
Para ejecutarlo, Diego se posicion sobre el tab con el nombre del
procedimiento, y con botn derecho seleccion la opcin Run with this only,
para que GeneXus construya y ejecute ese procedimiento nicamente. La cara
de asco de Mary no se hizo esperar. Es que el listado slo mostraba datos, sin
ningn formato. Diego no esper. Grab el procedimiento con otro nombre, y
le mejor el diseo y la informacin mostrada

obteniendo ahora en ejecucin:

143

Por fin Mary rompi el silencio.


Me atrae Pars Por qu no vienes esta noche a cenar a casa? Y me
sigues contando

144

Y las consultas?
Otro de los grandes alcances de GeneXus X es el objeto Query que permite
crear consultas a la base de datos, y mejorar la salida de la informacin
recuperada. sta puede ser visualizada en diferentes formatos (barras, tortas,
3D o planas, rea, etc.) lo que ayudar a enriquecer sus aplicaciones. Adems
permitir al usuario realizar consultas dinmicas (qu measure ver) a travs de
pivot tables, etc.
Una consulta de este tipo es definida como una estructura. Supongamos que
deseamos obtener una consulta de cantidad de despegues en una fecha dada
(FlightInstanceDate) por aerolnea (AirlineName) para cada ciudad
(CityName); en la siguiente imagen se resume esta intencin:

Al objeto Query, creado desde la ventana New Object, le hemos asignado el


nombre QSoldSeatsByArrivalCities. En el nodo Attributes hemos insertado los
atributos AirlineName y FlightArrivalCountryName, que sern los que
queramos ver en tiempo de ejecucin. Inmediatamente debajo, hemos

145

declarado la funcin Count, pero segn las necesidades, se pueden declarar


tambin a Sum y Average47
Podemos tambin incluir parmetros, y en este caso en particular hemos
incluido una variable basada en un atributo en particular.

Luego tenemos el nodo Filters donde, si fuera necesario, estableceremos las


condiciones para recuperar los registros a mostrar; en este caso, todos aquellos
cuyo valor del atributo FlightInstanceDate (incluido en FLIGHTINSTANCE)
sea igual al valor del parmetro que hemos nombrado como &DepartureDate.
Por ltimo, tenemos el nodo OrderBy donde, de ser necesario, deberemos
establecer el o los atributos que debern ser considerados; en este caso, los
datos se mostrarn en orden alfabtico segn el contenido del atributo
AirlineName.
Ahora, cmo ejecutamos esta consulta?
Deberemos crear un web panel con el aspecto que
deseemos, como cualquier otro, pero al cual le
deberemos insertar el User Control Query Viewer
que se encuentra en la Toolbox del IDE.

47
No todas las funciones de agregacin aplican para todos los tipos de atributos. Sum y Average estn solo disponibles para
atributos numricos.

146

Luego accedemos a sus propiedades y seteamos aquellas que sean


necesarias. En este caso se ha
modificado la propiedad Query, a la
cual se le asign el nombre del objeto
Query que definimos al inicio,
QSoldSeatsByArrivalCities, y tambin
se ha modificado la propiedad Type;
esta tiene por finalidad establecer alguno
de los tres tipos posibles de salidas:
Pivot Table, Table, y Chart. Le
recomendamos que pruebe para ver las
diferencias entre ellos. Considere que
para el valor Chart dispondr adems de
la propiedad ChartType donde podr escoger un estilo entre doce posibles. Y
eso es todo para lograr una construccin bsica de un Query.
En el selector SQL statement se puede observar el cdigo que GeneXus ha
generado y que ser ejecutado sobre la base de datos para obtener la vista
deseada en cuanto se ejecute el web panel diseado para tal fin.

147

Ahora <F5> y, voil!

148

Captulo 6

Ms declaraciones
Nuevos protagonistas del conocimiento: Data Providers
La meta de GeneXus: que usted declare, declare y declare. Cuando uno
declara dice el qu, y no se preocupa por el cmo, pues ste vara con el
tiempo. Con frecuencia se encuentran nuevas formas de implementacin,
mejores, ms eficientes. El qu es estable, la esencia. Conocimiento que
permite automatizar. Las transacciones y los business components eran, as, las
estrellas de GeneXus: declaraban la lgica del negocio. Declaraban
conocimiento. GeneXus encontraba, en cada etapa de su evolucin, un cmo.
Ahora, un nuevo protagonista irrumpe en escena: el Data Provider. Para una
gran variedad de casos, pasaremos de programar procedimientos, a declarar
data providers.
Qued usted intrigado? Mary tambin. Vea lo que pas.

Declarndose?
Sin responder a la pregunta que ella dejara sonando en el aire, Diego abre
torpemente su inbox de correo y encuentra un e-mail de la agencia donde le
solicitaban un nuevo requerimiento: deba generar un archivo de interfase con
formato XML para envirsela a cierta aerolnea donde figurara la cantidad de
plazas vendidas por vuelo de esa aerolnea, en cierta fecha.
Mira esto susurr a Mary girando la notebook para que ella leyera.
Fcil contest ella demorando en leer. Su vista se haba detenido
antes en otros mensajes de correo, y Diego lo percibi, pero no dijo nada.
Implementas un procedimiento parecido al que vimos. Pero cmo se hace en
GeneXus para generar la salida en formato XML? si bien pareca estar

149

pensando en otra cosa, su conversacin era completamente coherente. En qu


pensara sin decirlo?
No es complicado, ya veremos. Pero sabes una cosa? Esta vez no lo
haremos con un procedimiento. Antes de la X no nos quedaba otra opcin, pero
ahora disponemos de algo ms potente para este tipo de casos.
Ms potente?
S, nada de codificacin procedural. Fjate que aqu necesitas
consignar informacin estructurada: imagnate cmo debera ser el XML
resultante, por ejemplo . Cre un documento xml, escribi y mostr:

Los ojos de Mary, entrecerrados por el ceo contrado, habilitaron a


Diego a continuar la explicacin:
Para esto usaremos un Data Provider, que es un objeto ideado
especficamente para devolver datos estructurados. Te voy a mostrar una cosa:
si quisieras implementar este requerimiento como un procedimiento en
GeneXus, programaras algo as:

150

Ves cmo en este cdigo estn mezclados los elementos de la


entrada, con los elementos de la salida? Dime la verdad, sin importar si
entiendes o no el cdigo, no te resulta complicado aqu encontrar cul ser la
estructura resultante y de qu modo se carga? Esto es porque los
procedimientos privilegian el lenguaje de transformacin del input para
obtener el output. Por lo que el output queda oscurecido y no es fcil
identificarlo. Sin embargo, en los Data Providers lo privilegiado ser el Output.
De hecho, declaras tu intencin, mediante simples ecuaciones del estilo x = y
para cada elemento de la estructura jerrquica que quieres devolver cargada.
Muy interesante, Diego, pero se me hace un poco tarde, y veo que esto
puede llevar un tiempo
Cinco minutos! acot inmediatamente, ocupado en demorar el fin
del encuentro. Mary dud unos segundos y por fin continu:
Bueno, entonces anda, declara.
Diego cre un nuevo objeto, al que llam LoadNumberOfPassengers, de tipo
Data Provider. Mary observ la imagen.

151

Aj. Tiene casi los mismos selectores que los procedimientos.


S, lo que vara es lo que se escribe en el selector Source, pues no ser
cdigo procedural, sino declarativo. Pero vamos por partes. Segn el
requerimiento, algn otro objeto capturar del usuario el nmero de aerolnea y
la fecha, y a ambos los recibiremos como parmetros. As que definamos
entonces las variables y declarmoslas en las Rules tras lo cual lo hizo.
parm(in:&AirlineId, in:&DepartureDate);

Bien, ahora vamos al Source dijo Mary con confianza.


Bueno, todava no. Debemos definir un tipo de datos estructurado que
ser el tipo de datos de la informacin devuelta por el Data Provider.
Tipo de datos estructurado? Como si fuera un struct en C, o .Net, o
un record de Pascal?
Eso. Una estructura que puede contener tanto datos simples como
otras estructuras, as como colecciones (listas) de datos. Incluso puede ser l
mismo una coleccin. En GeneXus defines esos tipos de datos, no en la ventana
de Dominios, sino como objetos (algo parecido a como se hace en Java
definiendo clases que luego se instancian). Mira, en nuestro caso definiremos
un objeto de tipo Structured Data Type, o simplificando, SDT, y all
ingresaremos su estructura:

152

Ves? se apresur a proseguir-. Este tipo de datos se compone de


tres miembros, de nombres Name, DepartureDate y Flight. Los dos primeros,
de tipos de datos simples, y el tercero, ser una coleccin de tems (observa el
check box Is Collection), cada uno de los cuales es estructurado; les hemos
llamado FlightItem. Los miembros de ste ltimo estructurado tambin son
tres. Observa que como he llamado a los dos primeros miembros igual que
atributos de mi KB, infiri como su tipo de datos el mismo que el de los
atributos homnimos. Les puse el mismo nombre que a los atributos porque en
realidad voy a cargar este SDT con los valores de esos atributos, luego. Pero no
nos detengamos en ello.
Ante la atenta mirada de Mary, Diego pic sobre el nombre del SDT que
ahora apareca en el rbol del Folder View, lo arrastr hacia el rea Source del
Data Provider y solt el botn, tras lo cual apareci:

153

De forma automtica, GeneXus inicializ


en el Source la estructura que ser devuelta
por el Data Provider; es ms: dio valor a la
propiedad Output que indica cul ser la
estructura devuelta por el Data Provider.
Ahora Diego slo debe sustituir los
comentarios del Source por los valores que
correspondan a cada miembro.

154

Vio cmo los rojos labios de Mary se unan para pronunciar lo que adivin
ser un pero, aunque no lleg a saberlo, pues continu:
Espera, no he terminado. An no estoy filtrando por los parmetros
recibidos. Mira cmo completo el Data Provider:

Clusulas where, como las de los for eachs? pregunt Mary


pensativa, haciendo la asociacin clave.
155

Efectivamente. En el lenguaje de Data Providers tendrs grupos, estos


son los que contienen elementos. En nuestro caso: SeatsSoldByFlight, Flight y
FlightItem son grupos. Los grupos contienen elementos, variables y/u otros
grupos. En cualquier caso, un grupo podr presentarse en la salida una sola vez,
o mltiples veces. GeneXus tiene la inteligencia para determinarlo.
Cmo?
Por lo que decas t. La presencia de atributos a la derecha de las
asignaciones en los elementos, as como en las clusulas where del grupo estn
determinando que esos grupos son como for eachs, que acceden a una tabla
base.
Si no hubiera clusulas where, tal como estaba el Source antes de que
las agregaras, y si en lugar de atributos a la derecha de las asignaciones tuvieras
variables o literales
en ese caso, en la salida tendras cargado el SDT de forma tal que la
coleccin Flight estara compuesta nicamente por un tem. En cambio, en
nuestro caso, el grupo Flight contendr muchos tems, tantos como instancias
de vuelos haya para esa fecha y aerolnea, y en cambio el grupo raz
SeatsSoldByFlight ser nico, puesto que estamos filtrando por AirlineId.
Ah, entiendo exclam Mary. Es como si tuvieras un par de For
Each anidados. El primero, por los atributos que aparecen, recorrera la tabla
AIRLINE, y el segundo la tabla FLIGHTINSTANCE.
Perfectsimamente. Mira el listado de navegacin:

156

Observa adems cmo en el lado derecho de los elementos puedes


poner tanto atributos como cualquier funcin o frmula que devuelva un
resultado del mismo tipo de datos que el que definiste para ese elemento en el
SDT. Por eso utilizamos una frmula count para SoldSeats. En realidad, como
esa
frmula
la
tenemos
tambin
global
en
el
atributo
FlightNumberOfPassengers, podramos haber colocado directamente este
atributo. No lo hice para mostrarte que es posible escribir cualquier clculo.
Entiendo ahora por qu dices que los Data Providers son declarativos.
Lo que tienes que hacer es declarar cul ser la estructura resultante, y luego
cargarla a travs de ecuaciones x = y donde en y declaras cmo se calcula x.
Ahora, cmo devuelves el XML que necesitas?
Bueno, en realidad debers invocar a este Data Provider como si fuera
un procedimiento comn y corriente desde cualquier objeto, y hacer lo que
quieras con la salida, por ejemplo, convertirla a XML contest Diego-. Creo
que lo mejor ser que lo haga, as lo vas a entender mejor.

157

Cre un Web Panel y tres variables: &AirlineId, &DepartureDate y


&SeatsSoldXML, esta ltima de tipo de datos LongVarChar y de 2 MB (ser la
que contendr la informacin en formato xml):

A continuacin se posicion en el selector Events y escribi:

Espera, espera y la variable &SeatsSold a la que le ests asignando


lo devuelto por el DataProvider?
Olvid definirla tras lo cual lo hizo. Su tipo de datos ser,
lgicamente, el SDT devuelto, es decir: SeatsSoldByFlight.
Aj, e infiero que el mtodo ToXML aplicado a una variable SDT
tiene por efecto convertir el contenido del formato SDT al formato XML.
Cierto?

158

Cierto. El valor true del parmetro solamente est indicando que le


agregue el header al xml; ahora no importa entonces luego de ejecutado el
mtodo, la informacin est contenida en memoria dentro de esa variable
&SeatsSold.
Ahora lo nico que te queda es generar, por ejemplo, un archivo con
ese contenido y listo agreg Mary mirando su reloj pulsera.
S, y todava quiz mejor: puedo enviarlo directamente por mail a la
compaa area.
Aj Diego, escchame, no sigas. Te agradezco la explicacin, no te
enfades conmigo, pero me esperan, debo marcharme. Te espero esta noche en
casa, y seguimos con las declaraciones te parece?
S, pero omit decirte que un Data Provider tambin puede cargar y
devolver un business component, porque la estructura de un business
component es como la de un SDT. Luego puede ser insertado en la base de
datos desde el objeto llamador, con el mtodo Save, como siempre.
Me lo cuentas luego. Nos vemos esta noche, s?
Diego permaneci en el bar varios minutos ms, con la vista perdida por
donde ella haba partido minutos antes, dejando tras de s su estela de perfume.

159

160

Captulo 7

Soplan nuevos vientos


Poniendo la casa en orden: categorizacin
Esa noche Diego llev el vino. Y la notebook. La msica de fondo creaba
un ambiente acogedor.
Debes cumplir lo prometido reclam Mary sonriendo, mientras
llenaba su copa-. Dime ms.
Sobre GeneXus? Bueno, no s qu ms decirte- Pareca nervioso,
aunque pronto sali del paso-. Hoy por ejemplo estuve categorizando los
objetos de la KB. No s si recuerdas, pero el IDE tiene un panel rotulado
Category View en el contenedor Knowledge Base Navigator que despliega, en
rbol, todos los objetos que hayas clasificado dentro de sus correspondientes
categoras. Espera que te muestro dijo depositando la notebook en su falda y
la copa sobre la mesita prxima al sof.
No veo clara la finalidad respondi Mary sentndose a su lado.
Bueno -mientras la notebook terminaba
de iniciar, Diego llenaba el incmodo silencio-,
por ejemplo, en mi compaa solemos tener
categoras para identificar el estado de los
objetos: Operating, Under Review, Under
Construction. As, puedes saber en un simple
pestaeo, qu objetos estn prontos para ser
testeados, simplemente abriendo la categora
Under Review. En este caso, separamos
nuestro universo de objetos en categoras
disjuntas. De hecho, hasta puedes darle un
nombre a este criterio de clasificacin de tu
universo, justamente mediante una categora,
Status por ejemplo, que contenga a estas tres

161

subcategoras. Pero simultneamente, podemos querer categorizar el mismo


universo, de acuerdo a otros criterios. Lo que quiero decir: puedes incluir un
mismo objeto en varias categoras distintas. Por ejemplo, suponte que quieres
organizar adems por sistema, subsistema, etc. Nada impide que un objeto est
en la categora correspondiente a un subsistema, y adems en la Under
Review de la Status. O puedes categorizar los objetos segn si se utilizarn
en el Back-end de la aplicacin, o en el Front-end. Las categoras nos permiten
organizar y visualizar la informacin de nuestra KB de acuerdo con nuestras
necesidades puntuales.
Multicategorizar. A ella le brillaban los ojos. Al menos eso le
pareci a l.
Cuando seleccionas un objeto del Folder
View, debajo de la ventana de propiedades, tienes
un contenedor rotulado Categories que comienza
con una pequea toolbar en donde puedes tanto
agregarle categoras al objeto como eliminrselas.
Pero, como siempre, tienes varios caminos para
llegar a Roma
Hoy estuviste categorizando eso
significa que tuviste que ir uno por uno a todos
los objetos y asignarles las categoras
correspondientes, no? Mucho trabajo!
S contest un poco avergonzado-. Es
que en esta versin aparecieron las categoras, y
no me he acostumbrado a usarlas, si bien fue
decisin de la empresa el uso de categoras de estado. A veces es difcil
cambiar las costumbres. Tendramos que haber creado estas categoras desde el
vamos, y los objetos ya con la categora Under Construction y luego ir
movindolos de categora, en el cambio de estado. Hoy tuve que poner la casa
en orden, ya eran muchos los objetos de la KB. Pero slo tuve que hacerlo para

162

las subcategoras de Status porque la categora To-Do Diego es dinmica,


se mantiene sola.
Sola? Cmo es eso? . Mary estir el brazo hasta la botella de vino.
En este caso, aprovechando que tena que poner la casa en orden, puse
comentarios que contenan el texto To-Do Diego en algunos objetos que
tena pendientes de cerrar; tambin otros compaeros lo haban hecho. Luego
cre una categora dinmica. Las categoras dinmicas tienen asociada una
condicin de bsqueda (que podr ser por palabras o por propiedades, como ya
te mostrar). Todos los objetos resultantes de la bsqueda, pasan a formar parte
de la categora. Puse en la condicin de bsqueda que tuviera el texto To-Do
Diego y all aparecieron todas las cosas que tengo por hacer, varias por
cierto
Veamos cmo lo hizo

El que busca encuentra


GeneXus X tiene la capacidad de encontrar cualquier cosa que se halle en
la KB. Esta facilidad se presenta de la misma forma que experimentamos
cuando hacemos uso de los motores de bsqueda en la Web. Basado en
complejos algoritmos, el motor full-text search de GeneXus X localiza lo
buscado entre lo que podran ser toneladas de palabras contenidas en los
objetos que componen la KB. Y al igual que la mayora de los buscadores, nos
permite utilizar sintaxis intuitivas para acotar las bsquedas. En la siguiente
imagen puede ver la bsqueda por To-Do Diego

163

El motor full-text search explor la KB y report todos los lugares donde


estaba presente. Obsrvese adems cmo desde esta consulta puede crearse la
categora dinmica de igual nombre, To-Do Diego, que Diego mostr antes a
Mary. Para ello alcanza con hacer [Save as Category]. Tal vez sea lo que hizo
Diego ese da
Note que debajo se propone tambin una bsqueda, pero en este caso slo
de propiedades. Por ejemplo, si se quisieran ubicar todos los objetos de tipo
procedimiento, agregaramos una propiedad:

164

Base, rimel, sombras Maquillando la aplicacin


Esa misma tarde, unas cuantas horas antes, Julia terminaba la
documentacin en la KB cuando Mike, que finalizaba los ltimos testings,
coment:
Me enter por Diego que quieren cambiar el estilo de las pginas. l
estaba muy atareado, terminando el desarrollo de unos objetos, y me deriv este
tema a m. Me dijo que hablara contigo para pedirte los detalles.
S, me enviaron un e-mail que describe ms o menos el aspecto que
desean y lo copi como Talk del Main Document; luego lo documento bien.
Dejaron a nuestro gusto la composicin de colores y dems. Yo ya haba
ingresado hace tiempo el logo de ellos a la KB, en el nodo Images. Quieren que
quede situado arriba, en todas las pginas.
Eso lo hago ahora mismo. Slo tengo que abrir la master page
AppMasterPage creada con la KB y utilizada por defecto por todos los objetos.
Es donde se encuentra centralizado el encabezado y pie que tendrn todas las
pginas del sitio; luego sustituyo el encabezado Application Header que sale
por defecto, y listo. Para todo
lo otro que piden, llamemos a
Paul, el diseador grfico
Pero Paul no sabe nada de GeneXus, y t le vas a permitir que abra
los objetos y modifique los controles en los forms, cambindoles el color, el
tamao, y dems?!
Mike no pudo reprimir la carcajada.
No Julia, cada uno en lo suyo. Ni loco le dejo tocar nuestros objetos!
Pero necesito que configure para cada control de los forms, su diseo. Por
ejemplo, necesito que especifique para los botones de las transacciones su
tamao, color de fondo, tipo de letra, etc. Lo mismo para los grids y dems
controles. Quisiera centralizar eso y que l no tenga que tocar los controles
en los objetos. Para eso es que existe el objeto de tipo Theme. Observa que
bajo el nodo Themes bajo el Customer del Folder View, aparece uno de nombre
GeneXusX. Es el que asoci GeneXus por defecto a nuestros objetos. Si lo
165

abro, vers que se trata de una lista, en rbol, de clases de controles (aunque no
slo).

Aqu se configuran los


aspectos de diseo
para esta clase.

Cada tipo de control tiene varias clases posibles. Dentro de la clase


Button hay una subclase que es BtnDelete, que por defecto hereda sus
propiedades pero que te permite cambiarlas. Si ahora vamos a cualquier
transaccin y editamos el form, podremos ver en las propiedades del botn
[Delete] que
tiene asociada
esta
clase.
Puedes
cambirsela
por otra. Con
esto te queda
perfectamente
separado en tu
aplicacin el comportamiento del diseo. Te digo ms: ahora lo que har ser
exportar48 de nuestra KB el theme GeneXusX, envirselo a Paul para que l
configure los aspectos de las clases y me lo enve nuevamente, momento en que
48

No habamos hablado hasta el momento de exportacin/importacin en GeneXus. En este libro solamente diremos que se
pueden exportar objetos GeneXus y otro tipo de conocimiento de una KB en archivos de extensin xpz, que luego pueden ser
importados en otra o la misma KB. Para ello est la opcin del men Knowledge Manager.

166

lo importar y listo! Diseo aplicado! Paul no necesita tener GeneXus, sino


solamente el Theme Editor, un utilitario que slo permite trabajar con estos
objetos. Es especfico para el diseador grfico. Si no, tambin lo puedes hacer
desde dentro de GeneXus.
De hecho, ahora que veo, el logo de la empresa est en la lnea de los
naranjas. As que mejor utilicemos el Theme de nombre
Orange (para ello lo marcamos en el check box) y
hagmosle un Save as TravelAgencyTheme. As
usamos por entero uno propio. Envimosle este a Paul.
Para probar y mostrarte, mira, modifiquemos los
colores de algunas clases del theme tras lo cual, con
el nuevo theme TravelAgencyTheme abierto, se puso a
cambiar las propiedades de las clases Grid,
FreestyleGrid y Table, y grab-. Ahora lo que tengo
que hacer es decirle a la KB49 que utilice en todos los objetos ese tema:

Y habiendo cambiado tambin el web panel AppMasterPage, tras pedirle a


GeneXus que reconstruya todos los programas (Build/Rebuild All) para que
49

Estrictamente hablando a la versin de la KB que est activa. Sobre versionado de KB, busque prximos episodios o en las
distintas fuentes de documentacin de GeneXus.

167

tome en cuenta que los objetos tendrn ahora este theme, observe cmo luce en
ejecucin. Por ejemplo, veamos el Work With Airline, y luego la transaccin
para modificar una aerolnea:

Los tipos de objeto Master Page y Theme son los que ms importan a la hora de
disear la esttica de la aplicacin.

Espejito, espejitodime cundo y te dir cmo eras


Otra interesante posibilidad que ofrece GeneXus X es la de poder consultar
la evolucin de los objetos dentro de la KB a travs del tiempo. Es decir, cada
objeto tendr asociada una historia que estar registrada con su fecha y hora y
el usuario que hizo las modificaciones. Con esto se podr seguir la evolucin de
un objeto desde su inicio mismo.
Y lo que es ms: usted podr volver a una versin anterior del objeto,
seleccionando esa versin como activa, a travs de botn derecho.
En la siguiente imagen

168

se observa, a la izquierda, el contenido del panel Latest Changes View y a la


derecha la historia de la transaccin Airline. Note que existieron seis
modificaciones desde su fecha de creacin, por lo tanto hay siete nmeros de
versin.
Tambin podr comparar dos versiones entre s y obtener sus diferencias.
Por ejemplo, puede seleccionar dos versiones y luego, mediante botn derecho
del mouse, pulsar
sobre
Compare
Selected Revisions.
Como resultado de
comparar
las
revisiones 12 versus
14 de la transaccin Country, GeneXus mostrar las diferencias en dos
ventanas adyacentes, como se muestra a continuacin para el ejemplo (en la
versin 12 no haban reglas definidas).

169

Versionado de la KB?
El tiempo haca lo nico que sabe hacer; Mary y Diego parecan no percatarse
de ese avance inexorable.
Diego
S?
No crees que lleg el momento de se alis la falda con las manos,
y carraspe antes de continuar, segundos eternos para l-hacer una copia de
la KB?
Ah, copias de respaldo! Bueno, en realidad en GeneXus lo puedes
hacer muy muy muy fcilmente. De hecho, dentro de la misma KB puedes
contener fotografas de diversos estados de la misma en el tiempo. Y no solo
eso, puedes hacer desarrollos paralelos de distintas versiones. Por ejemplo,
quieres poner en produccin una versin, y continuar desarrollando nuevos
requerimientos, de tal manera que puedes ir luego haciendo correcciones a la
versin de produccin a medida que el usuario lo va requiriendo, que no
estorben el desarrollo principal.
Interesante, me lo cuentas luego? . Se levant del sof y parada
delante de l le ofreci extendida la palma de su mano-. Vienes?

170

Situaciones que se repiten: para no decir siempre lo mismo,


Data Selectors
Es comn encontrarnos codificando las mismas situaciones (filtros y
rdenes de acceso a la base de datos) en distintos lugares de nuestra aplicacin
donde recuperamos datos, desperdigando por variados lugares la misma lgica
(o parte de ella).
Observando los siguientes trozos de cdigo:

y comparando entre ellos, es evidente que obtienen resultados distintos,


aunque con un mismo trozo de lgica: ambos quieren filtrar por ciudades
africanas (CountryWorldRegion=WorldRegion.Africa), ordenndolas por
nombre. El primero despliega en la salida exactamente eso (supongamos que
City_Block contiene atributos de ciudades), y el segundo las atracciones de
categora Safaris de ciudades africanas. Obsrvese el bloque de cdigo en
comn, compuesto por un orden y un filtro. Podra haber decenas de objetos
GeneXus donde se necesitaran las ciudades africanas ordenadas por nombre.
Un Data Selector permite la centralizacin y el reuso de navegaciones, evitando la
duplicacin de cdigo.

Pero tiene ms ventajas. Es muy comn que la gente incorporada al staff de


desarrollo en un momento dado desconozca los criterios o filtros comunes de

171

una aplicacin. Suponiendo que se quiere promocionar fuertemente el turismo


africano, suele pasar, por ejemplo, que se le pida un listado de ciudades y
salgan todas las ciudades en lugar de slo las africanas. La centralizacin de
estos criterios reduce enormemente la curva de aprendizaje haciendo
productivo al personal rpidamente y reduciendo el nmero de errores.
En el ejemplo anterior, si le diramos un nombre a esas clusulas comunes
como si fuera una macro que luego pudiera expandirse obtendramos un
Data Selector! Un nombre para un criterio de bsqueda de datos. En nuestro
caso: AfricanCities.

Los procedimientos anteriores nos quedarn:

172

A la derecha del comando For each se ha escrito la clusula Using la cual


dice que se utilice el contenido del Data Selector AfricanCities; y eso es
todo si luego modificamos el criterio, lo hacemos dentro del objeto Data
Selector y se cambia en todos lados automticamente!

El camino de los procesos


Los humanos somos buenos
para muchas cosas, pero en tareas
como buscar un documento entre
cientos de otros, tener presente
sus vencimientos, y asegurarse de
que el trabajo terminado pase de
un lugar a otro respetando una
secuencia previamente definida...
hmmm lo somos?
GXflow, conocida herramienta
de Artech que se relaciona con la
automatizacin de los procesos en
las empresas, determinando flujos
de tareas, est tambin integrado
a GeneXus X. Por qu? Las
aplicaciones cada vez ms
contienen flujos de procesos, que
requieren de componentes de Workflow.
En efecto, usted podr crear sus propios diagramas dentro del IDE de
GeneXus, simplificando mucho las tareas de integracin y haciendo sencilla la
vinculacin de las actividades con los objetos de la KB.
En la imagen se ha diseado un sencillo ejemplo que muestra el flujo del
proceso de reserva de un vuelo.

173

La reserva en s misma, expresada por el primer bloque del esquema, no es


ni ms ni menos que la puesta en ejecucin de la transaccin a la que
representa.
Luego se evala determinada condicin, como podra ser que los datos
estn correctos y completos. A los efectos de exponer un ejemplo, vea las
siguientes condiciones:
Print Tickets IF FlightStatus = AUTHORIZED
Get in contact with Client IF FlightStatus = CORRECT PERSONAL INFORMATION

Estas condiciones son expresadas mediante un editor de condiciones. La idea


es que se puedan expresar reglas, donde primero se indica el nombre de la
tarea sucesora e inmediatamente la condicin que se tiene que cumplir para
que siga por ese camino. Sencillo, prctico y potente.

En caso de que as sea, se imprime el ticket de reserva y se enva a su


destinatario. De lo contrario, el flujo se deriva hacia la puesta en contacto con
el cliente, se actualiza la informacin (seguramente mediante la transaccin
correspondiente a los clientes), y se vuelve a retornar el flujo hacia la reserva,
reinicindose el ciclo.

Back y Front End - Intra e Inter Net


En este libro nos hemos permitido inmiscuir en algunos momentos de la
vida de nuestros personajes, lo que nos permiti observar cmo se han
implementado algunas partes de la aplicacin. El objetivo: ver un poco de cada
cosa. Pero no hemos visto el todo. Por momentos los autores sentimos un poco
de vergenza de nuestro voyeurismo y quitamos la mirada, para luego,
tentados, volver nuestros ojos a la historia. Por esta razn, hemos visto
entremezclados objetos que sern utilizados en el back-end de la aplicacin
(por ejemplo los Work With, dado que la actualizacin de la informacin de

174

aerolneas, pases, ciudades, vuelos, pasajeros, etc., slo podr ser efectuado
por empleados de la empresa, con permisos, a travs de la intranet), con otros
que pueden utilizarse en el front-end, es decir, en el sitio Web que ser
consultado por personas de todo el mundo va Internet.
Sin embargo, Diego, Mike y Julia han trajinado mucho ms de lo que
hemos podido apreciar. Han hecho la pgina principal de la Intranet,
modificando un poco la pgina Home creada por el pattern Work With. Han
agregado una seccin de login a la master page web panels con consultas
variadas y distintos mens.
Esa misma tarde, sin ir ms lejos, antes de la cita con Mary, mientras Paul
reciba un theme para modificar, Julia se contactaba con los usuarios de Travel
Agency y Mike terminaba los testeos. Diego observaba detenidamente cmo
haba quedado la pgina principal del sitio web de la empresa:

175

Obsrvese que se brinda informacin de hoteles, de rentadoras de autos y


del estado del clima. Estas son aplicaciones de terceros, publicadas como Web
Services que se pueden integrar (consumir) fcilmente dentro de GeneXus, con
el nuevo tipo de objeto External Object. A esta altura el lector tiene todos los
elementos para hacer la radiografa de la pgina y sospechar qu puede haber
detrs de la misma: un web panel, web components, master page, theme,
imgenes, contoles

Final o principio?
Hasta aqu hemos obtenido distintas piezas de un rompecabezas que usted
ir armando, valindose de la ms importante: su imaginacin.
Con ella, las piezas faltantes se le irn descubriendo en una bsqueda
continua. Inacabable. El puzzle est siempre prximo a pero nunca se
completa. All radica su secreto: mantenernos eternamente en vilo, buscando,
pensando, imaginando, cambiando.
Amigos, con fe, con alegra, con generosidad, con la sinergia
de esta Comunidad, vamos adelante, y preservemos la magia.
Breogn Gonda en el cierre del XVI Encuentro Internacional GeneXus
20 de Setiembre de 2006

Qu pas con nuestros personajes? Fue exitoso el proyecto de desarrollo?


Cmo termin esa cena con msica? Se habr convencido Mary de ingresar a
la Comunidad? Piezas que faltan, y que cada uno encontrar como los
secretos que an gesta la X
O es que esta historia recin empieza?

176

177

También podría gustarte