EVariantInvalidArgErr exception trying to setFocus to a cell in a dbgrid

bmayfield

Member²
We have a requirement to edit columns in the native Delphi 7 dbGrid component. In this case we are trying to validate days worked. The user's specfic requirement is if days worked is greater than 7, force the user back to that cell to re-enter the correct value. We would like to validate date fields as well that are in cells in the dbGrid. Here is the code that gets a EVariantInvalidArgErr exception on the line of code that is bold. If we do not set the value in the dataset, the validate event keeps firing in a loop because the value is still greater than 7 and does not give the user a chance to set the value less than 8. How can we get the dbGrid cell to behave the way we need it to?

procedure TFRIA0030dm.odsBatchSroiIndemnitiesPAY_ADJ_DAYS_PAIDValidate(
Sender: TField);
begin
if Sender.AsString > '7' then
begin
ShowMessage('Must be between 0 and 7!');
FRIA0030frm.dbgIndemnities.SetFocus;
FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID').Value := '';
FRIA0030frm.dbgIndemnities.SelectedField := odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID');
Exit;
end;
end;

Thanks.
Bruce
 
I don't think it's a good idea to navigate in validation triggers. You should preferably just raise an exception with an appropriate message:

Code:
procedure TFRIA0030dm.odsBatchSroiIndemnitiesPAY_ADJ_DAYS_PAIDValidate(Sender: TField);
begin
  if Sender.AsString > '7' then
    raise Exception.Create('Must be between 0 and 7!');
end;
 
We appreciate your response. Is there no way to validate data in a dbGrid cell, clear the data in error that was entered into that cell leaving the cursor in that cell so the user can enter the correct data? Attempts to clear the value of the data in error in the ODS remains in the cell in the dbgrid and the focus moves to the next cell.

Regards,
Bruce
 
That's what my example code does, except that it does not clear the data (which does not seem like a desirable feature anyway).
 
OK, in order to meet the user's requirements we had to do a work around. It isn't pretty but it does not use exceptions and we can move focus back to the column in error. I hope someday Delphi or some third party enhances the standard out of the box component. Here is the code:

procedure TFRIA0030dm.odsBatchSroiIndemnitiesBeforePost(DataSet: TDataSet);
begin
// Payment adjustment segment edits

if FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID').IsNull then
Begin
ShowMessage('Days Paid must be entered');
FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID').Clear;
FRIA0030frm.dbgIndemnities.SelectedField := FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID');
FRIA0030frm.stbStatusLine.Panels[1].Text := 'Please enter a valid number of days';
Abort;
Exit;
end;

if FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID').Value > 6 then
Begin
ShowMessage('Must be between 0 and 6!');
FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID').Clear;
FRIA0030frm.dbgIndemnities.SelectedField := FRIA0030dm.odsBatchSroiIndemnities.FieldByName('PAY_ADJ_DAYS_PAID');
FRIA0030frm.stbStatusLine.Panels[1].Text := 'Please enter a valid number of days';
Abort;
Exit;
end;

end;

Thanks.
Bruce
 
Back
Top