《Delphi程序设计实训教程》课件第6章_第1页
《Delphi程序设计实训教程》课件第6章_第2页
《Delphi程序设计实训教程》课件第6章_第3页
《Delphi程序设计实训教程》课件第6章_第4页
《Delphi程序设计实训教程》课件第6章_第5页
已阅读5页,还剩117页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章系教学管理系统之教务管理子系统

—基本的数据库应用

6.1教学管理系统案例分析

6.2相关知识点

6.3实现方法

6.4案例总结

6.1教学管理系统案例分析

6.1.1任务的提出

自动化与信息工程系的教务干事日常工作繁忙,如果教学管理仍然采用手工管理方式,其工作效率低。现希望有一个应用程序,能够对自动化与信息工程系的学生所学习的课程进行管理、记录该系学生选修课程的信息、对开设课程的成绩进行数据维护并能够提供给学生进行成绩查询。这些日常教学工作如果能够使用计算机进行管理,将提高工作效率。自动化与信息工程系的教学管理系统主要由两个子系统组成:教务管理子系统和学生教务子系统。本章讲解教务管理子系统的实现,学生教务子系统的实现将在第7章讲述。

教务管理子系统的实现主要是使用数据集组件TTable。通过本章子系统的实现,我们将学习对数据库中的数据进行维护的方式之一,即使用数据集组件所提供的诸多方法来操作数据集中的数据。

6.1.2系统设计

1.自动化与信息工程系教学管理系统之系统功能分析

本系统主要有以下功能要求:

●所开设课程的信息维护,包括增加、删除和修改课程信息。

●学生选课信息维护,包括添加、删除选课信息。

●课程成绩维护,包括输入、修改课程成绩。

学生成绩查询,包括学生所学课程成绩和该课程的基本统计信息。

2.系统功能模块设计

自动化与信息工程系教学管理系统由教务管理子系统和学生教务子系统组成。此处给出本章的教务管理子系统的功能模块图,如图6.1所示。

图6.1教务管理子系统功能模块图

6.1.3数据库设计及实现

1.数据库需求分析

教学管理系统需要以下数据项:

●课程:课程编号、课程名称、讲课教师、学分、学时、课程简介;

●学生:学号、姓名、性别、班级;

●成绩:学生、课程、成绩;

●班级:班级编号、班级名称、所属院系;

教师:教师编号、姓名、性别、所属研究室。

2.数据库概念结构设计

图6.2是本系统的E-R模型图,图中省略了各实体的属性。

图6.2教学管理系统E-R图

3.数据库逻辑结构设计

根据图6.2所示的E-R图,需要5个基本信息表:教师信息、课程信息、班级信息、学生信息和成绩信息。由于使用本系统的不仅仅是自动化与信息工程系的教务干事,每个学生都可以登录到学生教务子系统进行课程选择或成绩查询,因此需要对不同的登录人员进行用户名和密码认证并进行权限检查以防止出现越权行为。用户名、密码和权限数据保存在1个数据表——用户信息表中。这6个数据表的结构见表6-1~表6-6。

表6-1USER_INFO(用户)信息表

表6-3STUDENT(学生)基本信息表

表6-5COURSE(课程)基本信息表

表6-6SCORE(成绩)信息表

4.数据库结构的实现

在SQLServer2000的企业管理器中创建数据库TEACH,在查询分析器中用CREATETABLE语句创建各数据表。

1)创建用户信息表

CREATETABLEUSER_INFO(

IDCHAR(8)NOTNULLCONSTRAINTUSER_PKPRIMARYKEY,

PASSWDCHAR(10)NOTNULL,

AUTHORITYCHAR(1)NOTNULL

)

2)创建班级基本信息表

CREATETABLECLASS(

IDCHAR(6)NOTNULLCONSTRAINTCLASS_PKPRIMARYKEY,

NAMEVARCHAR(20)NOTNULL,

DEPARTMENTVARCHAR(20),

)

3)创建学生基本信息表

CREATETABLESTUDENT(

IDCHAR(8)NOTNULLCONSTRAINTSTU_PKPRIMARYKEY,

NAMEVARCHAR(20)NOTNULL,

SEXCHAR(1),

CLASSCHAR(6)CONSTRAINTCLASS_FKFOREIGNKEYREFERENCESCLASS(ID)

)

4)创建教师基本信息表

CREATETABLETEACHER(

IDCHAR(3)NOTNULLCONSTRAINTTEACHER_PKPRIMARYKEY,

NAMEVARCHAR(20)NOTNULL,

SEXCHAR(1),

OFFICEVARCHAR(20)

)

5)创建课程基本信息表

CREATETABLECOURSE(

IDCHAR(4)NOTNULLCONSTRAINTCOU_PKPRIMARYKEY,

NAMEVARCHAR(30)NOTNULL,

TEACHERCHAR(3)NOTNULLCONSTRAINTT_FKFOREIGNKEYREFERENCESTEACHER(ID),

CREDIT_HOURSMALLINT,

PERIODSMALLINT,

INTROVARCHAR(600)

)

6)创建成绩信息表

CREATETABLESCORE(

IDINTIDENTITY(1,1)NOTNULLCONSTRAINTSCORE_PKPRIMARYKEY,

STUDENTCHAR(8)NOTNULLCONSTRAINTS_FKFOREIGNKEYREFERENCES

STUDENT(ID),

COURSECHAR(4)NOTNULLCONSTRAINTC_FKFOREIGNKEYREFERENCES

COURSE(ID),

SCORESMALLINT

)

6.2相

6.2.1本章案例使用到的新组件

1.TMaskEdit组件

TMaskEdit组件用于输入单行文本,主要用于有格式要求的数据输入(如电话号码、日期等),它能够根据定制的格式来强迫用户输入指定格式的数据。

该组件位于组件面板的“Additional”标签页,类名为TMaskEdit。

TMaskEdit组件的主要属性如下:

EditMask属性

该属性用于设置输入掩码字符串,决定了输入数据及数据显示的格式。当输入的数据不符合要求时,该对象将拒绝接受此数据。

EditMask属性是一个TEditMask对象,实际上是一个字符串。掩码字符串包含用“;”分隔的三个部分:

(1)掩码本身。具体含义如下:

L:只能输入字母。

l:只能输入字母,但可以不输入。

A:允许输入字母或数字。

a:允许输入字母或数字,但可以不输入。

0:只能输入数字。

9:只能输入数字,但可以不输入。

#:只能输入数字或正负号,但可以不输入。

>:将该字符后的所有字符转换为大写字符,直至结束或遇到“<”。

<:将该字符后的所有字符转换为小写字符,直至结束或遇到“>”。

C:可输入任意一个字符。

c:可输入任意一个字符,但可以不输入。

::通常用来分隔时间的时、分、秒。

/:

通常用来分隔日期的年、月、日,将显示默认的字符,如“-”。

(2)指明掩码字符是否作为数据的一部分。

该部分的值取0或1。值为0,掩码字符不作为数据的一部分;值为1,则掩码字符作为数据的一部分。

(3)指明用什么字符代替未输入的字符。例如,课程编号由1个字母和3个数字组成,在输入课程编号时,可以使用掩码字符串“L000;1;_”来进行输入数据的限制。

Text属性

该属性可以取到该组件对象输入的文本内容。

TMaskEdit组件其实就是在文本编辑框的基础上加上了数据格式的限制,TEdit的常用方法及事件TMaskEdit组件也具有。如Clear方法、ClearSelection方法、SelectAll方法、OnChange事件、OnKeyPress事件等,详见前面关于文本编辑框TEdit组件的介绍。

2.TDBText组件

TDBText组件类似于TLabel组件,只是TDBText组件用于显示数据库表中记录的指定字段的值。因为TDBText组件显示的是表中当前记录指定的字段的值,所以它显示的内容也是动态的,在其中显示的内容随着记录指针的移动而变化。

TDBText组件位于组件面板的DataControls选项卡上,如图6.3所示。

图6.3组件面板上的DataControls选项卡

TDBText组件的主要属性如下:

DataSource属性

该属性是所有数据控制组件都有的,意义也相同,详见TDBGrid组件关于该属性的介绍。

DataField属性

大多数的数据控制组件如TDBText、TDBEdit、TDBMemo、TDBLookupComboBox等均具有该属性,是因为这些组件对象都是与数据库中表的某一个字段的值绑定在一起的,所以要指定该组件对象是与哪个字段绑定的。而TDBGrid组件没有该属性,是因为TDBGrid组件不是与某单个字段相关联的。

3.TDBEdit组件

TDBEdit组件是专门用于显示、编辑数据库表中当前记录的某个字段值的数据控制组件。在应用程序中,我们常常用一个TDBEdit组件来对应表中的一个字段。同样,通过设置其DataSource、DataField属性可以为TDBEdit组件对象指定表中相应的字段。

如果希望用户能够通过TDBEdit组件修改数据库表中的字段值,还要设置TDBEdit组件的ReadOnly属性值为False;若ReadOnly属性值为True,则只能浏览不能修改数据。

TDBEdit组件位于组件面板的DataControls选项卡上,如图6.3所示。

4.TDBMemo组件

TDBMemo组件能够显示多行文本,也允许用户在其中输入和修改多行文本信息,它是Delphi中用来显示和编辑数据库表中的大二进制类型的文本字段的唯一的数据控制组件。

TDBMemo组件位于组件面板的DataControls选项卡上,如图6.3所示。

1)TDBMemo组件的主要属性

ScrollBar属性

该属性指定TDBMemo组件是否显示滚动条。

AutoDisplay属性

由于TDBMemo组件中包含着大量的文本信息,因此应用程序在运行过程中要显示其中的信息便需要花费很多的时间,特别是当用户移动记录指针时,要更新TDBMemo组件中显示的信息,这样会大大减慢程序的运行速度。为此Delphi为TDBMemo组件设定了AutoDisplay属性,用来控制是否自动显示表中的备注型字段。当AutoDisplay设置为False时,在TDBMemo组件中只显示其对应表中的字段名而不显示字段中的文本信息,用户如果想浏览字段中的文本信息,双击TDBMemo组件即可;当设置AutoDisplay属性为True时,会自动显示其对应数据库表中的字段值。

WordWrap属性

该属性指定在TDBMemo组件中输入文本信息且输入到右边界时,是否自动换行。

2)TDBMemo组件主要的方法

在应用程序运行过程中,用户对TDBMemo组件中显示的文本信息是不能够进行剪切、复制和粘贴操作的,要想实现这些功能,用户必须在程序中调用TDBMemo的CutToClipboard、CopyToClipboard和PasteFromClipboard方法分别来实现剪切、复制和粘贴操作。

5.TDBLookupComboBox组件

TDBLookupComboBox组件在数据库应用程序中的作用比较大。例如,我们在修改课程信息时,课程信息中有授课的教师信息,该教师信息在课程信息表中是教师的员工编号,该员工编号是教师信息表中的主键,在课程信息表中是外键。在编辑该教师信息时,首先受到外键约束,不能随意修改;其次我们希望以下拉框的形式提供给我们选择而不是输入,并且希望下拉框中显示的数据为教师的姓名,这样更符合用户的需求。这样,提供给用户选择的是教师姓名(教师姓名在教师信息表中),而实际修改的却是课程信息表中的教师编号。这样的要求,看似比较复杂难于实现,但使用TDBLookupComboBox组件却可以轻松实现。

TDBLookupComboBox组件位于组件面板的DataControls选项卡上,如图6.3所示。

TDBLookupComboBox组件的主要属性如下:

DataSource属性

该属性指定修改的数据来自哪个数据集。

DataField属性

该属性指定修改的数据是数据集的哪个字段。

ListSource属性

该属性指定在下拉列表中提供选择的数据来自哪个数据集。

ListField属性

该属性指定在下拉列表中提供选择的数据来自数据集的哪个字段。

KeyField属性

该属性非常重要,在提供选择的数据与真正修改的数据之间一定是有联系的,由KeyField来说明这种联系。该属性可以在下拉列表中进行选择,提供选择的是ListSource属性对应的数据集的全部字段,该属性的值应该是与DataSource、DataField指定的字段值相对应的那个字段名称。

设置好上述属性,就可以在应用程序中实现:提供选择的是一组来自于一个数据表的某一字段的数据,而实际修改的是另一个数据表中的某字段值。

6.2.2TTable数据集组件对数据的操作

1.TTable组件的记录导航

TTable组件提供了一系列方法,对数据集中的记录进行导航,也即进行当前记录的定位。

First方法

该方法将记录指针移动到数据集的第一条记录。

Last方法

该方法将记录指针移动到数据集的最后一条记录。

Prior方法

该方法将记录指针移动到当前记录的前一条记录。

Next方法

该方法将记录指针移动到当前记录的后一条记录。

MoveBy方法

该方法接收一个Integer参数,将记录指针移动到当前记录的向前或向后指定数目的记录。

使用上述方法,结合BOF、EOF属性可以遍历数据表中的每一条记录。常用的方式

如下:

Table1.First;

whilenotTable1.EOFdo

begin

<处理当前的记录>

Table1.Next;

end;

2.TTable组件中的数据维护

数据集中的数据维护主要包括数据记录的添加、修改和删除。Delphi为TTable数据集组件提供了相应的方法用于其中的数据维护。

Edit方法

如果应用程序想对数据集中的数据记录进行修改,我们必须将数据集设置成编辑状态。Edit使数据集处于编辑状态,以便进行修改及删除等操作。当数据集处于编辑状态时,移动记录指针或调用Post方法都可以将当前记录的修改写回到磁盘数据库表中。在程序中,

Edit方法和Post方法常常配合在一起使用,用于修改表中的记录。

Append、Insert方法

Append和Insert方法都是将数据集组件置成插入状态,以在表中插入新记录。Append方法是在表的尾部插入一条空白记录,Insert方法是在当前记录的后面插入一条空白记录。不过增加记录到一个具有索引的表中时,都是按照索引顺序写入其位置,也就是说对于索引表Append方法和Insert方法的作用是一样的。

Insert方法和

Append方法插入的记录是空白记录,要真正插入一条新记录,我们还必须给新的空白记录的各个字段赋值,最后调用Post方法,将插入的记录写回数据库表。

Post方法

Post方法将插入或修改的记录写回磁盘上的数据库表,即投寄。当投寄成功时数据集回到浏览状态,若投寄不成功数据集仍然保持原有状态。

Post方法既可以显式地调用,也可以隐含地调用。当数据集处于编辑状态或插入状态,且移动记录指针时,Delphi会隐含地调用Post方法,将当前记录的修改写回数据库表;当程序调用Append方法或Insert方法时,也会隐含地调用Post方法,将先前数据集的修改写回数据库表。

Cancel方法

Cancel方法用于取消当前的操作。当程序还未调用Post方法对记录的修改写回数据库表时,调用Cancel方法,可以将记录恢复到没有修改之前的状态。在调用Cancel方法时,它总是将数据集置成浏览状态。

Delete方法

Delete方法用于删除表中的记录。调用Delete方法时,将删除表中当前记录,并且自动地将记录指针移到被删记录的下一条记录,同时将数据集置成浏览状态。

AppendRecord方法

语法:ProcedureAppendRecord(constValues:arrayofconst);

InsertRecord方法

语法:ProcedureInsertRecord(constValues:arrayofconst);

AppendRecord和InsertRecord方法分别与Append和Insert方法相似。它们都是用于在表中插入一条新记录,但这两个方法比Append和Insert方法更简单、更方便一些,它们直接在表中插入一条新记录,新记录的各个字段值组成的数组作为AppendRecord或InsertRecord方法的参数传递给新记录,并且不需显式地调用Post方法即可将插入的新记录写回数据库表。

在给插入的新记录赋字段值时,字段值数组可以为每一个字段提供一个值,或从左边一列开始依次为字段赋值。用户也可以省略字段序列后面的一些字段值,将会用空值来填充这些字段;用户也可以对那些明确希望用空值填充的字段传递给保留字NIL。

例如,数据表t1,有编号、姓名、成绩三个字段,可使用AppendRecord方法插入一条记录:

AppendRecord(['003','张三',90]);

SetFields方法

语法:ProcedureSetFields(constValues:arrayofconst);

调用该方法可以修改表中当前记录的多个字段的值。调用该方法之前必须将数据集部件置成编辑状态,调用该方法之后,还要调用Post方法,才能真正将当前记录的修改写回数据库表。调用该方法时,被修改的字段值必须要与表中实际存在的字段名对应,并且数据类型要相匹配。

Lookup方法

使用Lookup方法可用来查询数据,对数据表本身没有任何影响。

Lookup方法用于从参数KeyFields、KeyValues所标识的行中返回指定字段的值,其返回值是一个可变类型数组,存储返回的数据。其语法如下:

FunctionLookup(constKeyFields:String;constKeyValues:Variant;constResultFields:String):Variant;其中:

KeyFields标识查找的字段,若是多个字段,字段间用分号分隔;

KeyValues标识与KeyFields标识中的字段应相匹配;

ResultFields标识返回字段,如果是多个字段,字段间用分号分隔。

例如,下列代码将t_score数据集中查找student字段值为“20060058”且course字段值为“C001”的记录,返回该记录的score字段值并输出:

procedureTForm1.Button1Click(Sender:TObject);

var

r:variant;

s:string;

begin

t_score.Open;

r:=t_score.Lookup('student;course',vararrayof(['20060058','C001']),'score');

s:=r;

showmessage(s);

end;

Locate方法

Locate方法能够按照特定的条件进行记录定位。虽然同样可以用来查询数据,但与Lookup方法不同的是,查找到符合条件的记录指针将指向该记录,该记录成为当前记录,并返回True;若未定位成功,当前记录不变,并返回False。其语法如下:

FunctionLocate(constKeyFields:String;constKeyValues:Variant;Options:TLocateOptions)

:Boolean;

其中:

KeyFields、KeyValues同Lookup方法;

Options指定Locate方法的查找选项,参数值为loCaseInsensitive(忽略大小写)和loPartialKey(模糊查询)的集合。

例如,下列代码同样在t_score数据集中查找student字段值为“20060058”且course字段值为“C001”的记录,并输出该记录的score字段值:

procedureTForm1.Button1Click(Sender:TObject);

var

r:variant;

s:string;

begin

t_score.Open;

ift_score.Locate('student;course',vararrayof(['20060058','C001']),[])then

begin

s:=t_score['score'];

showmessage(s);

end;

end;

3.TTable组件中的字段值的引用

除了使用方法对数据进行操作,有时需要直接引用数据集中当前记录的字段值,以取其值或对其赋值。引用TTable组件对象当前记录的字段值的方式如下:

1)通过“数据集对象名['字段名']”形式直接引用字段值

这种对字段值的引用形式最常用也最简单。例如,数据集Table1对应着数据表COURSE,下列语句将COURSE表当前记录的ID字段的值赋值给Edit1的Text属性,以显示当前记录的ID字段值:

Edit1.Text:=Table1['ID'];下列语句将Edit1的文本内容赋值给COURSE表当前记录的ID字段,以修改当前记录的ID字段值:

Table1['ID']:=Edit1.Text;

2)通过字段组件对字段的值进行引用

数据库表的每一列在应用程序中都有其对应的一个字段组件。在应用程序运行过程中,随着数据集组件被激活,对应于数据库表中每一列的字段组件便动态地被创建。字段组件又称字段对象,它对应着数据库表中的列即字段,字段对象是不可见的组件。在设计过程中,程序设计人员利用字段编辑器(FieldsEditor)还可以创建永久性的字段组件。

字段组件在应用程序中始终是不可见的组件,在程序运行过程中如此,在程序设计阶段也是如此。但字段组件在应用中起着非常重要的作用,可以说它是所有数据控制组件从数据库表中显示、编辑数据的基础。这是因为字段组件直接对应着数据库表中的字段,浏览和修改表中的数据必须通过字段组件。

由于动态生成的字段组件是没有自己的名字的,因此必须利用特殊的手段获得数据库表中各字段对应的字段组件,然后对字段进行访问,方式有如下两种:

(1)使用数据集组件的Fields属性。

数据集组件的Fields属性是与数据集组件相关联的数据库表中各个字段对应的动态字段组件的名字列表。因此我们可以通过Fields属性的下标(即索引号)来访问各字段组件,从而访问数据库表中的各个字段。索引号从0开始,也就是说数据库表中第一个字段对应着Fields列表的0索引,第二个字段对应的Fields的索引号为1,以此类推。

下面的例子是访问COURSE表的第一个字段并在编辑框Edit1中显示其字段值,设数据集Table1与数据库表COURSE相关联:

Edit1.Text:=Table1.Fields[0].AsString;下面的代码是将编辑框Edit1中的字符值赋值给COURSE表中当前记录的第一个字段,以实现修改COURSE表当前记录的字段值:

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

(2)使用数据集组件的FieldByName方法。

在数据集组件中有一个FieldByName方法,专门用于访问数据集组件中动态生成的字段组件。调用FieldByName方法时,必须把数据库表中的字段名作为参数传给FieldByName,调用该方法后便可以得到该字段所对应的字段组件。这样通过字段组件我们便可以读写数据表中相应的字段值了。下面是访问COURSE表中的ID字段的代码:

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

Table1.FieldByName('ID').AsString:=Edit1.Text;6.2.3数据库自动连接

一般的应用程序均有自己实现的用户验证功能,进行使用该应用程序的用户名、密码及权限的验证。在这种情况下肯定不希望出现进行数据库连接的对话框,否则将有使用应用程序和登录数据库服务器的两套用户信息,会让用户感到极不方便。但是登录大部分的数据库服务器进行数据库连接时,要求提供操作数据库的用户名及密码,不出现输入用户名及密码的对话框,用户信息怎样提供呢?这就涉及到怎样实现无需输入连接数据库的用户信息就能够进行数据库的自动连接。

实现数据库的自动连接要使用TDatabase组件,除了设置其AliasName、DatabaseName之外,还有两个重要属性要进行设置:

LoginPrompt属性

LoginPrompt属性应该设置为False,此时将不显示数据库连接对话框。

Params属性

通过Params属性设置连接参数,一般要设置的参数有USERNAME和PASSWORD,其他参数根据需要决定是否进行设置。Params参数的设置可以在Params属性中直接进行,如图6.4所示;也可以通过双击TDatabase组件对象,在弹出的Database对话框中进行设置,如图5.13所示。图6.4中的参数之所以很多,是因为在Database对话框中点击了“Defaults”按钮,导入了默认参数。

图6.4TDatabase组件对象的Params属性设置

6.2.4主细表

有些时候,我们希望一个数据集中的数据是跟随另外一个数据集的当前记录在发生变化。例如,我们在操作课程信息表对应数据集时,希望教师信息表对应数据集的内容跟随课程信息表对应数据集的当前记录而发生变化,目的是反映出讲授某门课程的教师信息。例如,课程信息表当前记录的课程编号是“C005”,讲授教师员工号是“T06”,希望在教师信息表对应的数据集中只有教师员工号为“T06”的数据记录,这样我们可以非常方便地获取到“C005”课程的授课教师的姓名、所属教研室等信息,因为此时在教师信息表对应数据集中,只有该教师信息一条记录。而有时,我们希望是这样的情况,课程信息表的当前记录是哪门课程,在成绩表对应数据集中只有选修该门课程的所有学生的成绩信息,这样我们就可以非常方便地根据课程来浏览成绩信息。

这种情况在实际应用中是非常多见的,我们称之为主细表结构,跟随主表的当前记录而发生变化的表称为明细表。

实现主细表结构,需要设置明细表数据集组件对象的两个属性:

MasterSource属性

MasterSource属性指定主表对应的TDataSource组件对象名。

MasterFields属性

MasterFields属性指定主表和明细表之间建立联系的字段。主表和明细表之间建立一对多关系时,可能不只是基于一个字段,可能有多个字段。如果有多个字段,那么在说明MasterFields属性时,多个字段之间要用分号隔开。

在设计阶段一般是使用字段连接设计器(FieldLinkDesigner)为两个数据表创建一对多的关系,在ObjectInspector中双击明细表TTable组件的MasterFields便可以打开FieldLinkDesigner,进行一对多关系的创建。如创建COURSE表和TEACHER表之间的主细表关系时,使用FieldLinkDesigner设置明细表数据集对象的MasterFields,如图6.5所示。

图6.5使用FieldLinkDesigner设置MasterFields属性

6.3实

6.3.1教务管理子系统功能模块的创建

在Delphi7中创建一个新的工程,工程名为“TEACH.dpr”。

1.登录窗体

本工程的第一个窗体是登录窗体,窗体文件名是“clerk_login.pas”。用于用户身份验证。整个应用程序的数据库连接也在此窗体中实现。登录窗体的布局如图6.6所示。

图6.6登录窗体布局

表6-7登录窗体中主要组件对象及属性表

用户登录的功能在“登录”按钮button1的OnClick事件中完成,代码如下:

procedureTf_login.Button1Click(Sender:TObject);

begin

try

mydb.Open;

t_user.Filter:='id='''+edit1.Text+'''';

t_user.Filtered:=true;

t_user.Open;

except

application.MessageBox('请与系统管理员联系。','数据库连接错误',MB_OK);

application.Terminate;

end;

ift_user.RecordCount=1then

begin

ift_user['passwd']=edit2.Textthen

begin

ift_user['authority']='0'then

begin

f_login.Hide;

f_clerk.Show;

end

else

application.MessageBox('您不具备使用本系统的权限!','用户权限错误',MB_OK);

end

else

application.MessageBox('请确认密码!','密码错误',MB_OK);

end

else

application.MessageBox('请确认用户名!','用户名错误',MB_OK);

end;

2.主要功能窗体

主要功能窗体名为“clerk_main.pas”。教务管理子系统有两部分功能:课程信息维护和成绩数据维护。因此,使用PageControl组件的两个TabSheet来实现这两部分功能。为了对照普通组件和数据控制组件以凸显数据控制组件的优点,将添加课程信息和删除、修改课程信息分别处理,因此在“课程管理”页中又使用了一个PageControl组件,其两个TabSheet分别对应添加和删改课程信息。

1)添加课程信息

该界面的功能是添加课程信息,在界面上输入课程的具体信息,点击“确认”按钮,将该课程信息添加至COURSE表;点击“取消”按钮,则课程信息不添加至数据表。

界面布局如图6.7所示,其主要组件及属性见表6-8。

表6-8

添加课程界面主要组件对象及属性表

图6.7添加课程

关闭该窗体,整个应用程序应该关闭。在该窗体的OnClose事件中加入如下代码:

procedureTf_clerk.FormClose(Sender:TObject;varAction:TCloseAction);

begin

application.Terminate;

end;添加课程信息时要提供教师编号,由于教师编号直接输入不方便,且易违反外键约束。故使用Combobox组件进行教师信息的选择,这比输入的方式要方便许多,而且当中的教师信息来自于表TEACHER,所以不会违反外键约束。此处的教师信息是不随教学子系统的使用而发生变化的,所以在Combobox组件对象中填入教师号及姓名在窗体创建时完成即可。窗体的OnCreate事件代码如下:

procedureTf_clerk.FormCreate(Sender:TObject);

begin

t_teacher.Open;

combobox1.Clear;

whilenott_teacher.Eofdo

begin

combobox1.AddItem(t_teacher['id']+','+t_teacher['name'],nil);

t_teacher.Next;

end;

end;没有查看课程编号是否重复之前,不能进行添加操作,让“确认”不可用,代码在TabSheet4的OnShow事件中:

procedureTf_clerk.TabSheet4Show(Sender:TObject);

begin

button2.Enabled:=false;

end;查看在数据表COURSE中是否已经有此课程编号存在,若存在此编号还要添加该条记录,将违反主键约束。为了避免违反主键约束,放置命令按钮进行检查,若该课程编号在当前数据表COURSE中没有重复,“确认”按钮才可用,否则给出提示信息。

procedureTf_clerk.Button1Click(Sender:TObject);

begin

t_course.Filter:='id='''+trim(MaskEdit1.Text)+'''';

t_course.Filtered:=true;

t_course.Open;

ift_course.RecordCount=1then

begin

showmessage('该课程编号已存在,请重新输入!');

button2.Enabled:=false;

end

else

begin

showmessage('该课程编号可用!');

button2.Enabled:=true;

end;

end;

“取消”按钮的功能是不将输入的数据添加到数据表中,无需做什么操作,只需将前面输入的内容清除:

procedureTf_clerk.Button3Click(Sender:TObject);

begin

button2.Enabled:=false;

maskedit1.Text:='';

edit2.Text:='';

combobox1.Text:='';

spinedit1.Value:=0;

spinedit2.Value:=0;

memo1.Lines.Clear;

end;

“确认”按钮的功能是将当前输入的数据添加至数据表COURSE中。添加记录时数据集组件提供了Append与AppendRecord两种方法,注意两者的区别。为了使教师信息更加详细一些以便用户确认教师,在下拉框中给出了教师编号和姓名,在此要将这两个信息分离,取出教师编号添加至TEACHER字段中。记录添加后,应将前面输入的内容清除。代码如下:

procedureTf_clerk.Button2Click(Sender:TObject);

var

len1,len2,len:integer;

s1,s2,str:string;

begin

s1:=trim(combobox1.Text);

s2:=strpos(pchar(s1),pchar(','));

len1:=length(s1);

len2:=length(s2);

len:=len1-len2;

str:=copy(s1,1,len);//取教师列表中的教师编号

t_course.Filtered:=false;

t_course.Open;//t_course.AppendRecord([maskedit1.Text,trim(edit2.Text),str,spinedit1.Value,spinedit2.Value,memo1.

Text]);

t_course.Append;

t_course['id']:=maskedit1.Text;

t_course['name']:=trim(edit2.Text);

t_course['teacher']:=str;

t_course['credit_hour']:=spinedit1.Value;

t_course['period']:=spinedit2.Value;

t_course['intro']:=memo1.Text;

t_course.post;

Button3Click(nil);

end;

2)删除、修改课程信息

本界面的功能是对课程信息进行删除或修改操作。用一个RadioGroup组件对象让用户选择对课程信息做删除还是修改操作。删除、修改是对现有的课程信息进行操作,此处用一个DBGrid组件对象以表格形式给出现有的全部课程,以提供给用户进行选择。当选定数据表格中的一行时,在界面的右侧给出该课程的具体信息,删除操作时提供给用户进行课程确认,修改操作时直接在其中修改课程信息。点击“确认”按钮,确认删除或修改;点击“取消”按钮,取消前面的删除或修改操作。

图6.8删除、修改课程

表6-9删除、修改课程界面主要组件对象及属性表

表6-9删除、修改课程界面主要组件对象及属性表

“删除修改课程信息”页显示时,数据表格中应该出现现有全部课程的课程编号及课程名称信息。TabSheet5的OnShow事件代码如下:

procedureTf_clerk.TabSheet5Show(Sender:TObject);

begin

t_course.Filtered:=false;

t_course.Open;

dbgrid2.Columns[0].Width:=60;

dbgrid2.Columns[1].Width:=149;

dbgrid2.Refresh;

end;点击“取消”按钮,取消前面所做的更新。Button5的OnClick事件代码如下:

procedureTf_clerk.Button5Click(Sender:TObject);

begin

t_course.Cancel;

end;点击“确认”按钮,判断是删除还是修改操作,并执行相应操作。注意由于课程编号是SCORE数据表中的外键,删除课程信息时可能会违反外键约束。为了避免违反外键约束,删除课程信息之前应该先将SCORE数据表中的该课程的选修信息删除,删除前要让用户确认。

procedureTf_clerk.Button4Click(Sender:TObject);

begin

caseradiogroup1.ItemIndexof

0:

ifapplication.MessageBox('确认删除该课程信息吗?','删除确认',MB_OKCANCEL)=IDOK

then

begin

t_score.Filter:='course='''+t_course['id']+'''';

t_score.Filtered:=true;

t_score.Open;

ift_score.RecordCount>0then

begin

ifapplication.MessageBox('删除该课程信息将删除成绩表中此课程全部成绩信息,确认删除吗?','删除确认',MB_OKCANCEL)=IDOKthen

begin

whilenott_score.Eofdo

t_score.Delete;

t_course.Delete;

end;

end

else

t_course.Delete;

end;

1:

t_course.Post;

end;

end;

3)成绩管理

本界面的功能是按课程对该课程的成绩数据进行维护。在下拉框中选择课程编号,并在下方显示该课程的具体信息以便教务干事确认课程。确认是该课程后,点击“确认”按钮,将在下方的数据表格中显示课程编号、选修学生的学号及课程成绩,只有成绩列是可修改的,输入成绩数据即可。

图6.9成绩管理

表6-10成绩管理界面主要组件对象及属性表

编辑成绩信息,是针对某一门课程进行的,首先要确定课程的编号。课程的编号直接输入不够方便,在此使用ComboBox组件对象进行课程编号的选择。在“成绩管理”页显示时,应该在ComboBox2中填入现有的全部课程编号。TabSheet2的OnShow事件代码如下:

procedureTf_clerk.TabSheet2Show(Sender:TObject);

begin

dbgrid1.Columns[0].Width:=130;

dbgrid1.Columns[1].Width:=150;

dbgrid1.Columns[2].Width:=110;

dbgrid1.Enabled:=false;

t_course.Close;

t_teacher_1.Close;

t_course.DisableControls;

t_course.Filtered:=false;

t_course.Open;

combobox2.Clear;

whilenott_course.Eofdo

begin

combobox2.AddItem(t_course['id'],nil);

t_course.Next;

end;

end;

在下拉框中选择某课程编号后,下方立刻显示该课程的具体信息,注意显示的是教师姓名而非教师号,而教师姓名数据在COURSE表中是没有的,存在于TEACHER表中。怎样使教师表的当前记录动态地根据课程表的当前记录发生变化,从而使得教师表的当前记录即为教授课程表当前记录课程的教师信息?这里采用了主细表的方式,即COURSE表为主表,TEACHER表为明细表。主细表是通过明细表的MasterSource及MasterFields属性来设置的。

点击“确认”按钮,确认编辑该课程的成绩数据,数据表格dbgrid2中显示该门课程的全部选修信息,提供给用户编辑成绩。

procedureTf_clerk.Button6Click(Sender:TObject);

begin

t_score.Filter:='course='''+t_course['id']+'''';

t_score.Filtered:=true;

t_score.Open;

dbgrid1.Enabled:=true;

end;图6.10用户登录窗体

6.3.2系统的实现

通过以上步骤,本案例已完成。程序启动后,首先会弹出一个用户登录窗体,如图6.10所示。

输入用户名和密码后,单击“登录”按钮,程序验证用户名、密码和权限,若其中任一处验证失败,将分别给出提示信息。验证通过,将显示主要功能窗体,如图6.11所示。

图6.11添加课程信息

输入课程编号,点击“查看编号是否冲突”按钮,若数据表中已存在该课程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论