组合多个统计结果

本节内容可以参考CaseStudy目录下的文件:组合统计结果.Table

假定有下图所示三个表:

 

希望根据上述三个表得出下图所示的统计结果:

上述三个表之间,是一种多对多的关系,因为一个型号会有多次进货,也会有多次销售或多次退货,而且要统计的是在三个表中同名的数量列和金额列。
所以SQLGroupTableBuilder和SQLCrossTableBuilder对于这种统计是无能为力的,我们只能另想办法。
即使你精通SQL,这样的统计也是很伤脑筋的,而且对于大多数普通用户来说,精通SQL语言只是一种奢望而已。

上面统计虽然看似复杂,但细想一下,不过就是分别统计出每个型号的进货、出货和退货数据,然后组合在一起而已。
如果有一个方法,能够将多个统计结果组合在一起,那么就可以将复杂问题简单化,只需分别统计进货、销售和退货数据,然后组合在一起即可。

我们知道所有的统计工具都有一个BuildDataSource方法,用此方法生成的统计结果可以动态绑定到现有的Table中,例如:

Dim b As New GroupTableBuilder("统计表1",DataTables("订单"))
b
.Groups.AddDef("日期","月份")
b
.Totals.AddDef("数量")
Tables
("窗口1_Table1").DataSource = b.BuildDataSource
()

BuildDataSource方法生成的是一个fxDataSource类型的对象,此类型有一个Combine方法,用于 组合多个fxDataSource对象,语法为:

Combine(LeftColName, RightDataSource, RightColName)

LeftColName:     字符型,指定用于联接的列,可以是单个列名,也可以是数组。
RightDataSource:参与组合的另一个fxDataSource对象。
RightColName:   字符型,指定另一个fxDataSource用于联接的列,可以是单个列名,也可以是数组。

联接列的作用类似于关联列,将两个统计表联系起来。

有了这个Combine方法,我们就可以轻松完成之前的统计任务,新建一个窗口,在窗口中插入一个Table控件和一个按钮,将按钮的Click事件代码设为:

Dim bd1 As New GroupTableBuilder("统计表1",DataTables("进货单"))
Dim
dt1 As fxDataSource
bd1
.Groups.AddDef("型号") '根据型号分组
bd1
.Totals.AddDef("数量","进货_数量") '对数量进行统计
bd1
.Totals.AddDef("金额","进货_金额") '对金额进行统计
dt1
= bd1.BuildDataSource()

Dim
bd2 As New GroupTableBuilder("统计表2",DataTables("销售单"))
Dim
dt2  As fxDataSource
bd2
.Groups.AddDef("型号") '根据型号分组
bd2
.Totals.AddDef("数量","销售_数量") '对数量进行统计
bd2
.Totals.AddDef("金额","销售_金额") '对金额进行统计
dt2
= bd2.BuildDataSource()

Dim bd3 As New GroupTableBuilder("统计表3",DataTables("退货单"))
Dim
dt3 As fxDataSource
bd3
.Groups.AddDef("型号") '根据型号分组
bd3
.Totals.AddDef("数量","退货_数量") '对数量进行统计
bd3
.Totals.AddDef("金额","退货_金额") '对金额进行统计
dt3 = bd3.BuildDataSource()

dt1.Combine("型号",dt2,"型号") '将销售统计数据组合到进货统计数据
dt1
.Combine("型号",dt3,"型号") '将退货统计数据组合到进货统计数据

Tables("窗口1_Table1").DataSource = dt1 '将统计结果绑定到Table
With
DataTables("窗口1_Table1").DataCols  '用表达式列计算库存数据
   
.Add("库存_数量",Gettype(Integer), "IsNull([进货_数量],0) - ISNULL([销售_数量],0) - ISNULL([退货_数量],0)")
   
.Add("库存_金额",Gettype(Double), "[库存_数量] /[进货_数量] * [进货_金额]"
End With

这样单击此按钮,Table控件即可显示我们要求的统计结果。

说明:

1、由于三个表都要统计数量和金额列,所以在添加统计列的时候,必须将数量和金额列改名,以便区分:

bd1.Totals.AddDef("数量","进货_数量") '对数量进行统计
bd1
.Totals.AddDef("金额","进货_金额") '对金额进行统计

2、库存数据是无需直接统计的,直接用表达式列根据进货、销售、库存计算得出。


本页地址:http://www.foxtable.com/webhelp/topics/2305.htm