手工编码进行统计
普通用户可忽略本节的内容。
GroupTableBuilder可以让我们轻松地生成各种分组统计表。
CrossTableBuilder可以让我们轻松地生成各种交叉统计表。
但是,他们也不是万能的:
1、一些特殊的统计要求,它们是无法胜任的,例如本课的成绩分布统计。
2、如果希望事先设计好统计表的结构,需要的时候通过单击某个按钮刷新统计表的结果,显然这样的统计要求通过生成器是无法实现的。
在学习本课的内容之前,请打开示例文件"统计演示.Table"。
示例一
假定有下面这样的一个成绩表:
我们需要统计每一个科目的成绩分布范围,例如60分以下,60分以上,70分以上等等范围的人数。
首先新建一个数据表,因为考试的科目是固定的,所以这里我们不用临时表,而用数据表,设计好表之后,手工输入科目:
然后将这个表的DataColChanged设为:
Dim
dr
As
DataRow = e.DataRow
Dim dt As
DataTable =DataTables("学生成绩")
If e.DataCol.Name
= "科目"
And dr.IsNull("科目")
= False
Then
dr("分布_60分以下")
= dt.Compute("Count(姓名)",
dr("科目") &
" < 60")
dr("分布_60分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 60 And "
& dr("科目") &
" < 70" )
dr("分布_70分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 70 And "
& dr("科目") &
" < 80" )
dr("分布_80分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 80 And "
& dr("科目") &
" < 90" )
dr("分布_90分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 90 And "
& dr("科目") &
" < 100" )
dr("分布_100分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 100 And "
& dr("科目") &
" < 110" )
dr("分布_110分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 110 And "
& dr("科目") &
" < 120" )
dr("分布_120分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 120 And "
& dr("科目") &
" < 130" )
dr("分布_130分以上")
= dt.Compute("Count(姓名)",
dr("科目") &
" >= 130" )
End
If
经过上述设置,在任何时候,你只需选择科目列,然后单击菜单中的重置按钮,即可得到最新的成绩分布数据。
如果希望能够自动计算,而不是通过单击按钮去刷新结果,假定这个表的名称是“成绩分布”,可以在项目(数据库)事件的MainTableChanged事件中设置如下代码:
If
Maintable.Name
= "成绩分布"
Then
DataTables("成绩分布").DataCols("科目").RaiseDataColChanged()
End
If
示例二
继续上面的例子,如果希望得到下面的成绩统计表:
只需将该表的DataColChanged事件代码设为:
Dim
dr
As
DataRow = e.DataRow
Dim dt As
DataTable =DataTables("学生成绩")
If e.DataCol.Name
= "科目"
And
dr.IsNull("科目")
= False
Then
dr("最高分")
= dt.Compute("Max("
& dr("科目") &
")")
dr("最低分")
= dt.Compute("Min("
& dr("科目") &
")")
dr("平均分")
= dt.Compute("Avg("
& dr("科目") &
")")
End If
示例三
统计不同产品的销售数量和金额,我们采用事先设计好的临时表来显示统计结果。
1、首先增加一个临时表,包括产品、数量、金额三列。
2、将统计表的DataColChanged事件设置为:
Dim
dr As
DataRow
= e.DataRow
Dim dt
As
DataTable =
DataTables("订单")
If e.DataCol.Name
= "产品"
Then
dr("数量")
= dt.Compute("Sum(数量)","[产品]
= '" & dr("产品")
& "'")
dr("金额")
= dt.Compute("Sum(金额)","[产品]
= '" & dr("产品")
& "'")
End
If
3、MainTableChanged事件中加入如下代码:
If
Maintable.Name
= "销售统计"
Then
dim f
As New Filler
DataTables("销售统计").DataRows.Clear()
'清除原有数据
f.SourceTable =
DataTables("订单")
f.SourceCols = "产品"
f.DataTable
= DataTables("销售统计")
f.DataCols = "产品"
f.Fill()
End
If
这里假定这个统计表的名称为“销售统计”,以后我们每次选择这个表,即可得到最新的统计结果。
示例四
还是统计不同产品的销售数量和金额,不过我们这次全部用一段代码完成。
将下面的代码复制到命令窗口执行即可:
'生成统计表
Dim dtb As
New DataTableBuilder("统计")
dtb.AddDef("产品",
GetType(String),
32)
dtb.AddDef("数量",
GetType(Integer))
dtb.AddDef("金额",
GetType(Double))
dtb.Build()
'填充数据
dim f As
New Filler
f.SourceTable = DataTables("订单")
f.SourceCols = "产品"
f.DataTable
= DataTables("统计")
f.DataCols = "产品"
f.Fill()
'统计
For Each dr
As Datarow
In
DataTables("统计").DataRows
dr("数量") =
DataTables("订单").Compute("Sum(数量)","[产品]
= '" & dr("产品")
& "'")
dr("金额") =
DataTables("订单").Compute("Sum(金额)","[产品]
= '" & dr("产品")
& "'")
Next
MainTable=
Tables("统计")
当然,上面的代码如果改用GroupTableBuilder来实现,要容易很多。
之所以提供这样的例子,是为了让你知道,其实你有更多的选择,这样面对一些复杂的统计要求,你也能应付自如。
示例五
前面的统计,都使用了Filler来向统计表填充分组数据,实际上有时手工编码填充分组数据也是一个不错的选择。
还是以统计不同产品的销售数量和金额为例,如果手工编码填充分组数据,代码为:
Dim
dtb
As New
DataTableBuilder("统计")
dtb.AddDef("产品",
Gettype(String),
32)
dtb.AddDef("数量",
Gettype(Integer))
dtb.AddDef("金额",
Gettype(Double))
dtb.Build()
For Each nm
As String
In DataTables("订单").GetValues("产品")
Dim
dr As
DataRow
= DataTables("统计").AddNew()
dr("产品")
= nm
dr("数量")
= DataTables("订单").Compute("Sum(数量)","[产品]
= '" & dr("产品")
& "'")
dr("金额")
= DataTables("订单").Compute("Sum(金额)","[产品]
= '" & dr("产品")
& "'")
Next
MainTable=
Tables("统计")
代码是不是比示例四简洁很多呢?
本页地址:http://www.foxtable.com/webhelp/topics/0681.htm