delphi安卓开发教程(DELPHI基础教程:Delphi开发数据库应用程序概述(一)[4])
![delphi安卓开发教程(DELPHI基础教程:Delphi开发数据库应用程序概述(一)[4])](/static/images/bgimages/aperitif-2027177_1920.jpg)
本文目录
- DELPHI基础教程:Delphi开发数据库应用程序概述(一)[4]
- DELPHI基础教程:开发Delphi对象式数据管理功能(一)[1]
- DELPHI基础教程:开发Delphi对象式数据管理功能(二)[4]
- 如何在DelphiXE7下写一个AndroidAPP
- DELPHI基础教程:数据访问部件的应用及编程(三)[4]
- DELPHI基础教程:开发Delphi对象式数据管理功能(五)[1]
- DELPHI基础教程:Delphi开发数据库应用程序概述(一)[3]
- delphi10.4开发的程序如何在安卓12上运行
- DELPHI基础教程:开发Delphi对象式数据管理功能(四)[2]
DELPHI基础教程:Delphi开发数据库应用程序概述(一)[4]
值得指出的是在绝大多数数据库应用中 一般都是使用数据集部件TTable TQuery或TStoredProc与磁盘上的数据库进行连接 用TDataSource部件连接数据控制部件和数据集部件 当然用户也可以自定义数据集部件 用于数据库应用当中 TTable TQuery 和TStoredProc部件中都包含一个不可见的TField类型的对象Fields Fields是一个串列表 它对应于数据库表或一个查询结果的列或字段 Fields对象是伴随着TTable TQuery 和TStoredproc部件的活动状态动态地建立的 当数据库表被关闭时 Fields 对象也随之消失 它在程序设计和程序运行过程中都是不可见的
当然也可以利用Fields Editor建立永久性的Fields对象供Delphi应用程序使用 我们将在后面的内容中详细阐述
TTable部件
利用TTable部件程序设计人员甚至可以不需要编写任何程序便可对数据库进行访问 在一个应用程序窗体中放置一个TTable部件的过程如下
在部件选择板上选择Data Access页
单击Table图标
在窗体内单击鼠标 获得一个TTable部件
为TTable部件设置有关的属性
DatabaseName属性指定要访问的数据库所在的路径名 路径名可以用别名来表示
TableName属性指定要访问数据库中具体的数据库表
Active属性设置为True时 表示打开要访问的数据库表 设置为False时 暂时不打开要访问的数据库表
缺省情况下 TTtable部件中包含了要访问的数据库表中所有的字段和记录 用鼠标双击TTable图标时 会出现一个字段器(Fields Editor) 使用Fields Editor可以对TTable部件中包含的数据库表中的字段的显示格式等属性进行 具体可以控制
● 建立一个永久性的字段列表 包括字段的顺序 字段的类型等 即使磁盘上实际的数据库表的表结构发生了改变 我们建立的这个永久性的字段列表也不会发生改变
● 为每个字段指定一个便于阅读和使用的名字
● 指定字段显示的顺序
● 为每个字段指定一个用于显示的字符串
● 为字段增加合法性检验
● 为了显示的需要还可以建立新的字段(如可计算的字段)具体的使用方法见后面的内容
TQuery部件
TQuery部件是我们使用SQL语言开发数据库应用程序的有力工具 因为使用SQL语言 我们可以非常方便灵活地对一个或多个数据库表中的记录进行访问 所以利用TQuery我们可以查询本地的数据库如Pà?aradox和dBASE数据库系统中的数据 我们还可以使用TQuery部件对一个远地的数据库SQL服务器进行访问 建立Client/Server模式的应用程序
在一个应用程序窗体中放置一个TQuery部件的过程如下
在部件选择板上选择Data Access页
单击Query图标
在窗体内单击鼠标 获得一个TQuery部件
为TQuery部件设置有关的属性
DatabaseName属性指定将要访问的数据库的路径名
SQL属性指定对数据库表进行访问SQL语句 它可以是一条查询语句也可以是一条修改语句或插入语句等 在对象浏览器上 单击SQL属性时 会打开一个字符串器供程序设计者输入SQL语句
在这里要注意在TQuery部件中 不是用TableName 属性来指定要访问的数据库中的数据库表 而是在SQL属性中 通过SQL语句来指定将要访问的数据库表
TDataSouece部件
TDataSource部件是连接数据集部件TTable TQuery TStoredProc 和数据控制部件TDBGrid TDBEdit等的桥梁 TTable TQuery TStoredProc部件通过BDE可以实现与磁盘上的数据库连接即访问 但它们本身不能显示数据库中的数据信息 而数据控制部件如TDBGrid TDBEdit等能够提供可视化的界面 显示数据库中的数据信息 但它们不具备访问磁盘数据库的能力 正是TDataSource将这两者有机地结合起来 使得用户才能交互地对数据库中的数据信息进行查询 修改 插入 删除等操作
在应用程序窗体中放置TDataSource部件的过程如下
在部件选择板上选择Data Access页
单击DataSource图标
在窗体内单击鼠标 获得一个TDataSource部件
为TDataSource部件设置有关的属性
Dataset属性指定一个数据集部件 可以是TTable TQuery或TStoredProc部件的名字
返回目录 DELPHI基础教程
推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLE G数据库开发优化指南
Java程序性能优化 让你的Java程序更快 更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
lishixinzhi/Article/program/Delphi/201311/25181DELPHI基础教程:开发Delphi对象式数据管理功能(一)[1]
面向对象技术是九十年代的主流技术 各类应用软件如果以面向对象的方法构造并且渗透面向对象的风格将使软件具有更高的品质 在面向对象程序设计中 对象式数据管理占有很重要的地位 在Delphi中 对对象式数据管理的支持方式是其一大特色
Delphi是一个面向对象的可视化设计与面向对象的语言相结合的集成开发环境 Delphi的核心是部件 部件是对象的一种 Delphi应用程序完全是由部件来构造的 因此开发高性能的Delphi应用程序必然会涉及对象式数据管理技术
对象式数据管理包括两方面的内容
● 用对象来管理数据
● 对各类数据对象(包括对象和部件)的管理
Delphi在这两方面都做的相当出色 在Delphi的早期版本Turbo Pascal 中就曾有流(Stream) 群(Collection)和资源(Resource)等专门用于对象式数据管理的类 在Delphi中 这些功能得到了大大的加强 Delphi将对象式数据管理类归结为Stream对象(Stream)和Filer对象(Filer) 并将它们应用于可视部件类库(VCL)的方方面面 它们不仅提供了在内存 外存和Windows资源中管理对象的功能 还提供了在数据库BLOB字段中对象的功能
在本章中将介绍Stream对象和Filer对象的实现原理 应用方法以及在超媒体系统中的应用 这对于运用Delphi 开发高级应用是很重要的
流式对象的实现原理和应用
Stream对象 又称流式对象 是TStream THandleStream TFileStream TMemoryStream TResourceStream和TBlobStream等的统称 它们分别代表了在各种媒介上存储数据的能力 它们将各种数据类型(包括对象和部件) 在内存 外存和数据库字段中的管理操作抽象为对象方法 并且充分利用了面向对象技术的优点 应用程序可以相当容易地在各种Stream对象中拷贝数据
下面介绍各种对象的数据和方法及使用方法
TStream对象
TStream对象是能在各种媒介中存储二进制数据的对象的抽象对象 从TStream 对象继承的对象用于在内存 Windows资源文件 磁盘文件和数据库字段等媒介中存储数据
TStream中定义了两个属性 Size和Position 它们分别以字节为单位表示的流的大小和当前指针位置 TStream中定义的方法用于在各种流中读 写和相互拷贝二进制数据 因为所有的Stream对象都是从TStream中继承来的 所以在TStream中定义的域和方法都能被Stream对象调用和访问 此外 又由于面向对象技术的动态联编功能 TStream为各种流的应用提供了统一的接口 简化了流的使用 不同Stream对象是抽象了对不同存储媒介的数据上的操作 因此 TStream的需方法为在不同媒介间的数据拷贝提供了最简捷的手段
TStream的属性和方法
Position属性
声明
property Position: Longint;Position属性指明流中读写的当前偏移量
Size属性
声明
property Size: Longint;Size属性指明了以字节为单位的流的的大小 它是只读的
CopyFrom方法
声明
function CopyFrom(Source: TStream; Count: Longint) Longint;CopyFrom从Source所指定的流中拷贝Count个字节到当前流中 并将指针从当前位置移动Count个字节数 函数返回值是实际拷贝的字节数
Read方法
声明
function Read(var Buffer; Count: Longint) Longint; virtual; abstract;Read方法从当前流中的当前位置起将Count个字节的内容复制到Buffer中 并把当前指针向后移动Count个字节数 函数返回值是实际读的字节数 如果返回值小于Count 这意味着读操作在读满所需字节数前指针已经到达了流的尾部
Read方法是抽象方法 每个后继Stream对象都要根据自己特有的有关特定存储媒介的读操作覆盖该方法 而且流的所有其它的读数据的方法(如 ReadBuffer ReadComponent等)在完成实际的读操作时都调用了Read方法 面向对象的动态联编的优点就体现在这儿 因为后继Stream对象只需覆盖Read方法 而其它读操作(如ReadBuffer ReadComponent等)都不需要重新定义 而且TStream还提供了统一的接口
ReadBuffer方法
声明
procedure ReadBuffer(var Buffer; Count: Longint)ReadBuffer方法从流中将Count个字节复制到Buffer 中 并将流的当前指针向后移动Count个字节 如读操作超过流的尾部 ReadBuffer方法引起EReadError异常事件
ReadComponent方法
声明
function ReadComponent(Instance: TComponent) TComponent;ReadComponent方法从当前流中读取由Instance所指定的部件 函数返回所读的部件 ReadComponent在读Instance及其拥有的所有对象时创建了一个Reader对象并调用它的ReadRootComponent方法
如果Instance为nil ReadComponent的方法基于流中描述的部件类型信息创建部件 并返回新创建的部件
ReadComponentRes方法
声明
function ReadComponentRes(Instance: TComponent) TComponent;ReadComponentRes方法从流中读取Instance指定的部件 但是流的当前位置必须是由WriteComponentRes方法所写入的部件的位置
ReadComponentRes 首先调用ReadResHeader方法从流中读取资源头 然后调用ReadComponent方法读取Instance 如果流的当前位置不包含一个资源头 ReadResHeader将引发一个EInvalidImage异常事件 在Classes库单元中也包含一个名为ReadComponentRes的函数 该函数执行相同的操作 只不过它基于应用程序包含的资源建立自己的流
ReadResHeader方法
声明
procedure ReadResHeader;ReadResHeader方法从流的当前位置读取Windows资源文件头 并将流的当前位置指针移到该文件头的尾部 如果流不包含一个有效的资源文件头 ReadResHeader将引发一个EInvalidImage异常事件
流的ReadComponentRes方法在从资源文件中读取部件之前 会自动调用ReadResHeader方法 因此 通常程序员通常不需要自己调用它
Seek方法
声明
function Seek(Offset: Longint; Origin: Word) Longint; virtual; abstract;Seek方法将流的当前指针移动Offset个字节 字节移动的起点由Origin指定 如果Offset是负数 Seek方法将从所描述的起点往流的头部移动 下表中列出了Origin的不同取值和它们的含义
表 函数Seek的参数的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
常量 值 Seek的起点 Offset的取值
─────────────────────────────────
SoFromBeginning 流的开头 正 数
SoFromCurrent 流的当前位置 正数或负数
SoFromEnd 流的结尾 负 数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Write方法
在Delphi对象式管理的对象中有两类对象的方法都有称为Write的 Stream对象和Filer对象 Stream对象的Write方法将数据写进流中 Filer对象通过相关的流传递数据 在后文中会介绍这类方法
Stream对象的Write方法声明如下
function Write(const Buffer; Count: Longint) Longint; virtual; abstract;
Write方法将Buffer中的Count个字节写入流中 并将当前位置指针向流的尾部移动Count个字节 函数返回写入的字节数
TStream的Write方法是抽象的 每个继承的Stream对象都要通过覆盖该方法来提供向特定存储媒介(内存 磁盘文件等)写数据的特定方法 流的其它所有写数据的方法(如WriteBuffer WriteComponent)都调用Write担当实际的写操作
WriteBuffer方法
声明
procedure WriteBuffer(const Buffer; Count: Longint)WriteBuffer的功能与Write相似 WriteBuffer方法调用Write来执行实际的写操作 如果流没能写所有字节 WriteBuffer会触发一个EWriteError异常事件
WriteComponent方法
在Stream对象和Filer对象都有被称为WriteComponent的方法 Stream对象的WriteComponent方法将Instance所指定的部件和它所包含的所有部件都写入流中 Writer对象的WriteComponent将指定部件的属性值写入Writer对象的流中
lishixinzhi/Article/program/Delphi/201311/25104DELPHI基础教程:开发Delphi对象式数据管理功能(二)[4]
Truncate方法
该方法是通过调用BDE API函数实现的 其实现如下
procedure TBlobStream Truncate;
begin
if FOpened then
begin
Check(DbiTruncateBlob(FDataSet Handle FRecord FFieldNo FPosition))
FModified := True;
end;
end;
该方法从BLOB流的当前位置起删除所有数据 并设置修改标志FModified为True 在Delphi VCL中许多部件特别是数据库应用方面的部件都用BDE API函数完成对数据库的访问 如Data Access和Data Control部件 各种数据库部件都是BDE API函数外层的包装简化了对数据库的访问操作 BDE API中还提供了避开BDE配置工具在程序中直接处理Alias(建立 修改 删除等)的函数支持 这也是部件所没有提供的 在Delphi数据库应用安装程序中 这些Alias操作函数无疑是相当重要的 有关BDE API函数的详细介绍 可阅读Delphi Client/Server Suite所带的BDE API 帮助文件
读写对象的实现原理和应用
读写对象(Filer)包括TFiler对象 TReader对象和riter对象 TFiler对象是文件读写的基础对象 在应用程序中使用的主要是TReader和riter TReader和riter对象都直接从TFiler对象继承 TFiler对象定义了Filer对象的基本属性和方法
Filer对象主要完成两大功能
● 存取窗体文件和窗体文件中的部件
● 提供数据缓冲 加快数据读写操作
TFiler对象
TFiler对象是TReader和riter的抽象类 定义了用于部件存储的基本属性和方法 它定义了Root属性 Root指明了所读或写的部件的根对象 它的Create方法将Stream对象作为传入参数以建立与Stream对象的联系 Filer对象的具体读写操作都是由Stream对象完成 因此 只要是Stream对象所能访问的媒介都能由Filer对象存取部件 TFiler 对象还提供了两个定义属性的方法 DefineProperty和DefineBinaryProperty 这两个方法使对象能读写不在部件published部分定义的属性
因为Filer对象主要用于存取Delphi的窗体文件和窗体文件中的部件 所以要清楚地理解Filer对象就要清楚Delphi 窗体文件(DFM文件)的结构
DFM文件是用于Delphi存储窗体的 窗体是Delphi可视化程序设计的核心 窗体对应Delphi应用程序中的窗口 窗体中的可视部件对应窗口中的界面元素 非可视部件如TTable和TOpenDialog 对应Delphi应用程序的某项功能 Delphi应用程序的设计实际上是以窗体的设计为中心 因此 DFM文件在Delphi应用设计中也占很重要的位置 窗体中的所有元素包括窗体自身的属性都包含在DFM文件中
在Delphi应用程序窗口 界面元素是按拥有关系相互联系的 因此树状结构是最自然的表达形式 相应地 窗体中的部件也是按树状结构组织 对应在DFM文件中 也要表达这种关系 DFM文件在物理上 是以二进制方式存储的 在逻辑上则是以树状结构安排各部件的关系 Delphi窗口支持以文本方式显示DFM文件 从该文本中可以看清窗体的树状结构 下面是DFM文件的文本显示
Object Form : TForm
Left =
Top =
ActiveControl = DBIMage
…
Object Panell: TPanel
Left =
…
Object DBLabel : TDBText
…
end
Object DBImage : TDBImage
…
end
end
Object Panel : TPanel
Left =
…
Object Label : TLable
…
end
end
Object Panel : TPanel
Left =
…
Object DBLabel : TDBText
…
end
end
end
关于DFM文件中存储属性值的规则 请参见自定义部件开发这一章
对照TFiler对象的属性 Root属性就表示部件树的根──窗体 Filer对象的许多方法都是读从根起始的树中所有的部件 Ancestor属性表示根的祖先对象 IgnoreChildren属性则是读部件时忽略根的子结点
下面介绍Filer对象的属性和方法
返回目录 DELPHI基础教程
推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLE G数据库开发优化指南
Java程序性能优化 让你的Java程序更快 更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
lishixinzhi/Article/program/Delphi/201311/25103如何在DelphiXE7下写一个AndroidAPP
开发环境完全不一样
开发语言也不一样,delphi用的是pasic语言,vb用的是basic语言。
Delphi,是Windows平台下著名的快速应用程序开发工具(RapidApplicationDevelopment,简称RAD)。它的前身,即是DOS时代盛行一时的“Pascal”,最早的版本由美国Borland(宝兰)公司于1995年开发。主创者为AndersHejlsberg。经过数年的发展,此产品也转移至Embarcadero公司旗下。Delphi是一个集成开发环境(IDE),使用的核心是由传统Pascal语言发展而来的ObjectPascal,以图形用户界面为开发环境,透过IDE、VCL工具与编译器,配合连结数据库的功能,构成一个以面向对象程序设计为中心的应用程序开发工具。
VisualBasic是一种由公司开发的结构化的、模块化的、面向对象的、包含协助开发环境的事件驱动为机制的可视化程序设计语言。从任何标准来说,VB都是世界上使用人数最多的语言——不管是盛赞VB的开发者还是抱怨VB的开发者的数量。它源自于BASIC编程语言。VB拥有图形用户界面(GUI)和快速应用程序开发(RAD)系统,可以轻易的使用DAO、RDO、ADO连接数据库,或者轻松的创建ActiveX控件。程序员可以轻松的使用VB提供的组件快速建立一个应用程序。
DELPHI基础教程:数据访问部件的应用及编程(三)[4]
增加字段部件
字段器Fields Editor中的Add Fields菜单项用于向数据集部件中增加字段部件的 单击Add Fields菜单项时便会打开增加字段部件对话框 如图 所示 Available Fields列表框中显示出数据集部件TTable或TQuery中当前可以用于创建永久字段部件的全部的字段 也就是说Available Fields列表框中显示字段是数据库表中实际存在的字段 而且还没有为这些字段创建相应的永久性的字段部件 在缺省状态下所有的字段都被选择用于创建相应的永久性的字段部件 用鼠标单击其中的字段名可以有选择地创建其相应的永久性的字段部件 选择好有关的字段名之后 单击OK按钮便可以创建永久性的字段部件
字段器的增加字段部件对话框
删除字段部件
用字段器Fields Editor为数据集部件创建好的字段部件都会显示在字段器的Fields列表框中 如果用户认为其中的一些字段部件不合适或不再需要时 可以单击这些不需要的字段部件 然后单击鼠标右键弹出一佣弹出式菜单 从弹出式菜单中选择Delete菜单项 便可删除相应的字段部件 如果在弹出式菜单中单击Select All菜单项 然后选择Delete菜单项 这样会删除已创建好的所有的字段部件 某一个字段部件被删除以后 通过单击Add Fields菜单项可以重新创建 只是先前为该字段部件设定的一些属性将不复存在
定义新的字段部件
字段器Fields Editor中的弹出式菜单中New Fields菜单项是用来为数据集部件TTable或TQuery创建用于显示目的的新的字段部件 我们可以用它来为数据库表中实际存在的字段创建新的字段部件(如改变字段的数据类型 使它的字段值被显示时不再需有关的类型转换) 但是我们使用New Fields菜单项创建新的字段部件主要是创建计算字段 计算字段并不与数据库表中实际存在的字段对应 它的字段值是根据表中其它的字段值计算而来的 具体的计算表达式由用户为TTable部件或TQuery部件的OnCalCFields事件编写程序代码时决定
定义(创建)计算字段的过程如下
单击字段器中的New Fields菜单项 定义字段对话框如图 所示
在FieldName框中输入新字段部件的名字 或者从下拉式列表框中选择一个已存在的字段部件的名字
在FieldType列表框中为新字段部件选择一个字段类型
单击Calculated检查框 确认定义的新字段部件是计算字段
单击ok按钮 创建上述定义的计算字段部件 此时该字段部件的名字会自动地加入到字段中的Fields列表框中
创建新的计算字段
新的计算字段创建好了之后 它是没有任何字段值的 我们必须要编写相应的程序代码 根据数据库表中实际存在的字段的字段值为计算字段的宝定义字段值 我们为计算字段所在数据集部件的OnCalcFields事件编写代码来为计算字段赋值 其步骤如下
选择数据集部件TTable或TQuery
单击数据集部件的事件页
双击OnCalcFields事件为TTable或TQuery部件编写事件处理过程
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方法 如下所示
Report Run;
TReport部件所具有的重要方法如表 所示
表 TReport部件的方法
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
方法 功 能
────────────────────────────
Run 执行报表功能 输出报表
RunMacro 发送一个宏命令给Reportimith工具
Connect 预先连接报表文件和数据库 在输出报表时不需要登录到数据库
SetVariable 改变说明的报表变量
ReCalcReport 当报表变量改变以后 重新输出报表
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
还有一些其他的数据访问部件如TBatchMove部件 它主要用在两个数据库表之间移动或拷贝帆数据记录 具体的使用请参看本地SQL服务器的使用
应用举例 多个窗体显示同一个数据库表
在应用当中 我们常常需要以不同的视图显示同一个数据库表中的内容 例如要在两窗体中同时显示一个数据库表中一个记录的不同字段时 我们必须要想办法使两个窗体中的数据浏览部件同步地显示数据库表中的同一条记录的不同字段的值 要想做到以不同的视图显示同一个数据库表中的记录 下面两条规则是很重要的
● 多个TDataSource部件能够同时访问同一个数据集部件
● 在多个窗体中显示同一个表时 必须为每个窗体设置一个TDataSource部件 只须为其中的一个窗体设置一个TTable部件
例如 如果想在窗体Form 和Form 中同时显示一个数据库表的记录 最简单可行的办法是 为Form 和Form 各设置一个TDataSource部件叫DataSource DataSource 并在Form 中设置一个TTable部件Table 连接Form 中的Datasource 和Table 在程序运行过程中设置Form 中的DataSource 的DataSet属性为Form 中的Table 代码如下
Format DataSource Dataset := Form Table ;
这样 当Table 被打开时 两个窗体中便可以同步地显示数据库表中的同一条记录了
一个名叫OForms DPR的例子在C:\Delphi\DEMos\DB\TwoForms中(如果Delphi安装在其它的磁盘驱动器中 从相应的磁盘驱动器中可以找到该例子) 它演示了在两个窗体中显示同一个数据库表的记录 应用程序在第一个窗体中打开Contry DB表 并在窗体中显示Name Captial和Continent字段 在第二个窗体中显示Area和Population字段 在第一个窗体中有一个按钮用于打开第二个窗体 两个窗体中都有TDBNavigator部件 用于记录的导航
返回目录 DELPHI基础教程
推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLE G数据库开发优化指南
Java程序性能优化 让你的Java程序更快 更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
lishixinzhi/Article/program/Delphi/201311/25156DELPHI基础教程:开发Delphi对象式数据管理功能(五)[1]
第二十章 开发Delphi对象式数据管理功能(五)
写DFM文件的过程 WriteComponentResFie
该过程带有两个参数FileName和Instance FileName参数指定要写入的DFM文件名 Instance参数是TComponent类型的 它指定要写入的部件名 一般是TForm对象的子类 该过程将Instance部件和其拥有的所有部件写入DFM文件
这个过程的意义在于 可以在程序运行过程中产生Delphi的窗体部件和在窗体中插入部件 并由该函数将窗体写入DFM文件 支持了动态DFM文件的重用性
该过程的程序是这样的
procedure WriteComponentResFile(const FileName: string; Instance: TComponent)
var
Stream: TStream;
begin
Stream := TFileStream Create(FileName fmCreate)
try
Stream WriteComponentRes(Instance ClassName Instance)
finally
Stream Free;
end;
end;
函数中 用FileStream创建文件 用Stream对象的WriteComponetRes方法将Instance写入流中
读DFM文件的函数 ReadComponentResFile
ReadComponentResFile函数带有两个参数FileName和Instance FileName参数指定要读DFM文件名 Instance参数指定从DFM文件中要读的部件 该函数从DFM文件中将Instance和它拥有的所有部件 并返回该部件
这个函数的意义在于 配合WriteComponentResFile过程的使用支持DFM文件的重用性
该函数的程序是这样的
function ReadComponentResFile(const FileName: string; Instance: TComponent)
TComponent;
var
Stream: TStream;
begin
Stream := TFileStream Create(FileName fmOpenRead)
try
Result := Stream ReadComponentRes(Instance)
finally
Stream Free;
end;
end;
程序中使用FileStream对象打开由FileName指定的DFM文件 然后用Stream对象的ReadComponentRes方法读出Instance 并将读的结果作为函数的返回值
读取Delphi应用程序资源中的部件
函数InternalReadComponentRes可以读取Delphi应用程序资源中的部件 Delphi 的DFM文件在程序经过编译链接后被嵌入应用程序的资源中 而且格式发生了改变 即少了资源文件头
在第一节中曾经介绍过TResourceStream对象 该对象是操作资源媒介上的数据的 函数InternalReadComponentRes用了TResourceStream 程序是这样的
function InternalReadComponentRes(const ResName: string;
var Instance: TComponent) Boolean;
var
HRsrc: THandle;
begin { 避免 EResNotFound 异常事件的出现 }
HRsrc := FindResource(HInstance PChar(ResName) RT_RCDATA)
Result := HRsrc 《》 ;
if not Result then Exit;
FreeResource(HRsrc)
with TResourceStream Create(HInstance ResName RT_RCDATA) do
try
Instance := ReadComponent(Instance)
finally
Free;
end;
Result := True;
end;
HInstance是一个Delphi VCL定义的全局变量 代表当前应用程序的句柄 函数用了资源访问API函数FindResource来测定是否存在ResName所描述资源 因为在TResourceStream的创建过程还有FindResource等操作 所以函数中调用了FreeResource 最后函数调用了Stream对象的ReadComponent方法读出部件 因为函数的Instance是var类型的参数 所以可以访问Instance 得到读出的部件
DFM文件与标准文本文件(TXT文件)的相互转换
在Delphi可视化设计环境中 允许程序员在代码器中以文本的方式浏览和修改DFM文件内容 当用File/Open命令直接打开DFM文件或者选择窗体设计窗口的弹出式菜单上的View as Text命令时 就会在器中出现文本形式的信息 我们姑且将这种文本形式称之为窗体设计脚本 Delphi提供的这种脚本功能是对Delphi可视化设计的一大补充 当然这个脚本能力是有限制的 比方说不能在脚本任意地添加和删除部件 因为代码和DFM脚本是紧密相连的 任意添加和修改会导致不一致性 然而在动态生成的DFM文件中 就不存在这一限制 后面会介绍DFM动态生成技术的应用
实际上 DFM文件内容是二进制数据 它的脚本是经过Delphi开发环境自动转化的 而且Delphi VCL中的Classes库单元中提供了在二进制流中的文件DFM和它的脚本之相互转化的过程 它们是ObjectBinaryToText和ObjectTextBinary ObjectResourceToText和ObjectTextToResource
ObjectBinaryToText过程将二进制流中存储的部件转化为基于文本的表现形式 这样就可以用文本处理函数进行处理 还可以用文本器进行查找和替代操作 最后可以将文本再转化成二进制流中的部件
ObjectBinaryToText过程的主程序是这样的
procedure ObjectBinaryToText(Input Output: TStream)
var
NestingLevel: Integer;
SaveSeparator: Char;
Reader: TReader;
Writer: riter;
procedure WriteIndent;
const
Blanks: array of Char = ;
var
I: Integer;
begin
for I := to NestingLevel do Writer Write(Blanks SizeOf(Blanks))
end;
procedure WriteStr(const S: string)
begin
Writer Write(S Length(S))
end;
procedure NewLine;
begin
WriteStr(# # )
WriteIndent;
end;
procedure ConvertHeader;
begin
…
end;
procedure ConvertBinary;
begin
…
end;
procedure ConvertValue;
begin
…
end;
procedure ConvertProperty;
begin
…
end;
procedure ConvertObject;
begin
…
end;
begin
NestingLevel := ;
Reader := TReader Create(Input )
SaveSeparator := DecimalSeparator;
DecimalSeparator := ;
try
Writer := riter Create(Output )
try
Reader ReadSignature;
ConvertObject;
finally
Writer Free;
end;
finally
DecimalSeparator := SaveSeparator;
Reader Free;
end;
end;
过程中调用的ConvertObject过程是个递归过程 用于将DFM文件中的每一个部件转化为文本形式 因为由于部件的拥有关系 所以部件成嵌套结构 采用递归是最好的方式
procedure ConvertObject;
begin
ConvertHeader;
Inc(NestingLevel)
while not Reader EndOfList do ConvertProperty;
Reader ReadListEnd;
while not Reader EndOfList do ConvertObject;
Reader ReadListEnd;
Dec(NestingLevel)
WriteIndent;
WriteStr( end # # )
end;
NestStingLevel变量表示部件的嵌套层次 WriteIndent是写入每一行起始字符前的空格 ConvertHeader过程是处理部件的继承标志信息 转换成的头信息文本有两种形式
Inherited TestForm : TTestForm
或者
Object TestForm : TTestForm
前者是ffInherited和ffChildPos置位 后面是都没置位
ConvertProperty过程用于转化属性
procedure ConvertProperty;
begin
WriteIndent;
WriteStr(Reader ReadStr)
WriteStr( = )
ConvertValue;
WriteStr(# # )
end;
WriteIndent语句写入属性名前的空格 WriteStr(Reader ReadStr)语句写入属性名ConvertValue过程根据属性的类型将属性值转化为字符串 然后写入流中
lishixinzhi/Article/program/Delphi/201311/25088DELPHI基础教程:Delphi开发数据库应用程序概述(一)[3]
Visual Query Builder 以可视化的方式建立SQL语句对数据库表和表中的记录进行操作
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SQL links使得Delphi数据库应用程序利用SQL语言访问驻留在远程服务器上的数据 这些服务器包括ORACLE Sybase Microsoft SQL Server Informix InterBase 当安装SQL Link驱动程序之后 SQL语句便可以直接操作服务器上的数据
Delphi可以访问的数据源(DataSource)
Delphi数据库应用程序是通过BDE获取它们所需的数据的 BDE与不同类型的数据源打交道 BDE可以使用的数据源有如表 所示
表 Delphi可访问的数据源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
数据源(DataSource) 特 性 描 述 文件扩展名
─────────────────────────────────────
dBASE数据库 数据库表是通过dBASE数据库管理系统或DBD建立的 每个表是一个独立的文件 DBF
─────────────────────────────────────
Paradox数据库 数据库表是通过Paradox数据库管理系统 DB或DBD建立的 每个表是一个独立的文件
─────────────────────────────────────
ASCII文件 表是通过Database Desktop建立的 每个 TXT表是一个独立的文件
─────────────────────────────────────
本地InterBase服务器 数据库是通过InterBase数据库管理系统 GDB建立的 多个表包含在一个数据库文件中
─────────────────────────────────────
SQL数据库服务器 数据库是通过相应的数据库服务器提供的 依赖不同的ORACLE Sybase Informix 专用或通用工具建立的 也可以通过DBD来 数据库管理Microsoft SQL Server 创建数据库 并通过SQL Link访问数据库 系统InterBase
─────────────────────────────────────
ODBC数据源 主要是指那些具有ODBC接口的数据库系统 依赖于相应如MS Access Btrieve等的数据库
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Delphi数据库的体系结构
Delphi使用可视化的部件创建数据库应用 跟创建其它的非数据库应用程序一样 数据库部件都具备一定的属性 程序设计人员可以在设计过程中设置部件的多种属性 也可以在程序运行过程中通过程序来设置部件的各种属性
在Delphi部件板上有两页数据库部件用于开发数据库应用程序
数据访问部件页 该页上的部件主要用于说明有关的数据库的信息 如应用程序要访问(连接)的数据库 要访问数据库中的具体的数据库表 以及要访问表中哪些字段等 在实际的开发应用中常用的部件有TDataSource TTable TQuery等
数据控制部件页 该页上的部件主要用于显示浏览数据库中的数据信息 为用户提供了一个可视化的界面 常用的部件有 TDBGrid TDBEdit TDBCheck等 可以让用户对数据库中的信息进行有效的浏览 插入 删除等操作
TTable TQuery TStoredproc部件负责与实际的数据库表联系 并从中获取数据信息 因而它们又常常被称为数据集部件 它们在程序设计过程中是可见的 但在程序运行时是不可见的 它们通过 BDE 为应用程序提供与数据库的连接 数据控制部件通过TDataSource部件与数据集部件相连 为用户提供一个可视化的界面 并在其中显示数据库中的数据信息
数据访问部件
数据访问部件页上提供了一组数据访问部件用来访问数据库中的数据
当要创建一个数据库应用时 首先在窗体中选择一个数据访问部件 然后为数据访问部件设置有关的属性 说明要访问的数据库 数据表以及表中的记录等 数据访问部件为数据控制部件与数据源建立一条通道 数据访问部件在程序运行时是不可见的 下表列出了数据访问页上的数据访问部件以及它们的主要用途
表 数据访问部件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
部件名称 主 要 用 途
────────────────────────────
作为数据集部件TTable TQuery StoredProc组TDataSource 件与数据浏览件TDBGrid TDBEdit之间传送数据的通道
────────────────────────────
TTable 它是存取磁盘上数据库表的媒介 它通过BDE存取数据库表中的数据 TTable再与TDataSource进行 对话 使得数据浏览部件能够有效地从TTable中访问数据并能显示和其中的数据
────────────────────────────
TQuery 它利用SQL语言访问磁盘上数据库表中的数据 并与TDataSource 对话 实现数据浏览部件对数据库的访问
────────────────────────────
TStoredProc 在应用程序中 它主要用来访问远程服务器中的存贮过程
────────────────────────────
TDatabase 当应用程序要登录到一个远程服务器上的数据库时 可以用该部件来建立应用程序与数据库永久
性的连接
────────────────────────────
TBatchMove 用于复制数据库表的结构或表中的记录
────────────────────────────
TReport 用于创建数据库的输出报表
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
lishixinzhi/Article/program/Delphi/201311/25180delphi10.4开发的程序如何在安卓12上运行
1、首先,确保使用的Delphi版本兼容安卓12,在Delphi中设置项目的目标平台为安卓,在项目设置中选择支持的Android版本。
2、然后,进行程序的编码和调试,构建生成APK文件,将APK文件安装到安卓12设备上。
DELPHI基础教程:开发Delphi对象式数据管理功能(四)[2]
OnSetName事件
声明
property OnSetName: TSetNameEvent;OnSetName事件发生在Read对象设置部件的Name属性前 OnSetName事件处理过程的var参数Name参数是一个var参数 因此 事件处理过程再将Name赋给部件前 可以修改Name的值 这对于想过滤窗体中部件的名字是很有帮助的
下面的OnSetName事件处理过程 命名了名字中包含 Button 的部件 并用 PushButton 替代
procedure TForm ReaderSetName(Reader: TReader; Component: TComponent;
var Name: string)
var
ButtonPos: Integer;
begin
ButtonPos := Pos( Button Name)
if ButtonPos 《》 then
Name := Copy(Name ButtonPos ) + PushButton +
Copy(Name ButtonPos + Length(Name))
end;
ReadValue方法
声明
function ReadValue: TValueType;ReadValue方法读取流中紧著的项目的类型 函数返回后 流的指针移到值类型指示符之后
TValueType是枚举类型 存储在Filer对象的流中的每个项目之前都有一个字节标识该项目的类型 在读每个项目之前都要读取该字节 以指导调用哪个方法来闱取项目 该字节的值就TValuetype定义的值类型之一
NextValue方法
声明
function Nextvalue: TValuetype;Nextvalue方法的作用也是返回Reader对象流中紧接着的项目的类型 它与ReadValue的区别在于并不移动指针位置
ReadBoolean方法
声明
function ReadBoolean: Boolean;ReadBoolean方法从Reader对象的流中读取一个布尔值 并相应地移动流位置指针
ReadChar方法
声明
function ReadChar: char;ReadChar方法从Reader对象的流中读取一个字符
ReadFloat方法
声明
function ReadFloat: Extended;ReadFloat方法从流中读取浮点数
ReadIdent方法
声明
function ReadIdent: string;ReadIdent方法从流中读取标识符
ReadInteger方法
声明
function ReadInteger: LonginReadInteger方法从流中读取整型数字
ReadString方法
声明
function Read String: string;ReadString方法从Reader对象的流中读取一个字符串 并返回字符串中的内容 该字符串是由Writer对象的WriteString方法写入
TReader对象的实现
Filer对象的作用主要是Delphi用来在DFM文件中读写各种类型的数据(包括部件对象) 这些数据的一个本质特征是变长 而且Filer对象将读写数据操作抽象化 包装成对象提供了大量的读写方法 方便了程序的调用 因此在应用程序中可以广泛使Filer对象 充分利用Delphi的面向对象技术 而且Filer对象与Stream对象捆绑在一起 一方面可以在各种存储媒介中存取任意格式的数据 另一方面 由于充分利用面向对象的动态联编 各种读写方法的使用方法是一致的 因此 方法调用很简单 下面我们着重介绍Reader 对象中与读写数据操作有关的属性和方法的实现
TReader属性的实现
在TReader对象的属性实现中我们重点介绍Position的实现
Position属性的定义了使用了读写控制 它们分别是GetPosition和SetPosition方法
TReader = class(TFiler)
private
…
function GetPosition: Longint;
procedure SetPosition(Value: Longint)
public
…
property Position: Longint read GetPosition write SetPosition;
end;
Postition的读写控制方法如下
function TReader GetPosition: Longint;
begin
Result := FStream Position + FBufPos;
end;
procedure TReader SetPosition(Value: Longint)
begin
FStream Position := Value;
FBufPos := ;
FBufEnd := ;
end;
在TReader的父对象TFiler对象中介绍过FBufPos和FBufEnd变量 Filer对象内部分配了一个BufSize大小的缓冲区FBufPos就是指在缓冲区中的相对位置 FBufEnd是指在缓冲区中数据结束处的位置(缓冲区中的数据不一定会充满整个缓冲区)
在GetPosition方法中可以看到Reader对象的Position值和Stream对象的Position值是不同的 Reader对象多了一个FButPos的编移量
Defineproperty和DefineBinaryproperty方法的实现
这两个方法是虚方法 在TFiler中是抽象方法 在TReader和riter对象中才有具体的实现
它们在TReader中的实现如下
procedure TReader DefineProperty(const Name: string; ReadData: TReaderProc;
WriteData: riterProc; HasData: Boolean)
begin
if CompareText(Name FPropName) = then
begin
ReadData(Self)
FPropName := ;
end;
end;
procedure TReader DefineBinaryProperty(const Name: string;
ReadData WriteData: TStreamProc; HasData: Boolean)
var
Stream: TMemoryStream;
Count: Longint;
begin
if CompareText(Name FPropName) = then
begin
if ReadValue 《》 vaBinary then
begin
Dec(FBufPos)
SkipValue;
FCanHandleExcepts := True;
PropValueError;
end;
Stream := TMemoryStream Create;
try
Read(Count SizeOf(Count))
Stream SetSize(Count)
Read(Stream Memory^ Count)
FCanHandleExcepts := True;
ReadData(Stream)
finally
Stream Free;
end;
FPropName := ;
end;
end;
在两个方法都将Name参数值与当前的属性名比较 如果相同则进行读操作 在DefineBinaryproperty中 创建了一个内存流 先将数据读到内存流中然后调用ReadData读取数据
FlushBuffer的实现
FlushBuffer方法用于清除Reader对象的内部缓冲区中的内容 保持Reader对象和流在位置(Position)上的同步 其实现如下
procedure TReader FlushBuffer;
begin
FStream Position := FStream Position (FBufEnd FBufPos)
FBufPos := ;
FBufEnd := ;
end;
ReadListBegin ReadListEnd和EndOfList方法
这三个方法都是用于从Reader对象的流中读取一连串的项目 并且这些项目都由WriteListBegin写入的标志标定开始和WriteListEnd写入标志 标定结束 在读循环中用EndOfList进行判断 它们是在Reader对象读取流中数据时经常用于的 它们的实现如下
procedure TReader ReadListBegin;
begin
CheckValue(vaList)
end;
procedure TReader ReadListEnd;
begin
CheckValue(vaNull)
end;
function TReader EndOfList: Boolean;
begin
Result := ReadValue = vaNull;
Dec(FBufPos)
end;
项目表开始标志是VaList 项目表结束标志是VaNull VaList和VaNull都是枚举类型TValueType定义的常量
lishixinzhi/Article/program/Delphi/201311/25093![delphi安卓开发教程(DELPHI基础教程:Delphi开发数据库应用程序概述(一)[4])](/static/images/bgimages/barley-676551_1920.jpg)
本文相关文章:
json时格式自动换行(数据库中数据偶尔有换行符、回车符,在java里取出数据拼JSON格式字符串的时候要出问题)
2025年11月1日 17:45
sqlite3读取性能(csv和sqllite数据库读取哪个快)
2025年10月24日 04:30
java数据库(java中怎么向数据库插入数据(java怎么导入数据库))
2025年10月23日 18:00
数据库逻辑运算符有哪些(智慧芽专利数据库支持哪几种逻辑运算符)
2025年10月22日 00:30
windows7不自带access怎么办(为什么Win7里面数据库access不能用)
2025年10月21日 08:00
sql server 2008合成模板库失败(SQL Server2008数据库引擎等安装失败的原因)
2025年10月9日 08:00
更多文章:
amaze ui 树状结构导航(网站结构怎么做SEO,树状结构与扁平结构的区别)
2026年4月15日 09:00
jquery多级联动下拉菜单(jQuery实现动态级联选择问题,比如3个下拉框,选择第一个其他的2个选项自动把内容选中.)
2025年9月15日 16:15
vue页面之间回调(vue.http 怎么定义jsonp的回调名)
2026年7月27日 06:30
a和b的ascii码(英文字母A的ASCII码值十进制的是65,那么B的ASCII码是什么)
2026年1月28日 12:30
学51单片机编程选用Keil uvision 和medwin哪个软件更好?为什么没有国产的C/C++的编译器
2025年10月8日 05:45
用fprintf为什么写不进文件(急求C语言大神,下面的程序运行正常也能读取文件,但是无法向文件中写入,问题出在哪)
2025年11月22日 18:45
登陆界面背景图(Win7登录界面背景图在哪里改(输入密码那))
2026年7月27日 18:00
我的世界displayname(minecraft我的世界怎样给物品改名)
2026年1月14日 14:45
shell脚本写加减乘除运算(用shell做个加减乘除运算)
2025年6月20日 21:30
sql语句查询男女生人数(SQL查询,按性别显示学生信息,并分别汇总男生女生人数)
2026年7月25日 08:00










