0

我正在使用 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;

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

4

2 回答 2

3

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

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

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

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;

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

于 2013-04-03T06:28:52.133 回答
1

我更喜欢使用字段的 OnValidateend_datestart_date,因为这将在设置字段值时引发,这将在发布之前很久发生。如果必须输入大量字段并且例如用户在发布时在第三个选项卡上进行编辑,而日期的输入在第一个选项卡上,这可能会很有趣。

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;
于 2013-04-03T06:42:13.383 回答