Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Validar un dato antes de saber su value (https://www.clubdelphi.com/foros/showthread.php?t=90880)

IVAND 26-09-2016 07:01:43

Validar un dato antes de saber su value
 
Hola a todos tratare de explicarles lo que necesito

Tengo un dbedit , escribo sobre el y presiono la tecla '/' el programa debe ser capaz de tomarme el valor ingresado y efectuar un calculo cualquiera , pero resulta que siempre me da cero voy a explicarle mas claramente


Estoy digitando 10203 y presiono la tecla '/' la cual capturo en el evento keypress es ahi que deseo saber el valor ingresado y no sale el dato si no hasta cuando presiono enter y asi no deseo , conocen uds alguna forma de saber ese valor antes de presionar enter

nota: no utilizo campos persistentes

Gracias muy amable por su tiempo

Neftali [Germán.Estévez] 26-09-2016 09:00:31

¿Puedes colocar el trozo de código que estás utilizando para obtener el valor?

bitbow 26-09-2016 18:42:20

Usa los eventos del dataset OnCalcFields, OnNewRecord, etc.

Saludos.

IVAND 26-09-2016 18:50:56

Gracias por respondes

En el evento keypress

If key='/' Then

campo:=producto.fieldByname('precio').value/100 ;


// La variable campo deberia o quisiera que tomara el valor del campo que estoy escribiendo pero al no dar enter no me toma el valor claro esta, por eso es mi pregunta q como saber el valor del campo q estoy escribiendo antes que llegue a su propiedad value

Nota: No uso campos persistentes

Gracias de nuevo

Neftali [Germán.Estévez] 26-09-2016 19:42:18

¿Y si evalúas directamente el valor que hay en el componente?

IVAND 26-09-2016 20:05:03

Bueno estoy haciendo el ingreso sobre el componente que tiene asociado su dataset y todo si doy enter me muestra el valor en su propiedad value pero si no doy enter que es lo que necesito no muestra nada


Por eso es que necesito saber antes de dar enter su valor por ahi lei algo sobre onsettext creo q es una propiedad del campo pero creo q no la se utilizar


El ejemplo claro para que necesito esto es para cuando el usuario digite un valor sobre este componente y presione la tecla '/' se cambie su valor dividiendo este para el iva asi si yo digito 10 y presiono '/' el calculara 10/1.12 y deberia mostrarme 8.9286 , si pulso enter sobre el campo este pasara el foco al campo siguiente y me tocara con el mouse regresar al componente anterior y presionar '/' para q haga el calculo lo cual no es tan practico

roman 26-09-2016 20:34:47

Cita:

Empezado por IVAND (Mensaje 509116)
asi si yo digito 10 y presiono '/' el calculara 10/1.12 y deberia mostrarme 8.9286

¿Y qué se supone que pasa después de hacer el cambio? ¿El usuario puede seguir escribiendo en ese mismo campo? Suena a una interfaz confusa. Si vuelve a imprimir "/" entonces ¿vuelve a dividir?

¿Por qué no mejor mantener el valor original en el campo y mostrar el nuevo valor en otro campo calculado?

LineComment Saludos

Al González 26-09-2016 21:22:47

Que el compañero describa el objetivo final de lo que desea programar. :)^\||/

IVAND 27-09-2016 04:27:14

Hola Al

efectivamente es solo un tema visual porque lo que realmente se requiere es darle facilidad al usuario , aca en ecuador los precios de los productos se graban con el iva incluido y por comodidad del usuario y evitar poner en mi pantalla mas objetos quería implementar esta opción q vi en otro aplicativo

pero muy aparte de ello se me presenta la duda mas profunda es como acceder al valor de un campo sin darle enter no se si me logro hacerme entender

ya logre hacerlo con un edit.text usando una chapuza (en el evento onchange le asigno el valor del edit.text a una variable y luego en su propiedad onkeypres divido la variable utilizada para el valor q sea

pero sigo sin entender como tomar el dato de un campo de la base de datos sin utilizar estos artificios

utilizo los componentes jfcontrols , le he escrito a soporte técnico y me respondieron lo siguiente
Cita:


Hola Ivan,

En los controles de tipo dataaware el valor debes obtenerlo y manejarlo a través de los campos (fields) del dataset asociado al control. Esta es la forma estándar de hacerlo en Delphi.


Al González 27-09-2016 07:39:22

Hola Iván.

Si tuviera que volver al área de las interfaces de usuario, probablemente yo diseñaría esa pantalla de otra manera. Sin embargo, recordando algo acerca de los data links, decidí escribir una pequeña prueba que puede servirte.

Todos los controles data-aware poseen en su interior un objeto que sirve como enlace entre el control (en este caso un DBEdit) y el componente DataSource asociado. Dicho objeto es el DataLink —enlace de datos— del control. Usando el depurador, poniendo sencillos puntos de ruptura en algunos eventos, puedes darte cuenta de que cuando un componente DBEdit pierde el foco, éste llama a un método de nombre UpdateRecord de su objeto interno DataLink.
Código Delphi [-]
procedure TDBEdit.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  //...
Dentro de la llamada a UpdateRecord se realiza la validación del texto capturado en el DBEdit y la asignación de ese texto al respectivo campo TField (que existe aunque no sea persistente). Parece entonces que llamar al método UpdateRecord del enlace de datos desde tu manejador de eventos OnKeyPress podría ser más que útil. Pero desafortunadamente estos enlaces de datos están declarados de forma privada en la mayoría de los controles data-aware. No obstante, es posible acceder a ellos mediante la lista DataLinks del objeto DataSource asociado. Esta lista contiene los enlaces de datos de todos los controles de captura que emplean el objeto DataSource en cuestión para leer o escribir el contenido de uno o más campos.
Código Delphi [-]
  TDataSource = class(TComponent)
  private
    //...
    FDataLinks: TList<TDataLink>;
    //...
  protected
    property DataLinks: TList<TDataLink> read FDataLinks;
  //...
Al ser TDataSource.DataLinks una propiedad protegida, y no privada, podemos acceder a ella de forma segura mediante el clásico truco de definir una hipotética clase hija TDataSourceAccess, o de forma segura y además elegante mediante un ayudante de clase. Considerando que la necesidad de acceder a las instancias TDataLink puede ser algo eventualmente necesario en tus desarrollos, podrías definir un ayudante como el siguiente en tu biblioteca personal:
Código Delphi [-]
Type
  TDataSourceHelper = Class Helper For TDataSource
    Function FieldDataLink (Const AControl :TComponent) :TFieldDataLink;
  End;

//...

Function TDataSourceHelper.FieldDataLink (Const AControl :TComponent)
  :TFieldDataLink;
Var
  LLink :TDataLink;
Begin
  For LLink In DataLinks Do
    If (LLink Is TFieldDataLink) And
    (TFieldDataLink (LLink).Control = AControl) Then
      System.Exit (Pointer (LLink));

  Result := Nil;
End;
Lo anterior en esencia es equivalente a añadir un nuevo método público, de nombre FieldDataLink, a la clase TDataSource, pero sin modificar la unidad donde esta clase nativa se encuentra. FieldDataLink se encarga de buscar el objeto de clase TFieldDataLink que pertenezca a un control de captura dado —parámetro AComponent—. Con él, esta vez sí podrías llamar al método UpdateRecord desde el manejador de eventos OnKeyPress, como aparece en este ejemplo (ds1 es el DataSource, edPrice el DBEdit y da1 es el DataSet de almacenamiento):
Código Delphi [-]
procedure TForm1.edPriceKeyPress(Sender: TObject; var Key: Char);
begin
  If Key <> '/' Then
    System.Exit;

  ds1.FieldDataLink (edPrice).UpdateRecord;
  VCL.Dialogs.ShowMessage ('The value of the Price field is ' +
    da1.FieldByName ('Price').AsString);
  Key := #0;
end;
De este modo conseguimos que el texto introducido en el control data-aware se procese hacia el campo que se captura, antes de realizar alguna operación que necesite del campo actualizado.

NOTA: En caso de no contar con una versión de Delphi que soporte ayudantes de clases, puedes conseguir lo mismo con una clase TDataSourceAccess hija de TDataSource, poniendo en ella el nuevo método y accediendo a este mediante un molde de tipo sobre el DataSource. Un truco ya bastante conocido. Y de no estar soportado el For-In en tu compilador, esa parte del código puede usar un For normal.

Puede que esta no sea la solución más concisa, pero es similar a lo que yo haría si quisiera lograr lo mismo que tú.

Un abrazo más impuestos.

Al González. :)


La franja horaria es GMT +2. Ahora son las 12:46:05.

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