Link to home
Start Free TrialLog in
Avatar of blash
blash

asked on

Exiting gracefuly from an if statement?!

I have this following if statement:

procedure TForm1.Table2BeforePost(DataSet: TDataSet);
begin
  if StrToInt(DBEdit7.Text)<50 then
  begin
   ShowMessage('Value must be more than 50');
   Table2.Cancel;
  end;
end;

So after the message gets displayed, and the Table2 gets canceled I get an annoying: 'Access violation at address...Read od address FFFFFFFF.'

How do I workaround this?

Thanks, Blash
Avatar of Epsylon
Epsylon

You can't cancel something that has not yet been committed.
Could it be that you are trying to cancel an event that has not yet occured? I think you should try to put your validation in the afterPost event.
ASKER CERTIFIED SOLUTION
Avatar of kretzschmar
kretzschmar
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
There's obviously a problem with the Cancel command, not the way it's been structured within the If statement.

If we could see some more code we may be able to help better.

John.
just to say,

you must cancel the post process and not the edited data.

best way to abort the post process is to raise an (silent) exception.

the dataset is keeping in the editmode (after this, no data are posted)

meikl ;-)
Hi,

Well, apparently what you should do in the BeforePost event is raise an excaption.  Your code should look like this :

 if StrToInt(DBEdit7.Text)<50 then
 begin
  Raise Exception.Create('Value must be more than 50');
 end;

By raising an exception the post will be aborted, thus you wont lose modifications and the dataset will still be in edit mode so the user can fix the problem.

Best regards,


Stefaan

Oops, didn't notice it but Meikl already suggested the same thing.

Stefaan
In the DBEdit's OnEnter event save the current value to a global variable then do your checking in the OnExit event.

var
  TempVal: String; {Global Variable}

OnDBEditEnter();
begin
  TempVal := DBEdit.Text;
end;

OnDBEditExit();
begin
  if StrToInt(DBEdit.Text) < 50 then
    begin
      DBEdit.Text := Temp
      ShowMessage('Value must be more than 50!');  
    end;

Hope this helps...
Hi Piscean,

Not a good idea to use the OnEnter and OnExit events for this kind of thing.  If you have 5 different forms all showing the same dataset with that field, you will have to code this in the OnEnter and OnExit events of the DBEdit on 5 different forms ! ! ! This means that the code won't be easy to maintain.

If you really want to use validation on one field, you should use a Persistent Field and code your thing in the OnValidate event of that field.  Something like this :

procedure TdtmED_Opleidingsdossier.OnValidateField(
  Sender: TField);
begin
  { The Validation occurs of the F_DURATION Field }
  if ( Sender.FieldName = 'F_DURATION' ) then
  begin
    { Check if the Duration is between 6 and 24 }
    if ( Sender.AsInteger < 6 ) or ( Sender.AsInteger > 24 ) then
    begin
      { Raise an Exception if it isn't }
      Raise Exception.Create( 'The duration shoul be between 6 and 24' );
    end;
  end;
end;

The advantages of this approach are the following :

- Field validation is maintained in one place : On the datamodule ( in my case ) in the OnValidate event of the persistent field, which makes the code much more readable and maintaintable.  If the validation changes in the future, I only have to modify the code in one place.
- It doesn't matter what DB control I use, I could use an DBEdit, a Grid, or whatever data aware control, the validation will always be done.
- I dont have to do anything on my forms, even if I have 10 forms which all use this dataset, they will all have the same validation rule for that field, thus the User interface layer and the Database Layer are well seperated.


Well, just thought I could show you this.  If you code your field validations in this way instead of using the OnEnter and OnExit events of the data aware controls, your code will be easier to read and to maintain, which will make Code Reviewers ( like me ) a bit happier ;-)

Best regards,


Stefaan
Avatar of blash

ASKER

Thanks everyone,

Blash
Stefaan,
Thanks for the tip man! (Though it took me a couple of minutes (maybe 3 ...) trying to find that event. Actually, I haven't used that trick before so I don't know where that event occurs. Most of the time, I use OnDataChange and OnEnter/OnExit and share the event handler so there's not much coding ...) Just noticed one thing ..., you don't have to check the field name (it's needed only if the event is shared within fields with common validation rules ...)
Anyway, thanks! I'll be using that one on my next project (Workstation Inventory).

piscean
Hi Piscean,

Indeed you don't have to check the FieldName if you use the event handler for only one field.  But most of the time I put all FieldValidations into one method and use it as the event handler for all the fields which need some validation.  This way IMHO makes it easier to read.

Well, I didn't provide the answer to this question ( well I wasn't the first one to propose it ), but I helped out someone else ;-)

Best regards,


Stefaan
;-)