Ao usar Delphi para design de banco de dados, é inevitável envolver a entrada de campos de data. No entanto, em comparação com a versão chinesa do Access 97 da Microsoft, os métodos de exibição e entrada dos campos de data fornecidos pelo próprio Delphi não são adequados aos hábitos do povo chinês. Portanto, muitas soluções foram propostas para o processamento de campos de data, mas os resultados do processamento não são uniformes na exibição e na entrada. Por exemplo, o formato "aaaa ano mm mês dd dia" pode ser realizado durante a exibição, mas ainda precisa. a ser inserido ao inserir. Use "aaaa-mm-dd" de acordo com a alfândega estrangeira. Entrada no formulário; é sempre problemático usar TdateTimePicker para entrada de seleção. Alguns métodos também precisam modificar algumas propriedades de configuração do sistema, portanto, as propriedades do sistema precisam ser ajustadas ao publicar software usando controles de terceiros; é empacotado e liberado. Além disso, os formatos de data habitualmente utilizados, como "1999" e "Novembro de 1999", não são processados em conformidade. Aqui, com base em minha própria prática, uso a combinação dos eventos OnGetText e OnSetText do TField para obter a unificação da exibição e entrada de campos de data e posso lidar com nossas datas comuns, como "1999" e "novembro de 1999". e a entrada de formulários são implementadas usando os eventos fornecidos pelo Delphi e não há necessidade de modificar nenhuma configuração do sistema. Após a expansão correspondente, ele também pode ser usado para exibição e entrada de tempo, como "hh ponto mm minuto" etc. Ao mesmo tempo, como os eventos do TField são controlados diretamente, seja por meio de TDBGrid ou TDBEdit, eles podem ser processados de forma unificada sem a necessidade de considerá-los separadamente. Uma abordagem semelhante também pode ser aplicada à entrada de datas em aplicações que não sejam de banco de dados.
1 ideia básica
Use a propriedade EditMask de TField para servir como máscara de exibição e de entrada. A exibição do campo de data é processada no evento OnGetText de TField e o julgamento de validade do valor de entrada é processado no evento OnSetText. Para reutilizar o código, coloque os procedimentos e funções chamados pelos manipuladores de eventos OnGetText e OnSetText em uma unidade separada.
2 Código de implementação específico
{Unidade de exibição e julgamento}
unidade DBDateEditMaskTrans;
interface
usa
Windows, SysUtils, Controles, Formulários, Banco de Dados;
{Processo de exibição do campo de data, chamado no evento OnGetText}
PRocedure DateFieldGetText(Remetente: TField; var Texto: String);
{Função de julgamento de entrada do campo de data, chamada no evento OnSetText}
função DateFieldSetText(Remetente: TField; const Texto: String):Boolean;
implementação
procedimento DateFieldGetText(Remetente: TField; var Texto: String);
var
dData:TDate;
wAno,wMês,wDia:Palavra;
aryTestYMD:Array [1..2] of Char;{Matriz temporária para máscara de entrada de teste}
iYMD:Inteiro;
começar
dDate:=Sender.AsDateTime;
DecodeDate(dData,wAno,wMês,wDia);
{Teste o formato contido na máscara de entrada.}
aryTestYMD:='ano';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
DMIM:=1;
aryTestYMD:='mês';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
iYMD:=2;
aryTestYMD:='Dia';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
DMIM:=3;
caso iYMD de
1:{A máscara de entrada está no formato "aaaa ano".}
Text:=IntToStr(wAno)+'ano';
2: {A máscara de entrada está no formato "aaaa ano mm mês".}
Text:=IntToStr(wAno)+'ano'+IntToStr(wMês)+'mês';
3: {A máscara de entrada está no formato "aaaa ano mm mês dd dia".}
Text:=IntToStr(wAno)+'ano'+IntToStr(wMês)+'mês' +IntToStr(wDia)+'dia';
else {O padrão é: formato "aaaa ano mm mês dd dia".}
Text:=IntToStr(wAno)+'ano'+IntToStr(wMês)+'mês' +IntToStr(wDia)+'dia';
fim;
fim;
função DateFieldSetText(Remetente: TField; const Texto: String):Boolean;
var
dData:TDate;
sAno,sMês,sDia:String;
aryTestYMD:Array [1..2] de Char;
iYMD:Inteiro;
começar
{Obtenha a data inserida pelo usuário}
ano:=Copiar(Texto,1,4);
sMês:=Copiar(Texto,7,2);
SDay:=Copiar(Texto,11,2);
{Teste o formato contido na máscara de entrada.}
aryTestYMD:='ano';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
DMIM:=1;
aryTestYMD:='mês';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
DMIM:=2;
aryTestYMD:='Dia';
se StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil então
DMIM:=3;
{Use Try...Except para converter a data de entrada}
tentar
começar
caso iYMD de
1: {A máscara de entrada está no formato "aaaa ano".}
começar
dDate:=StrToDate(sYear+'-01-01') ;{O formato de data padrão do Windows chinês é: aaaa-mm-dd O mesmo abaixo}.
Sender.AsDateTime:=dData;
fim;
2: {A máscara de entrada está no formato "aaaa ano mm mês".}
começar
dData:=StrToDate(sAno+'-'+sMês+'-01');
Sender.AsDateTime:=dData;
fim;
3: {A máscara de entrada está no formato "aaaa ano mm mês dd dia".}
começar
dData:=StrToDate(sAno+'-'+sMês+'-'+sDia);
Sender.AsDateTime:=dData;
fim;
else {O padrão é: formato "aaaa ano mm mês dd dia".}
começar
dData:=StrToDate(sAno+'-'+sMês+'-'+sDia);
Sender.AsDateTime:=dData;
fim;
fim;
DateFieldSetText:=Verdadeiro;
fim;
exceto
{Erro de conversão de data}
começar
application.MessageBox(PChar(Text+'Data não válida!'), 'Erro',mb_Ok+mb_IconError);
DateFieldSetText:=Falso;
fim;
fim;
fim;
fim.
{unidade da janela principal}
unidade Principal;
interface
usa
…{omitir outro conteúdo}
procedimento Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean);
procedimento Table1BirthdaySetText (Remetente: TField; const Text: String);
privado
{Declarações privadas}
público
{Declarações públicas}
……{um pouco}
implementação
{Incluir unidades personalizadas}
usa DBDateEditMaskTrans;
{$R *.DFM}
...{Outros processos omitidos}
procedimento TForm1.FormActivate(Sender: TObject);
{Defina a máscara de entrada de um campo de data, que pode ser colocada na definição do campo TField. }
começar
Tabela1.FieldByName('Aniversário').EditMask:= '99-99-99;1;_';
fim;
procedimento TForm1.Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean);
começar
DateFieldGetText(Remetente,Texto);
fim;
procedimento TForm1.Table1BirthdaySetText(Sender: TField; const Text: String);
começar
se DateFieldSetText(Remetente,Texto)=Falso então
Abortar; {Falha na conversão, data é ilegal}
fim;
fim.