防止日期不匹配

时间:2013-04-03 06:20:43

标签: delphi devexpress delphi-xe2 delphi-xe

我正在使用cxGrid,其中我有两个日期字段(start_date和end_date),它们从查询中获取结果。我试图阻止用户在网格中输入数据时输入错误的日期范围。我试图阻止用户输入低于start_date的end_date。我试过了:

procedure TForm1.ABSQuery1BeforePost(DataSet: TDataSet);
begin
 if (ABSQuery1.FieldByName('end_DATE').AsDateTime < ABSQuery1.FieldByName('start_DATE').AsDateTime) then
 showmessage('end date  cant be lower than start date ');
 ABSQuery1.Cancel;
end;

我收到错误:数据集未处于插入或编辑模式。我该如何解决这个问题,还是有更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:3)

您的代码错误:您在if构造中调用Cancel,因此您也将其称为有效记录,但不要在验证例程中调用Cancel方法

在这种情况下,cxGrid负责DataSet编辑,所以如果你真的想阻止用户输入错误的日期:

如果您发现无法验证的内容,合同将引发异常,因此您可以将代码更改为以下内容:

procedure TForm1.ABSQuery1BeforePost(DataSet: TDataSet);
begin
 if (ABSQuery1.FieldByName('end_DATE').AsDateTime < ABSQuery1.FieldByName('start_DATE').AsDateTime) then
   raise Exception.Create('end date can''t be lower than start date');
end;

如果你定义自己的Exception类以避免引发(太)泛型Exception实例会更好,例如:

type
  EInputValidationError = class(Exception)
  end;

procedure TForm1.ABSQuery1BeforePost(DataSet: TDataSet);
begin
 if (ABSQuery1.FieldByName('end_DATE').AsDateTime < ABSQuery1.FieldByName('start_DATE').AsDateTime) then
   raise EInputValidationError.Create('end date can''t be lower than start date');
end;

这样,将来,您可以将输入验证错误与程序中引发的其他类型的异常区分开来。

答案 1 :(得分:1)

我会更好地使用字段end_datestart_date的OnValidate,因为这会在设置字段值时引发,这将在发布之前很久发生。如果必须输入许多字段,例如,这可能会很有趣。用户在发布时正在第三个选项卡上进行编辑,而日期的输入则在第一个选项卡上。

procedure TForm5.DateSpanValidateValidate(Sender: TField);
begin
  if not Sender.DataSet.FieldByName('end_DATE')
    .IsNull and not Sender.DataSet.FieldByName('start_DATE').IsNull then
    if (Sender.DataSet.FieldByName('end_DATE')
        .AsDateTime < Sender.DataSet.FieldByName('start_DATE').AsDateTime) then
      raise EYourValidationError.Create(
        'end date can''t be lower than start date');
end;