5.数据集组件中的字段
在 Delphi 的数据集组件中,属性 Fields 是 TField 类型对象的数组,是数据集的一部分,是不可见组件,代表的是数据集上的字段。字段对象的功能:
改变数据集中的字段值转换字段值的类型对用户输入的值进行有效性校验定义字段的显示或编辑方式根据数据集的 OnCalcFields事件计算字段的值5.1字段的访问
访问当前记录的字段:
使用数据集组件的属性 Fields 访问当前记录的某个字段,方式为:Fields[i]每个字段对象对应于数据库表中的一个字段,数据集中的所有字段存在于属性 Fields 数组中,索引 0 表示最左边的一列,即第一列。
通过索引号来访问 Fields 属性中的字段可以在 For 循环中对索引进行迭代,但在实际开发中,通过字段名来访问更加易读。
使用数据集组件的方法 FieldByName 按字段名来访问FieldByName('字段名')5.2字段的属性
显示属性Alignment - 字段值在组件内的对齐方式DisplayLabel - 显示在 TDBGrid 表头的字段名称DisplayName - 用于显示的字段名称DisplayText - 用于显示字段值的字符串DisplayWidth - 在 TDBGrid 中显示字段值的宽度,单位为字符数EditFormat - 指定数据的显示方式EditMask - 指定限制字符输入的掩码约束条件属性约束条件的设置是为了让输入的字段值合法,字段对象可以根据用户的自定义约束条件进行检查。
HasConstraints - 只读属性,判断是否使用约束条件对字段值进行合法性检查ImportedConstraint - 从数据字典或 SQL 服务器引入的约束条件CustomConstraint - 用户自定义的约束条件ConstraintErrorMessage - 设置当字段值不复合约束条件时显示的提示信息5.3字段的事件
字段的常用事件:
OnChange - 字段值发生改变时触发OnValidate - 对字段值进行有效性检查时触发OnGetText - 读取属性值 Text 时触发OnSetText - 设置属性值 Text 时触发5.4字段的方法
Assign - 将另一个 TField 对象的属性值赋值AssignValue - 为字段值赋值Clear - 清空字段值GetData - 获取字段最原始的值,未经过转化的数据SetData - 用最原始的值,未经过转化的数据设置字段值FocusControl - 使字段的第一个敏感组件获得输入焦点5.5固定字段
当把数据集组件(如 Table、Query 或者 StoredProc 等)放入窗体或者数据模块中并打开后,Delphi 就会为数据集中的每个字段创建一个 TField 对象,这些对象可以通过代码控制其属性,称之为动态字段。
对应地,固定字段时在窗体或数据模块设计时完成的。通过字段编辑器创建固定字段,在对象查看器中设置字段的属性。也可以通过字段编辑器增加计算字段。
固定字段对象会加入到窗体单元的 TForm 类定义中,并保存在应用程序中,如果数据库的表结构发生变化,它也会一直保留着。
动态字段与固定字段的比较:
动态字段对数据集的适应性强,但不容易控制其属性,也不能增加新的计算字段固定字段比较容易控制其属性,可以增加计算字段,但当表结构变化后,需要对固定字段的设置进行相应的调整在应用程序中,对于同一个数据集只能选择使用其中一种,不能两者同时使用。
固定字段的设计方法:
1.创建应用程序并在应用程序中创建数据模块,数据模块中添加 TADOConnection、TADOTable 组件,设置其属性连接到数据库上。
2.右击 ADOTable1 组件,选择 Fields Editor (字段编辑器)菜单,如下图所示:
3.在字段编辑器中右击弹出菜单,如下图所示:
4.选择 Add Fields ...,如下图所示:
所有字段全部显示,单击 OK 按钮。
5.查看数据模块单元中的代码,会发现增加了字段的定义,代码如下:
TDataModule2 = class(TDataModule) ADOConnection1: TADOConnection; DataSource1: TDataSource; ADOTable1: TADOTable; ADOTable1student_id: TWideStringField; ADOTable1name: TWideStringField; ADOTable1sex: TWideStringField; ADOTable1chinese: TBCDField; ADOTable1math: TBCDField; ADOTable1english: TBCDField;固定字段的访问相对于动态字段对象的访问比较简单,通过字段对象名称即可进行访问。如:
procedure TDataModule2.DataModuleCreate(Ser: TObject);begin ADOTable1student_id.DisplayLabel := '学号'; ADOTable1name.DisplayLabel := '姓名'; ADOTable1sex.DisplayLabel := '性别'; ADOTable1chinese.DisplayLabel := '语文'; ADOTable1math.DisplayLabel := '数学'; ADOTable1english.DisplayLabel := '英语'; ADOTable1student_id.DisplayWidth := 10;;5.6字段的数据类型
常用的字段对象的数据类型如下:
TBBLOB - 二进制数据对象TBooleanField - 布尔类型TCurrentyField - 货币型数据TDateField - 日期类型TFloatField - 实数类型TIntegerField - 整数类型TMemoField - 文本类型,最大 2GTStringField - 字符串类型,最大 8192BTTimeField - 时间类型TWordField - 0 ~ 65535 的整数TField 数据相关的属性:
Value - 字段值,按照不同的字段类型,字段值的数据类型也不同Text - 显示的字段值,数据类型为字符串IsNULL - 字段值是否为空AsBoolean - 将字段值转换为布尔类型AsDateTime - 将字段值转换为日期时间类型AsFloat - 将字段值转换为浮点类型AsInteger - 将字段值转换为整数类型AsString - 将字段值转换为字符串类型AsVariant - 将字段值转换为可变类型5.7数据库应用程序示例
数据准备:
create table d_students1 ( student_id varchar(64) primary key, name varchar(16), sex boolean, birthday date, department_id int4, total_score decimal(9,1));INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210001', '张三', true, '2000-05-06', 1, 520);INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210002', '李四', true, '2000-03-09', 1, 539);INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210003', '周五', false, '2001-09-10', 2, 528);INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210004', '赵六', true, '2000-08-28', 1, 517);INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210005', '姜七', false, '2000-07-06', 2, 547);INSERT INTO d_students1(student_id, "name", sex, birthday, department_id, total_score)VALUES('x-20210006', '贺八', true, '2000-11-01', 2, 533);数据模块设计界面如下图:
数据模块组件:
组件
属性
值
ADOConnection1
ConnectionString
Provider=MSDASQL.1;Persist Security Info=False;Data Source=demodb;
Connected
True
ADOTable1
Connection
ADOConnection1
TableName
d_students1
Active
True
DataSource1
DataSet
ADOTable1
窗体设计如下图:
窗体组件:
组件
属性
值
Panel1
Caption
''
Align
alTop
Label1
Caption
姓名
Edit1
Text
''
ReadOnly
True
Label2
Caption
总分
Edit2
Text
''
ReadOnly
True
DBNavigator1
DataSource
DataModule2.DataSource1
VisibleButtons
[nbFirst,nbPrior,nbNext,nbLast,nbPost]
Button1
Caption
开关数据集
DBGrid1
DataSource
DataModule2.DataSource1
Align
alClient
StatusBar1
Panels
单击右侧 ... 按钮,增加三个 Panels[0]、Panels[1]、Panels[2]
设计完成后,运行程序,未编写代码的情况下,运行结果如下图:
1.将 DBGrid 的标题修改为中文
在 数据集组件 ADOTable1 上添加全部字段,在数据模块上编写 OnCreate 事件,代码如下:
procedure TDataModule2.DataModuleCreate(Ser: TObject);begin ADOTable1student_id.DisplayLabel := '学号'; ADOTable1name.DisplayLabel := '姓名'; ADOTable1sex.DisplayLabel := '性别'; ADOTable1birthday.DisplayLabel := '生日'; ADOTable1department_id.DisplayLabel := '所在系ID'; ADOTable1total_score.DisplayLabel := '总分';;2.将 DBGrid 中 Sex 的值显示为 男 或 女
在对象观察器中选择 ADOTable1sex 组件,设置其 OnGetText 事件,代码如下:
procedure TDataModule2.ADOTable1sexGetText(Ser: TField; var Text: string; DisplayText: Boolean);begin if Ser.Value then Text := '男' else Text := '女';;由于同时需要进行录入数据的处理,所以设置其 OnSetText 事件,代码如下:
procedure TDataModule2.ADOTable1sexSetText(Ser: TField; const Text: string);begin if Text = '男' then Ser.Value := True else Ser.Value := False;;3.在窗体的 Edit1 和 Edit2 中显示当前记录的姓名和总分
在数据模块的 ADOTable1 上增加 AfterScroll 事件,代码如下:
procedure TDataModule2.ADOTable1AfterScroll(DataSet: TDataSet);begin Form1.Edit1.Text := ADOTable1name.Value; Form1.Edit2.Text := ADOTable1total_score.AsString;;由于数据可能会被修改,所以,在数据源的 DataChange 中也需要对编辑框的 Text 进行赋值,代码如下:
procedure TDataModule2.DataSource1DataChange(Ser: TObject; Field: TField);begin Form1.Edit1.Text := ADOTable1name.Value; Form1.Edit2.Text := ADOTable1total_score.AsString;;4.在状态上显示所有学生的总分和平均分
在窗体上的 DBGrid1 上设置其 DblClick 事件,代码如下:
procedure TForm1.DBGrid1DblClick(Ser: TObject);var index: Integer; sum, avg: real;begin with DataModule2 do begin ADOTable1.DisableControls; try ADOTable1.First; sum := 0; index := 0; while not ADOTable1.Eof do begin sum := sum + ADOTable1total_score.AsFloat; index := index + 1; ADOTable1.Next; ; avg := sum / index; StatusBar1.Panels[0].Text := '总分:' + floattostr(sum); StatusBar1.Panels[1].Text := '平均分:' + floattostr(avg); finally ADOTable1.EnableControls; ; ;;在上面的代码中,调用了数据集的 DisableControls 方法,其目的是防止在迭代的过程中对数据进行操作,在程序的最后调用 EnableControls 恢复对组件的控制。
4.在状态栏上显示数据集的当前状态
添加数据源的 StateChange 事件,代码如下:
procedure TDataModule2.DataSource1StateChange(Ser: TObject);var StatusString: String;begin case ADOTable1.State of dsBrowse: StatusString := '浏览'; dsEdit: StatusString := '编辑'; dsInsert: StatusString := '插入'; else StatusString := '其他'; ; Form1.StatusBar1.Panels[2].Text := StatusString;;5.单击开关数据集按钮时,如果数据集打开,则执行关闭操作,如果数据集关闭则执行打开。
代码如下:
procedure TForm1.Button1Click(Ser: TObject);begin with DataModule2 do if ADOTable1.Active then ADOTable1.Close else ADOTable1.Open;;6.当数据集关闭时,检查数据是否需要保存并提示
设置数据集的 BeforeClose 事件,代码如下:
procedure TDataModule2.ADOTable1BeforeClose(DataSet: TDataSet);begin if (ADOTable1.State in [dsEdit, dsInsert]) then case MessageDlg('保存修改的数据吗?', mtConfirmation, mbYesNoCancel, 0) of mrYes: ADOTable1.Post; mrNo: ADOTable1.Cancel; mrCancel: Abort; ;;
「10.Delphi数据库编程」5.数据集组件的字段
下一篇:返回列表