Solved

Exiting gracefuly from an if statement?!

Posted on 2001-07-16
13
171 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
  • 4
  • 3
  • 2
  • +4
13 Comments
 
LVL 13

Expert Comment

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

Expert Comment

by:comptebidon81
Comment Utility
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 50 total points
Comment Utility
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
 
LVL 6

Expert Comment

by:Jaymol
Comment Utility
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
Comment Utility
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
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 3

Expert Comment

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

Stefaan
0
 
LVL 1

Expert Comment

by:piscean
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks everyone,

Blash
0
 
LVL 1

Expert Comment

by:piscean
Comment Utility
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
Comment Utility
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
Comment Utility
;-)
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

772 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now