手工编码进行统计

普通用户可忽略本节的内容。

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