0

I am using cxGrid in which I have two date fields (start_date and end_date) which get its results from a query. I am trying to prevent user from entering wrong date span when entering data in the grid. I am trying to prevent user from entering end_date lower than the start_date. I tried :

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;

I get error : dataset is not in insert or edit mode. How can I fix this or is there a better way to do this ?

user763539
  • 3,509
  • 6
  • 44
  • 103

2 Answers2

3

Your code is wrong: you call the Cancel out of your if construction, so you call it for valid records also, but don't call the Cancel method inside your validation routines.

In this case, the cxGrid is in charge of the DataSet editing, so if you really want to prevent your users to enter wrong dates:

The contract is to raise an exception if you find something that doesn't validate, so you may change your code to something like this:

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;

It would be better if you define your own Exception class to avoid raising the (too) generic Exception instance, for example:

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;

That way, in the future, you can distinguish the input validation errors from other types of exceptions raised inside your program.

jachguate
  • 16,976
  • 3
  • 57
  • 98
1

I'd perfer the usage of OnValidate of the Fields end_date and start_date, since this will be raise on setting the fields values, which will happen long before post. This might be interesting if lots of fields have to entered and e.g. user is editing on the third tab when posting, while input of the dates is on first tab.

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;
bummi
  • 27,123
  • 14
  • 62
  • 101