GeneXus determina ejecutar cada regla definida en una transacción, en el primer momento en el cual tiene todos los valores involucrados como para ejecutarla. La mayoría de las veces, las reglas se ejecutan en el momento que pretendemos. Sin embargo en algunos casos, tenemos la necesidad de modificar el momento de disparo de alguna regla. Analicemos a modo de ejemplo la regla señalizada en la transacción Flight en la diapositiva. Se trata de una invocación a un objeto (en este caso un procedimiento), el cual devuelve un valor de identificador de vuelo específico, armado con determinados caracteres según cierto criterio. ¿Cuándo se disparará esa regla? Ni bien ejecutemos la transacción, puesto que la regla no tiene una condición definida que determine su ejecución ni envía parámetros al objeto invocado por los cuales haya que esperar su valor. Sin embargo, nuestra necesidad es que la llamada al procedimiento se ejecute inmediatamente después que el usuario haya confirmado que desea realizar la inserción del vuelo, pues queremos evitar que suceda que el procedimiento devuelva un identificador y tal vez luego el usuario cierre el formulario sin confirmar, perdiendo así el valor del identificador que generó el procedimiento. Explicaremos a continuación cómo modificar el momento de disparo de la regla para que la misma se ejecute en el instante adecuado. Para fijar ideas, resulta útil esquematizar lo siguiente: • Las reglas sin evento de disparo, se dispararán interactivamente en el primer momento en el cual se tengan todos los valores involucrados como para ejecutarlas. Luego, cuando el usuario presione el botón Confirm, las mismas se volverán a disparar para volver a realizar las evaluaciones antes de grabar en la base de datos. • Las reglas con evento de disparo, se dispararán solamente después de que el usuario haya presionado Confirm. Es importante conocer bien los distintos eventos de disparo y en qué momento específico se ejecutan de acuerdo a las acciones que se realizan en la base de datos, para poder emplearlos adecuadamente. Veremos esto a continuación. Las reglas con evento de disparo, se ejecutan después de que el usuario haya presionado el botón Confirm, en el momento específico que corresponda. Veremos cuándo ocurre exactamente cada evento de disparo. Evento de disparo: BeforeValidate Este evento de disparo ocurre un instante de tiempo antes de que la información de la instancia con la que se está trabajando (cabezal o línea x) sea validada. Es decir, ocurrirá un instante de tiempo antes de la acción de “validación del cabezal” o “validación de la línea”, según corresponda. Observar que aquí también se habrán disparado ya todas las reglas que no estén condicionadas a evento de disparo alguno. Eventos de disparo: AfterValidate, BeforeInsert, BeforeUdate, BeforeDelete El evento de disparo AfterValidate permite especificar que una regla se ejecute inmediatamente antes de que se grabe físicamente cada instancia del nivel al cual está asociada la regla, en la tabla física correspondiente, y después de que se hayan validado los datos de esa instancia. En otras palabras, si se le agrega el evento de disparo AfterValidate a una regla, la misma se ejecutará para cada instancia del nivel al cual esté asociada, inmediatamente antes de que la instancia se grabe físicamente (ya sea que se inserte, modifique o elimine) como registro en la tabla física asociada al nivel. El siguiente ejemplo pretende mostrar visualmente en qué momentos se irán disparando las reglas y fórmulas definidas en una transacción. Reglas stand alone Son aquellas reglas que: 1. Pueden ejecutarse con la información provista por los parámetros recibidos. 2. No dependen de nada para ejecutarse. • Ejemplos de reglas stand alone (por poder ejecutarse con la información provista por los parámetros): &A = parámetro2; Msg( ‘...’ ) if parámetro1 = 7; • Ejemplos de reglas stand alone (por no depender de nada para ejecutarse): msg( ‘You are in the flight transaction’); &A = 7; Por lo tanto, son las primeras reglas que se ejecutan. Luego de la ejecución de las reglas stand alone, se ejecutan las reglas y fórmulas asociadas al primer nivel de la transacción que no tengan evento de disparo definido (es decir que no tengan especificado on ….) en la medida que se vaya disponiendo de los valores involucrados para ejecutarlas. Y al trabajar en el 2do nivel (grid), para cada línea se ejecutan las reglas y fórmulas asociadas al 2do nivel de la transacción que no tengan evento de disparo definido (es decir que no tengan especificado on ….) en la medida que se vaya disponiendo de los valores involucrados para ejecutarlas. 11 Cuando el usuario confirme, se volverán a disparar todas las reglas y fórmulas en orden para volver a realizar las evaluaciones antes de grabar en la base de datos. Además, se dispararán las reglas con evento de disparo, antes o después de cada acción realizada o por realizarse en la base de datos, tal como muestra el esquema. Es importante conocer bien los distintos eventos de disparo y en qué momento específico se ejecutan de acuerdo a las acciones que se realizan en la base de datos, para poder emplearlos adecuadamente. Reglas con el mismo evento de disparo Cuando en una transacción se definen dos o más reglas con el mismo evento de disparo, y no existe ninguna dependencia entre ellas, las mismas se ejecutarán respetando el orden de definición. Ejemplos: 1) Se definen las siguientes reglas en una transacción: xxx() on AfterComplete; yyy() on AfterComplete; Como las dos reglas definidas están condicionadas con el mismo evento de disparo, y no existe ninguna dependencia entre ellas, las mismas se ejecutarán en el mismo orden en el cual se han escrito. 2) En una transacción se necesita invocar a un procedimiento que realiza determinada validación y retorna un valor ‘S’ o ‘N’; si el valor devuelto es ‘N’, se debe dar un mensaje de error. Para resolver esto, evaluaremos dos posibilidades: 2.1) Definir las reglas: Something(FlightId, &flag) on AfterComplete; error(‘…’) if &flag=‘N’ on AfterComplete; 2.2) O definir las reglas: &flag = Something(FlightId) on AfterComplete; error(‘…’) if &flag=‘N’ on AfterComplete;