表达式列的特殊性
我们知道,列的值发生变化,会相继触发DataColChanging和DataColChanged事件。
但是有一个例外: 表达式列的值发生变化时,并不会触发这两个事件。
假定C列是一个表达式列,根据A列和B列的值计算得出,而D列的值则根据C列的值用代码计算得出。
通常我们会这样编写DataColChanged事件的代码:
Select
Case
e.DataCol.Name
Case
"C"
'计算D列的代码
End Select
但是上述代码是无效的,因为作为表达式列,C列发生变化的时候,并不会触发DataColChanged事件。
我们可以换个思路,既然C列是有A列和B列计算得出,那么C列发生变化,肯定是因为A列或B列发生变化引起的。
所以正确的代码是:
Select
Case e.DataCol.Name
Case "A"
,"B"
'计算D列的代码
End
Select
通过子表触发父表事件
还有一个特殊情况,表达式列并非由本表的列计算得出,而是由子表数据计算得出。
例如假定订单表有个数量列,是表达式列,用于累计订单明细表的数量,其表达式为:
Sum(Child.数量)。
再假定订单表的DataColChanged事件设置了如下代码:
If
e.DataCol.name
= "数量" Then
'相关计算代码
End If
当我们在订单明细表输入数量时,订单表的数量会自动更新,但是上面的代码永远不会执行,因为数量是一个表达式列,不会触发事件。
我们需要在订单明细表的DataColChanged事件加上代码:
If
e.DataCol.name
=
"数量"
Then
Dim
pr
As
DataRow
= e.DataRow.GetParentRow("订单")
'找出对应的父行
If
pr IsNot
Nothing Then
DataTables("订单").DataCols("数量").RaiseDataColChanged(pr)
'通知系统此父行的数量列发生了改变,触发DataColChanged事件
End If
End If
这样在订单明细表输入数量,就会在订单表针对该订单的数量列触发DataColChanged事件。
有的用户编写代码不严谨,简单地将订单明细的代码设置为:
If
e.DataCol.name
=
"数量"
Then
DataTables("订单").DataCols("数量").RaiseDataColChanged
End If
上面的代码效率极低,因为修改某个订单明细的数量,就会重算所有订单的数量,而不是只重算相应订单的数量。