I'm maintaining a Delphi application since a few days. The customer wants to add a percentage column to a DBGrid, now showing a "Quantity" column. Of course the percentage would be the Row quantity / Total Quantity * 100
I cannot modify the underlying TADOTable since it is used elsewhere in the code, but I tried to add a calculated field to the TADOTable - but is seems the calculated field cannot have a value based on an aggregate value (i.e. sum of quantity).
I succeeded in adding an empty column to the DBGrid, but is there any way to populate the % values in each row ?
What you want is straightforward to do, but you need to be careful how you do it.
Leaving the gui aspect aside for a moment, what you want to do is to add a calculated column to your TAdoDataSet and initialise it in its
OnCalcFields
event. However, what you DON'T want to do is to calculate theTotalQuantity
in that event. because a) theOnCalcFields
event will be called for each row in the dataset AND b) doing anything inside theOnCalcFields
event which moves the dataset's cursor - like traversing the dataset as suggested in another answer - will recursively call theOnCalcFields
event.The way to avoid this recursion problem, and to avoid doing any more work than is necessary, is to only calculate the TotalQuantity when the table is first opened and anytime its value could change, that is, when a row is edited, inserted or deleted, and then save the result in a field of your form or datamodule. There are two main ways you could do this calculation: 1) using a TAdoQuery to execute Sql like "SELECT SUM(Quantity) FROM MyTable" or 2) using a second instance of TAdoDataSet opened on your table. Preferably this second instance should not have any gui controls connected to it, so it can be traversed as quickly as possible without having to use
DisableControls
andEnableControls
.To add the Percentage field to your AdoDataSet, double click it to pop up the Fields Editor, right-click in it and select
New field
. Make sure you set itsType
toCalculated
.Once you have your
GetTotalQuantity
procedure set up, you need to set event handlers to call it from your AdoDataSet's BeforeOpen, BeforeInsert, BeforeEdit and AfterDelete events.Then in your
OnCalcFields
event, calculate and assign the value of your Percentage calculated to it.The code required to do all this is pretty trivial, something like
Or
OnCalcFields event:
Once you've added your Percentage calculated field to your AdoDataSet and set up the OnCalcFields event for the dataset, your DBGrid will be happy to display it, just like any other field of the dataset.