Foxtable(狐表)用户栏目专家坐堂 → 新的跨表更新的方法,务必要掌握


  共有30865人关注过本帖树形打印复制链接

主题:新的跨表更新的方法,务必要掌握

帅哥哟,离线,有人找我吗?
狐狸爸爸
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:47497 积分:251403 威望:0 精华:91 注册:2008/6/17 17:14:00
新的跨表更新的方法,务必要掌握  发帖心情 Post By:2009/6/3 17:13:00 [显示全部帖子]

在6.2更新中,RaiseDataColChanged有了一个新的语法:

RaiseDataColChanged(Filter)

Filter:  可选参数,一个条件表达式,针对符合此条件的行触发

增加这个语法,是为了更方便地实现跨表计算的自动更新。

夸表更新


上一节提到,通过在
订单表的DataColChanged事件中加入如下代码:


If
e.DataCol.Name = "产品名称" Then '如果内容发生变动的是产品列
    If e.NewValue Is Nothing Then '如果新值是空白,也就是产品列的内容为空
        e.
DataRow("单价") = Nothing '那么清空此行单价列的内容
   
Else
        Dim
dr As DataRow
       
'否则在产品表查找同名的产品行,将找到的行赋值给变量dr
        dr =
DataTables("产品").Find("[产品名称] = '" & e.NewValue & "'")
        If
dr IsNot Nothing Then '如果找到了同名的产品行,也就是dr不是Nothing
            e.
DataRow("单价") = dr("单价")
        End
If
    End
If
End
If


可以使得订单表自动从产品表中取得对应产品的单价,然后填入订单表的单价列。
如果我们修改某一个产品的单价,那么该产品原有订单的单价会保持不变,只有新增的订单才会使用新的单价。
可是也有一些场合,可能会要求修改产品单价后,原有订单的产品单价也自动更新。

为此,我们可以在产品表的DataColChanged事件中加入如下代码:


If
e.DataCol.Name = "单价"
   
Dim Filter As String = "[品名] = '" & e.DataRow("品名") & "'"
   
DataTables("订单").DataCols("品名").RaiseDataColChanged(Filter)
End
If


上述代码的原理是:如果修改了产品表的单价,则针对订单表的品名列触发DataColChange事件,触发条件为订购此产品的行,从而实现了订单表单价的自动更新。

RaiseDataColChanged
的条件是动态合成的,条件表达式分为三部分

"[品名] = '" & e.DataRow("品名") & "'"


如果品名为"PD01",那么三部分组合起来的结果是:


[品名]  = 'PD01'


这是我们第二次介绍动态合成表达式,这是属于基本功,不掌握是不行的。


有条件的跨表更新


上面我们已经介绍了如何实现跨表更新,可是更新有的时候是有条件的。
例如如果在产品表中修改单价,希望订单表中已经锁定的订单,继续保持原单价不变,而未锁定的订单采用新的单价。
为此,我们可以在产品表的
DataColChanged事件中加入如下代码:


If
e.DataCol.Name = "单价"
    Dim
Filter As String = "[品名] = '" & e.DataRow("品名") & "'"
    Dim
drs As List(Of DataRow) = DataTables("订单").Select(Filter)
    For Each
dr As DataRow In drs
        If
dr.Locked = False '如果此行没有锁定
            DataTables(
"订单").DataCols("品名").RaiseDataColChanged(dr)
        End If
    Next
End If


一定要用RaiseDataColChanged吗?


当然不,例如我们可以用下面的代码,同样可以实现上面的要求:


If e.DataCol.Name = "单价"
   
Dim Filter As String = "[品名] = '" & e.DataRow("品名") & "'"
    Dim
drs As List(Of DataRow) = DataTables("订单").Select(Filter)
    For
Each dr As DataRow In drs
        If
dr.Locked = False
'如果此行没有锁定
            dr("单价") = e.DataRow("单价")
'则采用新的单价

        End If
    Next
End If


看上去代码似乎更简单一些。不过大多数时候,还是用RaiseDataColChanged方法较好,因为:
1、如果使用RaiseDataColChanged实现自动更新,更新代码不会涉及具体的计算,所以代码是通用的,基本上不会因为计算要求的变动,而去修改更新代码。
2、如果不使用RaiseDataColChanged实现自动更新,那么更新代码必须包含计算功能,等于基本类似的代码同时出现在两个位置;代码简单的话(例如本节的例子)倒无所谓,如果计算部分的代码较为复杂,就显得累赘了,也不便于维护。


 回到顶部