表达式列的影响

如果表达式列引用父表数据,或者统计子表数据,那么对于批量修改数据的效率影响很大,不过我们有很好的方法避免这种情况的发生。

在编写此节内容之前,我建立了一个文件,该文件包括两个表,分别是产品和订单,两者建立了关联。
产品表的“总金额”列是一个表达式列,其表达式为:Sum(Child.金额)。
订单表则有两个表达式列,其中“单价”列的表达式为:Parent.单价,“金额”列的表达式为:数量 * 单价 * (1 - 折扣)
产品表有1千行数据,订单表有1万行数据。

示例一

假定希望所有产品都提价5%,代码为:

For Each dr As DataRow In DataTables("产品").DataRows
    dr("单价") = dr("单价") * 1.05

Next

在产品表只有区区1000行数据的情况下,执行上述代码居然花费了31秒。
这是因为订单表的单价列引用了产品表的单价,每修改一个产品的单价,都必须同步去更新该产品所有订单的单价。
为了避开这种影响,我将代码改为:

DataTables("订单").DataCols("单价").Expression = ""
For Each
dr As DataRow In DataTables("产品").DataRows
    dr
("单价") = dr("单价") * 1.05
Next
DataTables(
"订单").DataCols("单价").Expression = "Parent.单价"

经过测试,执行上述代码花费0.16秒,比之前提高了足足200倍。
原理很简单,先清除订单表单价列的表达式,待代码执行结束后,再重新设置此列的表达式。
实际上只要子表引用了父表的数据,批量修改父表中的任何一列都会受到影响,当然批量修改被引用的列受影响的程度最为明显。

示例二

假定希望给所有订单增加5%的折扣,代码为:

For Each dr As DataRow In DataTables("订单").DataRows
    dr(
"折扣") = dr("折扣") + 0.05

Next

经过测试,执行上述代码耗时78秒,效率很低。
究其原因,是因为修改订单的折扣,会重算订单的金额,而订单金额的变化又会重算产品的总金额。
知道原因就好办,我将代码改为:

DataTables("订单").DataCols("金额").Expression = ""
For
Each dr As DataRow In DataTables("订单").DataRows
    dr(
"折扣") = dr("折扣") + 0.05
Next
DataTables(
"订单").DataCols("金额").Expression =
"数量 * 单价 * (1 - 折扣)"

经过测试,执行上述代码仅耗时0.95秒,效率大幅度提高。

如果将所有的表达式清除:

DataTables("订单").DataCols("金额").Expression = ""
DataTables(
"订单").DataCols("单价").Expression = ""
DataTables
("产品").DataCols("总金额").Expression = ""
For Each
dr As DataRow In DataTables("订单").DataRows
    dr
("折扣") = dr("折扣") + 0.05
Next
DataTables(
"订单").DataCols("单价").Expression = "Parent.单价"
DataTables(
"订单").DataCols("金额").Expression = "数量 * 单价 * (1 - 折扣)"
DataTables
("产品").DataCols("总金额").Expression = "Sum(Child.金额)"

效率得到进一步的提高,现在耗时只需0.54秒,当然一般没有必要这么做,清除影响最大的表达式即可,毕竟不到半秒的差距在实际使用的过程中是很难感觉到的。


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