Antonio tengo un DW grilla, solo un campo del DW se actualiza pero cada vez que sea modificado el campo debo hacer una serie de validaciones antes de que de enter y pase al siguiente registro. ¿Dime en que evento debo incluir mi validación? Probé hacerlo en el itemchanged pero ahí no puedo capturar el valor anterior del campo por si se de el caso de que después de las validaciones el cambio no proceda y debo setear el valor anterior nuevamente. ¿Indicame qué evento seria el más optimo para utilizar y como podría hacerlo? Programo en PB9.
1 Respuesta
Respuesta de Antonio Garcia
2
2
Antonio Garcia, clipper todas sus versiones (manejo total) power builder todas...
El proceso de validación en un datawindow (independientemente del tipo), es dado en el evento ITEMCHANGED() Este evento cuenta con 3 variables de referencia. ROW = fila activa DWO = objeto que contiene el foco DATA = el valor antes de ser cambiado (en formato string) Ademas el evento funciona de tal forma que con retornar un valor del tipo numérico, indico una acción de comportamiento. Los valores son: 0 - todo fue bien, y no tiene acción extra 1 - rechaza el valor ingresado y no permite cambiar de foco de edición 2 - rechaza el valor ingresado y si permite cambiar de foco de edición Con estos elementos ya podemos hacer una validación. Un ejemplo. INTEGER li_return = 0 DECIMAL{2} ldc_cantidad CHOOSE CASE LOWER(dwo.name) CASE 'cantidad' ldc_cantidad = DEC(data) IF (ldc_cantidad < 0) THEN li_return = 1 MESSAGEBOX('ERROR', 'NO PUEDE INGRESAR NEGATIVOS') END IF END CHOOSE RETURN(li_return) En el anterior script de ejemplo. Valida un valor que proviene de una columna llamada "cantidad", la cual se encuentra en un datawindow, al momento que el usuario presiona TAB o ENTER, indica la integración del valor, en ese momento es disparado el evento itemchanged(), y en este los pasos son: - Primero detecto el nombre de la columna que tiene el foco, en este caso "cantidad" - luego convierto el valor en DATA, de STRING a DECIMAL - Ahora evalúo si el valor de LDC_CANTIDAD es menor a 0 - En el caso de cumplirse la condición entonces la variable li_return toma el valor 1, y envío un mensaje al usuario - En el caso de no cumplirse la condición de evaluación el proceso sigue con su rumbo normal OJO: Hay agujeros negros que pueden ser de tu interés. Por ejemplo, el usuario ingreso el valor y en lugar de confirmar con ENTER o TAB, uso el cursor del ratón para presionar un botón por ejemplo el cual puede servir para grabar. En este caso el valor no es trasladado definitivamente a la columna correspondiente, entonces en el script del evento clicked del botón, lo primero que tendrás que hacer sera utilizar la función ACCEPTTEXT() Esta función retorna un valor numérico 1 si todo fue bien y -1 si hay un error. Lo que hace esta función es obligar a la ultima columna que tenia el foco, a integrar el valor de la pantalla en su contenido propio, lo cual genera que el evento ITEMCHANGED() sea disparado y por ende disparada la regla de validación Mi recomendación es la siguiente IF (dw_1.ACCEPTTEXT() = 1) THEN ---- PROCESO -- ... ... .. . END IF Como veras en el script, no integro un mensaje al usuario, pues el mensaje va a ser disparado en la regla de validación si lo hiciera seguramente redundaría en mensajería.
Antonio, gracias por el ejemplo. Pero tengo otra pregunta, ¿según el ejemplo que me indicas de los valores negativos en caso se de que el cambio no proceda como capturo la data que estaba anteriormente y la vuelvo a pintar?, ¿El itemchanged me guarda el valor anterior?
Para extraer el valor de una columna simplemente lo haces con la ayuda de la función GETITEMXXXX Las XXXX representan el tipo del item Por ejemplo GETITEMSTRING() -> extrae valores tipo string GETITEMNUMBER() --> extrae valores tipo numerico GETITEMDECIMAL() --> extrae valores tipo decimal GETITEMDATE() --> extrae valores tipo fecha GETITEMTIME() --> extrae valores tipo hora GETITEMDATETIME() --> extrae valores tipo fecha-hora Entonces el valor actual que contiene la columna lo extraes con cualquiera de estas funciones dependiendo del tipo de la columna. Por ejemplo Siguiendo con mi anterior respuesta. El valor actual de la columna cantidad, que se encuentra en la fila 1 Es DECIMAL{2} ldc_cant_actual ldc_cant_actual = dw_1.GetItemDecimal(1, 'cantidad') De esta forma obtienes el valor de la columna antes de la modificación de su valor.