设计时实现的分组统计:

运行时实现的分组统计:
//前期只需要添加 ClientDataSet1、DataSource1、DBGrid1; 事件只需要关联窗体的 OnCreate
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, DB, DBClient;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DataSource1: TDataSource;
ClientDataSet1: TClientDataSet;
procedure FormCreate(Sender: TObject);
private
procedure OnGetText_Agg1(Sender: TField; var Text: string;
DisplayText: Boolean);
procedure OnGetText_Agg2(Sender: TField; var Text: string;
DisplayText: Boolean);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
{ 关联数据控件 }
DBGrid1.DataSource := DataSource1;
DataSource1.DataSet := ClientDataSet1;
{ 先打开前面例子中留下的测试文件 }
ClientDataSet1.LoadFromFile('C:\Temp\Test.xml');
{ 添加索引, 其中分组级别是 2 }
ClientDataSet1.AddIndex('Index1', '班级;年龄', [], '', '', 2);
{ 给数据集指定此索引 }
ClientDataSet1.IndexName := 'Index1';
{ 数据结构变化时一般需要先关闭数据集 }
ClientDataSet1.Close;
{ 添加统计字段 Agg1: 按班分组统计语文总成绩 }
with TAggregateField.Create(Self) do begin
FieldName := 'Agg1';
Expression := 'Sum(语文成绩)';
IndexName := 'Index1';
GroupingLevel := 1;
Active := True;
OnGetText := OnGetText_Agg1;
DataSet := ClientDataSet1;
end;
{ 添加统计字段 Agg2: 各班分别按年龄分组统计语文总成绩 }
with TAggregateField.Create(Self) do begin
FieldName := 'Agg2';
Expression := 'Sum(语文成绩)';
IndexName := 'Index1';
GroupingLevel := 2;
Active := True;
OnGetText := OnGetText_Agg2;
DataSet := ClientDataSet1;
end;
{ 需要在 DBGrid 中显示的字段 }
with DBGrid1.Columns do begin
Add.FieldName := '班级';
Add.FieldName := '姓名';
Add.FieldName := '年龄';
Add.FieldName := '语文成绩';
Add.FieldName := 'Agg1';
Add.FieldName := 'Agg2';
end;
{ 打开数据集并激活统计 }
ClientDataSet1.Open;
ClientDataSet1.AggregatesActive := True;
end;
procedure TForm1.OnGetText_Agg1(Sender: TField; var Text: string; DisplayText: Boolean);
begin
if gbLast in ClientDataSet1.GetGroupState(1) then
Text := Sender.AsString else Text := '';
end;
procedure TForm1.OnGetText_Agg2(Sender: TField; var Text: string; DisplayText: Boolean);
begin
if gbLast in ClientDataSet1.GetGroupState(2) then
Text := Sender.AsString else Text := '';
end;
end.