Upload
adriano-vieira-da-silva
View
636
Download
1
Embed Size (px)
Citation preview
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:
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.
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
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
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.
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
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