Rss & SiteMap

Foxtable(狐表) http://www.foxtable.com

新一代数据库软件,完美融合Access、Foxpro、Excel、vb.net之优势,人人都能掌握的快速软件开发工具!
共14 条记录, 每页显示 10 条, 页签: [1] [2]
[浏览完整版]

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

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

2楼
mr725 发表于:2009/6/3 17:15:00

学习啊~

3楼
yangming 发表于:2009/6/3 17:18:00
还没看,学习!
4楼
八婺 发表于:2009/6/3 19:16:00
学习。
5楼
程兴刚 发表于:2009/6/3 19:32:00
刚看见!
6楼
woodiy 发表于:2009/6/3 20:31:00

有实例学习一下吗?

7楼
hlxz 发表于:2009/6/3 21:34:00
知识点好多,知识面好多,

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

有实例学习一下吗?

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

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

9楼
btsfdz 发表于:2009/6/3 21:53:00
努力学习,学习,学习!
10楼
听雪落的声音 发表于: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编辑过]
共14 条记录, 每页显示 10 条, 页签: [1] [2]

Copyright © 2000 - 2018 foxtable.com Tel: 4000-810-820 粤ICP备11091905号

Powered By Dvbbs Version 8.3.0
Processed in .04688 s, 3 queries.