Foxtable(狐表)用户栏目专家坐堂 → 乱七八糟一大堆,看完定有收获。


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

主题:乱七八糟一大堆,看完定有收获。

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


加好友 发短信
等级:管理员 帖子:47476 积分:251245 威望:0 精华:91 注册:2008/6/17 17:14:00
乱七八糟一大堆,看完定有收获。  发帖心情 Post By:2009/5/26 12:18:00 [只看该作者]

 

再谈TableDataTable

有了前面的知识,我们可以更深入地理解TableDataTable的区别。


示例一


假定有一个订单表,这个表有1000行,假定其中100个订单是订购产品PD01的,我们在该表筛选出PD01的订单,现在你在订单表看到的行数是100行。

我们在窗口执行下面的代码:


For Each
r As Row in Tables("订单").Rows
    r(
"
折扣") = 0.2
Next


上面的代码,将你看到的100(订购PD01的订单)的折扣设为0.2

我们再来测试下面的代码:


For Each
dr As DataRow in DataTables("订单").DataRows
    dr(
"
折扣") = 0.2
Next


上面的代码所有1000(全部订单)的折扣设为
0.2

总之,如果你要对看得见的行进行操作,你就用Table,如果你要对所有行进行操作,你就用DataTable


示例二


例如我们要统计产品PD01的销售数量,通常使用DataTableCompute方法:


Dim
Total As Double
Total = DataTables(
"
订单").Compute("Sum(金额)","产品 = 'PD01'")


为什么不用TableCompute方法呢? 因为TableCompute方法计算范围仅限于可见的行,假定用户通过菜单在订单表进行了筛选操作,筛选出了2008年的数据,那么下面的计算出来的就是2008年产品PD01的销售金额,而不是PD01的总销售金额:


Dim
Total As Double
Total = Tables(
"
订单").Compute("Sum(金额)","产品 = 'PD01'")


示例三


DataTable
中的行用DataRow表示,Table中的行用Row表示。
Table
的数据来自于DataTable,所以每一个Row都对应一个DataRowRow有一个名为DataRow的属性,用于返回该Row所对应的DataRow
例如重新加载订单表的选定行:

Tables(
"订单").Current.DataRow.Load()


提示:Row并没有Load方法,所以要重新加载某一行,必须执行DataRowLoad方法。

同样DataTable中的列用DataCol表示,Table中的列用Col表示,每一个Col都对应一个DataColCol有一个名为DataCol的属性,用于返回该Col对应的DataCol
例如要重置当前表选定列,但是Col并没有重置列的方法,我们只能调用DataColRaiseDataColChanged方法:


With CurrentTable

    .Cols(.ColSel).DataCol.RaiseDataColChanged()

End With


对应的,Table也有一个名为DataTable的属性,用于返回该Table所属的DataTable
例如要重新加载当前表,因为Table没有重新加载的命令,只能调用DataTableLoad方法:


CurrentTable.
DataTable.Load()


示例四


上面的例子提到,TableRowCol都有对应的属性,用于返回其所属的DataTableDataRowDataCol
但是却不可能反过来操作,因为一个DataTable,可能对应有多个Table
不过通过TableFindRow方法,我们可以获得某一个DataRowTable中的位置。
例如我们希望在订单表中,将光标定位到最近一次订购PD01的行上:


Dim
dr As DataRow
Dim
po As Integer
dr = DataTables(
"
订单").Find("产品 = 'PD01'","日期 Desc") '找出最后一次订购PD01产品的DataRow
po = Tables(
"
订单").FindRow(dr) '找出该DataRowTable中的位置
If
po >= 0 Then '如果找到
    Tables(
"订单").Position = po '选定
End If


因为
Table可能会进行筛选,所以一个DataRow可能不会出现在Table中,此时FidnRow方法会返回-1,表示没有找到指定的DataRow

再例如正在订单表操作,希望在订单表中选定一行时,客户表的光标能够自动定位到该客户,这样我一旦从订单表回到客户表,即可看到刚刚所选订单的客户资料。
为此我们在CurrentChanged事件中设置如下代码: 


Dim
wz As Integer
Dim
dr As DataRow
dr = DataTables(
"
客户").Find("[客户ID] = '" & e.Table.Current("客户ID") & "'")
If
dr IsNot Nothing Then
    wz = Tables(
"
客户").FindRow(dr)
    If wz >= 0 Then
        Tables
(
"
客户").Position = wz
    End If
End
If


这种在不同表之间联动的技巧应该掌握,也许你觉得通过关联,不就可以在订单表中以关联表的形式显示客户信息吗?

但是:
1
、有的时候我们并不希望建立太多的关联。
2
、即使建立了关联,我们也可能关闭了Foxtablede的双向关联特性,这样就无法以关联表的形式查看父表数据了。


示例五


其实
Table也有Find方法,不过TableFind方法是根据内容查找,而不是根据表达式来查询,返回的是行的位置。

例如:


With CurrentTable
    Dim
r As Integer
   
r = .Find("PD01", 0,
"
产品", False, False, True)
    If
r > - 1 Then '如果找到符合条件的行
        .
Position = r
    End If
End With


Table
Find方法功能较弱,但是使用简单,通常用于进行简单的查找和定位。
Table
还有一个FidRow方法,可以使用表达式进行查找,例如订单表的公司名称列中,查找包括“湛江”二字的单位:


With Tables(
"订单")
    Dim
r As Integer
    r = .FindRow(
"[
公司名称] Like '*湛江*'", .Position + 1, True ) '从当前行开始查找
    If
r >= 0 Then '如果找到的话
       
.Position = r '定位到找到的行。
   
End If
End With


显然
TableFindFindRow方法的查找结果,会受筛选的影响,因为作为Table的方法,只是在可见的行中进行查找;此外因为没有排序参数,这两个方法无法按照特定的顺序进行查找,只能从上往下地顺序查找。

相对来说,
DataTableFind方法则要强大很多,不仅可以用表达式查询,有排序参数,还可以指定返回第几个符合条件的行,而且可以不受筛选的影响,只要有符合条件的行,始终都能找出来。
一些复杂的查找,用TableFindFindRow方法是无法实现的,我们可以先用DataTableFind方法,找出符合条件的DataRow,让后利用TableFindRow方法 ,找出该DataRowTable中的位置。
例如我们希望定位到客户CS01第二次订购PD01产品的行:


Dim
dr As DataRow
Dim
Index As Integer
dr = DataTables(
"
订单").Find("客户 = 'CS01' And 产品 = 'PD01'","日期",1)
Index = Tables(
"
订单").FindRow(dr)
If
Index > 0 Then
    Tables(
"
订单").Position = Index
End If


提示:
TableFindRow有两个语法,一个是根据表达式查询,一个是查找指定的DataRow在表中的位置。


示例六


除非需要定位的符合条件的行,否则是不需要使用
TableFindFindRow方法的。

例如希望在订单表输入产品编号,能够从产品表提取该产品的名称、型号、规格,自动输入到订单表的相关列中。
为实现此目的,可在订单表的DataColChanged事件中输入如下代码:


If
e.DataCol.Name = "产品编号" Then '发生变化的是产品名称吗?
    '
在产品表找出该产品
   
Dim dr As DataRow = DataTables("产品").Find("编号 = " & "'" & e.DataRow("产品编号") & "'" )
    If dr IsNot Nothing
'
如果找到, 则设置各列内容
        e.DataRow(
"
品名")= dr("品名")
        e.DataRow(
"
型号")= dr("型号")
        e.DataRow(
"
规格")= dr("规格")
    End If
End
If


在上面的代码中,我们是在
DataTable中查找所输入编号的产品,这是显然的, 首先我们只是引用数据,并不需要定位,其次如果在Table中查找,一旦Table进行了筛选,而你输入的产品编号恰好不符合筛选条件,那么就无法实现自动输入。


示例七


DataTable
有一个Select方法,以集合的形式,返回所有符合指定条件的行。
例如对于199914日订购PD01的订单,希望将其折扣统一设置为0.12,代码为:


Dim
drs As List(Of DataRow)
drs = DataTables(
"
订单").Select("[产品] = 'PD01' And [日期]= #1/4/1999#")
For Each
dr As Datarow In drs
    dr(
"
折扣") = 0.12
Next


Table
也有Select方法,不过作用是完全不同的,该方法用于选定指定位置的单元格或区域。
例如选定当前表的第1行第1:

CurrentTable
.Select(0,0)


我们经常需要选定整行、整列、甚至整个表,可以参考下面的代码:


'
选定第二列
With Tables("订单")
    .Select(0, 1, .Rows.Count - 1, 1)
End With

'选定数量列
With Tables("订单")
   
Dim c As Integer= .Cols("数量").Index
    .
Select(
0, c, .Rows.Count - 1, c)
End With

'选定第三行
With Tables("订单")
    .Select(2, 0, 2, .Cols.Count - 1)
End With

'选定第三行的数量单元格
With
Tables("订单")
   
Dim c As integer = .Cols("数量").Index
    .
Select(2, c, 2, c)
End With

'选定整个表
With Tables("订单")
    .
Select(0, 0, .Rows.Count - 1, .Cols.Count - 1)
End With


示例八


DataTable的一些方法是特有的,Table中没有可对应的方法。
例如
DeleteFor和ReplaceFor方法。
可是有的时候,我们真的只是希望对可见的行进行操作,却没有对应的办法,那么该怎么办呢?
其实很简单,这些方法是可以设置条件的,例如进行筛选后,你希望删除所有筛选出的行,只需:


CurrentTable
.DataTable.DeleteFor(CurrentTable.Filter)


我们将Table的Filter属性传递给DataTable的DeleteFor方法,显然删除的就是我们筛选出来的行。
反过来,如果在筛选后,删除不符合条件的行,也就是被隐藏的行,只需:


With CurrentTable

    .
DataTable.DeleteFor("(" & .Filter & ") = False")
End With


假定原来的筛选条件: [产品] = 'PD01',那么上面的代码传递给DeleteFor的条件就是:([产品] = 'PD01') = False。
删除的自然就是条件不成立的行,也就是被隐藏的行。


示例九


很多类型,例如常用的CrossTableBuilder和GroupTableBuilder,只能对DataTable进行操作。
如果你希望对筛选后的数据,也就是Table中的数据进行统计,那么该怎么办呢?
其实一样,将这些类型的Filter属性的值,设为将Table的Filter属性值即可。

例如:


Dim
g As New GroupTableBuilder("统计表1", DataTables("订单"))
g.Groups.AddDef(
"产品")
g.Totals.AddDef(
"数量")
g.Filter =
Tables("订单").Filter
g.Build()

MainTable
= Tables("统计表1")

[此贴子已经被作者于2009-5-26 12:33:43编辑过]

 回到顶部
美女呀,离线,留言给我吧!
yangming
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:超级版主 帖子:4109 积分:23338 威望:0 精华:21 注册:2008/9/1 20:07:00
  发帖心情 Post By:2009/5/26 12:33:00 [只看该作者]

再次学习,呵呵

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/5/26 12:34:00 [只看该作者]

不错,一条一条~   像个『山寨』型的帮助文件,很管用~~   图片点击可在新窗口打开查看

 回到顶部
帅哥哟,离线,有人找我吗?
狐哥
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:三尾狐 帖子:719 积分:5181 威望:0 精华:1 注册:2008/9/24 10:41:00
  发帖心情 Post By:2009/5/26 12:37:00 [只看该作者]

太感谢了.

 回到顶部
帅哥哟,离线,有人找我吗?
八婺
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:童狐 帖子:252 积分:1355 威望:0 精华:0 注册:2009/4/5 13:06:00
  发帖心情 Post By:2009/5/26 15:08:00 [只看该作者]

先顶下贴,有时间再来看。

 回到顶部
帅哥哟,离线,有人找我吗?
shixia
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:三尾狐 帖子:759 积分:7038 威望:0 精华:1 注册:2008/9/2 20:04:00
  发帖心情 Post By:2009/5/26 15:15:00 [只看该作者]

好啊,先顶后看,一定有收获

 回到顶部
帅哥哟,离线,有人找我吗?
实话实说
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2649 积分:19390 威望:0 精华:1 注册:2008/9/12 9:19:00
  发帖心情 Post By:2009/5/26 15:40:00 [只看该作者]

应该再编一本《教材》,就象上面那样,会吸引很多人。

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2009/5/26 16:12:00 [只看该作者]

以下是引用实话实说在2009-5-26 15:40:00的发言:
应该再编一本《教材》,就象上面那样,会吸引很多人。

出教材很累人的~   我说应该开辟一个新贴子,将大家的测试过的小段代码加上说明贴上来,标明分类的类别(比如:复制、粘贴, 跨表取数、等。。。。这个由老大确定),标错类别由版主更正之~  这就成了活的教材~  
最后有狐表公司汇总,可随系统发布,或方便上论坛的人打包下载,定能增加论坛的人气。人气足了,论坛可以增加些小广告了~~~~ 呵呵

贺总你看呢~


 回到顶部
帅哥哟,离线,有人找我吗?
老有所乐
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:三尾狐 帖子:746 积分:6673 威望:0 精华:1 注册:2008/9/1 11:46:00
  发帖心情 Post By:2009/5/26 17:12:00 [只看该作者]

这样好理解多了


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


加好友 发短信
等级:管理员 帖子:47476 积分:251245 威望:0 精华:91 注册:2008/6/17 17:14:00
  发帖心情 Post By:2009/5/26 17:13:00 [只看该作者]

我这个已经加到帮助了。

 回到顶部
总数 16 1 2 下一页