我正在使用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;
我收到错误:数据集未处于插入或编辑模式。我该如何解决这个问题,还是有更好的方法来做到这一点?
答案 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_date
和start_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;