Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Validación coma y decimales Keypress (https://www.clubdelphi.com/foros/showthread.php?t=91825)

Soa Pelaez 08-05-2017 16:56:16

Validación coma y decimales Keypress
 
Buen día.

Quisiera saber si me pueden colaborar, tenía este código que encontre en un foro en el evento keypress de un edit y funciona correctamente me valida que solo deje ingresar dos decimales y que si escribo un punto lo modifique y lo cambie por una coma, como necesito realizar esta validación para varios edits quise hacerlo como un procedimiento, pero al hacerlo no me realiza la validación correctamente (no me cambia el punto por la coma y no lo muestra en el edit).

Alguien que me pueda ayudar a corregir o decirme el motivo por el cual no me funciona. Gracias.

Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char;Edit:TrDBEdit;Sender: TObject);
var
  pos: Cardinal;
begin
  i:=0;
  if ( StrScan('0123456789.,'+chr(7)+chr(8)+#13, Caracter) = nil ) then  Caracter := #0;
  // cambia el punto decimal por coma
  if (Caracter = '.') or (Caracter = ',') then Caracter := ',';
  //controlar entrada una sola coma
  for i := 1 to length(Edit.Text) do
    if ( copy(Edit.Text,i,1) = ',' ) and not ( StrScan(',', Caracter) = nil ) then  Caracter := #0;

  with Sender as TrDBEdit do
  begin
    pos := System.Pos(',', Text);
    if not LongBool(Pos) then Dec(Pos);
      ReadOnly := not (Caracter in ['0'..'9',#13, ',', #8]) or
        (Pos <> $FFFFFFFF) and (Caracter = ',') or
        ((Caracter <> #8) and (Caracter <> #13) and (Pos < (SelStart - 1)));
  end;
end;

orodriguezca 08-05-2017 18:44:58

Creo que el problema esta en la línea:

Código Delphi [-]
if ( copy(Edit.Text,i,1) = ',' ) and not ( StrScan(',', Caracter) = nil ) then  Caracter := #0;

En esa línea de codigo haces referencia directa al objeto Edit. Prueba a cambiarla de esta forma para hacerlo más genérico:

Código Delphi [-]
if ( copy((Sender as TrDBEdit), i , 1) = ',' ) and not ( StrScan(',', Caracter) = nil ) then  Caracter := #0;

Soa Pelaez 09-05-2017 15:45:06

Buen día.

Lo probe de la manera que planteas pero al compilarlo me saler un error y dice que tipos incompatibles y señala la parte del código donde dices (Sender as TrDBEdit).

Gracias espero puedas colaborarme y decirme como organizarlo.

movorack 09-05-2017 17:18:51

Cita:

Empezado por Soa Pelaez (Mensaje 516348)
Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char;Edit:TrDBEdit;Sender: TObject);

Cita:

Empezado por Soa Pelaez (Mensaje 516429)
... pero al compilarlo me saler un error y dice que tipos incompatibles y señala la parte del código donde dices (Sender as TrDBEdit)

Solo cámbialo por el objeto correcto.

Soa Pelaez 09-05-2017 18:45:04

Cita:

Empezado por movorack (Mensaje 516437)
Solo cámbialo por el objeto correcto.

El código lo modifique así como me dices, pero al compilar sigue con el mismo error de tipos incompatibles.
Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char;Edit:TrDBEdit;Sender: TObject);
var
  pos: Cardinal;
begin
  i:=0;
  if ( StrScan('0123456789.,'+chr(7)+chr(8)+#13, Caracter) = nil ) then  Caracter := #0;
  // cambia el punto decimal por coma
  if (Caracter = '.') or (Caracter = ',') then Caracter := ',';
  //controlar entrada una sola coma
  for i := 1 to length(Edit.Text) do
    if ( copy((Sender as TrDBEdit), i , 1) = ',' ) and not ( StrScan(',', Caracter) = nil ) then  Caracter := #0;

  with Sender as TrDBEdit do
  begin
    pos := System.Pos(',', Text);
    if not LongBool(Pos) then Dec(Pos);
      ReadOnly := not (Caracter in ['0'..'9',#13, ',', #8]) or
        (Pos <> $FFFFFFFF) and (Caracter = ',') or
        ((Caracter <> #8) and (Caracter <> #13) and (Pos < (SelStart - 1)));
  end;
end;

movorack 09-05-2017 19:10:51

y entrega el valor correcto a la función que te lanza el error

Soa Pelaez 09-05-2017 19:28:50

Cita:

Empezado por movorack (Mensaje 516453)
y entrega el valor correcto a la función que te lanza el error

No entiendo como sería.

movorack 09-05-2017 19:41:14

Cita:

Empezado por Soa Pelaez (Mensaje 516455)
No entiendo como sería.

¿Leíste lo del enlace?

El error es generado en la función Copy. Ya que la función requiere un texto con el que trabajar

Al hacer el cast

Código Delphi [-]
(Sender as TrDBEdit)

A la función le estás pasando es un objeto no el texto del objeto lo que obtendrías con

Código Delphi [-]
(Sender as TrDBEdit).text

Recomendación:

Ya que al parecer estás usando un control de base de datos, podrías validar el valor almacenado en el campo en lugar al del control.

Código Delphi [-]
QueryFieldavalidar.AsString

Soa Pelaez 09-05-2017 19:53:24

Cita:

Empezado por movorack (Mensaje 516457)
¿Leíste lo del enlace?

El error es generado en la función Copy. Ya que la función requiere un texto con el que trabajar

Al hacer el cast

Código Delphi [-]
(Sender as TrDBEdit)

A la función le estás pasando es un objeto no el texto del objeto lo que obtendrías con

Código Delphi [-]
(Sender as TrDBEdit).text

Recomendación:

Ya que al parecer estás usando un control de base de datos, podrías validar el valor almacenado en el campo en lugar al del control.

Código Delphi [-]
QueryFieldavalidar.AsString

Si esa parte la entendí pero mi problema no es como tal el pasarle el objeto sea de un campo de base de datos o de un edit. El problema es que al invocar el procedimiento desde el evento keypress de un Edit al ingresar un punto no lo muestra y no realiza correctamente la validación del procedimiento que es modificar ese punto cambiarlo por una coma y visualizarlo en el edit con sus respectivos decimales.

Es que lo que tengo en el procedure funciona correctamente si es invocado directamente desde el keypress del edit, me explico sin invocar un procedimiento externo sino aplicar todo el código ahi, pero como lo necesito para varios edits por eso decidí volverlo un procedure pero al hacer esto como te comento no me realiza correctamente la validación.

roman 09-05-2017 20:33:41

Cita:

Empezado por Soa Pelaez (Mensaje 516458)
El problema es que al invocar el procedimiento desde el evento keypress de un Edit

Pon el código con el que invocas al procedimiento.

LineComment Saludos

ecfisa 09-05-2017 20:34:34

Hola.
Cita:

Empezado por Soa Pelaez (Mensaje 516458)
...
Es que lo que tengo en el procedure funciona correctamente si es invocado directamente desde el keypress del edit, me explico sin invocar un procedimiento externo sino aplicar todo el código ahi, pero como lo necesito para varios edits por eso decidí volverlo un procedure pero al hacer esto como te comento no me realiza correctamente la validación.

¿ Y por que no asignas ese código (que funciona correctamente) al evento OnKeyPress de todos los componentes TrDBEdit en que lo necesites ?

Saludos :)

Soa Pelaez 09-05-2017 21:05:43

Cita:

Empezado por roman (Mensaje 516460)
Pon el código con el que invocas al procedimiento.

LineComment Saludos

De esta manera lo invoco en el keypress.

Código Delphi [-]
procedure TFormulario.DBPorcentajeKeyPress(Sender: TObject; var Key: Char);
begin
  ValidarPorcentajeKeyPressEdit(Key,DBPorcentaje,Sender);
end;

Soa Pelaez 09-05-2017 21:07:30

Cita:

Empezado por ecfisa (Mensaje 516461)
Hola.

¿ Y por que no asignas ese código (que funciona correctamente) al evento OnKeyPress de todos los componentes TrDBEdit en que lo necesites ?

Saludos :)

Porque de la manera en procedure lo puedo llamar de muchas partes (distintos formularios), sin realizar uses de unidades.

roman 09-05-2017 21:32:18

Y ¿por qué manejas dos componentes TrDBEdit e el mismo procedimiento? ¿Cuál es la relación entre Edit y Sender?

Es que, de verdad, no se entiende lo que quieres hacer. Hablas de validar la entrada en un Edit pero en el procedimiento con el que quieres hacer la validación se involucra otro Edit.

Trata de ser más explícito y detallado.

LineComment Saludos

Soa Pelaez 09-05-2017 21:35:46

Cita:

Empezado por roman (Mensaje 516467)
Y ¿por qué manejas dos componentes TrDBEdit e el mismo procedimiento? ¿Cuál es la relación entre Edit y Sender?

Es que, de verdad, no se entiende lo que quieres hacer. Hablas de validar la entrada en un Edit pero en el procedimiento con el que quieres hacer la validación se involucra otro Edit.

Trata de ser más explícito y detallado.

LineComment Saludos

No es que maneje otro edit, es que trato de enviar el TRDBEdit donde se entra el texto como parametro al procedure y asi quede general para todos los componentes TRDBEdit.

roman 09-05-2017 21:50:41

Entonces, tu procedimiento debe tener sólo dos parámetros:

Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char; Edit:TrDBEdit);
begin
...
end;

y lo invocas pasando el Sender AS TrDBEdit:

Código Delphi [-]
procedure TFormulario.DBPorcentajeKeyPress(Sender: TObject; var Key: Char);
begin
  ValidarPorcentajeKeyPressEdit(Key, Sender as TrDBEdit);
end;

y modifica tu procedimiento acordemente.

LineComment Saludos

Soa Pelaez 09-05-2017 22:34:58

Cita:

Empezado por roman (Mensaje 516470)
Entonces, tu procedimiento debe tener sólo dos parámetros:

Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char; Edit:TrDBEdit);
begin
...
end;

y lo invocas pasando el Sender AS TrDBEdit:

Código Delphi [-]
procedure TFormulario.DBPorcentajeKeyPress(Sender: TObject; var Key: Char);
begin
  ValidarPorcentajeKeyPressEdit(Key, Sender as TrDBEdit);
end;

y modifica tu procedimiento acordemente.

LineComment Saludos

Lo aplique de esa manera, modifique el procedimiento y aun asi sigue sin realizar el cambio de punto a coma.

roman 09-05-2017 22:42:24

Pon el código final del procedimiento.

LineComment Saludos

Soa Pelaez 09-05-2017 22:52:23

Cita:

Empezado por roman (Mensaje 516472)
Pon el código final del procedimiento.

LineComment Saludos

Aqui está.

Código Delphi [-]
procedure ValidarPorcentajeKeyPressEdit(Caracter: Char;Edit:TrDBEdit);
var
  pos: Cardinal;
begin
  i:=0;
  if ( StrScan('0123456789.,'+chr(7)+chr(8)+#13, Caracter) = nil ) then  Caracter := #0;
  // cambia el punto decimal por coma
  if (Caracter = '.') or (Caracter = ',') then Caracter := ',';
  //controlar entrada una sola coma
  for i := 1 to length(Edit.Text) do
    if ( copy((Edit.Text), i , 1) = ',' ) and not ( StrScan(',', Caracter) = nil ) then  Caracter := #0;

  with Edit as TrDBEdit do
  begin
    pos := System.Pos(',', Text);
    if not LongBool(Pos) then Dec(Pos);
      ReadOnly := not (Caracter in ['0'..'9',#13, ',', #8]) or
        (Pos <> $FFFFFFFF) and (Caracter = ',') or
        ((Caracter <> #8) and (Caracter <> #13) and (Pos < (SelStart - 1)));
  end;
end;

//EJECUCIÓN DESDE EL KEYPRESS DEL COMPONENTE TRDBEDIT
procedure TForm.DBPorcentajeKeyPress(Sender: TObject; var Key: Char);
begin
  ValidarPorcentajeKeyPressEdit(Key,Sender AS TrDBEdit);
end;

olbeup 10-05-2017 09:03:06

Hola Soa Pelaez,

Sólo quieres controlar si al pulsar un (.) se cambie por una (,) y delimitar el número de decimales que puedes introducir, pues yo utilizo esto.

Código Delphi [-]
procedure ValidOnKeyPress(var Key: Char; MaxDecimals: Integer; Text: String);

  const
    WVK_POINT       = '.';
    WVK_COMMA       = ',';
    WVK_NULL        = #0;
    WVK_BACKDELETE  = #8;


  function CountDecimals: Byte;
  var
    nPos: Integer;
  begin
    Result := 0;
    nPos := Pos(',', Text);
    if (nPos <> 0) or (nPos <> Length(Text)) then
      Result := (Length(Text) - nPos);
  end;

begin
  if (Key = WVK_POINT) then
    Key := WVK_COMMA;

  if not (Key in ['0'..'9', WVK_BACKDELETE, WVK_COMMA]) then
    Key := WVK_NULL;

  if (Key = WVK_COMMA) and (Pos(WVK_COMMA, Text) > 0) then
    Key := WVK_NULL;

  if (CountDecimals = MaxDecimals) and (not (Key = WVK_BACKDELETE)) then
    Key := WVK_NULL;
end;
Y la llamada lo hacemos asi.
Código Delphi [-]
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  ValidOnKeyPress(Key, 2, Edit1.Text);
end;
O
Código Delphi [-]
procedure TForm1.DBEdit1KeyPress(Sender: TObject; var Key: Char);
begin
  ValidOnKeyPress(Key, 2, DBEdit1.Text);
end;
Un saludo.


La franja horaria es GMT +2. Ahora son las 12:34:24.

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