Question

I am making a app in Delphi 6 + MySQL database using standard data-aware components and dbExpress. The app allows a users to view records in a grid and edit data (insert and/or delete records) client side. These data edits are then only written to database on clicking the submit button. All of this works fine and has the following setup:

Controls: 1. DBGrid1 linked to a DataSource1 to display data visually. 2. DataSource1 is linked to ClientDataSet1 to offer data for DBGrid to display. 3. ClientDataSet1 is linked to DataSetProvider1 to provide client-side data for editing. 4. DataSetProvider1 is linked SQLDataSet1 which selects records from a single DB table. 5. SQLDataSet1 is linked to SQLConnection to provide connection to MySQL database.

Actions: 1. User inserts a record: I use ClientDataSet1.InsertRecord; 2. User deletes a record: I use ClientDataSet.Delete; 3. User submits data: I use ClientDataSet1.ApplyUpdates(-1);

This all works great in terms of handling data & posting data (with the inclusions of a small hack on DataSetProvider1BeforeUpdateRecord to delete records).

NOW FOR MY PROBLEM: When the user first loads the form, the DBGrid1 displays all original records, removes all deleted records. But when the user inserts a new record in ClientDataSet1, a blank record is displayed in DBGrid1. The actual data is not lost or set as NULLS as when you ClientDataSet1.ApplyUpdates, this record is correctly written to the DB.

I know TClientDataSet has a data property for original data and a Delta property for edited data. Can these two properties with data by displayed in a single DBGrid at one time & still allowing the user to edit the data?

I have looked at 30+ resources and demo apps & all avoid this issue. Can this be done?

Was it helpful?

Solution

Ok...this question has been viewed a fair amount without much feedback. I did some research by downloading many tutorials, demo apps & read multiple articles/help info discussing the use of these controls.

The net result:

  1. These controls are a bit buggy in general.
  2. In specific reference to my question, it is safe to say the controls cannot do what I describe as a standard.

This is based on the 30+ demo apps, articles and tutorials I reviewed that either don't describe displaying both the original data with Delta data in a single data grid. Sure you could hack this outcome (which is what I did) using a Listbox or StringGrid, but that also indicates the control cannot or not usable at providing this functionality (on the slim chance it might).

This functionality is an obvious oversight in my opinion as a user wants to see the potential outcome of their actions, conveniently in a single data grid AND a developer wants to provide that in a simple & pain free way i.e. using a datagrid to display data!

Question Answered [if you can prove differently with a demo app that I want to review, I will remove this].

If you created a demo app and couldn't get it to work, up vote my answer. Thanks

OTHER TIPS

The TDBGrid control provided with Delphi does not have the built-in functionality to display both the old and new values for fields. You are welcome, of course, to inherit from the Grid or create your own and add the functionality, or buy a third party component that accomplishes what you want. You are not limited to the standard controls, though they do provide the most commonly required functions.

You can also accomplish what you want by using calculated fields. For example, if you have a String field Name, add a new calculated String field to the dataset called OldName, with the same length as Name.

Then in your OnCalcFields event for the dataset, simply enter code like the following:

if DataSet.State = dsEdit then
begin
  DataSet.FieldByName('OldName').Value := DataSet.FieldByName('Name').OldValue;
end
else
begin
  DataSet.FieldByName('OldName').Value := Null;
end;

TClientDataset will handle itself the correct record status. Changes are logged, but unless you ask it explicity to show some other status (see StatusFilter property), it will show the actual state of a record.

It is possible InsertRecord bypasses some notification mechanism, so the field display is not updated. What if you perform simpy an Insert and the set field values?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top