foxtable编程

更新时间:2024-06-14 15:28:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基本概念

下面的概念非常重要,务必要掌握。 DataTable和Table

假定在一个简化的订单管理系统中,包括产品、客户、订单三个表:

Foxtable中有一个集合DataTables,通过该集合可以获得指定名称的表,例如: DataTables(\产品\) '产品表 DataTables(\客户\) '客户表 DataTables(\订单\) '订单表

实际上你是看不到DataTable的,你看到的是Table,也就是说,上面的三个图,实际上就是三个Table。

那么什么是Table呢?你可以这样理解,DataTable就像一个仓库,所有从数据文件中加载的数据,都存放在这里,而且这个仓库是不直接面对用户的;而Table就像一个展厅,是负责和用户打交道的,这个展厅(Table)从仓库(DataTable)中取得数据,并呈现给用户。

同样,Foxtable中也有一个集合Tables,通过该集合可以获得指定名称的Table,在没有建立关联的情况下,我们这个简化的订单管理系统包括三个Table,分别是: Tables(\产品\) Tables(\客户\) Tables(\订单\)

在初始的情况下,Table会从DataTable中提取所有数据呈现给用户,如果你设置了筛选条件,Table就会从DataTable提取符合筛选条件的数据,然后呈现给用户。

例如订单表有1000行数据,那么DataTables(\订单\)从头到尾,始终都会有1000行数据,不

受筛选的影响。而Tables(\订单\)却不一样,如果没有进行筛选,那么Tables(\订单\)也会包括所有数据,也就是1000行数据全部可见。如果现在从中筛选出产品为PD01的订单,且PD01的订单是200个,那么经过筛选后,Tables(\订单\)会包括200行数据,也就是你看到的那200个产品为PD01的订单。

所以关于DataTable和Table的关系,较为完整的描述是: ?

从数据文件加载到Foxtable中的数据,是存放在DataTable中的,它就像一个仓库,不直接面对用户;而Table就像一个展厅,是负责和用户打交道的,它根据指令从仓库(DataTable)中提取符合条件的数据,然后呈现给用户;通过菜单进行的日常数据管理工作,例如增加行、删除行、排序、筛选、汇总等等,都是在Table中进行的;除了编程,用户没有办法直接对DataTable进行操作,因为它是不可见的。 ? ? ?

在任何时候,DataTable都包括所有已经加载的行。

Table中的行,既可以排序,也可以筛选,所有Table中行的数量和顺序都是可变化的,我们平时所看到的、所操作的,都是Table中的行。

我们在Table中进行的任何操作,最终都会反映到DataTable,例如我们通过菜单在Table中删除行,DataTable也会删除一行。

关联表和Table

假定在上面这个简化的订单管理系统中,我们建立如下两个关联:

父表 产品 客户 子表 订单 订单 产品编号 客户编号 关联列 因为关联的建立,DataTable和Table不再是一一对应的关系,例如我选择产品表的时候,就会出现三个Table,分别是:

三个Table的作用为:

Tables(\产品\:主表,用于显示所有产品

Tables(\产品.订单\:如果在Tables(\产品\中选定一个产品,这里会显示该产品的全部订单。 Tables(\产品.订单.客户\:如果在Tables(\产品.订单\中选定一个订单,这里会显示该订单所属的客户。

同样在选择客户表的时候,也会出现三个Table: Tables(\客户\Tables(\客户.订单\Tables(\客户.订单.产品\

而选择订单表,出现的三个Table为: Tables(\订单\Tables(\订单.产品\Tables(\订单.客户\

由此我们可以看出,同一个DataTable可以有多个Table,例如下面三个Table: Tables(\产品\Tables(\订单.产品\Tables(\客户.订单.产品\

它们的数据全部来自于DataTables(\产品\。

由此可见,DataTable的数量是固定的,而Table的数量会随着关联的增加而增加,同一个DataTable可以有多个Table,每个Table都各取所需地从DataTable中提取数据呈现给用户。

概述

通过DataTables集合,可以获得指定名称的DataTable(表)。 例如:

Dim dt As DataTable dt = DataTables(\订单\) DataCol表示DataTable中的列。

通过DataCols集合,可以获得指定名称的DataCol(列)。 例如:

Dim dt As DataTable = DataTables(\订单\) Dim dc As DataCol = dt.DataCols(\日期\)

DataRow表示DataTable中的行。

通过DataRows集合,可以获得某一位置的DataRow(行)。 例如:

Dim dr As DataRow

dr = DataTables(\订单\).DataRows(0)

行是从0开始编号的,所以0表示第一行,1表示第二行。 通过列名称,我们可以得到或设置某一行指定列的内容。 例如:

Dim r As DataRow Dim v As Double

r = DataTables(\订单\).DataRows(0) r(\数量\) = 100 v = r(\折扣\)

由此可知,DataTable、DataRow、DataCol构成了表、行、列这样一个完整的结构体系,接下来我们具体介绍这三个对象。

常用属性

通过DataTables集合,可以获得指定名称的DataTable(表)。 例如:

Dim dt As DataTable dt = DataTables(\订单\)

如果要禁止编辑某个DataTable,只需将其AllowEdit属性设为False,例如: DataTables(\订单\).AllowEdit = False

在命令窗口执行上述代码,你会发现订单表的左上角出现一个锁形标记,表示此表已经被锁定,不能在其中输入数据。

如果你要取消锁定表,只需将其AllowEdit属性重新设为True: DataTables(\订单\).AllowEdit = True

下表列出了DataTable的常用设置属性,它们的用法和AllowEdit属性完全一样: 属性名 说明 AllowEdit AllowAddNew 是否允许修改表中数据 是否允许增加行 AllowClipBoard 是否允许复制粘贴数据 AllowInitialize AutoAddNew AllowDelete AllowLockRow 是否允许初始化此表 是否允许自动增加行,也就是在最后一行的最后一个单元格按回车键时,是否自动增加一行 是否允许删除行 是否允许锁定行 AllowUnlockRow 是否允许取消锁定行 我们在编辑数据的时候,如果按回车键或Tab键,光标会向右移到下一单元格,通过下面的属性,你可以改变这种默认的光标移动方式: 属性名 说明 EnterKeyActionDown 按回车键是否向下移到另一单元格 TabKeyActionDown 按Tab键是否向下移到另一单元格 例如你希望按回车键向下移动光标,而不是向右移动,只需将EnterKeyActionDown属性设为True即可:

DataTables(\订单\).EnterKeyActionDown = True 最后三个常用的属性为: 属性名 Name 说明 返回DataTable的名称 返回一个整数,表示DataTable的类型: 1 内部数据表 Type 2 内部查询表 3 外部数据表 4 外部查询表 5 临时表 HasChanges 逻辑型,判断DataTable的数据是否已经被修改 例如执行下面的代码,将列出所有已经修改过的DataTable: Output.Show(\已经修改的数据表:\) For Each dt As DataTable In DataTables If dt.Type = 1 Orelse dt.Type = 3 Then

If dt.HasChanges Then Output.Show(dt.Name) End If End If Next

AddNew

在DataTable中增加一行或多行,并返回所增加的第一行。 AddNew() AddNew(Count)

Count: 可选参数,要增加的行数,如果省略,则只增加一行。 例如:

Dim dr As DataRow

dr = DataTables(\订单\).AddNew()

dr(\日期\) = Date.Today '将新增行的日期设为当天日期。

其实我们很少直接向DataTable增加行,更多的时候,我们是向Table中增加行,原因以后会讲述。 Save 保存数据。 语法: Save() Save(Setting)

Setting: 可选参数,是否保存设置。 例如单单保存数据: DataTables(\订单\).Save() 同时保存数据和设置: DataTables(\订单\).Save(True) 保存设置比较耗时,会影响保存速度。 菜单中的保存命令是同时保存数据和设置的。

如果你学会了设计菜单或窗口,你可以自己设计一个保存按钮,将其代码设为:

For Each dt As DataTable In DataTables dt.Save() Next

这样单击这个按钮就能保存所有表,但是不会保存设置;对于一个成熟的、已经交付使用的项目,有时是没有必要保存设置的。

GetUniqueValues

从指定列中,获取不重复的值,以集合的形式返回。 语法:

GetUniqueValues(Filter, Col1, Col2, Col3....)

Filter: 条件表达式,请参考表达式的运算符和函数 和 条件表达式 Col1: 指定列名称,可以指定多列。

如果只从一列中提取不重复值,那么返回的是一个字符串集合;如果从多列中提取不重复值,那么返回的是一个字符串数组集合,数组的长度等于指定的列数。

在执行以下示例之前,请打开CaseStudy目录下的示例文件\统计演示.Table\。 示例一

列出1999年6月1日后订购过PD01产品的客户名单: Dim Customers As List(Of String)

Customers = DataTables(\订单\).GetUniqueValues(\产品]= 'PD01' And [日期] > #6/1/1999#\, \客户\)

For i As Integer = 0 To Customers.Count - 1 '其实用For Each好一点,这里只是顺便提供遍历集合的另一种用法。 Output.Show(Customers(i)) Next 示例二

Filter参数是不能省略的,如果希望无条件地返回值的集合,将Filter参数设置为\即可。 例如列出订单表中所有的客户名单: Dim Customers As List(Of String)

Customers = DataTables(\订单\).GetUniqueValues(\\客户\) For Each Customer As String In Customers Output.Show(Customer) Next

示例三

可以同时从多列提取不重复的值,此时返回的不是字符的集合,而是字符数组的集合。 例如从客户列和产品列提取不重复的值:

'定义数组集合的时候,要在类型后加上括号,表示这是一个数组集合。 Dim Arys As List(Of String())

Arys = DataTables(\订单\).GetUniqueValues(\\客户\产品\) '注意循环变量是字符型数组,所以类型是String(),而不是String For Each Ary As String() In Arys Output.Show(Ary(0) & \ & Ary(1)) Next

上面的代码是从客户和产品两列提取不重复的值,返回的不是一个字符集合,而是一个字符数组集合,每个数组包括两个元素,第一个元素是客户值,第二个元素是产品值。

GetComboListString

从指定的列中提取不重复的值,用符号\将这些值连接成一个字符串,并返回这个字符串。 此方法通常用于动态设置列表项目。 语法:

GetComboListString(ColumnName,Filter, Sort) ColumnName:列名称,从此列中提取不重复的值。

Filter: 可选参数,指定一个条件表达式,只返回符合此条件的值。

Sort: 可选参数,指定排序列,如果省略,则根据取值列排序,通常无需设置。

请参考表达式的运算符和函数 和 条件表达式 示例

Output.Show(DataTables(\订单\).GetComboListString(\产品\)) 也可以设置条件,例如从客户表中提取华北地区的客户名单: Dim s As String

s = DataTables(\客户\).GetComboListString(\客户名称\,\地区] = '华北'\) Output.Show(s)

Compute

根据条件统计表中数据。 语法:

Compute(Expression, Filter)

Expression: 要计算的表达式,使用聚合函数进行统计。

Filter: 可选参数,用于设置计算条件,请参考表达式的运算符和函数 和 条件表达式。 在执行以下示例之前,请打开CaseStudy目录下的示例文件\统计演示.Table\。 示例一

计算总的销售数量和金额: Dim Total As Integer Dim Amount As Double With DataTables(\订单\) Total = .Compute(\数量)\) Amount = .Compute(\金额)\) End With

Output.Show(\数量:\& Total) Output.Show(\金额:\& Amount) 示例二

计算产品PD01的销售数量: Dim Total As Long

Total = DataTables(\订单\).Compute(\数量)\, \产品 = 'PD01'\) Output.Show(Total) 示例三

计算每个客户的订购数量:

Dim dt As DataTable = DataTables(\订单\) Dim Total As Integer

Dim Customers As List(Of String)

Customers = dt.GetUniqueValues(\\客户\) For Each Customer As String In Customers

Total = dt.Compute(\数量)\, \客户] = '\ & Customer & \) Output.Show(Customer & \ & Total) Next

上述代码中,Filter参数分成了三部分,各部分用运算符&连接起来: \客户] = '\ & Customer & \

如果客户名称为CS01,那么三部分组合后,Filter参数就等于:

\客户] = 'CS01'\

通过代码动态合成条件表达式,是一种基本的技能,大家务必要掌握。 参考:GetUniqueValues

Find

在DataTable查找符合条件的行,如果找到的话,返回找到的行,否则返回Nothing。 如果有多个符合条件的行,默认返回第一个,也可以指定返回第几个符合条件的行。 语法:

Find(Filter,Sort,Index)

Filter: 条件表达式,请参考表达式的运算符和函数 和 条件表达式。 Sort: 可选参数,指定排序方式。

Index: 可选参数,指定返回第几个符合条件的行,0表示第一行。 示例一: Dim dr As DataRow

dr = DataTables(\产品\).Find(\产品编号 = '03'\) '找出编号为03的产品 With DataTables(\订单\)

dr = .Find(\产品 = 'PD01'\,\日期\) '找出第一次订购PD01产品的记录 dr = .Find(\产品 = 'PD01'\,\日期\,1) '找出第二次订购PD01产品的记录 End With 示例二:

有的时候,我们需要查找倒数第几行数据,例如最近一次订购某产品的记录。 可以参考下面的代码: Dim dr As DataRow With DataTables(\订单\)

dr = .Find(\产品 = 'PD01'\,\日期 Desc\) '找出最后一次订购PD01产品的记录 dr = .Find(\产品 = 'PD01'\,\日期 Desc\,1) '找出倒数第二次订购PD01产品的记录 End With

可以看到代码和原来几乎一样,唯一的变化是排序参数,被改为:日期 Desc

加上DESC使得日期按照降序排序,最后的日期排在最前面,我们所找出的第一条记录,就是最后一次订购产品PD01的记录。 示例三

通常应该在代码中判断是否找到了符合条件的行,然后再运行后续的代码。 例如要找出最近一次订购产品数量超过1000的订单,并显示订单的日期和客户: Dim dr As DataRow

dr = DataTables(\订单\).Find(\数量 > 1000\,\日期 Desc\) If dr IsNot Nothing Then '如果找到的话 Output.Show(\日期:\ & dr(\日期\)) Output.Show(\客户:\ & dr(\客户\)) End If

如果我们不加上判断,直接: Dim dr As DataRow

dr = DataTables(\订单\).Find(\数量 > 1000\,\日期 Desc\) Output.Show(\日期:\ & dr(\日期\)) Output.Show(\客户:\ & dr(\客户\))

一旦订单表并不存在订购数量超过1000的订单,那么Find方法返回Nothing,导致后续代码运行出错。

Find函数只能找出一条符合条件的行,如果要同时找出所有符合条件的行,可以使用Select方法。

Select

以集合的形式,返回所有符合指定条件的行。 语法:

Select(Filter) Select(Filter,Sort)

Filter: 条件表达式,请参考表达式的运算符和函数 和 条件表达式。 Sort: 可选参数,指定排序方式

我们经常需要对符合某一条件的记录,统一进行处理,此时Select方法就派上用场了。 示例一

例如,对于1999年1月4日订购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

示例二

再例如,希望列出1999年1月4日订购PD01的客户,按订购的数量排序: Dim drs As List(Of DataRow)

drs = DataTables(\订单\).Select(\产品] = 'PD01' And [日期]= #1/4/1999#\,\数量 DESC\) For Each dr As Datarow In drs Output.show(dr(\客户\)) Next

上面的代码将Sort参数设置为“数量 DESC”,这样返回的行不仅按数量排序,而且数量多的行排在前面。 示例三

Filter参数不能省略,如果希望返回所有行,将Filter参数设置为\即可。 例如希望按总分高低,依次显示所有学生的姓名:

For Each dr As DataRow In DataTables(\成绩表\).Select(\,\总分 DESC\) Output.Show(dr(\姓名\)) Next

DeleteFor

删除符合条件的行。 语法:

DeleteFor(Filter)

Filter: 一个表达式,用于指定删除条件,请参考表达式的运算符和函数 和 条件表达式 例如:

删除订单表中2007年2月1日以前的行,代码为:

DataTables(\订单\).DeleteFor(\日期] < #2/1/2007#\)

RemoveFor

移除符合条件的行。

所谓移除行,只是让用户再也看不到这些被移除的行,就像这些行从来没有被加载过一样;移除行从来都不会真正从文件中删除行,重新打开文件后,被移除的行将再次出现。

语法:

RemoveFor(Filter)

Filter: 指定移除条件。请参考表达式的运算符和函数 和 条件表达式。 例如:

DataTables(\订单\).RemoveFor(\产品] = 'PD01'\) ReplaceFor

找出符合条件的行,并将指定列的内容替换为指定值。 语法:

ReplaceFor(DataColName,Value,Filter) DataColName:替换的列 Value: 替换值

Filter: 替换条件,请参考表达式的运算符和函数 和 条件表达式。

例如将订单表中,订购数量大于600的订单的折扣设为0.15,只需简单的一行代码即可: DataTables(\订单\).ReplaceFor(\折扣\, 0.15, \数量] > 600\) 如果不用ReplaceFor,最精简的代码也是:

For Each dr As DataRow in DataTables(\订单\).Select(\数量] > 600\) dr(\折扣\) = 0.15 Next

RejectChanges

撤销自打开文件或最近一次保存以来,对该表做出的修改。 示例

撤销对表A的修改:

DataTables(\表A\).RejectChanges()

StopRedraw

我们对表做的任何变动,例如编辑数据、增加行、删除行、调整行高列宽,都会导致Table重新绘制,以便显示变动后的结果。

如果要对DataTable连续地进行大量的操作,为了避免相关Table(表)不停地闪烁,可以先执行StopRedraw方法禁止绘制表,操作完成后再执行ResumeRedraw方法重新绘制表。

StopRedraw方法会禁止绘制所有基于该DataTable的Table,直到执行ResumeRedraw方法恢复绘制。

例如我们要在订单表中增加500行,代码如下: With DataTables(\订单\) .StopRedraw

For i As Integer = 1 To 500 .AddNew() Next

.ResumeRedraw End With

注意最后一定要记得执行ResumeRedraw方法,否则表格不会再刷新。 如果你将代码修改为: With DataTables(\订单\) For i As Integer = 1 To 500 .AddNew() Next End With

你可以看到代码执行过程中会不停地闪烁,而且执行速度也比之前慢很多。

StopRedraw和ResumeRedraw必须配对执行,如果执行了两次StopRedraw,那么对应的就必须执行两次ResumeRedraw,才会恢复绘制Table。

上面的代码只是用于演示,实际上增加500行最简单的代码是: DataTables(\订单\).AddNew(500) 属性 属性名 Type Name Caption HasChanges AllowEdit AllowAddNew 说明 整数型,返回一个整数,表示DataTable的类型 字符型,返回DataTable的名称 字符型,返回DataTable的标题 逻辑型,判断DataTable的数据是否已经被修改 逻辑型,是否允许用户修改表中数据 逻辑型,是否允许用户增加行 AllowClipBoard AllowInitialize AutoAddNew AllowDelete AllowLockRow AllowUnlockRow AllowDragColumn AllowFreezeColumn AllowResizeColumn AllowResizeRow AllowResizeSingleRow EnterKeyActionDown TabKeyActionDown MultiRowHeader FillLoadTimeOut SourceType 逻辑型,是否允许复制粘贴数据。 逻辑型,是否允许初始化此表。 逻辑型,是否自动增加行 逻辑型,是否允许用户删除行 逻辑型,是否允许用户锁定行 逻辑型,是否允许用户取消锁定行 逻辑型,是否允许通过拖动列标题来调整列位置 逻辑型,是否允许通过鼠标拖动来调整冻结区 逻辑型,是否允许通过鼠标拖动来调整列宽 逻辑型,是否允许通过鼠标拖动来调整行高 逻辑型,是否允许单独调整某一行的高度 逻辑型,按回车键是否向下移到另一单元格 逻辑型,按Tab键是否向下移到另一单元格 逻辑型,是否启用多层表头。 整数型,设置加载数据时的超时时限,默认30秒,一般不需要设置此属性。 整数型,返回数据源的类型,0表示Access,1表示SQL Server,2表示Oracle。 方法 方法 AddNew Compute Find Select Save ReplaceFor DeleteFor RemoveFor RejectChanges AcceptChanges GetUniqueValues GetComboListString 说明 在DataTable中增加一行,并返回所增加的行 根据指定的条件计算指定的内容 在DataTable查找符合条件的行,如果找到的话,返回找到的行,否则返回Nothing 以集合的形式,返回所有符合指定条件的行 保存数据 找出符合条件的行,并将指定列的内容替换为指定值 删除符合条件的行 移除符合条件的行 撤销自打开文件或最近一次保存以来,对该表做出的修改。 接受所有修改结果,使得这些修改不被保存。 从指定列中,获取不重复的值,以集合的形式返回 从指定的列中提取不重复的值,用符号\将这些值连接成一个字符串,并返回这个字符串

本文来源:https://www.bwwdw.com/article/tyy3.html

Top