Delphi をデータベース設計に使用する場合、日付フィールドの入力は避けられません。ただし、Microsoft の Access 97 中国語版と比較すると、Delphi 自体が提供する日付フィールドの表示方法や入力方法が中国人の習慣に合っていません。そのため、日付フィールドの処理については多くの解決策が提案されていますが、表示時と入力時で処理結果が統一されていない、例えば表示時に「yyyy年mm月dd日」の形式は実現できますが、依然として必要となります。入力時は海外の習慣に従って「yyyy-mm-dd」を入力してください。フォームへの入力。選択入力に TdateTimePicker を使用するのは常に面倒です。一部のメソッドではシステムの一部の設定プロパティも変更する必要があるため、サードパーティ コントロールを使用する場合はシステム プロパティも調整する必要があります。パッケージ化されて発売されます。さらに、「1999」や「1999 年 11 月」などの一般的に使用される日付形式は、それに応じて処理されません。ここでは、私自身の実践に基づいて、日付フィールドの表示と入力を統一するために TField の OnGetText イベントと OnSetText イベントを組み合わせて使用し、「1999」や「1999 年 11 月」などの一般的な日付を処理できるようにします。フォームの入力と入力はすべて Delphi が提供するイベントを使用して実装され、システム設定を変更する必要はありません。対応拡張後は「hh点mm分」などの時間表示・入力にも使用できます。同時に、TField のイベントは TDBGrid を使用しても TDBEdit を使用しても直接制御されるため、個別に考えることなく統一的に処理できます。同様のアプローチは、データベース以外のアプリケーションの日付入力にも適用できます。
1 基本的な考え方
TField の EditMask プロパティを表示マスクと入力マスクとして使用します。日付フィールドの表示は TField の OnGetText イベントで処理され、入力値の有効性の判定は OnSetText イベントで処理されます。コードを再利用するには、OnGetText および OnSetText イベント ハンドラーによって呼び出されるプロシージャと関数を別のユニットに配置します。
2 具体的な実装コード
{表示・判定部}
ユニット DBDateEditMaskTrans;
インタフェース
用途
Windows、SysUtils、コントロール、フォーム、データベース。
{OnGetText イベントで呼び出される日付フィールド表示処理}
PROcedure DateFieldGetText(Sender: TField; var Text: String);
{OnSetTextイベントで呼び出される日付フィールド入力判定関数}
function DateFieldSetText(Sender: TField; const Text: String):Boolean;
実装
プロシージャ DateFieldGetText(Sender: TField; var Text: String);
変数
dDate:TDate;
w年、w月、w日:単語;
aryTestYMD:Array [1..2] of Char;{テスト入力マスクの一時配列}
iYMD:整数;
始める
dDate:=Sender.AsDateTime;
DecodeDate(dDate,wyear,wMonth,wDay);
{入力マスクに含まれる形式をテストします。}
aryTestYMD:='年';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=1;
aryTestYMD:='月';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=2;
aryTestYMD:='日';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=3;
iYMDの場合
1:{入力マスクは「yyyy year」の形式です。}
テキスト:=IntToStr(wyear)+'年';
2: {入力マスクは「yyyy年mm月」の形式です。}
Text:=IntToStr(wyear)+'year'+IntToStr(wMonth)+'month';
3: {入力マスクは「yyyy年mm月dd日」の形式です。}
テキスト:=IntToStr(wyear)+'year'+IntToStr(wMonth)+'month' +IntToStr(wDay)+'day';
else {デフォルトは「yyyy年mm月dd日」形式です。}
テキスト:=IntToStr(wyear)+'year'+IntToStr(wMonth)+'month' +IntToStr(wDay)+'day';
終わり;
終わり;
function DateFieldSetText(Sender: TField; const Text: String):Boolean;
変数
dDate:TDate;
s年、s月、s日:文字列;
aryTestYMD:Char の配列 [1..2];
iYMD:整数;
始める
{ユーザーが入力した日付を取得する}
s年:=コピー(テキスト,1,4);
sMonth:=Copy(Text,7,2);
SDay:=Copy(テキスト,11,2);
{入力マスクに含まれる形式をテストします。}
aryTestYMD:='年';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=1;
aryTestYMD:='月';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=2;
aryTestYMD:='日';
if StrScan(PChar(Sender.EditMask),
aryTestYMD[1])< >nil の場合
iYMD:=3;
{Try...を使用して入力日付を変換する}
試す
始める
iYMDの場合
1: {入力マスクは「yyyy year」の形式です。}
始める
dDate:=StrToDate(s Year+'-01-01') ;{中国語 Windows のデフォルトの日付形式は、yyyy-mm-dd です。以下同様}
Sender.AsDateTime:=dDate;
終わり;
2: {入力マスクは「yyyy年mm月」の形式です。}
始める
dDate:=StrToDate(s年+'-'+s月+'-01');
Sender.AsDateTime:=dDate;
終わり;
3: {入力マスクは「yyyy年mm月dd日」の形式です。}
始める
dDate:=StrToDate(s年+'-'+s月+'-'+s日);
Sender.AsDateTime:=dDate;
終わり;
else {デフォルトは「yyyy年mm月dd日」形式です。}
始める
dDate:=StrToDate(s年+'-'+s月+'-'+s日);
Sender.AsDateTime:=dDate;
終わり;
終わり;
DateFieldSetText:=True;
終わり;
を除外する
{日付変換エラー}
始める
application.MessageBox(PChar(Text+'有効な日付ではありません!'), 'エラー',mb_Ok+mb_IconError);
DateFieldSetText:=False;
終わり;
終わり;
終わり;
終わり。
{メインウィンドウユニット}
ユニットメイン;
インタフェース
用途
…{他の内容を省略}
プロシージャ Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean);
プロシージャ Table1BirthdaySetText(送信者: TField; const Text: String);
プライベート
{プライベート宣言}
公共
{公的宣言}
……{わずかに}
実装
{カスタム単位を含める}
DBDateEditMaskTrans を使用します。
{$R *.DFM}
...{その他の処理は省略}
プロシージャ TForm1.FormActivate(送信者: TObject);
{TField フィールド定義に配置できる日付フィールドの入力マスクを設定します。 }
始める
Table1.FieldByName('Birthday').EditMask:= '99-99-99;1;_';
終わり;
プロシージャ TForm1.Table1BirthdayGetText(Sender: TField; var Text: String;DisplayText: Boolean);
始める
DateFieldGetText(送信者,テキスト);
終わり;
プロシージャ TForm1.Table1BirthdaySetText(送信者: TField; const Text: String);
始める
DateFieldSetText(Sender,Text)=False の場合
中止; {変換に失敗しました。日付が不正です}
終わり;
終わり。