?
Solved

Exiting gracefuly from an if statement?!

Posted on 2001-07-16
13
Medium Priority
?
193 Views
Last Modified: 2010-04-06
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
0
Comment
Question by:blash
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +4
13 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 6285624
You can't cancel something that has not yet been committed.
0
 

Expert Comment

by:comptebidon81
ID: 6285629
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.
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 200 total points
ID: 6285653
two possibilties

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

or

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

meikl ;-)
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:Jaymol
ID: 6285753
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.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6285847
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 ;-)
0
 
LVL 3

Expert Comment

by:Stefaan
ID: 6285862
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

0
 
LVL 3

Expert Comment

by:Stefaan
ID: 6285863
Oops, didn't notice it but Meikl already suggested the same thing.

Stefaan
0
 
LVL 1

Expert Comment

by:piscean
ID: 6288646
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...
0
 
LVL 3

Expert Comment

by:Stefaan
ID: 6288725
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
0
 

Author Comment

by:blash
ID: 6289133
Thanks everyone,

Blash
0
 
LVL 1

Expert Comment

by:piscean
ID: 6291723
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
0
 
LVL 3

Expert Comment

by:Stefaan
ID: 6292457
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
0
 
LVL 1

Expert Comment

by:piscean
ID: 6296269
;-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses
Course of the Month12 days, left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question