首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 資料庫日期欄位顯示與輸入統一處理:OnGetText/OnSetText 事件實作中文化格式 (yyyy年mm月dd日)

     編輯:Delphi

問題背景

Delphi 原生日期顯示/輸入格式 (如 yyyy-mm-dd) 不符中文習慣。期望目標:

  • 顯示:1999年11月25日、1999年11月、1999年
  • 輸入:同格式直接輸入,自動驗證
  • 統一處理 TDBGrid、TDBEdit 等所有資料感知控件
  • 不修改系統地區設定、不需第三方元件

核心設計:TField 事件 + EditMask

  • OnGetText:資料 → 顯示字串 (格式化輸出)
  • OnSetText:輸入字串 → 資料 (解析驗證)
  • EditMask:同時作為顯示/輸入遮罩,編碼格式資訊 (如含「年」、「月」、「日」)

通用處理單元


unit DBDateEditMaskTrans;
interface
uses Windows, SysUtils, Controls, Forms, Db;

procedure DateFieldGetText(Sender: TField; var Text: String);
function DateFieldSetText(Sender: TField; const Text: String): Boolean;
implementation

procedure DateFieldGetText(Sender: TField; var Text: String);
var
  D: TDateTime;
  Y, M, Dd: Word;
  MaskHasYear, MaskHasMonth, MaskHasDay: Boolean;
begin
  D := Sender.AsDateTime;
  DecodeDate(D, Y, M, Dd);

  // 分析 EditMask 判斷格式
  MaskHasYear  := Pos('年', Sender.EditMask) > 0;
  MaskHasMonth := Pos('月', Sender.EditMask) > 0;
  MaskHasDay   := Pos('日', Sender.EditMask) > 0;

  if MaskHasYear and MaskHasMonth and MaskHasDay then
    Text := Format('%d年%d月%d日', [Y, M, Dd])
  else if MaskHasYear and MaskHasMonth then
    Text := Format('%d年%d月', [Y, M])
  else if MaskHasYear then
    Text := Format('%d年', [Y])
  else
    Text := Format('%d年%d月%d日', [Y, M, Dd]); // 預設完整格式
end;

function DateFieldSetText(Sender: TField; const Text: String): Boolean;
var
  Y, M, D: String;
  DT: TDateTime;
  MaskHasYear, MaskHasMonth, MaskHasDay: Boolean;
begin
  Result := False;
  MaskHasYear  := Pos('年', Sender.EditMask) > 0;
  MaskHasMonth := Pos('月', Sender.EditMask) > 0;
  MaskHasDay   := Pos('日', Sender.EditMask) > 0;

  // 簡易解析:假設輸入格式固定對應 EditMask
  try
    Y := Copy(Text, 1, 4);
    if MaskHasMonth then M := Copy(Text, Pos('年', Text)+1, 2) else M := '01';
    if MaskHasDay then D := Copy(Text, Pos('月', Text)+1, 2) else D := '01';

    // 組合為系統可識別格式 (yyyy-mm-dd)
    DT := StrToDate(Y + '-' + M + '-' + D);
    Sender.AsDateTime := DT;
    Result := True;
  except
    Application.MessageBox(PChar(Text + ' 不是有效的日期!'), '錯誤', MB_OK + MB_ICONERROR);
    Result := False;
  end;
end;
end.

主表單套用


uses DBDateEditMaskTrans;

procedure TForm1.FormActivate(Sender: TObject);
begin
  // 設定 EditMask:9=數字、\=逸出字元、;1;_ = 存儲字面字元、底線佔位
  Table1.FieldByName('Birthday').EditMask := '9999\年99\月99\日;1;_';
end;

procedure TForm1.Table1BirthdayGetText(Sender: TField; var Text: String; DisplayText: Boolean);
begin
  DateFieldGetText(Sender, Text);
end;

procedure TForm1.Table1BirthdaySetText(Sender: TField; const Text: String);
begin
  if not DateFieldSetText(Sender, Text) then
    Abort; // 取消輸入
end;

EditMask 格式說明


'9999\年99\月99\日;1;_'
||||  ||  ||  ||  | |
||||  ||  ||  ||  | +-- 佔位符
||||  ||  ||  ||  +---- 存儲字面字元 (1=是)
||||  ||  ||  |+------- 分隔符
||||  ||  ||  +-------- 逸出 '日'
||||  ||  |+----------- 兩位數月份
||||  ||  +------------ 逸出 '月'
||||  |+--------------- 兩位數日期
||||  +---------------- 逸出 '年'
++++------------------- 四位數年份

擴展應用

  • 時間格式:同理處理 hh點mm分、hh點mm分ss秒
  • 非資料庫場景:直接掛在 TEdit 的 OnExit/OnKeyPress 事件
  • 多語系:EditMask 內嵌語系關鍵字,通用處理單元自動適配

總結

利用 TField.OnGetText/OnSetText 搭配 EditMask 編碼格式資訊,集中在通用單元實作解析/格式化邏輯,可達到「顯示輸入統一、中文化格式、零系統相依、全控件通用」的最佳效果。此模式同樣適用於時間、貨幣、自訂格式等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved