mascara de dinheiro.... estilo caixa eletrônico...

Delphi

16/12/2004

Olá,


alguém sabe como faço uma mascará para quando o usuário vai digitando o valor o mesmo vai sendo automaticamente formatado, estilo os de caixas eletrônicos.


desde já, obrigado.


Balceiro

Balceiro

Curtidas 1

Melhor post

Emerson Nascimento

Emerson Nascimento

21/12/2004

tente esse código, que não necessita de nenhum componente adicional:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
   Texto, Texto2: string;
   i: byte;
begin
   if (Key in [´0´..´9´,chr(vk_back)]) then
   begin
      // limito a 23 caracteres senão haverá um erro na função StrToInt64()
      if (key in [´0´..´9´]) and (Length(Trim(TEdit(Sender).Text))>23) then
         key := 0;

      // pego somente os caracteres de 0 a 9, ignorando a pontuação
      Texto2 := ´0´;
      Texto := Trim(TEdit(Sender).Text)+Key;
      for i := 1 to Length(Texto) do
         if Texto[i] in [´0´..´9´] then
            Texto2 := Texto2 + Texto[i];

      // se foi pressionado BACKSPACE (única tecla válida, fora os números)
      // apago o último caractere da string
      if key = chr(vk_back) then
         Delete(Texto2,Length(Texto2),1);

      // formato o texto que depois será colocado no Edit
      Texto2 := FormatFloat(´#,0.00´,StrToInt64(Texto2)/100);

      // preencho os espaços à esquerda, de modo a deixar o texto
      // alinhado à direita (gambiarra)
      repeat
         Texto2 := ´ ´+Texto2
      until Canvas.TextWidth(Texto2) >= TEdit(Sender).Width;

      // atribuo a string à propriedade Text do Edit
      TEdit(Sender).Text := Texto2;

      // posiciono o cursor no fim do texto
      TEdit(Sender).SelStart := Length(Texto2);
   end;

   Key := 0;
end;

procedure TForm1.Edit1Click(Sender: TObject);
begin
   // retorno o cursor para o final do texto, caso tenha sido utilizado
   // o mouse para mover o cursor dentro do Edit
   TEdit(Sender).SelStart := Length(TEdit(Sender).Text);
end;


talvez os colegas possam melhorar esse código, mas em princípio creio que atenda à sua necessidade.


GOSTEI 2

Mais Respostas

Jc_analista

Jc_analista

16/12/2004

utilize os componentes RX la em um RXCurrencyEdit


GOSTEI 0
Balceiro

Balceiro

16/12/2004

esse componente é bom, mas na verdade estou utilizando o componente flatstyle e se eu sar o rx os componentes ficarão diferentes.


GOSTEI 0
Balceiro

Balceiro

16/12/2004

será que alguém poderia me ajudar?


GOSTEI 0
Fer_nanda

Fer_nanda

16/12/2004

Tente atribuir a formatação assim pro componente
FormatFloat(´R$ ,0.00´,edit.text);

Até


GOSTEI 0
Balceiro

Balceiro

16/12/2004

desse jeito não funciona.


GOSTEI 0
Renato_sp

Renato_sp

16/12/2004

Amigo me de um exemplo de como vc quer se eu fosse digitar o numero

15.762,00
como ia ficando? Assim fica mais facil para tentar montar uma function para vc... Valeu

Renato / SP


GOSTEI 0
Balceiro

Balceiro

16/12/2004

exemplo.

se eu digitar 1 o edit é preenchido com 0,01
se eu digitar o próximo caracter 5 o edit é preenchido com 0,15
se eu digitar o próximo caracter 5 o edit é preenchido com 1,58
se eu digitar o próximo caracter 7 o edit é preenchido com 15,87

e assim por diante....


GOSTEI 0
Renato_sp

Renato_sp

16/12/2004

Amigo nao tinha entendido como vc queria, agora com seu exemplo ficou mais facil montar uma function.. embora nao basta apenas uma function tem que ser tratado alguns eventos para que funcione perfeitamente, fiz alguns testes e te envio o codigo. Teste e verifica se é isso que vc quer.. pelo exemplo que vc me passou ficou exatamente igual, qualquer duvida ou sugestao so falar que tentarei resolver seu problema... Ai vai o codigo com alguns comentarios

var
  Form1: TForm1;
  v1, v2:String;    // PRIMEIRO DECLARE ESSAS DUAS VARIAVEIS GLOBAIS

// AGORA ESTA A FUNCTION DE FORMATACAO

Function FormatarBanco(Valor:String; Quant:Integer):String;
begin
   case Length(Valor) of
      0:result:=´´;
      1:result:=´0,0´+Valor;
      2:result:=´0,´+Valor;
      3:result:=FormatMaskText(´0,00;0´, Valor);
      4:result:=FormatMaskText(´00,00;0´, Valor);
      5:result:=FormatMaskText(´000,00;0´, Valor);
      6:result:=FormatMaskText(´0.000,00;0´, Valor);
      7:result:=FormatMaskText(´00.000,00;0´, Valor);
      8:result:=FormatMaskText(´000.000,00;0´, Valor);
   end;
end;

Fiz com somente ate 8 digitos mas a ai é so colocar mais no case, 9, 10 etc e jogar sua mascara como nos anteriores

// Aqui no evento Change  ( ou seja quando tar escrevendo ) chamo a function que declarei em cima.. vc vai perceber que tem uma variavel sendo dado o valor de outra, isso é para quando digitar o proximo numero, a virgula e o ponto nao dobre ficando um numero inexistente.. algo como 0,,,,15

procedure TForm1.Edit1Change(Sender: TObject);
begin
   v2:=v1;
   Edit1.text:=FormatarBanco(v2, Length(v2));
end;

// Caso é apertado o delete é apagado tudo para que seja refeito o valor

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if key=vk_delete then
      Begin
         Edit1.clear;
         v1:=´´;
      end;
end;

// Aqui eu atribuo o valor a variavel v1 para que seja jogado depois para o v2 para fazer a formatacao

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
   v1:= v1 + key;
end;



Embora o codigo possa parecer meio confuso foi uma alternativa para fazer o que vc quer... Qualquer duvida sobre ele me avise que assim que possivel retornarei

Espero ter ajudado
Renato / SP


GOSTEI 0
Paulo_amorim

Paulo_amorim

16/12/2004

Olá

Fiz uma função para fazer isso, acho que atende:

function Mascara(Texto: String): String;
var
   sAux: String;
   i, iPos: Integer;
begin
     { Deixa só com os números }
     for i := 1 to Length(Texto) do
     begin
          if not (Texto[i] in [´0´..´9´]) then
             Delete(Texto,i,1);
     end;

     { Completar com ´0´ para deixar tamanho correto }
     sAux := StringOfChar(´0´,11 - Length(Texto)) + Texto;
     sAux := FormatMaskText(´000.000.000,00;0´,sAux);

     { Mostrar somente a parte relevante }
     iPos := 1;
     for i := 1 to Length(sAux) do
     begin
          if sAux[i] = ´,´ then
          begin
               iPos := i -1;
               Break;
          end;

          if not (sAux[i] in [´0´,´.´]) then
          begin
               iPos := i;
               Break;
          end;
     end;
     Result := Copy(sAux,iPos,Length(sAux) );
end;

Coloque esse código no OnChange do seu Edit...
Para deixar mais dinâmico, inclua a linha
Edit.SelStart := Length(Edit);
para deixar o cursor sempre no final do edit...

Espero que ajude
Até+


GOSTEI 0
Tinorj

Tinorj

16/12/2004

Acho que esse vai ficar legal.

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if not (Key in [´0´..´9´, 8]) then
    Key := 0;
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);

  function StrTran(pVariavel, pVelho, pNovo: String): String;
  var
    NovoTexto, Texto: String;
    PosIni, TamTexto, TamVelho: Integer;
  begin
    Texto := pVariavel;

    while Pos(pVelho, Texto) > 0 do begin

      PosIni := Pos(pVelho, Texto);
      TamTexto := Length(Texto);
      TamVelho := Length(pVelho);

      if PosIni = 1 then
        NovoTexto := pNovo+Copy(Texto, PosIni+TamVelho, TamTexto-TamVelho)
      else if PosIni = TamTexto then
        NovoTexto := Copy(Texto, 1, TamTexto-TamVelho)+pNovo
      else
        NovoTexto := Copy(Texto, 1, PosIni-1)+pNovo+Copy(Texto, PosIni+TamVelho, TamTexto-PosIni+TamVelho-1);

      Texto := NovoTexto;
    end;

    Result := Texto;
  end;

var
  Valor: Currency;
  Apoio: String;
begin
  Valor := 0.00;

  if TEdit(Sender).Text <> ´´ then try
    Apoio := TEdit(Sender).Text;

    Apoio := StrTran(Apoio, CurrencyString, ´´);
    Apoio := StrTran(Apoio, ThousandSeparator, ´´);
    Apoio := StrTran(Apoio, DecimalSeparator, ´´);
    Apoio := StrTran(Apoio, ´ ´, ´´);

    Valor := StrToCurr(Apoio) / 100;
  except
    Valor := 0.00;
  end;

  TEdit(Sender).Text := FormatCurr(CurrencyString + ´ #,0.00´, Valor);

  if TEdit(Sender).SelLength = 0 then
    TEdit(Sender).SelStart := Length(TEdit(Sender).Text);
end;



GOSTEI 0
Balceiro

Balceiro

16/12/2004

gente muito obrigado pelas dicas...

na verdade eu e o emerson.en quebramos a cabeça e fizemos (quer dizer) alteramos um componete para que ele fizesse isso... e funcionou perfeitamente, se quiser me mande um e-mail ou entre em contato pelo msn quilezi@hotmail.com que eu envio o componente.

até mais.


GOSTEI 0
Aldus

Aldus

16/12/2004

Olá amigos, tenho acompanhado as sugestões de vários colegas sobre a melhor forma de se implementar a digitação tipo caixa eletrônico. Como iniciante, fiz alguns testes com vários desses exemplos e funcionaram perfeitamente. O que poderia ser mudado para que aceitasse uma vez a virgula ou ponto, o cursor ficasse sempre antes da virgula até que ela fosse digitada, e só depois entraria no decimal. Refiro-me a essa opção no caso de estarmos lançando vendas por acaso, que é muito comum quantidades inteiras, e com os exemplos para se digitar 1 unidade teria que ser digitado 100, o que convenhamos para a maioria dos usuários é um sacrifício.

Caso tenham alguma sugestão, postem aqui, pois pela quantidade de visitas, deu pra notar que é um tópico muito interessate e esclarecedor.

Um grande abraço

Mario


GOSTEI 0
Dpinho

Dpinho

16/12/2004

tente esse código, que não necessita de nenhum componente adicional:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
   Texto, Texto2: string;
   i: byte;
begin
   if (Key in [´0´..´9´,chr(vk_back)]) then
   begin
      // limito a 23 caracteres senão haverá um erro na função StrToInt64()
      if (key in [´0´..´9´]) and (Length(Trim(TEdit(Sender).Text))>23) then
         key := 0;

      // pego somente os caracteres de 0 a 9, ignorando a pontuação
      Texto2 := ´0´;
      Texto := Trim(TEdit(Sender).Text)+Key;
      for i := 1 to Length(Texto) do
         if Texto[i] in [´0´..´9´] then
            Texto2 := Texto2 + Texto[i];

      // se foi pressionado BACKSPACE (única tecla válida, fora os números)
      // apago o último caractere da string
      if key = chr(vk_back) then
         Delete(Texto2,Length(Texto2),1);

      // formato o texto que depois será colocado no Edit
      Texto2 := FormatFloat(´#,0.00´,StrToInt64(Texto2)/100);

      // preencho os espaços à esquerda, de modo a deixar o texto
      // alinhado à direita (gambiarra)
      repeat
         Texto2 := ´ ´+Texto2
      until Canvas.TextWidth(Texto2) >= TEdit(Sender).Width;

      // atribuo a string à propriedade Text do Edit
      TEdit(Sender).Text := Texto2;

      // posiciono o cursor no fim do texto
      TEdit(Sender).SelStart := Length(Texto2);
   end;

   Key := 0;
end;

procedure TForm1.Edit1Click(Sender: TObject);
begin
   // retorno o cursor para o final do texto, caso tenha sido utilizado
   // o mouse para mover o cursor dentro do Edit
   TEdit(Sender).SelStart := Length(TEdit(Sender).Text);
end;
talvez os colegas possam melhorar esse código, mas em princípio creio que atenda à sua necessidade.



Amigos, Estou precisando utilizar esta rotina em um DBEdit, e preciso que quando for precionado a tecla enter ou tab salte pra o proximo DBedit
Alguem poderia ajudar


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

16/12/2004

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); 
var 
   Texto, Texto2: string; 
   i: byte; 
begin 
   if (Key in [´0´..´9´,chr(vk_back)]) then 
   begin 
      // limito a 23 caracteres senão haverá um erro na função StrToInt64() 
      if (key in [´0´..´9´]) and (Length(Trim(TEdit(Sender).Text))>23) then 
         key := 0; 

      // pego somente os caracteres de 0 a 9, ignorando a pontuação 
      Texto2 := ´0´; 
      Texto := Trim(TEdit(Sender).Text)+Key; 
      for i := 1 to Length(Texto) do 
         if Texto[i] in [´0´..´9´] then 
            Texto2 := Texto2 + Texto[i]; 

      // se foi pressionado BACKSPACE (única tecla válida, fora os números) 
      // apago o último caractere da string 
      if key = chr(vk_back) then 
         Delete(Texto2,Length(Texto2),1); 

      // formato o texto que depois será colocado no Edit 
      Texto2 := FormatFloat(´#,0.00´,StrToInt64(Texto2)/100); 

      // preencho os espaços à esquerda, de modo a deixar o texto 
      // alinhado à direita (gambiarra) 
      repeat 
         Texto2 := ´ ´+Texto2 
      until Canvas.TextWidth(Texto2) >= TEdit(Sender).Width; 

      // atribuo a string à propriedade Text do Edit 
      TEdit(Sender).Text := Texto2; 

      // posiciono o cursor no fim do texto 
      TEdit(Sender).SelStart := Length(Texto2); 
   end
   else
   if ord(key) <> VK_RETURN then
      Key := 0; 
end; 

procedure TForm1.Edit1Click(Sender: TObject); 
begin 
   // retorno o cursor para o final do texto, caso tenha sido utilizado 
   // o mouse para mover o cursor dentro do Edit 
   TEdit(Sender).SelStart := Length(TEdit(Sender).Text); 
end;



GOSTEI 0
Anderson_blumenau

Anderson_blumenau

16/12/2004

Olá Fiz uma função para fazer isso, acho que atende:
function Mascara(Texto: String): String;
var
   sAux: String;
   i, iPos: Integer;
begin
     { Deixa só com os números }
     for i := 1 to Length(Texto) do
     begin
          if not (Texto[i] in [´0´..´9´]) then
             Delete(Texto,i,1);
     end;

     { Completar com ´0´ para deixar tamanho correto }
     sAux := StringOfChar(´0´,11 - Length(Texto)) + Texto;
     sAux := FormatMaskText(´000.000.000,00;0´,sAux);

     { Mostrar somente a parte relevante }
     iPos := 1;
     for i := 1 to Length(sAux) do
     begin
          if sAux[i] = ´,´ then
          begin
               iPos := i -1;
               Break;
          end;

          if not (sAux[i] in [´0´,´.´]) then
          begin
               iPos := i;
               Break;
          end;
     end;
     Result := Copy(sAux,iPos,Length(sAux) );
end;
Coloque esse código no OnChange do seu Edit... Para deixar mais dinâmico, inclua a linha
Edit.SelStart := Length(Edit);
para deixar o cursor sempre no final do edit... Espero que ajude Até+



eh preciso alguma biblioteca extra?


FormatMaskText aparece indeficador nao declarado


GOSTEI 0
Anderson_blumenau

Anderson_blumenau

16/12/2004

ja achei



MaskUtils


GOSTEI 0
Leleti

Leleti

16/12/2004

10 anos depois... Ae galera, usei esses exemplos e funcionou perfeitamente! Porém quando vou conferir no banco de dados o valor está com várias casas decimais!
Ex: no Delphi inseri o valor de 15,99
no banco esse valor está 15,9899997711182

Nessa tela onde cadastrei esse valor no Delphi tenho um DBGrid para mostrar os produtos e valores já salvo, que chamo os dados do banco, e nesse DBGrid o valor está como o valor gravado no banco: 15,9899997711182

Como faço para gravar o valor exato no banco? Ou pelo menos chamar o valor exato no DBGrid...

Mais uma vez, valeu pelas dicas!!! Nota 10
GOSTEI 0
Pedro Amaral

Pedro Amaral

16/12/2004

OMG 10 anos depois mesmo. kkkk
GOSTEI 0
Leleti

Leleti

16/12/2004

Consegui, o meu problema é que havia colocado o campo como float...
agora mudei para numeric e ficou tudo tranquilo!!!
Uso o Firebird (IBExpert)...
GOSTEI 0
Hélio Kuhn

Hélio Kuhn

16/12/2004

Olá,


alguém sabe como faço uma mascará para quando o usuário vai digitando o valor o mesmo vai sendo automaticamente formatado, estilo os de caixas eletrônicos.


desde já, obrigado.



Tenta esse codigo amigo, da uma olhada se é por ai

//Evento onchange do edit
procedure TForm6.Edit1Change(Sender: TObject);
var
i: integer;
c: currency;
s: string;
begin

if Edit1.Text = EmptyStr then
Edit1.Text := '0,00';

for i := 1 to length(Edit1.Text) do
if Edit1.Text[i] in ['0' .. '9'] then
s := s + Edit1.Text[i];

c := strtocurr(s);
c := (c / 100);

Edit1.Text := currtostr(c);
Edit1.SelStart := length(Edit1.Text);;
end;
//evento onkeypress do edit
procedure TForm6.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if NOT(Key in ['0' .. '9', #8]) then
Key := #0;

end;

end.
GOSTEI 0
Hélio Kuhn

Hélio Kuhn

16/12/2004

exemplo.

se eu digitar 1 o edit é preenchido com 0,01
se eu digitar o próximo caracter 5 o edit é preenchido com 0,15
se eu digitar o próximo caracter 5 o edit é preenchido com 1,58
se eu digitar o próximo caracter 7 o edit é preenchido com 15,87

e assim por diante....



Tenta isso amigo
//evento onchange do edit
procedure TForm6.Edit1Change(Sender: TObject);
var
i: integer;
c: currency;
s: string;
begin

if Edit1.Text = EmptyStr then
Edit1.Text := '0,00';

for i := 1 to length(Edit1.Text) do
if Edit1.Text[i] in ['0' .. '9'] then
s := s + Edit1.Text[i];

c := strtocurr(s);
c := (c / 100);

Edit1.Text := currtostr(c);
Edit1.SelStart := length(Edit1.Text);;
end;
//no evento onkeypress do edit
procedure TForm6.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if NOT(Key in ['0' .. '9', #8]) then
Key := #0;

end;

end.
GOSTEI 0
POSTAR