当前位置: 首页 > 文档资料 > Delphi 基础教程 >

第十五章 数据访问部件的应用及编程(三)

优质
小牛编辑
127浏览
2023-12-01
第十五章 数据访问部件的应用及编程(三)

15.6.1 字段部件

字段部件在应用程序中始终是不可见的部件。在程序运行过程中是如此,在程序设计阶段也是如此,但是它在应用中起着非常重要的作用,可以说它是所有数据浏览部件从数据库表中显示、编辑数据的基础。这是因为字段部件直接对应着数据库表中的字段,浏览和修改表中的数据必须要通过字段部件,同时字段部件所拥有的属性可以用来说明数据库表中对应的字段的数据类型、当前的字段值、显示格式、编辑格式等,字段部件的事件如OnValidate可以用来设定输入字段值时进行有效性检验。

数据库表的每一列在应用程序中都有其对应的一个字段部件,在缺省情况下,当TTable或TQuery的Active属性被置为False或调用close方法时,与表中各列对应的字段部件也随即消失,要想为应用程序创建永久性的字段部件,我们必须要在程序设计阶段使用字段编辑器(Fields Editor)来创建。使用字段编辑器创建永久性字段的好处是:我们在程序代码中利用永久性字段部件可以更加有效、方便、可靠地访问数据库表中记录的各字段值, 在任何时候我们都可以以同样的字段顺序、固定的字段显示表中的记录,即使数据库表的结构已发生了变化。当然如果在数据库表中与字段部件对应的字段已经不存在时,应用程序就不能正常地执行下去了,Delphi会弹出一个错误信息框,告诉用户表中的字段已经不存在了。

15.6.1.1 字段部件的属性及应用

字段部件具有很多的属性,通过设置字段部件有关的属性,可以控制字段对象在数据浏览部件中的显示方式、字段值能否被修改等。特别是对于用字段编辑器创建的永久性的字段部件,我们在程序设计阶段便可以在Object Inspector中方便地选取字段部件, 进行有关属性的设置。

字段部件的主要属性如表15.6所示,该表中列出的属性只是字段部件的部分属性,它主要用来控制字段对象的显示方式。

表15.6 字段部件的主要属性

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

属性名 功 能

───────────────────────────────

Alignment 说明字段值在数据浏览部件中显示时的对齐方式:

左对齐、右对齐、居中三种方式。

───────────────────────────────

Calculated 说明字段是否是计算字段,属性值为True时,该

字段是计算字段、字段值可以根据表中其它字段

的值计算得出。

───────────────────────────────

Currency 等于true时,以货币格式显示数值,等于False时,

不以货币格式显示数值型数据。

───────────────────────────────

DisplayFormat 用于说明字段值在数据浏览部件中的显示格式

───────────────────────────────

DisplayLabel 字段在网格(TDBGrid部件)中显示时,为字段指定

显示标题。

───────────────────────────────

DisplayNidth 字段在网格(TDBGrid部件)中显示时,为字段指定

显示宽度,单位是字符数。

───────────────────────────────

EditFormat 说明字段在数据浏览部件中的编辑输入格式

───────────────────────────────

EditMask 在进行字段值的编辑输入时,限定输入字段值的

过滤条件(即字段值的范围)。

───────────────────────────────

FieldName 该字段部件对应实际数据库表中的字段的名字

───────────────────────────────

Index 该字段部件在数据集所有字段部件中的顺序号

───────────────────────────────

MaxValue 说明可以为该字段输入最大的数值

───────────────────────────────

MinValue 说明可以为该字段输入最小的数值

───────────────────────────────

Name 字段部件的名字

───────────────────────────────

ReadOnly 等于true时,只能读取该字段的字段值,不能修改;

等于False时,可以对该字段的字段值进行读写。

───────────────────────────────

Size 说明字段的大小,单位是字符数

───────────────────────────────

Visible 为True时,该字段可以在TBDBGrid部件中显示;

为False时,该字段不能在TDBGrid部件中显示

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

表15.6中的属性并不是所有类型的字段部件都拥有的,如一个TStringField类型的字段部件是没有Currency、MaxValue、MinValue和DisplayFormat属性的,一个TFloatField类型的字段部件是没有Size属性的。

对于布尔型属性,在设计过程中的Object Inspector中双击该属性,该属性的值将会在True和False之间来回切换,其他属性需要用户输入属性值或从下拉式列表框中选取属性值。所有的属性都可以通过程序代码进行设置。大多数属性可以独立地设置,只有DisplayFormat,EditFormat和EditMask是相互联系的。在设置它们的属性值时一定要确保相互协调。

利用EditMask属性为字段设定编辑模式:

为字段部件设置一定的EditMask属性值,当编辑输入该字段的字段值时,用户只能根据EditMask设定的编辑模式进行编辑或输入字段值。在为EditMask属性设置属性值时可以用手动方式也可以用输入模式编辑器来完成,当为某字段部件设置EditMask属性时,双鼠标双击EditMask属性便可以打开输入模式编辑器(Input Mask Editor) 。例如在为Customer.DB表的Phone字段设定编辑模式时,首先在Object Inspector中选取与Phone字段对应的Table1Phone字段对象,然后双击EditMask属性,打开输入模式编辑器。

字段输入模式编辑器

在字段输入模式编辑中可以选择一种输入模式,而且在TestInput编辑框中输入字段值进行检验。

因为TStringField类型的字段部件没有DisplayFormat属性,但是可以把EditMask属性当DisplayFormat属性使用。

设定字段的显示和编辑格式:

Delphi本身为某些类型的字段对象提供了设定其显示和编辑格式的例程,并且为字段部件的DisplayFormat和EditFormat属性指定了缺省值,例如对于与浮点型数值字段对应的TFloatField类型的字段部件,而且该字段部件的Currency属性设置为True 时,字段值1234.56的显示格式为$1234.56,编辑格式是1234.56。表15.7是Delphi提供了设置字段显示和编辑格式的例程。

表15.7 字段格式例程

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

例 程 名 运用的字段对象

─────────────────────────────

FormatFloat TFloatField,TCurrencyField

FormatDateTime TDateField,TTimeField,TDateTimeField

FormatInteger TIntegerField,TSmallIntField,TWordField

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

上述这些用于设定日期时间类型、数值型以及货币型字段的显示和编辑格式的例程,都是按国际上通行格式来设定相应类型字段的格式的,用户可以自己设置字段部件的DisplayFormat和EditFormat属性,来设定适合自己使用的格式,还可以为有关字段对象的OnGetText和OnSetText事件编写代码来设定字段的显示和编辑格式。

15.6.1.2 字段部件的事件及应用

字段部件常需处理的事件如表15.8所示

表15.8 字段部件的事件

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

事件名 用 途

────────────────────────────

OnChange 当字段部件的字段值发生改变时,触发该事件

OnGetText 当字段部件获得字段值时,触发该事件

OnSetText 当字段部件被设置字段值时,触发该事件

OnValidata 当字值被修改或插入新的字段值时,对字段值

进行有效性检验时,触发该事件

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

用户想自己设定字段的显示和编辑格式时,可以编写OnGetText事件和OnSetText事件的处理过程,以达到设定字段的显示和编辑格式。

15.6.1.3 字段部件的类型转换函数及使用

字段部件具有一些内部函数用于转换字段值的类型,对于不同的字段类型,这些转换函数的作用是不一样的,表15.9概括了不同类型的字段及转换函数的作用。

表15.9 字段部件的转换函数

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

字段类型 AsString AsInteger AsFloat AsDatetime AsBoolean

────────────────────────────────────

TStringField 转换成 转换成整数 若能转换 日期 转换成布型

Stringg型 (若能转换) 则转换成 (若能转换)

────────────────────────────────────

TIntegerField

TSmallField 字符型 整数型 浮点型 不允许 不允许转换

TWordField

────────────────────────────────────

TFloatField

TCurrencyField 字符串型 舍入成整数 浮点型 不允许 不允许

TBCDField

────────────────────────────────────

TDateField

TDateTimeField 字符串 不允许 浮点数 日期型 不允许

TTimeField

────────────────────────────────────

TBooleanField 转换成Time 不允许 不允许 不允许 布尔型

或False

────────────────────────────────────

TBytesField

TVarBytesField 字符串 不允许 不允许 不允许 不允许

TBlobField

────────────────────────────────────

TMemoField 二进制 不允许 不允许 不允许 不允许

TGraphilField 字段

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

上述这些转换函数可以在任何与字段部件有关的表达式中使用,只要是表15.9中允许进行转换的数据类型,这些转换函数其实是当做字段部件的属性来使用的,它们可以出现在赋值语句的两边。例如下面的程序代码是将字段部件TableMyField的字段值转变成字符串类型的数据,并将它赋给编辑框Edit1的Text属性:

Edit1.Text := TableMyField.AsString;

而下面的代码是进行相反的操作,它将编辑框部件Edit1的Text属性值以字符串的形式赋给字段TableMyField,TableMyField通过AsString接受字符串并将其转变成自身的数据类型。

TableMyField.AsString :=Edit1.Text;

15.6.1.4 字段部件的访问

字段部件对应着数据库表中实际的字段,用户要读写数据库表中的字段值其实是通过访问相应的字段部件进行的。在前面的章节中我们介绍过在Delphi的数据库应用程序中有两类字段部件:一类是利用字段编辑器创建的永久性字段部件;另一类是随着数据集部件被激活(被打开)而动态生成的字段部件。对于永久性字段部件的访问可以直接调用使用字段部件的名字进行。假设我们在设计阶段利用字段编辑器创建了对应于Customer.DB表中Company字段的字段部件Table1Company,下面的代码访问Company字段的字段值,并将该字段值显示在编辑框部件Edit1中。

Edit1.Text := Table1Company.Value;

因为company字段是字符串类型的数据,它与Edit1中的数据类型相匹配的,因此可以直接使用字段部件的Value属性读取字段值。如果两个变量的类型不匹配,则要使用表15.9中的转换函数进行字段值的读取。例如:要读取Customer.DB表中的CustNo字段的值并将它显示在编辑模框Edit1中,假设我们已用字段编辑器(Fields Editor)创建了CustNo相应的字段部件,Table1CustNo,则程序代码如下:

Edit1.Text := Table1CustNo.AsString;

访问动态生成的字段部件相对要困难一些,因为动态生成的字段部件是没有自己的名字的,我们必须利用特殊的手段获得数据库表中各字段对应的字段部件,然后对字段进行访问。一般采用的方法有两种:

使用数据集部件的Fields属性

使用数据集部件的FieldByName方法

1. 使用数据集部件的Fields属性访问数据库表中各字段

数据集部件的Fields属性是与数据集部件相连的数据库表中各个字段对应的动态字段部件的名字列表,因此我们可以通过Fields属性的下标(即索引号)来访问各字段部件,从而达到访问数据库表中的各个字段,索引号从0开始,也就是说数据库表中第一个字段对应着Fields列表的第一行即0索引,第二个字段对应的Fields的索引号为1,以此类推。下面的例子是访问Customer.DB表中的第一个字段并在编辑框Edit1中显示其字段值。假设Table1与数据库表Customer.DB相连。

Edit1.Text := Table1.Fields[0].AsString;

下面的代码是将编辑框Edit1中的字符值赋给Customer.DB表中当前记录的第一个字段,以实现修改Customer.DB表中的字段值。

Table1.Fields[0].AsString := Edit1.Text;

2.使用数据集部件的FieldByName方法访问字段部件

在数据集部件所拥有的方法中,有一个FieldByName方法,它是专门用于访问数据集部件中动态生成的字段部件的,调用FieldByName方法时,必须要把数据库表中的字段名作为参数传给FieldByName,调用该方法后便可以得到该字段所对应的字段部件,这样通过字段部件我们便可以读写表中相应的字段值了,用这种方法访问字段部件时,必须要知道数据库表中各个字段的名字,否则是没有办法调用该方法的。还是基于上面的假设。下面是访问Customer.DB表中的CustNo字段的程序代码:

Edit1.Text := Table1.FieldByName('CustNo').AsString;

Table1.FieldByName('CustNo').AsString := Edit1.Text;

在使用这两种方法访问动态生成的字段部件时,可以使用表15.9中的转换函数,在变量和字段值之间进行数据类型的转换。

15.6.2 字段编辑器的使用

字段编辑器(Fields Editor)主要是用于创建永久性的字段部件。在前面的内容中我们知道,当TTable或TQuery部件与数据库表相连接时,且TTable或TQuery部件被激活时(Active属性被设置成True或调用Open方法),Delphi便动态地为表中各字段创建相应的字段部件,字段部件中包含着相应字段的很多信息如字段值、字段值的显示、编辑格式等,有时我们在应用程序中为了更加方便、可靠地访问数据库表中各个字段,需要创建永久性的字段部件,这时我们必须要借助于字段编辑器来实现我们的设想。字段编辑器的主要功能如下:

创建永久性的字段部件

修改永久性字段的显示属性,如显示格式、显示宽度等

删除永久性的字段部件

增加新的永久性的字段部件

定义计算字段(不对应数据库表中实际的字段,字段值根据表中其他字段的值计算得出)

15.6.2.1 打开字段编辑器

为TTable和TQuery部件打开字段编辑有两种方法:

用鼠标左键双击TTable或TQuery部件

选择TTable部件或TQuery部件,然后单击鼠标右键,然后从弹出式菜单中选择 Fields Editor

字段编辑器Fields Editor被打开以后,窗体的名字和数据集部件的名字会显示在窗口的标题上。

字段编辑器Fields itor中的Fields列表框是用于显示已经创建的永久性字段部件的名字的。字段编辑器Fields Editor第一次被打开时, 该列表框是空的,因为在此之前的字段部件都是动态生成的,只要Fields列表框中有字段部件,那么与数据集部件相连的数据浏览部件中只显示Fields中列出的字段的字段值,在Fields列表框中,可以通过拖放字段部件的名字来改变相应的字段值在数据浏览部件中的显示顺序,如在TDBGrid部件中根据各字段在Fields列表框中的顺序显示各字段的值。

在字段编辑器Fields Editor窗体上面的导航按钮是用来移动TTable或TQuery部件中的记录指针的,使用导航按钮可以将记录指针向前、向后移动,也可以移到第一条记录处或最后一条记录处。

字段编辑器中的弹出式菜单

15.6.2.2 增加字段部件

字段编辑器Fields Editor中的Add Fields菜单项用于向数据集部件中增加字段部件的,单击Add Fields菜单项时便会打开增加字段部件对话框,如图15.9所示。Available Fields列表框中显示出数据集部件TTable或TQuery中当前可以用于创建永久字段部件的全部的字段,也就是说Available Fields列表框中显示字段是数据库表中实际存在的字段,而且还没有为这些字段创建相应的永久性的字段部件,在缺省状态下所有的字段都被选择用于创建相应的永久性的字段部件,用鼠标单击其中的字段名可以有选择地创建其相应的永久性的字段部件,选择好有关的字段名之后,单击OK按钮便可以创建永久性的字段部件。

字段编辑器的增加字段部件对话框

15.6.2.3 删除字段部件

用字段编辑器Fields Editor为数据集部件创建好的字段部件都会显示在字段编辑器的Fields列表框中,如果用户认为其中的一些字段部件不合适或不再需要时,可以单击这些不需要的字段部件,然后单击鼠标右键弹出一佣弹出式菜单,从弹出式菜单中选择Delete菜单项,便可删除相应的字段部件,如果在弹出式菜单中单击Select All菜单项,然后选择Delete菜单项,这样会删除已创建好的所有的字段部件。某一个字段部件被删除以后,通过单击Add Fields菜单项可以重新创建,只是先前为该字段部件设定的一些属性将不复存在。

 15.6.2.4 定义新的字段部件

字段编辑器Fields Editor中的弹出式菜单中New Fields菜单项是用来为数据集部件TTable或TQuery创建用于显示目的的新的字段部件,我们可以用它来为数据库表中实际存在的字段创建新的字段部件(如改变字段的数据类型,使它的字段值被显示时不再需有关的类型转换),但是我们使用New Fields菜单项创建新的字段部件主要是创建计算字段。计算字段并不与数据库表中实际存在的字段对应,它的字段值是根据表中其它的字段值计算而来的,具体的计算表达式由用户为TTable部件或TQuery部件的OnCalCFields事件编写程序代码时决定。

定义(创建)计算字段的过程如下:

1.单击字段编辑器中的New Fields菜单项,定义字段对话框如图15.11所示。

2.在FieldName编辑框中输入新字段部件的名字,或者从下拉式列表框中选择一个已 存在的字段部件的名字。

3.在FieldType列表框中为新字段部件选择一个字段类型。

4.单击Calculated检查框,确认定义的新字段部件是计算字段。

5.单击ok按钮,创建上述定义的计算字段部件,此时该字段部件的名字会自动地加入 到字段编辑中的Fields列表框中。

创建新的计算字段

新的计算字段创建好了之后,它是没有任何字段值的,我们必须要编写相应的程序代码,根据数据库表中实际存在的字段的字段值为计算字段的宝定义字段值,我们为计算字段所在数据集部件的OnCalcFields事件编写代码来为计算字段赋值,其步骤如下:

1.选择数据集部件TTable或TQuery

2.单击数据集部件的事件页

3.双击OnCalcFields事件为TTable或TQuery部件编写事件处理过程

 15.7 TReport部件及其应用

在一般的数据库应用程序中都包含着为最终用户提供输出报表的功能,使用Delphi开发数据库应用程序时,可以使用一个叫TReport的部件来执行报表功能的,报表的具体格式和内容是由Delphi提供的一个专用报表生成工具ReprotSmith创建的,它报表的具体格式和内容生成一个报表文件,然后为TReport部件设置相应的属性参数,由TReport部件执行报表功能。

我们可以在设计阶段双击TReport部件,调用ReportSimith工具或者在Delphi程序组内双击ReportSmith图标来调用ReportSmith工具来创建一个报表文件,具体的操作步骤和设计方法请参看ReportSimth工具的使用说明。

我们在使用TReport部件执行报表功能时,要设置TReport部件的一些的一些属性,这些属性是:

ReportName属性:说明报表文件的名字,就是用ReportSmith创建的报表文件。

ReportDir属性:说明报表文件所在的途径名。

PreView属性:这是一个布尔型属性。若它的值为True,那么在执行报表功能时,只是在屏幕上显示报表;若它的值为False,则报表内容将在缺省的打印机打印出来。

AutoUnload属性:布尔型属性,它的值为True时,在执行完一个报表功能后,自动地从内存中卸出ReportSmith工具;它的值为False时,在运行完一个报表功能后,不从内存中卸出ReportSmith工具。一般情况下,如果应用程序只有一个报表或者只有较少的报表要输出时,应设置AutoUnload属性为True,如果应用程序一次要输出多个报表,那么要应设置AutoUnload属性为False。

InitialValues属性:这是一个字符串类型的属性,它是说明报表文件中使用的变量,每一条说明一个变量。如:

ReportVAR := Value;

要详细了解创建和使用报表变量的过程请参看创建报表一节。

TReport部件要真正执行报表功能以输出一个报表需要调用Run方法。如下所示:

Report1.Run;

TReport部件所具有的重要方法如表15.10所示。

表15.10 TReport部件的方法

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

方法 功 能

────────────────────────────

Run 执行报表功能,输出报表

RunMacro 发送一个宏命令给Reportimith工具

Connect 预先连接报表文件和数据库,在输出报表时不

需要登录到数据库

SetVariable 改变说明的报表变量

ReCalcReport 当报表变量改变以后,重新输出报表

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

还有一些其他的数据访问部件如TBatchMove部件, 它主要用在两个数据库表之间移动或拷贝帆数据记录,具体的使用请参看本地SQL服务器的使用。

15.8 应用举例:多个窗体显示同一个数据库表

在应用当中,我们常常需要以不同的视图显示同一个数据库表中的内容,例如要在两窗体中同时显示一个数据库表中一个记录的不同字段时,我们必须要想办法使两个窗体中的数据浏览部件同步地显示数据库表中的同一条记录的不同字段的值。要想做到以不同的视图显示同一个数据库表中的记录,下面两条规则是很重要的:

多个TDataSource部件能够同时访问同一个数据集部件

● 在多个窗体中显示同一个表时,必须为每个窗体设置一个TDataSource部件,只须 为其中的一个窗体设置一个TTable部件

例如,如果想在窗体Form1和Form2中同时显示一个数据库表的记录,最简单可行的办法是:为Form1和Form2各设置一个TDataSource部件叫DataSource1、DataSource2,并在Form1中设置一个TTable部件Table1,连接Form1中的Datasource1和Table1,在程序运行过程中设置Form2中的DataSource2的DataSet属性为Form1中的Table1,代码如下:

Format2.DataSource1.Dataset := Form1.Table1;

这样,当Table1被打开时,两个窗体中便可以同步地显示数据库表中的同一条记录了。

一个名叫TWOForms.DPR的例子在C:\Delphi\DEMos\DB\TwoForms中(如果Delphi安装在其它的磁盘驱动器中,从相应的磁盘驱动器中可以找到该例子),它演示了在两个窗体中显示同一个数据库表的记录。应用程序在第一个窗体中打开Contry.DB表,并在窗体中显示Name、Captial和Continent字段,在第二个窗体中显示Area和Population字段,在第一个窗体中有一个按钮用于打开第二个窗体,两个窗体中都有TDBNavigator部件,用于记录的导航。