Example: TcxDataSummary.OnAfterSummary, TcxCustomDataController.Groups
- 4 minutes to read
In this example, a summary value is calculated based on the results of other two summaries. The TcxDataSummary.OnAfterSummary event, which occurs when all summaries are already calculated, is used to calculate a new summary.
Let us examine a table that represents information from the pricelist containing three columns: VendorNo, Description, and ListPrice. We want to group data by vendor and calculate three summaries: the summary that displays a sum of the ListPrice column values, the summary representing the number of goods supplied by a specific vendor and the summary that displays the average value of the ListPrice column values. Though it is possible to create an average summary by specifying its skAverage type, we will calculate it based on two other summary values and format it in a specific manner.
The Initialize procedure groups data by vendor and creates three summaries. The third summary is of the skNone type. It is substituted for the average summary in the MyAfterSummary procedure (a TcxDataSummary.OnAfterSummary event handler).
procedure TForm1.Initialize;
var
ASummaryItem: TcxDataSummaryItem;
begin
//group by vendor
DBTableView1VendorNo.GroupIndex := 0;
DBTableView1VendorNo.Visible := False;
with DBTableView1.DataController.Summary do
begin
BeginUpdate;
try
//set prefix and postfix for a group capion
DefaultGroupSummaryItems.BeginText := '{';
DefaultGroupSummaryItems.EndText := '}';
//summary on ListPrice
ASummaryItem := DefaultGroupSummaryItems.Add;
ASummaryItem.Kind := skSum;
ASummaryItem.ItemLink := DBTableView1ListPrice;
ASummaryItem.Position := spFooter;
//summary on Description
ASummaryItem := DefaultGroupSummaryItems.Add;
ASummaryItem.Kind := skCount;
ASummaryItem.ItemLink := DBTableView1Description;
ASummaryItem.Position := spFooter;
//dummy summary on Description
ASummaryItem := DefaultGroupSummaryItems.Add;
ASummaryItem.Kind := skNone;
ASummaryItem.ItemLink := DBTableView1Description;
//subscribe to the OnAfterSummary event
OnAfterSummary := MyAfterSummary;
finally
EndUpdate;
end;
end;
end;
The MyAfterSummary procedure is a TcxDataSummary.OnAfterSummary event handler. As data is only grouped by one column, we need to iterate the data groups only at level 0. The TcxCustomDataController.Groups property allows you to determine data group indexes which are required by the TcxDataSummary.GroupSummaryValues property. The CalculateGroupAverage procedure evaluates the average price for every data group. The output string for the average summary is constructed by the Format function.
procedure TForm1.MyAfterSummary(ASender: TcxDataSummary);
var
AChildDataGroupsCount: Integer;
AChildDataGroupIndex, AParentDataGroupIndex: TcxDataGroupIndex;
AChildPosition: Integer;
begin
//iterate through data groups at the level 0
AParentDataGroupIndex := -1;
with DBTableView1.DataController.Groups do
begin
AChildDataGroupsCount := ChildCount[AParentDataGroupIndex];
for AChildPosition := 0 to AChildDataGroupsCount - 1 do
begin
//data group index of a child
AChildDataGroupIndex := ChildDataGroupIndex[AParentDataGroupIndex, AChildPosition];
CalculateGroupAverage(AChildDataGroupIndex);
end;
end;
end;
procedure TForm1.CalculateGroupAverage(ADataGroupIndex: TcxDataGroupIndex);
var
AVarSum, AVarCount, AVarAverage: Variant;
begin
with DBTableView1.DataController.Summary do
begin
//get sum of prices for a specific data group
//the second argument identifies a summary index in the
//TcxDataSummary.DefaultGroupSummaryItems collection
AVarSum := GroupSummaryValues[ADataGroupIndex, 0];
//get records count in a group
AVarCount := GroupSummaryValues[ADataGroupIndex, 1];
if not (VarIsNull(AVarSum) or VarIsNull(AVarCount)) then
begin
AVarAverage := AVarSum / AVarCount;
GroupSummaryValues[ADataGroupIndex, 2] := Format('%m / %d = %m', [Double(AVarSum), Integer(AVarCount), Double(AVarAverage)]);
end;
end;
end;
The following image demonstrates a grid control after executing the Initialize procedure.