Solved

How to edit dbf records in Delphi 1.02 with uniqueness demand?

Posted on 1997-07-03
11
389 Views
Last Modified: 2010-04-06
How to edit dbf records? I try to work out a proper way of doing it. Let's say I have dbf file with an index and I want inserted records to be unique. On the other hand I do not want to use additional components (TEdit or TMaskEdit) to keep the data before inserting new record.
So, I have DBGrid on my form connected to Table1. It is used to browse the data. And I have a couple of DBEdits connected with current record in DBGrid. They are disabled. I push edit button on my form and I enable DBEdits and disable DBGrid. The user change data in DBEdits. They are accepted and then I have to check out if the key is unique. In dbf standard I have to seek for the new value, but moving the pointer in the table calls post method and the changes are written to the file. Somebody told me I can use two TTable components to connect to the same dbf file. Table1 is connected to DBGrid, Table2 to DBEdits. The user can edit data in DBEdits, and the program can check the data using Table1. It does not call the post for Table2. It works great, but after inserting record into Table2 I cannot get Table1 and Table2 synchronized. DBGrid does not show newly inserted records, although I make Table1.Refresh.
So my question is - how to edit dbf files which require uniqueness without additional components?
Thanks
0
Comment
Question by:shrldu
11 Comments
 
LVL 2

Expert Comment

by:icampbe1
ID: 1338109
Use the BeforePost event.  In the handler, use FindKey to see if the key exists.  If it does, don't even add the record (raise an EAbort exception to cancel the post).  In this way you don't have to worry about grids and edit boxes etc...

Ian C.

0
 

Author Comment

by:shrldu
ID: 1338110
I've just tried the solution. I used BeforePost event to check the key. Before FindKey I called SetKey. And this called BeforePost. And this called SetKey. And this called BeforePost... Until Runtime error happend, you know... The problem is that trying to check the key invokes Post method, I suppose...
0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1338111
I'm not sure why you called SetKey, but that doesn't matter.  If you have a recursion problem, then disconnect your handler while you are working.

PROCEDURE Txxxx.BeforePostHandler;
BEGIN
   Table.BeforePost := NIL;
   {do your key stuff here}
   Table.BeforePost := BeforePostHandler;
END;

This will let you work without calling yourself.

Let me know.
Ian C.

0
 

Author Comment

by:shrldu
ID: 1338112
Yes, it solves the recursion problem. But FindKey now calls a Post (I put a ShowMessage in AfterPost event handler), this time without entering Table1BeforePost. In THIS moment the new value is written to the file. Then, after restoring the BeforePost handler and aborting, the program returns and I have two records with the same key values... just what I wanted to prevent.


procedure TForm1.Table1BeforePost(DataSet: TDataset);
begin
  Table1.BeforePost := NIL;
  if Table1.FindKey(['3']) then
  begin
    Table1.BeforePost := Table1BeforePost;
    Abort;
  end;
  Table1.BeforePost := Table1BeforePost;
end;

0
 
LVL 1

Expert Comment

by:buemoh
ID: 1338113
Sorry, your only chance is to put a simple TEDIT control on the form, use the OnChange method of your TTable component to update the TEDIT control - only for informating the user.

Let the User put in something in the TEDIT control, make your requests with FindKey and the decide, is the Key present, tell the User to select an other, if not, make a new database record.

If this is not clear, I can send some source.

Bye

Hartwig

0
What Is Threat Intelligence?

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

 

Author Comment

by:shrldu
ID: 1338114
Thank you, Mr Hartwig, that was my first attempt, later I tried to connect two TTables to one dbf file. Any advice on why I cannot synchronize those two tables after the record is inserted in one of them?

Bye

0
 
LVL 2

Accepted Solution

by:
icampbe1 earned 50 total points
ID: 1338115
If you are willing to use another TTable then there are several solutions.

procedure TForm1.Table1BeforePost(DataSet: TDataset);
Var tt2: TTable;
begin
  tt2 := TTable.Create(self);
  TRY
     tt2.tablename := Dataset.TableName; {and other setup}
     if Tt2.FindKey(['3']) then
     begin
        Abort;
     end;
   FINALLY
     Tt2.Free;
     END;
end;

If you want to keep the table around, thats up to you.  You don't have to re-create it for every use in this manner.   Also if you want to synchronize them then use Table2.GoToCurrent(Table1) for example.

With two ttable objects there are several solutions.  Let me know if you want more help, however this should do the trick.

Cheers,
Ian C.
0
 

Author Comment

by:shrldu
ID: 1338116
That's great, Ian, it works at least, just what I needed. I am going to accept this answer, but you wrote there are SEVERAL solutions with two tables. Could you write a couple of words on this, please?
0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1338117
When you grade me, also give me your E-mail.  I'll send you some other thoughts in this area.  I have done extensive work with this.
Ian C.  :)
0
 

Author Comment

by:shrldu
ID: 1338118
lobster@silesia.top.pl
0
 
LVL 4

Expert Comment

by:bamboo7431
ID: 1338119
That's what you should do:

As far as I understand, you have one TTable, one TDataSource and one TDBGrid. You need to have one more TTable which will have exactly the same DatabaseName, TableName and TableType as Table1 does. On Table1.BeforePost you call Table2.FindKey() and check: if the key value is already there, you cancel your post. You do not want to keep the tables synchronized since second TTable is used only for lookup purposes and its current record is not shown anywhere. Table1.Refresh should show the inserted record in DBGrid attached to Table1. Beware - Windows can cache the output so the record could be not physically written yet. In the database engine I use (Apollo) there is a setting to dump all updates to the disk automatically but I am not sure about BDE.
Closing and reopening Table1 always helps but that could be very slow.
Also be sure both TTables have Exclusive set to False. (Someone reported he could have two TTables on one form with Exclusive=True pointing to the same physical table, but I never could reproduce that)
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

759 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

18 Experts available now in Live!

Get 1:1 Help Now