Você está na página 1de 7

http://www.edudelphipage.com.

br/artigos/mascaras-de-datas-no-delphi

Mscaras de Data no Delphi


por Eduardo Rocha - Publicado em 14/06/10 No sei se uma "falha" do Delphi ou minha :), pois nunca conseguir resolver uma situao simples:

"Permitir que o usurio limpe o contedo de um DBEdit se o campo estiver com mscara de Data na propriedade EditMask".

Faa voc mesmo o teste. Inicie um projeto do zero, adicione um ClientDataSet e no FieldsEditor crie um campo do tipo Date.

Neste campo ajuste a propriedade EditMask usando aquela mscara de data sugerida pelo prprio Delphi no Editor de Mascara: "!99/99/00;1;_". Em seguida ajuste tambm o DisplayFormat para "dd/mm/yy".

Agora volte ao formulrio e adicione um DataSource ligando-o no ClientDataSet. Adicione tambm um DBEdit ligando-o no DataSource e no campo Data recm criado.

Para realizarmos os testes precisamos conseguir "sair" do DBEdit, ou seja, perder o foco, portanto, coloque qualquer componente que receba foco ao lado do DBEdit, pode ser um Edit, por exemplo.

No evento OnCreate do formulrio apenas crie o ClientDataSet em memria:

procedure TForm1.FormCreate(Sender: TObject); begin ClientDataSet1.CreateDataSet; end;


Execute a aplicao e no DBEdit digite uma data qualquer em seguida aperte o TAB.

Legal, nenhuma mensagem apareceu e o foco foi para o Edit.

Agora volte ao DBEdit e apague a data. Em seguida tente sair do campo, veja a mensagem que aparece:

Por que isso?

No help do Delphi diz que o caractere "0" nos obriga a termos um valor numrico naquela posio, enquanto que o caractere "9" no obriga.

Analisando a mscara de data sugerida pelo Delphi temos:

!99/99/00;1;_

Veja os dois caracteres "0" (zero) no final, ou seja, somos obrigados a preencher os dois ltimos dgitos (ano) da data, por isso a mensagem anterior exibida quando tentamos limpar o campo.

S no consegui entender por que a mscara padro usou "0" somente no ano :)

Bom, ento simples, basta trocar o "00" por "99" correto?

Vamos l, faa este ajuste na mscara deixando-a assim:

!99/99/99;1;_

Agora repita o mesmo teste, ou seja, preencha a data no campo e depois tente apagar e sair do campo e veja uma nova mensagem:

Mas por que isso?

Debugando descobri que isso acontece por que ao limparmos o DBEdit, o que de fato est tentando ser "gravado" no campo " / / " e isso realmente no uma data vlida, por isso a mensagem de "data invlida" exibida. Inclusive desta vez o TField quem est alertando e no mais o TDBEdit devido mscara.

Bom, a soluo que encontrei foi ajustar o evento OnSetText do campo para checar, se estiver recebendo este valor, simplesmente limpa o campo, caso contrrio define o valor que est recebendo.

Portanto, abra o FieldsEditor do ClientDataSet e no evento OnSetText deste campo codifique da seguinte forma:

procedure TForm1.ClientDataSet1DATASetText(Sender: TField; const Text: String); begin if Trim(Text) = '/ /' then Sender.Clear else Sender.AsString := Text; end;

Pronto, agora pode fazer os mesmos testes e ver que o problema est solucionado.

Bom, este problema sim, mas esqueci de falar de um outro.

Faa o seguinte teste: digite a data 01/01/01 no dbedit (o objetivo ter diversos zeros). Em seguida saia do campo e entre novamente, veja o que acontece:

No dia e no ms, onde deveria aparecer o zero ficou aparecendo o "_", por que ser?

Boa pergunta, tambm no entendi. Mas a soluo que adotei foi implementar um cdigo no evento OnGetText do campo da seguinte forma:

procedure TForm1.ClientDataSet1DATAGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if not Sender.IsNull then Text := FormatDateTime('dd/mm/yy', Sender.AsDateTime) else Text := ''; end;
Pronto, agora sim tudo funciona perfeitamente!

Bom, isso, queria deixar esta dica aqui, mas se algum tiver uma soluo mais simples, please, me diga, pois como disse no incio, no sei se uma "falha" do nosso amigo Delphi ou minha!

Abraos

7 Comentrios

Pablo Carvalho - 16/06/10 09:01 Eduardo, acredito que o problema dos Zeros possa se resolver trocando o "_" por "0" na mscara ("!99/99/99;1;0"), assim voc indica que o caracter assumido na falta de digitao o zero, e com isso grava Parabns pelo artigo. a data corretamente.

Eduardo Rocha - 16/06/10 09:15 Pablo,

Agradeo Entre Quem Obrigado Abs

pela a

ajuda, data tiver

mas

testei

que por

voc

disse ele

gerou troca

um o

outro "20"

problema. por "02". mandar!

com

"20/11/82", outra

exemplo, dica,

pode

Jean - 16/06/10 09:30 Sua soluo funciona, mas isso pode ser muito trabalhoso se considerarmos que utilizamos data no sistema todo, e ainda pode ocorrer de esquecermos de codificar o evento OnSetText de algum field. Para solucionar este problema adotei o component JvDBDateEdit da biblioteca Jedi, que resolve este problema e muito til para o usurio final utilizar.

Eduardo Rocha - 16/06/10 09:35 Jean, Muito obrigado pela sua dica, certamente usar um componente que j faa todo "trabalho" muito mais prtico. Abs

Pablo Carvalho - 16/06/10 10:19 Tem razo, na minha sugesto anterior as datas que terminavam com zero ficavam erradas. Consegui uma soluo alterando o EditMask para !99/99/99;1;0 e o evento onSetText por: if Sender.Clear else Sender.AsString := StringReplace(Text, ' ', '0', [rfReplaceAll]); Trim(Text) = '/ /' then

Dessa maneira no preciso codificar o evento onGetText.

Eduardo Rocha - 16/06/10 10:32 Pablo, Agora funcionou, o nico "inconveniente" que ao entrar no campo fica "00/00/00" caso no haja uma data Mas Obrigado Abs preenchida. funcionou.

Vladimir Sousa - 20/07/10 12:33 Eduardo testei a sua soluo e Funcionou perfeitamente, havia 3 semanas que procurava na internet e no procedure TForm1.ClientDataSet1DATASetText(Sender: encontrava. TField;

const begin if Sender.Clear else Sender.AsString end; Voc salvou meu dia, muito obrigado. Trim(Text) =

Text: '/ /'

String); then

:=

Text;

http://soprogramando.wordpress.com/2009/10/01/comoformatar-mascaras-com-delphi/ Como Formatar Mscaras com Delphi


outubro 1, 2009soprogramandoDeixe um comentrioIr para os comentrios

Usando mscaras.. para propriedade Mask do TMaskEdit ou equivalente.. A mscara basicamente consiste de trs campos, separados por ponto e vrgula. A primeira parte a mscara propriamente dita. A segunda parte determina se os caracteres fixos devem ser ou no salvos com a mscara (ex: /, -, (, ). A terceira parte da mscara representa o caracter em branco, podendo ser substitudo por outro (ex: _, @, ). Caracteres especiais utilizados com a mscara:
! Faz com que a digitao da mscara fique parada no primeiro caracter, fazendo com que os caracteres digitados que se movam. Ex: !;0;_ > Todos os caracteres alfabticos digitados aps este smbolo sero convertidos para maisculos.Ex: >aaa;0;_ <> Anula o uso dos caracteres > e <. Ex: >aaa<>aaa;0;_ \ Utilizado para marcar determinado caractere no especial como fixo, no podendo sobrescrevlo.Ex: !\(999\)000-0000;0;_ L Caracteres alfabticos (A-Z, a-z.) de preenchimento obrigatrio. Ex: LLL;1;_ l (Letra ele minscula) Caracteres alfabticos (A-Z, a-z.) de preenchimento opcional. Ex: lll;1;_ A Caracteres alfanumricos (A-Z, a-z, 0-9) de preenchimento obrigatrio. Ex: AAA;1;_ a Caracteres alfanumricos (A-Z, a-z, 0-9) de preenchimento opcional. Ex: aaa;1;_ C Exige preenchimento obrigatrio com qualquer caractere para a posio. Ex: CCC;1;_ c Permite qualquer caractere para a posio de preenchimento opcional. Ex: ccc;1;_ 0 Caracteres numricos (0-9) de preenchimento obrigatrio. Ex: 000;1;_ 9 Caracteres numricos (0-9) de preenchimento opcional. Ex: 999;1;_ # Caracteres numricos (0-9) e os sinais de ou + de preenchimento opcional. Ex: ###;1;_ : Utilizado como separador de horas, minutos e segundos. Ex: !00:00:00;1;_ / Utilizado como separador de dia, ms e ano. Ex: !99/99/9999;1;_ ; Separa os trs campos da mscara. _ Caractere usado normalmente nas posies do campo ainda no preenchidas.

Formatando Strings A funo Format requer como parmetros uma string com o texto bsico e alguns marcadores de lugar (usualmente indicadas pelo snbolo %) e um array de valores, um de cada marcador de lugar. Por exemplo, para formatar dois nmeros em uma string voc pode escrever. Format (Primeiro %d, Segundo %d , [n1, n2]); Onde n1 e n2 so dois valores Integer.
d (decimal) O valor inteiro correspondente convertido para uma string de dgitos decimais

x (hexadecimal) O valor inteiro correspondente convertido para uma string de dgitos hexadecimais p (ponteiro) O valor inteiro correspondente convertido para uma string expressa com dgitos decimais s (string) A string correnpondente, caractere, ou valor Pchar copiado para uma string

e (hexadecimal) O valor de ponto flutuante correspondente convertido para uma string. f (ponto flutuate) O valor de ponto flutuante correspondente convertido para uma string. g (geral) O valor de ponto flutuante correspondente convertido para uma string decimal menor possvel usando notao de ponto flutuante ou exponencial. x (nmero) O valor de ponto flutuante correspondente convertido para uma string de ponto flutuante mas usa tambm separador de milhares. m (moeda) O valor de ponto flutuante correspondente convertido para uma string representando uma quantidade em dinheiro. A converso baseada nas configuraes regionais. Formatando Data e Hora (DateTime)
FormatDateTime(dddd, Date); // Data por extenso FormatDateTime(dd-mm-yyyy, Date); // dia-mes-ano FormatDateTime(HH:mm, Time); Retirado de:

http://0x1f.blogspot.com/2008/06/mscaras-e-format-delphi.html