Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-11-2011
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Validacion en celda DBGrid OnKeyPress, OnKeyUp, OnKeyDown

Hola compañeros, iré directo al grano.
Quiero hacer dentro de un DBGrid la validación de valores numéricos. En concreto al introducir una cantidad numérica en una celda que compruebe si el valor introducido es valido con respecto de un stock.

Si al introducir el valor pulso inmediatamente la tecla Intro, se ejecuta el OnKeyPress del DBGrid y en ese evento hago la validación llegándole al método el valor introducido. Hasta aquí todo perfecto.

Como el usuario puede introducir la cantidad, pero en lugar de pulsar Intro, pulsar teclas de desplazamiento como Tab, Left, Right, Up o Down, dentro de los métodos que se ejecutan en estos eventos del DBGrid hago una simple llamada al método OnKeyPress para reutilizar el código que en él se contiene.
La pega es que el valor introducido al hacer las llamadas en los métodos del Grid OnKeyDown y OnKeyUp no contienen aún el valor introducido en la celda (al contrario del método OnKeyPress). Por ello al ejecutar el evento OnKeyPress desde la llamada en los eventos OnKeyDown y OnKeyUp, se recibe en este el valor anterior al introducido, por lo que la validación no se realiza con el valor deseado e introducido.

Por ejemplo: si en una celda del DBGrid tengo un valor 0, e introduzco el valor 23 y pulso Intro, entonces se ejecuta el OnkeyPress validando el valor 23. Por el contrario si en lugar de pulsar Intro pulso teclas de movimiento como Left o Right, se ejecuta el evento KeyDown llamando al KeyPress tal como se muestra en el siguiente código, pero el valor que se pasa no es el 23, si no el valor anterior en la celda, en este ejemplo 0.

El problema es que captura el código de escape y ejecuta el método, todo antes de capturar el valor.

Código Delphi [-]
procedure TForm.DBGridKeyPress(Sender: TObject; var Key: Char);
begin
   if (Key=#13) then showmessage(DBGrid.fields[5].AsString);
end;

procedure TForm.DBGridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  Tecla: Char;
begin
     if ((Key = VK_DOWN) or (Key = VK_UP) or (Key = VK_LEFT) or (Key = VK_RIGHT)) and (DBGrid.SelectedIndex = 5) then
     begin
          Tecla := #13;
          DBGridKeyPress(Sender, Tecla);
     end;
end;

¿Como puedo validar el valor?

He buscado y buscado, pero no he hayado nada.
Gracias.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #2  
Antiguo 25-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Una forma puede ser aprovechar el evento OnSetText del campo a evaluar, que ocurre cuando se le asigna un valor a la propiedad Text del TField pero antes de guardar el cambio.
Lo podés crear desde el Object Inspector, haciendo doble click sobre el campo persistente, o bién por código.

Un ejemplo por código:
Código Delphi [-]
type
  Form1 = class(TForm)
    ...
  private
    procedure DataSetStockSetText(Sender: TField; const Text: String);
  public
  end;
....
implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSet.FieldByName('STOCK').OnSetText:= DataSetStockSetText;
end;

(* Se le asignó un valor a la propiedad Text del TField  *)
procedure TForm1.DataSetStockSetText(Sender: TField; const Text: String);
var
  Stock: Double;  // El tipo de la variable dependerá del tipo de tu campo
begin
  if not TryStrToFloat(Text, Stock) then  // ó TryStrToInt, TryStrToCurr, ... (según el tipo de tu campo)
    raise Exception.Create('Error no es un número válido')
  else if Stock > DataSet.FieldByName('STOCK').AsFloat then
    raise Exception.Create('Stock inexistente')
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
  DataSet.FieldByName('STOCK').OnSetText:= nil;
end;

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 25-11-2011 a las 13:02:18. Razón: Agregar comentarios al código
Responder Con Cita
  #3  
Antiguo 28-11-2011
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Sin duda genial. Gracias.
Aún y así desearía conocer como no poder salir de una celda de una DBGrid hasta que el usuario pulse Intro.
Gracias y un saludo.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #4  
Antiguo 28-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Cabanyaler.

De este modo creo que estaría haciendo todo lo que buscas:
Código Delphi [-]
...
// verificar Stock
procedure TForm1.DataSetStockSetText(Sender: TField; const Text: String);
var
  Stock: Double; 
begin
  if not TryStrToFloat(Text, Stock) then 
    raise Exception.Create('Error no es un número válido')
  else if Stock > DataSet.FieldByName('STOCK').AsFloat then
    raise Exception.Create('Stock inexistente')
  else
    DataSet.FieldByName('STOCK').Value:= Stock;
end;

// No salir de modo edición hasta que se pulse Intro
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if DBGrid1.EditorMode then
  begin
    if Key in [VK_ESCAPE,VK_TAB,VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT] then
      Key:= 0;
  end;
end;

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 29-11-2011
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Gracias, así funciona.

No obstante, he solucionado el problema de la edición de forma distinta. Tipo "Send" de formularios Web, es decir, primero valido todas las líneas y si hay alguna incongruencia por no validación, la corrijo antes de enviar en lote la confirmación al lado servidor.

Gracias a todos por vuestra colaboración. Espero que este hilo solucione futuramente dudas alrededor de los grids, sus validaciones, sus ventajas y sus "carencias" o formas de trabajo.

__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
OnKeyPress dentro de DBGrid cell Gaim2205 OOP 5 07-10-2011 14:52:05
Capturar tecla Tab en OnKeyPress,OnkeyUp... NEG1414 C++ Builder 2 09-11-2008 18:04:32
OnKeyPress, OnKeyUp, OnKeyDown en MonthCalendar santiago14 Varios 6 29-03-2008 01:18:16
validacion dbgrid Sir_Roc Varios 1 07-02-2006 16:48:21
Como Pintar Solo la Celda y No Toda la Columna de la Celda de un dbGrid?? AGAG4 Varios 11 15-11-2004 20:53:28


La franja horaria es GMT +2. Ahora son las 08:46:23.


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
Copyright 1996-2007 Club Delphi