以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.com/bbs/index.asp)
--  专家坐堂  (http://foxtable.com/bbs/list.asp?boardid=2)
----  新的跨表更新的方法,务必要掌握  (http://foxtable.com/bbs/dispbbs.asp?boardid=2&id=3010)

--  作者:狐狸爸爸
--  发布时间: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实现自动更新,那么更新代码必须包含计算功能,等于基本类似的代码同时出现在两个位置;代码简单的话(例如本节的例子)倒无所谓,如果计算部分的代码较为复杂,就显得累赘了,也不便于维护。


--  作者:mr725
--  发布时间:2009/6/3 17:15:00
--  

学习啊~


--  作者:yangming
--  发布时间:2009/6/3 17:18:00
--  
还没看,学习!
--  作者:八婺
--  发布时间:2009/6/3 19:16:00
--  
学习。
--  作者:程兴刚
--  发布时间:2009/6/3 19:32:00
--  
刚看见!
--  作者:woodiy
--  发布时间:2009/6/3 20:31:00
--  

有实例学习一下吗?


--  作者:hlxz
--  发布时间:2009/6/3 21:34:00
--  
知识点好多,知识面好多,

不知帮助是否更新了,,看来以前得打印的帮助要报销了,
看来要熟练应用 要加油 加油 更加油
狐爸爸 也辛苦,支持一下
--  作者:狐哥
--  发布时间:2009/6/3 21:53:00
--  
以下是引用woodiy在2009-6-3 20:31:00的发言:

有实例学习一下吗?

哈,我刚好做了一个在练习.共享一下啦.

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目2.table


--  作者:btsfdz
--  发布时间:2009/6/3 21:53:00
--  
努力学习,学习,学习!
--  作者:听雪落的声音
--  发布时间:2009/6/4 11:16:00
--  

第一个代码中e.newvalue什么意思?我加代码里好像不行。
另外
If e.DataCol.Name = "发放银行"
    Dim Filter As String = "[单位] = \'" & e.DataRow("单位") & "\'"
    DataTables("人员信息").DataCols("发放银行").RaiseDataColChanged(Filter)
End If

这些代码没有反应啊?

[此贴子已经被作者于2009-6-4 11:32:24编辑过]