你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
Delphi之查询输入释疑
 

  :全面诠释Delphi中各种查询输入方法中的疑点。

 

“查询输入”,是指数据表中某字段的值来源于另一张表,编程时将“查询数据”源表与某个列表框捆绑起来,用户操作时中“查询”该列表框来实现输入,这是数据库编程中常用的技术,但一般资料上,没有详细介绍以上各种方法的使用细节,相反,有些资料上误导读者,尤其是在对DbGrid控件的处理上更是错误百出,疑点较多,使我们在编程中经常性遇到麻烦,笔者经过尝试,将以上方法一一摸透,关键地方一一点破,疑点难点予以破解。“查询输入”在Delphi 中实现方式有:

l         在建立表结构时从Table Properties中选Table LookUp可实现该功能;

l         通过Master(主要)/Detail(明细)窗体,以“多对一”关联操作来实现此功能

l         在表的Field Editor.(字段编辑器)中新建一个LookUp字段,用DbGrid(网格控件)或单个DbEdit控件来实现此功能。

l         DataControls选项卡选择DbLookupCombobox来实现此项功能,该方法只能用在DbEdit控件上。

l         如果Lookup字段的取值不多,或者在程序运行中是固定不变的,则一个Dbgrid控件的列对象上捆绑一个下拉列表框,在其PickList属性中添入该Lookup字段的不同取值及DbListBoxDbCombobox

一、利用表结构窗体中Table Lookup实现“查询输入”

如果你的数据量不大,又不想编程序,则可此方法直接在数据库桌面(DataBase DeskTop)中实现“查询输入”,

实例:课程表Class.db中的TNO字段的值,是教师表Teacher.dbTNO字段的值,现在建立为Class.dbTNO字段建立其“查询输入”方式。操作步骤如下:

在数据库桌面(DataBase Desktop)中打课程表,如D:\989101\CTC\DB\CLASS.DB,进入结构修改窗口àTable Properties中选Table Lookupà单击“Define”按钮,进入如图“Table LookUP”所示的设置窗体,按如图所示方式设置好,存盘结束结构重构窗体,à进入Class表的“编辑”状态,在其TNO字段上,按Ctrl+Space键可弹出Teacher.db供你选择à有一点要请注意,在WindowsCtrl+Space是中英文切换键,所以要在Windows的控制面板选“输入法”,将其“关闭/打开输入法”的热键从Ctrl+Space换成其它形式,如Alt+Space,这样不会与Delphi 发生冲突了。

   

 

 

 

 

 

 

 

 

 

 

 

 

该方法一般用于临时输入少量数据,如果想删除该功能,可进入“表结构重构”窗体中,选中TNO字段àTable PropertiesàTable Lookupà这时TNO的查找表Teacher.db会显示出来à单击Erase按钮。

可为一张表的多个字段建立查找表。

二、Master(主要)/Detail(明细)窗体实现“查询输入”

Master/Detail主要用于像发票、财务凭证、入库单等数据的处理过程中,一张发票上日期、发票号、收款人等Master(主要)信息在一张发票中仅出现一次,但所购物品的名称、单价、规格Detail(明细)信息会出现多次,这种“主要/明细”操作,从数据库角度来看,它属于“一对多”关联操作。

我们“逆用“该技术,即变成“多对一”,利用“多对一”关联操作,也可以实现“查询输入”。其操作界面如下图所示,你输入一个TNO字段的值,在其下方显示其相关的数据,帮助你做出正确判断,这种方式在财务类软件较活用。

本例中涉及到两张表是:Class.db的结构是CNo SCname A(20)Cdate DeCHour SCfeeph NCcostPh NTno S,主键是CnoTeacher.db的结构是 Tno STname A(8)Tadd A(20)Tzip ITtel A(20),主键是Tno。均保存在C:\db目录中。

实例:要求Class.db表中的Tno字段用“查询输入”方式输入,下面操作步骤如下:

1、新建一个项目文件àFileàNewàData Moduleà建立一个数据模块à添加如下表所示的对象à根据下表设置各对象的属性àDmod1.Pas存盘。

对象名

属性值

Table1

DataBaseName=C:\db    TableName=Class.db Active=True

DataSource1

DataSet=Table1

Table2

DataBaseName=C:\db  TableName=Teacher.db  MasterSource=DataSource1

MasterField=Tno Active=True

DataSource22

DataSet=Table2

    在设置Table2MasterFields会弹出“Field Link Designer”对话框,你必须先在“Detail Fields”的下方选中TNO字段,然后在Master Fields的下方选中Tno,再单击Add按钮,最后OK按钮。

2、在Form1中添加2个网格对象à并按F12切换到其代码窗体,添上Uses Pmod1à设置两个网格对象的DataSource分别为DataSource1DataSourc2àPM_1.PasZM_1.Dpr保存其单位文件与项目文件,最后窗体界面如图所示。

 

三、在DbGrid(网格)控件“查询输入”

DbGrid(网格)控件是Delphi 数据库编程中使用最频繁的一个DataControls,直观方便,几乎所有数据库编程环境都提供该控件,在该控件的“列”对象上捆绑“ComboBox”以实现“查询输入”是一项最基本的工作,是任何数据库编程者都会遇到的一个问题,也是必须面对的一个问题,但就是这个问题,很多资料甚到一些“内幕”书籍上也没有明确指明,笔者为此痛苦了好久。

要透切理解“DbGrid”控件中的“查询输入”方法,必须先明白,“LookUp”字段的真实用途?LookUp字段实质上是一个“辅助”字段,在窗体运行时它将直观的数据显示一个Combobox控件中,这些直观的数据并不保存对应的数据表中,保存的是这些直观数据对应的代码。

还以前面提到的Class.dbTeacher.db为例,Class.db中的教师代号Tno的值,谁也记不准,希望在输入课程表Class.db中各项数据时,TNO字段能以“Combobox”控件的方式“直观”显示出每位教师的“姓名”,选中某位教师后,该教师的代号的值,自动送到Class.db表的Tno字段中,这就是“LookUp”字段的真实含义。

LookUp字段的建立是接收数据表(Class.db)Fields Editor…(字段编辑器)中进行的,具体操作细节见下。

1、 建立数据模块

新建一个项目文件àFileàNewàData Moduleà建立一个数据模块à添加如下表所示的对象à根据下表设置各对象的属性àDmod3.Pas存盘。

对象名

属性值

Table1

DataBaseName=C:\db    TableName=Class.db Active=True

DataSource1

DataSet=Table1

Table2

DataBaseName=C:\db  TableName=Teacher.db Active=True此处切记不要设置其MasterSourceMasterFields,这与主表/明细表结构不一样,否则会出错

这就是诸多大侠们一头“雾水”的地方。

DataSource2

DataSet=Table2

2、在主表Table1建立查询字段CTname

    在数据模块Dmod3.pas中双击数据表对象Table1à进入字段编辑器à右击先“Add All Fields”将所有字段添加字段编辑器中à再右击选“New Fieldsà弹出“New Fields”图,按图示设置好有关属性,这里每个属性的含义一定准确理解。

   

 

 

 

 

Names:是指“主表”中建立的“查询字段”,它并不在主表中保存数据,仅起一个辅助作用,是“虚拟字段”,显示的数据为“从表”中Result Fields对应的字段的值。

KeyFields:它是“主表”中的字段,此处为TNO,可以理解为接收字段,就是它的值要用“查询输入”的方式来输入。它常常是主表中的“外码”。

    DataSet:它指明“从表”的名称,我们“查询输入”时,查询的数据就是这张表中某个字段的数据。此处为Table2,即Teacher.db对应的表对象。

    LookUpKeys:指明“从表”的索引字段,大多数情况下是“从表”的主键,并且与“主表”中的接收字段即“KeyFields”对应的字段同名。值得注意的是LookupKyes指明的字段,Key Fields指明的字段不同名时,这两者所指明的字段类型必须相同、含义必须相同。

    Result Fields:指明在主表的查询字段(Names所指字段)显示的数据是“从表”中哪个字段,此处为从表中的Tname字段。

    以上设置过程,你也可以在该CTName的对象观察器(Object Inspector)直接进行修改,其属性名依次为KeyFieldsLookUpDataSetLookUpKeyFieldsLookupResultFields,同时你也会发现其FieldKindsfkLookup

3、建立显示窗体

 

    切换到主窗体àF12进入其代码窗体,在其Implementation的下方写上Uses Dmod3à在主窗体上添加一个网格控件à DataSourceDataSource1à分别在Pdb.Pas单元文件保存以上窗体,以Zdb.Dpr保存其项目文件àF9运行得到如上图所示的效果,此愿望最终实现了。不写一条语句实现了“查询输入”,真是爽极了!

    在网格中实现“查询输入”最关键之处:

l         在数据模块中既要建立“查询”数据对应的表对象,但绝不能设置其MasterSourceMasterFields两属性;这是最容易犯错误的地方。

l         在主表中建立“查询字段”,仅起一个辅助作用。

l         在主窗体中只能建立主表对应的DbGrid(网格)控件,不能再建立一个从表(即查询表)对应的DbGrid(网格)控件,要不落入了“Master(主表)/Detail(明细表)”的套路中,同时可能会触发一些致命的错误,这也是最容易犯错误的地方。

四、利用DbLookUpCombobox来实现“查询输入”

方法三介绍的是“在DbGrid(网格)控件”中实现“查询输入” ,如果处理的数据的控件不是DbGrid控件,而是DbEdit控件等,这是方法三提供的方法行不通了,这时只能采用DbLookUpListBox控件或DbLookupCOmbobox控件来实现,操作过程如下:

1、     建立数据模块

新建一个项目文件àFileàNewàData Moduleà建立一个数据模块à添加如下表所示的对象à根据下表设置各对象的属性àDmod4.Pas存盘。

对象名

属性值

Table1

DataBaseName=C:\db    TableName=Class.db Active=True

DataSource1

DataSet=Table1

Table2

DataBaseName=C:\db  TableName=Teacher.db Active=True此处切记不要设置其MasterSourceMasterFields

DataSource2

DataSet=Table2

2、建立主窗体

    在主窗体的代码窗体之Implementation的下方à写上Uses Dmod4à在窗体上添置如图所示的控件,具体设置如下:

 

 

 

 

 

 

 

 

 

 

1.       在“Cno”右边添加DbEdit控件,其DataSource设为DataSource1;其DataFieldsCNo,表示该控件用来编辑CNo字段的;

2.       似处理处理其它控件;

3.       TNO字段设置“查询输入”方式:

l         在“TNO“右边添加DbLookUpCombobox,其DataSourceDataSource1,其DataFieldsTno

l         最重要的是,其ListSource(显示数据源)DataSource2,即Teacher.db对应的数据源;

l         显示字段属性ListFields Tname

l         KeyFieldsTNo,表示提供查询数据的“从表”按此字段进行索引;

l         属性Key Fields所指的字段实际相当于“方法三”定义Lookup字段时的“Lookup Keys”所指的字段,并不相当于“方法三”定义Lookup字段时的Key Fields 所指的字段,就是因为这字面上相同,使得很多前辈在此百思不得其解!

l         基于与“方法三”中同样的理由,Key Fields(此处为Tno)所指的“从表”字段名,与DataFields(此处为Tno)所指的“主表”中“接收字段”是互相对应的,这两者所指的字段其名称一般是相同的(VB/VFP是必须相同的),在Delphi 中可以不同名,只要其数据类型、所指明的含义相同即可。

l         通过ListSourceListFieldsKeyFields 三属性,使得主表(此处为Class.db)可使用“查询输入”方式从“从表”(此处为Teacher.db)中选择性的输入数据。

1、  在窗体的下方添加一个数据导航条,其DataSourceDataSource1

此例仅对DBLookupCombobox举了例,对于DbLookupListBox的用法是完全类似的。

五、其它方式实现“查询输入”

如果某字段的值不是来源于另一张表,而是某几个固定取值之一,这时根据具体情况使用如下方法来解决:

1、      如果“方法三”中的DbGrid对象中某列数据是从某几个固定数据中取值,那么可双击该DbGrid控件,进入“Column Propertis Editor(列属性编辑器)选中该列,然后在其PickList属性输入这几个固定值。

2、      如果“方法四”中某个DbEdit对象的数据,为某些固定值中的一个,则可用DbListBoxDbCombobox两控件,在其Items属性中输入这几个固定值即可。

3、      也可以动态修改“列”对象的PickList属性或者DbListBoxItems属性,以实现将其它表中的字段做为原始数据,实现“查询输入”,这可能是最灵活的方式,但是消耗的资源会受点影响,速度会慢一点。

六、总结

    本文从DataBase Desktop(数据库桌面)Master(主要)/Detail(明细)控件、DbGrid(数据库网格)对象、dbLookupListBox(数据库查询列表框)DbLookupCombobox(数据库查询组合框)等五个方面,较系统的的介绍了各种“查询输入”方法的具体实现细节,不与一行代码就实现了“查询输入”,这大概也是Delphi 的独到之处。

最后请注意在不同的实现方法中,彼此细微的区别是最关键的,千万不要出现“知识串户”的现象。

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089