Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Curso Genexus 9.0 Ejercicios Prácticos: Julio de 2006
Curso Genexus 9.0 Ejercicios Prácticos: Julio de 2006
0
Ejercicios Prácticos
Julio de 2006
SAO PAULO – BRAZIL Rua Samuel Morse 120 Conj. 141 +55 11 5502-6722
Curso GeneXus – Ejercicios Prácticos
Notas previas
El presente material corresponde a los ejercicios prácticos que el alumno del curso GeneXus deberá ir desarrollando en
forma paralela a las clases teóricas.
Con este práctico el alumno podrá familiarizarse con la herramienta, su ambiente, menús, barra de herramientas, etc.,
así como podrá poner en práctica de una manera guiada y gradual los conceptos más importantes.
Finalizada esta parte práctica del curso, el alumno estará en condiciones de analizar una realidad simple y modelarla
utilizando GeneXus, con el apoyo de un instructor, de forma tal de cerrar un módulo completo de aprendizaje
fundamental para poder empezar a desarrollar sus propias aplicaciones.
Dado que la finalidad de este curso es aprender la lógica de GeneXus, su esencia, independientemente de la plataforma
en que la aplicación vaya a implementarse, podría ud. prototipar en cualquiera de las plataformas soportadas por
GeneXus.
El instructor deberá entregarle al comenzar el práctico los datos de la plataforma elegida para el curso, de manera tal
que ud. configure el modelo de prototipo con esa información.
Encontrará notas a continuación de algunos ejercicios, que invitan a la reflexión sobre lo realizado. Fueron incluidas para
que el alumno no pase por alto conceptos teóricos importantes que están siendo aplicados. También las habrá con
sugerencias de variaciones al ejercicio, para que las pruebe si así lo desea.
2
Curso GeneXus – Ejercicios Prácticos
Entrar a GeneXus y crear una base de conocimiento de nombre “Practico” para comenzar el desarrollo de la aplicación.
2. Ejercicios de transacciones
A continuación se solicita que se definan algunas transacciones en la base de conocimiento creada antes. Para cada una de
ellas se muestra una imagen del form Web y una lista de atributos a incluir en su estructura (sin embargo, podrá ser
necesario incluir otros). Se ejercitan diversas características de las transacciones (definición de reglas, fórmulas, etc.).
Sugerencias:
- Utilizar la inserción de reglas, funciones, etc., mediante los ítems Insert/Rules, Insert/Functions, etc.
- Decidir qué valor utilizar en la property “Confirmation” y en caso de que su aplicación sea Win, qué valor utilizar
en la property “Client Side Validation”.
- Numerar automáticamente las claves con la propiedad “Autonumber” de los atributos numéricos clave.
- Utilizar: Tools/List Database.
- Utilizar: Tools/List Attributes.
- Hacer Diagrama de Tablas mediante la opción: Tools/Diagrams/Tables.
Transacción “Country”
Atributos:
Luego de haber ingresado el CountryId en la estructura de la transacción, con toda su información relacionada
(Description, Type, Nulls, etc.), y cuando esté pronto para digitar el próximo atributo CountryName, en lugar de
digitar la primera letra, “C”, para escribir Country, digite punto ‘.’. ¿Qué sucedió?
Si hace doble clic o F2 sobre el campo Nulls del atributo CountryName en la estructura, se le abrirá un combo box
con los valores posibles para esa propiedad (“Yes”, “No”, por defecto es “No”). ¿Qué sucede si hace lo mismo para
el atributo CountryId? ¿Por qué no aparece el combo para poder cambiar el valor por defecto?
Form Web:
Reglas:
3
Curso GeneXus – Ejercicios Prácticos
Transacción “Customer”
Definir los dominios: Name como Character(50) y Price como Numeric(9.2), siguiendo lo que se indica a continuación.
Atributos:
Edite el dominio Name y modifique su tipo de datos para que en vez de Character(50) sea Character(30). Observe la
repercusión en los atributos que tienen este dominio asociado (ver atributos CountryName y CustomerName).
4
Curso GeneXus – Ejercicios Prácticos
Form Web:
Generalidades:
• Definir CustomerGender para que aparezca en el form como un control Radio Button.
Reglas:
• No se permiten clientes sin nombre.
• Avisar en caso de que no se ingrese la dirección.
• No permitir que se ingrese valor en el total de compras (se irá actualizando dede las facturas del cliente).
• El saldo del cliente se calcula como la diferencia entre sus compras y pagos.
• No permitir que se ingrese valor en este atributo (CustomerBalance)
Luego de definidas las dos transacciones anteriores en el modelo de Diseño, querrá probar en ejecución lo hecho, para lo
cuál deberá implementar la aplicación en una plataforma determinada.
Recuerde que un modelo de prototipo o producción corresponderá a una implementación del sistema.
5
Curso GeneXus – Ejercicios Prácticos
Deberá configurar la interfaz que utilizará (win o web), el lenguaje (ej: .Net), DBMS (ej: Sql Server), así como el
servidor en el que se encuentra la base de datos que asociará a su modelo, en la que se crearán las tablas, el
nombre de dicha base de datos, usuario y password de la base de datos con los que se conectará a la misma, etc.
Cuando termine de configurar el modelo se realizará el análisis de impacto, cuyo resultado será el IAR (reporte de
análisis de impacto). Observe detenidamente la información que le brinda el reporte. Luego de ejecutado el
programa de Creación de la base de datos, estará pronto para generar los programas correspondientes a los dos
objetos creados. Puede abrirse una ventana inmediatamente después, que le preguntará si desea ejecutar
GeneXusQuery. Dígale que NO.
Especifique y genere sus objetos (aquí generará los fuentes en el lenguaje elegido; por ejemplo, si su prototipo es .Net se
creará por cada objeto GeneXus un archivo de extensión cs)
Compile y ejecute el DeveloperMenu (menú creado automáticamente por GeneXus que contiene una entrada por cada
objeto generado. Desde allí podrá ejecutar sus dos transacciones).
Ingrese algunos países y clientes. Luego:
Clave candidata
Si en su realidad no pueden existir 2 clientes con el mismo nombre, es decir, si CustomerName no puede tener valores
duplicados, ¿cómo representa esto en el Diseño para que sea chequeado automáticamente?
Defina un índice unique sobre la tabla CUSTOMER, compuesto por el atributo CustomerName, de tipo ascendente.
Como habrá visto, los programas GeneXus controlan la integridad referencial entre las tablas, de modo que no se le
permitió ingresar un cliente en la transacción “Customer” sin asociarle país (sin ingresar un código de país válido).
Pero algunos clientes pueden no brindarle la información del país del que son originarios, o puede ser información
desconocida para algún cliente en particular. Si desea poder ingresar un cliente sin país asociado, ¿qué deberá modificar
del diseño de la transacción “Customer”?
¿Por qué no puede modificarse el valor de la columna Nulls del atributo CountryId en la estructura de la transacción
“Customer” en el modelo de Prototipo y deberá ir a Diseño para hacerlo?
Después de modificada en Diseño la propiedad Nulls del atributo CountryId, que es foreign key en “Customer”, pase a
Prototipo para probar en ejecución la nueva transacción. Para ello especifique y genere nuevamente la transacción
“Customer” para que se tenga en cuenta el cambio en el programa generado. Compile y ejecute intentando dejar un
cliente sin país y observe que ahora esto será posible.
6
Curso GeneXus – Ejercicios Prácticos
Transacción “Product”
Atributos:
Form Web:
Reglas:
• No aceptar el stock del producto si se está modificando un artículo ya existente; solo permitir ingresar el
stock del producto si se está insertando un producto.
• No permitir que el stock quede con valor vacío cuando se ingresa un producto nuevo.
Transacción “Invoice”
Atributos:
7
Curso GeneXus – Ejercicios Prácticos
Form Web:
Observar que esta transacción es de dos niveles. ¿Le puso nombre al nivel 2? Si ud. no lo hace, GeneXus lo hará por ud.
¿Qué nombres le dará GeneXus por defecto a las tablas correspondientes al primer nivel y al segundo de la transacción
“Invoice”?
Vaya al folder de nombre “Tables” que aparece en el árbol de directorios de la izquierda del ambiente de Prototipo y
observe las tablas que GeneXus diseñó de acuerdo al diseño de transacciones que ud. realizó. Busque las tablas que
correpondan al nivel 1 y 2 de la transacción “Invoice” y observe qué atributos aparecen en cada una. Observe que la
clave primaria de la tabla correspondiente al nivel dos está conformada por dos atributos: InvoiceId e InvoiceLineId.
Observe los índices que creará GeneXus sobre esta tabla.
Observe que el form anterior está personalizado: CustomerId y CustomerName se han puesto en la misma fila.
CustomerTotalPurchases no aparece en el form (Deberá borrar este control).
herramientas Formatting indicado aquí: logra que se le muestren en diseño los bordes de las tablas
donde están contenidos los controles del form. Cliquee allí y le aparecerán dichos bordes.
Para eliminar una fila vacía de una tabla, posicionándose en una celda de esa fila, hacer botón
derecho/Table/Delete Rows. Para insertar una tabla, un camino possible es Insert/Table.
Obsérvese que ProductStock no aparece en el grid del form presentado antes. Deberá borrarlo. Para ello recuerde que
para trabajar con las columnas de un grid y eliminar atributos o variables de las columnas, reordenar las columnas, etc
cuenta con:
En form Web: botón derecho/Column sobre él. Observe que aquí aparecerán no solo los atributos del 2do. nivel
de la transacción, sino que la primera columna corresponde a una variable &GxRemove, que aparece en el grid como
un check box. ¿Para qué incluye GeneXus esta variable automáticamente? Le quedará más claro cuando ejecute la
aplicación.
En form Win: botón derecho/Properties.
8
Curso GeneXus – Ejercicios Prácticos
Los nombres de las columnas del grid se han acortado (no coinciden con las descripciones que le dimos a los atributos).
¿Cómo logra esto? Recuerde que puede especificar el nombre que desea que aparezca por defecto como título de
columna de un atributo cuando éste aparezca en grids, mediante la propiedad del atributo: Column Title. (haciendo
botón derecho/properties sobre el atributo en la estructura). La otra opción es cambiar el título del atributo en la columna
del grid particular donde se encuentra. ¿Cómo?
Win: se arrastra con el mouse al lugar donde desea que quede. Puede utilizar la plaleta de herramientas Form para
alinear los controles. Para que salga en el form de color rojo además cambiar al valor Original la propiedad del
modelo de prototipo “Color in Read-Only Fields”. (Esto se hace en: File/Edit Model/botón “Properties”/grupo “User
Interface”/property “Color in Read-Only Fields”)
Reglas:
3. Numerar las líneas de la factura en forma automática (a partir de aquí el atributo InvoiceLineId no necesita ser
ingresado por el usuario. Deshabilitarlo.)
4. Actualizar el total de compras del cliente.
5. Actualizar el stock del producto.
6. Controlar que el stock del producto no sea menor que cero.
7. Evitar que se ingresen más de 5 líneas en la factura (relacionado a fórmula 3).
Fórmulas:
¿Tiene que ir a Diseño para agregar reglas en una transacción? ¿No es suficiente definirlas en la transacción en
Prototipo?
¿Por qué debió incluir el atributo ProductStock en la estructura de la transacción pese a que no lo incluyó en el form?
(lo mismo que para CustomerTotalPurchases)
¿Cómo muestra GeneXus la fórmula 3 en la estructura de la transacción: en mayúscula o en minúscula (COUNT ó
Count)? ¿Existe alguna diferencia?
Recuerde volver a especificar y generar el objeto que sufrió las modificaciones para que se cree el programa
correspondiente con las modificaciones (sino quedará el viejo). Aquí solo modificó la transacción “Invoice” por lo que
no necesita hacer “Build All”…sino “Sepecify”.
9
Curso GeneXus – Ejercicios Prácticos
Si solamente inserta el atributo CustomerBalance en el form y olvida declararlo en la estructura le dará un error al
grabar (‘Atributo’: Invalid attribute). Recuerde declarar siempre en la estructura los atributos de la tabla extendida
que vaya a utilizar en el form o en las reglas.
Pruebe ingresar una factura para un cliente determinado y observe que se dispara la regla 4 definida: add( InvoiceTotal,
CustomerTotalPurchases), pero no se actualiza el saldo, CustomerBalance, de acuerdo al cálculo anterior. ¿Por qué?
Modifique el atributo CustomerBalance para que siempre que se consulte, desde cualquier objeto GeneXus, se calcule.
Normalización
Si en la estructura de la transacción “Invoice” se agregan al primer nivel los atributos CountryId y CountryName, ¿qué
ocurrirá con la tabla INVOICE? ¿Se almacenará el atributo CountryId como foreign key a la tabla COUNTRY? ¿O se
normalizará y GeneXus entenderá que ese atributo deberá inferirse, al igual que CustomerName, del cliente, CustomerId?
Pruébelo en GeneXus y corrobore si el comportamiento es el que ud. esperaba. Reflexione sobre lo hecho.
¿Y si quisiera que la factura tuviera un país propio, que el usuario final deba ingresar junto con la factura, es decir, si
quisiéramos que el país no fuera inferido del cliente? Por ahora ud. no cuenta con las herramientas para resolverlo.
Lo hará al final del práctico, cuando estudie subtipos.
Transacción “Customer”
Compare el form que mostramos antes para la transacción “Customer” con el siguiente (encuentre las diferencias):
10
Curso GeneXus – Ejercicios Prácticos
Lo que se hizo aquí fue “disfrazar” el atributo CountryId de CountryName, para permitirle al usuario en ejecución
trabajar con descripciones en lugar de tener que trabajar con códigos. Para el usuario será más fácil recordar el
nombre de un país, que su identificador. El sistema internamente sigue trabajando con el identificador. ¿Cómo se
logra este comportamiento?
Pruébelo en su transacción, editando las propiedades del control atributo CountryId en el form (botón
derecho/Properties) y modificando la propiedad que corresponda de forma de conseguir lo que busca (sugerimos
revisar el material teórico). Deberá quitar el atributo CountryName del form, pues ya no será necesario.
Al hacerlo en el control del form, en lugar de hacerlo de manera centralizada en las propiedades del atributo en la
estructura, solo aplicará a este form particular de esta transacción particular.
Pruebe, sumada a la utilización de descripciones en lugar de códigos, la facilidad de sugerirle al usuario en ejecución
a medida que va digitando el nombre del país, todos los países que empiecen con las letras que el usuario haya
digitado hasta el momento, de manera tal que no deba recordar el nombre completo de memoria, sino solo cómo
empieza, para poder luego seleccionarlo de los sugeridos.
11
Curso GeneXus – Ejercicios Prácticos
Interfaz Web: para poder visualizar directamente desde el browser un reporte, debe ser generado como PDF. Debe
configurar las siguientes propiedades del objeto reporte:
Main = ‘YES’
Call Protocol = HTTP
Report Output = Only to File
Y la siguiente regla:
Output_file(‘nombre-archivo.pdf’ , ‘PDF’)
1. Reporte de clientes en un rango de nombres [si está prototipando en Win: el rango será definido por el usuario; en
caso contrario (prototipo Web) hasta que no estudie web panels deberá dejarlo fijo en el Source (hardcoded). Si ya vio
como implementar un Web panel para pedirle datos al usuario, hágalo]. Los datos que se desean listar para cada
cliente son : Nombre, Dirección y Saldo (Balance).
Al crear un objeto reporte se le abrirá automáticamente el Report Wizard para ayudarlo en la definición del Layout y
Soruce del reporte. Cancele este Wizard, así practica la creación de cero del reporte.
¿Es necesario pasar a Diseño para crear un reporte, o puede crearse directamente en Prototipo?
Al especificar el reporte dedique unos minutos a estudiar el listado de navegación (es muy importante hacerlo en
todos los casos).
Observe el orden que eligió GeneXus para el for each. ¿Está optimizado este reporte?
Observe las diferencias en el listado de navegación que surgen de agregar o quitar la cláusula “order
CustomerName” del for each.
¿Qué tablas está accediendo el for each?
Ahora agregue el nombre del país del cliente a la información que quiere mostrarse, y observe la repercusión en el
listado de navegación.
3. Reporte de ventas por cliente, incluyendo sólo los clientes que tienen facturas (Corte de Control).
Cliente : CliXXX
Cliente : CliYYY
12
Curso GeneXus – Ejercicios Prácticos
Observe cuidadosamente el listado de navegación. ¿Cómo sabe que implementó un corte de control?
Si además de querer agrupar las facturas por cliente, totalizando el importe, desea que salgan ordenadas las
facturas por número, ¿qué deberá hacer? Pruébelo. En el ejemplo la factura 11 debería salir antes que la 15.
¿Por qué GeneXus informa en el listado de navegación que el orden será el mismo para los dos for eachs, incluso
cuando ud. especificó un orden para el externo y otro orden para el anidado?
4. Reporte de ventas por fecha, agrupadas por cliente. Es decir, para cada fecha en la que hay facturas, se desea ver la
información de las mismas (Identificador e Importe), pero agrupada por cliente. (Doble corte de control).
Fecha: 01/01/06
Cliente: CliXXX
Id Importe
2 $150
3 $10
Cliente : CliYYY
Id. Importe
1 $700
4 $300
Fecha: 02/02/06
Cliente: CliYYY
Id Importe
5 $200
Este tema no aparece en las transparencias del curso, pero sí en las notas que se incluyen al final del tema Corte de
Control. Lea cuidadosamente el ejemplo e implemente el reporte que se le pide.
¿Cuántos for eachs son necesarios para implementar un corte de control doble?
¿Dónde se especifica cada criterio de corte?
5. Realizar la siguiente modificación de diseño en la transacción “Product”: que cada producto en lugar de tener un
solo precio, tenga un histórico de precios según la fecha.
Y su form Web:
13
Curso GeneXus – Ejercicios Prácticos
Como consecuencia del cambio de diseño anterior en la transacción “Product”, ya no es posible inferir el atributo
ProductPrice en el segundo nivel de la transacción “Invoice” (porque ProductPrice ya no pertenece a la tabla extendida de
la tabla INVOICELINE).
Se debe quitar al atributo ProductPrice del segundo nivel de la transacción “Invoice”, definir un nuevo atributo
(InvLineProductPrice) y calcular el valor de ese atributo (hay que encontrar el precio del producto de acuerdo a la fecha de
la factura).
Tiene varias opciones, una de las cuales es invocar a un procedimiento que realice el cálculo devolviendo el resultado.
Podrá definir a InvLineProductPrice como fórmula horizontal, que se calcula mediante el procedimiento anterior.
Implemente el procedimiento que busque el precio del producto de acuerdo a la fecha de la factura y lo devuelva como
resultado en el atributo fórmula anterior.
6. Definir un procedimiento para generar una nueva lista de precios para los productos. El procedimiento debería recibir
por parámetros: fecha de aumento y porcentaje de aumento. Otra vez, cuando estudiemos el objeto Web Panel podrá
realizar este pedido al usuario e invocar a este procedimiento enviándole esos parámetros. Por ahora, coloque esos
valores en el Source de manera fija (hard code) y pruebe de esa manera. Para cada producto deberá generar un
nuevo registro en el histórico de precios, con la fecha ingresada como parámetro y el precio que resulte de aplicar el
porcentaje de aumento, al último precio del producto, anterior a la fecha de aumento.
En el procedimiento suponemos que no existirán registros para la fecha (recibida por parámetro ó hardcoded), y por
tanto siempre se insertará un nuevo registro para cada producto. Modifique ahora su solución de forma tal de que si
sí existiera ya un registro para algún producto con la fecha recibida, el mismo se actualice de forma tal de aplicarle el
porcentaje a su precio.
Y definir un procedimiento que realice lo siguiente: para cada cliente, sumarice el importe total de todas sus
facturas, y genere un recibo de pago para el cliente, con la fecha del día, y el importe total a cobrarle.
En la solución que implementó, si un cliente no tuviera facturas, ¿tendría igualmente un recibo por total cero,
generado? Si la respuesta es afirmativa, ¿cómo modifica esto para que solo los clientes con facturas tengan un
recibo generado?
14
Curso GeneXus – Ejercicios Prácticos
Generalidades: Crear un folder y agrupar en el mismo a los web panels que se definan.
Para definir web panels, las principales funcionalidades se encuentran en las barras de herramientas que se detallan a
continuación:
Las opciones de esta segunda barra son accesibles mediante las opciones del Menú- Insert.
15
Curso GeneXus – Ejercicios Prácticos
10. Definir los eventos de usuarios necesarios para poder realizar con los registros todas las operaciones descriptas en el
punto anterior.
11. Programar los eventos necesarios para realizar la paginación de los registros.
Observar que en el grid de este web panel no se está mostrando el atributo CustomerId. Estudie si hay que realizar
algo con dicho atributo para que las funcionalidades solicitadas se ejecuten adecuadamente.
12. Agregar un botón más en el form e invocar en su evento al web panel “View Customer Invoices” pasándole por
parámetro el cliente (CustomerId) que se encuentre seleccionado en la grilla.
13. Definir el web panel “View Customer Invoices”:
que recibe por parámetro un identificador de cliente (del cual se desean consultar sus facturas).
Se desea que el web panel “View Customer Invoices” despliegue la lista de facturas ordenada por fecha, del cliente
recibido como parámetro. Los datos que se desean desplegar en la parte fija del web panel son Identificador y Nombre
del cliente, y en la grilla: Nro. de Factura, Fecha y Total de Factura.
Además:
• Incluir en este web panel un bitmap con el logo de la empresa (una imagen cualquiera).
• Agregar un botón en este web panel, que al presionarlo llame a la transacción “Invoice” en modo display para
visualizar todos los datos de la factura seleccionada.
14. Definir el siguiente web panel “sin tabla base”: se solicita un web panel que muestre para cada cliente, su total
facturado, pero sólo de los clientes que tengan facturas. En tiempo de ejecución el resultado de la consulta deberá
lucir así:
15. Resolver la misma consulta que se solicita en el punto anterior con web panel “con tabla base”.
16. Definir un web panel con 3 grids: en el primer grid se deben mostrar todos los clientes; y cada vez que el usuario
seleccione un cliente en el mismo, se deberán cargar sus facturas en el segundo grid. A su vez cada vez que el usuario
seleccione una factura del segundo grid, se deberán cargar sus líneas en el tercer grid.
16
Curso GeneXus – Ejercicios Prácticos
El Prompt de Productos es un web panel (generado automáticamente por GeneXus, de nombre GX00NN) que puede ser
llamado desde la transacción de facturas y permitirá seleccionar un producto.
Lo que se pide es tener la posibilidad de dar altas, bajas y modificaciones de productos (llamando a la transacción
“Productos”) desde este prompt.
17
Curso GeneXus – Ejercicios Prácticos
5. Subtipos
Si ahora queremos representar que una factura pertenece a un país, independientemente del país del cliente de la
misma, ¿qué modificaciones debe realizar? Impleméntelas.
Observar que la factura pertencerá a un país, por ejemplo Uruguay, y el cliente de la factura podrá pertenecer a otro
país distinto, por ejemplo United States.
6. Business Components
Para probar las ventajas que brinda la posibilidad de encapsular toda la lógica de una transacción para poder actualizar y
consultar la información de sus tablas sin requerir de su interfaz, pero aplicando toda esa lógica, cree un procedimiento o
reporte a partir del cual ingresará varias facturas al sistema, utilizando business components en lugar del comando new del
procedimiento.
¿Qué ocurre cuando edita las propiedades de la transacción “Invoice” y configura la propiedad “Business Component”
en True y graba? Aparecerán dos nuevos tipos de datos Business Components. Observe los nombres dados a los
mismos.
¿Qué sucede al especificar la transacción “Invoice”? ¿Por qué aparecen dos listados de navegación?
¿Cómo utiliza ahora estos business components creados dentro del reporte o procedimiento para dar de alta algunas
facturas? Observe que necesita crear una variable basada en el business component correspondiente al cabezal de
factura y otra para las líneas.
Dé de alta en el reporte o procedimiento una factura correspondiente a un cliente que exista, en la fecha de hoy, y luego
dos líneas, con productos existentes, que tengan stock suficiente. Es decir, asegúrese de ingresar una factura cuyo ingreso
sería exitoso si se hiciera a través de la transacción.
Ejecute el reporte o procedimiento, abra la transacción “Invoice” y posiciónese en el último registro. Deberá corresponder
al que ingresó en forma batch.
Ahora modifique el reporte o procedimiento anterior, ingresando un cliente inexistente, en una fecha mayor a la del día de
hoy, un producto inexistente para una línea, y para la otra un producto que exista, pero que no tenga stock suficiente para
cubrir la cantidad llevada.
En el mismo reporte y procedimiento, programe el manejo de errores, es decir, consulte la lista de mensajes del business
component, mostrándolos en pantalla mediante el comando msg.
7.
18