Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   OnValidate y Foco (https://www.clubdelphi.com/foros/showthread.php?t=563)

javiermorales 19-05-2003 09:07:23

OnValidate y Foco
 
Buenos Días, tengo un problema con el foco de unos DBEdit, ya que cuando sales de un DBEdit, se activa el evento OnValidate del campo asociado y en este evento, se realiza la actualización de diversos campos (asociados a DBEdits de ese Form) y estos a su vez activan sus eventos OnValidate.

Al final, el campo que debe tener el foco, parece que lo tiene, ya que si haces una nueva tabulación pasa al siguiente campo en el orden correcto de tabulación. El problema está en que aunque parezca que tenga el foco si intentas escribir sobre él, se modifica, aunque al pasar al siguiente campo se pierden los cambios. Además no aparece como seleccionado.

Por favor, he intentado de todo (desactivando la actualización del formulario, con LockWindowUpdate, etc).

Realizando la traza todo funciona correctamente y el foco aparece correcto.

Estoy desesperado, alguien tiene alguna idea.

Gracias.

javiermorales 19-05-2003 13:48:20

Cualquier sugerencia será bienvenida ya que he llegado a un callejón sin salida.

Un saludo.

Bacterion 19-05-2003 15:58:16

Supongo que , al cambiar un campo de valor, quieres cambiar otros campos.

El OnValidate, se supone, es para que valides si el valor que vas a poner sigue las reglas que hayas definido para ese campo (que no sea 0, que no sea negativo, que rime con Pascual), y si no se cumplen, abortar (mensaje, silencioso, formateando el disco duro...). Mejor ponlo en el OnChange.

¿De todas formas, no podrías dar un ejemplo que reproduzca ese comportamiento (código?) para que veamos de que se trata?
A ver si es que lanzas un cambio sobre un campo que a su vez lanza otro cambio sobre el actual, etc...

Kafu 19-05-2003 16:23:31

Estoy con Bacterion en cuanto a que tiene pinta de haber cruce de referencias entre varios componentes. De todas formas comentas que cuando lo traceas no tienes el problema. Evidentemente al coger el foco el depurador cuando vuelves a ver la pantalla windows ya ha gestionado el movimiento del foco, así que no te sirve ese traceo. Contando con dos monitores, uno para el depurado y otro con la aplicación sí verías el resultado real. Si no cuentas con ese segundo monitor yo escribiría a un fichero la información que quieras tracear, en tu caso iría rastreando el activecontrol, etc. Los showmessages tampoco te sirven porque te moverían el foco. En cuanto a poner las validaciones en el onchange no sé, es según la intención que tengas. Yo no suelo usar validaciones parciales y además ahí sí que hay riesgo de recursividad, si desde un onchange disparas otro. Pero claro depende de cómo esté programado.
Bueno un saludo,

javiermorales 20-05-2003 08:15:42

Muchas gracias por contestar. En efecto lo que se busca es actualizar el valor de varios campos.
Ejemplo:

"Cantidad" "Precio" "Importe"

Cuando Actualizo "Cantidad", en el OnValidate, llamo a una función (CalculaPrecPAR) dentro del DataModule que realiza un cálculo en cascada de los datos que se ven afectados en la misma tabla del mismo formulario:

procedure TDM.CalculaPrecPAR();
begin
//Calcula PrecioCoste=(Precio*(%MA))*(%CI)
TaPTOPAR.FieldByName('PTOPAR_PREC2').ReadOnly := false;
TaPTOPAR.FieldValues['PTOPAR_PREC2'] := ((TaPTOPAR.FieldValues['PTOPAR_PREC'] *
(1+(TaPTOPAR.FieldValues['PTOPAR_MA']/100))) *
(1+(TaPTOPAR.FieldValues['PTOPAR_CI']/100)));
TaPTOPAR.FieldByName('PTOPAR_PREC2').ReadOnly := true;
//Calcula ImporteCoste=Cantidad x Precio2
TaPTOPAR.FieldByName('PTOPAR_IMP').ReadOnly := false;
TaPTOPAR.FieldValues['PTOPAR_IMP'] := TaPTOPAR.FieldValues['PTOPAR_CAN'] *
TaPTOPAR.FieldValues['PTOPAR_PREC2'];
TaPTOPAR.FieldByName('PTOPAR_IMP').ReadOnly := true;
//Calcula ImporteOferta=ImporteCoste x K
TaPTOPAR.FieldByName('PTOPAR_OFER').ReadOnly := false;
TaPTOPAR.FieldValues['PTOPAR_OFER'] := TaPTOPAR.FieldValues['PTOPAR_IMP'] *
TaPTOPAR.FieldValues['PTOPAR_K'];
TaPTOPAR.FieldByName('PTOPAR_OFER').ReadOnly := true;
//Calcula PrecioOferta=PrecioCoste x K
TaPTOPAR.FieldByName('PTOPAR_POFER').ReadOnly := false;
TaPTOPAR.FieldValues['PTOPAR_POFER'] := TaPTOPAR.FieldValues['PTOPAR_PREC2'] *
TaPTOPAR.FieldValues['PTOPAR_K'];
TaPTOPAR.FieldByName('PTOPAR_POFER').ReadOnly := true;
end;

Muchas Gracias.

marcoszorrilla 20-05-2003 09:15:08

Yo para este tipo de casos, creo una "Procedure" que hace el trabajo y la llamo desde el OnChange de los campos susceptibles de producir cambios.

Teniendo cuidado de no incurrir en recursividad, por ejemplo en una línea de factura tanto se cambien las unidades como el precio se produce un cambio en el importe, en el OnChange de ambos campos llamo a un Procedimiento que hace el cálculo pertinente.

Un Saludo.

javiermorales 20-05-2003 09:21:19

Gracias Marcos, una cuestión, el evento OnChange, ¿se dispara con cada modificación del importe, es decir con cada pulsación de un digito de la cifra?. En ese caso, ¿no serán demasiadas llamadas al procedimiento?.

¿Que tal te va a tí?. Gracias. Un saludo.

Bacterion 20-05-2003 12:09:49

No, el evento OnChange se dispara cuando se cambia el valor del campo. Y como el TDBEdit (y demás componentes dbaware) solo mandan el cambio cuando sales de la celda (o edit) en la que estés editando, pues solo se te disparan una vez.

Por cierto, quizás esos cálculos puedas realizarlos en campos calculados y quitarte muchos problemas...

Otro problema que puedes tener puede venir de tus activaciones y desactivaciones del readonly. Si un campo es readonly, deja que lo sea (pobre). Casi te está indicando que debes usar Calculados.

javiermorales 20-05-2003 12:14:58

Muchas Gracias Bacterión, probaré tus consejos.

Un abrazo.

javiermorales 21-05-2003 08:10:16

Hola, os comento. Lo he probado en el evento OnChange y se dispará en 3 ocasiones:

1.- Cuando se carga el formulario
2.- Cuando pasas al estado dsEdit
3.- Cuando sales del campo

Como se disparaba varias veces, al final he optado por los campos calculados, como me indicaba Bacterión.

Con ellos no he tenido problemas, además como deseaba guardar dichos resultados en la BD, cuando se produce el evento OnPost hago que se guarden los campos calculados en sus correspondientes de la BD.

Muchas Gracias a todos, ahora funciona perfectamente.


La franja horaria es GMT +2. Ahora son las 13:59:30.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi