7
http://www.edudelphipage.com.br/artigos/mascaras-de-datas- no-delphi Máscaras de Data no Delphi por Eduardo Rocha - Publicado em 14/06/10 Não sei se é uma "falha" do Delphi ou minha :), pois nunca conseguir resolver uma situação simples: "Permitir que o usuário limpe o conteúdo de um DBEdit se o campo estiver com máscara de Data na propriedade EditMask". Faça 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 máscara de data sugerida pelo próprio Delphi no Editor de Mascara: "!99/99/00;1;_". Em seguida ajuste também o DisplayFormat para "dd/mm/yy". Agora volte ao formulário e adicione um DataSource ligando-o no ClientDataSet. Adicione também um DBEdit ligando-o no DataSource e no campo Data recém 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 formulário apenas crie o ClientDataSet em memória: procedure TForm1.FormCreate(Sender: TObject); begin ClientDataSet1.CreateDataSet; end; Execute a aplicação 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:

Mascaras Em DBEdits

Embed Size (px)

Citation preview

Page 1: Mascaras Em DBEdits

http://www.edudelphipage.com.br/artigos/mascaras-de-datas-no-delphi

Máscaras de Data no Delphipor Eduardo Rocha - Publicado em 14/06/10

Não sei se é uma "falha" do Delphi ou minha :), pois nunca conseguir resolver uma situação

simples:

"Permitir que o usuário limpe o conteúdo de um DBEdit se o campo estiver com máscara de

Data na propriedade EditMask".

Faça 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 máscara de data sugerida pelo

próprio Delphi no Editor de Mascara: "!99/99/00;1;_". Em seguida ajuste também o

DisplayFormat para "dd/mm/yy".

Agora volte ao formulário e adicione um DataSource ligando-o no ClientDataSet. Adicione

também um DBEdit ligando-o no DataSource e no campo Data recém 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 formulário apenas crie o ClientDataSet em memória:

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

Execute a aplicação 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:

Page 2: Mascaras Em DBEdits

Por que isso?

No help do Delphi diz que o caractere "0" nos obriga a termos um valor numérico naquela

posição, enquanto que o caractere "9" não obriga.

Analisando a máscara 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 dígitos (ano) da data, por isso a mensagem anterior é exibida quando tentamos

limpar o campo.

Só não consegui entender por que a máscara padrão usou "0" somente no ano :)

Bom, então é simples, basta trocar o "00" por "99" correto?

Vamos lá, faça este ajuste na máscara 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 não é uma data válida, por isso a

mensagem de "data inválida" é exibida. Inclusive desta vez é o TField quem está alertando e

não mais o TDBEdit devido à máscara.

Bom, a solução que encontrei foi ajustar o evento OnSetText do campo para checar, se

estiver recebendo este valor, simplesmente limpa o campo, caso contrário define o valor que

está recebendo.

Page 3: Mascaras Em DBEdits

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.

Faça 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 mês, onde deveria aparecer o zero ficou aparecendo o "_", por que será?

Boa pergunta, também não entendi. Mas a solução que adotei foi implementar um código 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 alguém tiver uma solução mais simples,

please, me diga, pois como disse no início, não sei se é uma "falha" do nosso amigo Delphi

ou minha!

Abraços

Page 4: Mascaras Em DBEdits

7 Comentários

Pablo Carvalho - 16/06/10 09:01

Eduardo, acredito que o problema dos Zeros possa se resolver trocando o "_" por "0" na

máscara ("!99/99/99;1;0"), assim você indica que o caracter assumido na falta de digitação é

o zero, e com isso grava a data corretamente.

Parabéns pelo artigo.

Eduardo Rocha - 16/06/10 09:15

Pablo,

Agradeço pela ajuda, mas testei o que você disse e gerou um outro problema.

Entre com a data "20/11/82", por exemplo, ele troca o "20" por "02".

Quem tiver outra dica, pode mandar!

Obrigado

Abs

Jean - 16/06/10 09:30

Sua solução 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 usuário final utilizar.

Eduardo Rocha - 16/06/10 09:35

Jean,

Muito obrigado pela sua dica, certamente usar um componente que já faça todo "trabalho" é

muito mais prático.

Abs

Pablo Carvalho - 16/06/10 10:19

Tem razão, na minha sugestão anterior as datas que terminavam com zero ficavam erradas.

Consegui uma solução alterando o EditMask para !99/99/99;1;0 e o evento onSetText por:

if Trim(Text) = '/ /' then

Sender.Clear

else

Sender.AsString := StringReplace(Text, ' ', '0', [rfReplaceAll]);

Dessa maneira não é 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 não

Page 5: Mascaras Em DBEdits

haja uma data preenchida.

Mas funcionou.

Obrigado

Abs

Vladimir Sousa - 20/07/10 12:33

Eduardo testei a sua solução e Funcionou perfeitamente, havia 3 semanas que procurava na

internet e não encontrava.

procedure TForm1.ClientDataSet1DATASetText(Sender: TField;

const Text: String);

begin

if Trim(Text) = '/ /' then

Sender.Clear

else

Sender.AsString := Text;

end;

Você salvou meu dia, muito obrigado.

Page 6: Mascaras Em DBEdits

http://soprogramando.wordpress.com/2009/10/01/como-formatar-mascaras-com-delphi/

Como Formatar Máscaras com Delphioutubro 1, 2009soprogramando Deixe um comentário Ir para os comentários

Usando máscaras.. para propriedade Mask do TMaskEdit ou equivalente..

A máscara basicamente consiste de três campos, separados por ponto e vírgula. A primeira parte é a máscara propriamente dita.A segunda parte determina se os caracteres fixos devem ser ou não salvos com a máscara (ex: /, -, (, …).A terceira parte da máscara representa o caracter em branco, podendo ser substituído por outro (ex: _, @, …).Caracteres especiais utilizados com a máscara:

! Faz com que a digitação da máscara fique parada no primeiro caracter, fazendo com que os

caracteres digitados que se movam. Ex: !;0;_

> Todos os caracteres alfabéticos digitados após este símbolo serão convertidos para

maiúsculos.Ex: >aaa;0;_

<> Anula o uso dos caracteres > e <. Ex: >aaa<>aaa;0;_

\ Utilizado para marcar determinado caractere não especial como fixo, não podendo sobrescrevê-

lo.Ex: !\(999\)000-0000;0;_

L Caracteres alfabéticos (A-Z, a-z.) de preenchimento obrigatório. Ex: LLL;1;_

l (Letra ele minúscula) Caracteres alfabéticos (A-Z, a-z.) de preenchimento opcional. Ex:

lll;1;_

A Caracteres alfanuméricos (A-Z, a-z, 0-9) de preenchimento obrigatório. Ex: AAA;1;_

a Caracteres alfanuméricos (A-Z, a-z, 0-9) de preenchimento opcional. Ex: aaa;1;_

C Exige preenchimento obrigatório com qualquer caractere para a posição. Ex: CCC;1;_

c Permite qualquer caractere para a posição de preenchimento opcional. Ex: ccc;1;_

0 Caracteres numéricos (0-9) de preenchimento obrigatório. Ex: 000;1;_

9 Caracteres numéricos (0-9) de preenchimento opcional. Ex: 999;1;_

# Caracteres numéricos (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, mês e ano. Ex: !99/99/9999;1;_

; Separa os três campos da máscara.

_ Caractere usado normalmente nas posições do campo ainda não preenchidas.

Formatando StringsA função Format requer como parâmetros uma string com o texto básico e alguns marcadores de lugar (usualmente indicadas pelo sínbolo %) e um array de valores, um de cada marcador de lugar. Por exemplo, para formatar dois números em uma string você pode escrever.

Format (‘Primeiro %d, Segundo %d ‘, [n1, n2]);

Onde n1 e n2 são dois valores Integer.

d (decimal)

O valor inteiro correspondente é convertido para uma string de dígitos decimais

x (hexadecimal)O valor inteiro correspondente é convertido para uma string de dígitos hexadecimaisp (ponteiro)O valor inteiro correspondente é convertido para uma string expressa com dígitos decimaiss (string)A string correnpondente, caractere, ou valor Pchar é copiado para uma string

Page 7: Mascaras Em DBEdits

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 possível usando notação de ponto flutuante ou exponencial.x (número)O valor de ponto flutuante correspondente é convertido para uma string de ponto flutuante mas usa também separador de milhares.m (moeda)O valor de ponto flutuante correspondente é convertido para uma string representando uma quantidade em dinheiro. A conversão é baseada nas configurações 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