设计方法及代码
一、设计要求方法
创建一个学生信息管理系统,可以完成学生基本信息及成绩的输入、修改和查询。具体要求如下:
(一)建立“学生信息”数据库
1. 建立数据库
利用Microsoft Access或VB中的“可视化数据管理器”建立数据库,名称为“Student.mdb”。 2. 建立数据表
在Student.mdb数据库中建立5个表: (1)学籍表
该表存放学生的基本信息,名称为“学籍”,结构如表3-1所示。
表3-1 学籍表结构
字段名 学号 姓名 性别 类型 大小 说明 字段名 类型 大小 说明 文本(Text) 20 文本(Text) 10 文本(Text) 2 主索引 出生日期 日期(Date) 班级 文本(Text) 20
表中暂时存放一条记录,各字段均不应为空。
(2)成绩表
该表存放学生成绩,名称为“成绩”,结构如表3-2所示。
表3-2 成绩表结构 字段名 学号 课程 分数 类型 文本(Text) 文本(Text) 大小 20 20 整型(Integer) 说明:
为减少数据冗余,成绩表中仅存储学号,不存储学生姓名,需要时根据学号从学籍表中获取姓名。
按照数据库设计规范,对“课程”亦应作类似处理。经过处理后,程序代码的编写量和难度均会明显增加。为了减轻初学者的编程负担,在成绩表中未对课程作规范化处理,而是
直接存储课程名称。
(3)课程信息表
该表存放课程信息,名称为“课程信息”,结构如表3-3所示。
表3-3 课程信息表结构
字段名 课号 课程 类型 大小 说明 主索引 文本(Text) 10 文本(Text) 20
说明:
基于前面所述的原因,在程序中没有将“课号”作为检索字段。 (4)用户表
该表存放用户登录信息,名称为“用户”,结构如表x-4所示。
表3-4 用户表结构
字段名 类型 大小 16 16 10 说明 主索引 用户名 文本(Text) 密码 权限 文本(Text) 文本(Text)
表中暂时存放两条记录,内容如表3-5所示。
表3-5 用户表内容 用户名 Admin User 密码 权限 123456 管理员 123 普通
(5)临时表
该表作为临时工作表,名称为“临时”,用于输入成绩,结构如表3-6所示。
表3-6 临时表结构 字段名 学号 姓名 分数 类型 文本(Text) 文本(Text) 整型(Integer) 大小 20 10
方法:
在数据库中设计“临时”表的目的是兼顾DataGrid控件的使用和减少数据冗余。
为了减少数据冗余,在“成绩”表中未包含学生姓名,而以“学号”与“学籍”表相关联。尽管这样做符合数据库设计规范,但是某些数据绑定控件的使用却因此而受到。例如,DataGrid控件以表格形式显示数据,具有较强的数据显示和编辑功能,可以进行成批数据的连续录入。令人遗憾的是,与DataGrid控件绑定的记录集必须使用客户端游标(CursorLocation=adUseClient),若记录集采用服务器端游标(adUseServer),该控件将无法显示数据。使用客户端游标的记录集在功能上有很多,对于多表查询来说,若所生成的
记录集的输出字段来自两个或更多表,则不能进行更新操作;若查询虽然涉及多表,但输出字段仅来自其中一个表,修改更新操作不受影响。以下面的两条SQL语句为例:
① SELECT 成绩.学号,学籍.姓名,成绩.课程,成绩.分数 FROM 成绩,学籍 WHERE 成绩.学号=学籍.学号
② SELECT 成绩.学号,成绩.课程,成绩.分数 FROM 成绩,学籍 WHERE 成绩.学号=学籍.学号
语句①所选择的查询输出字段(SELECT语句)来自两个表,采用客户端游标生成记录集后可以在各种数据绑定控件中正常显示,但不能修改、更新数据。若在程序中执行更新操作,将出现如图3-2所示的错误提示。
图3-2 错误信息
语句②的查询输出字段仅来自“成绩”表,尽管在查询条件(WHERE子句)中涉及两个表,但不影响更新操作。
为了充分发挥DataGrid控件的数据编辑功能,同时兼顾数据库设计规范,可以用一个临时工作表存放多表查询的结果,将多表操作转换为单表操作。数据流程如下:
多表查询→记录集→临时表→录入、修改→存入基本表。
(二)用户登录窗体
本窗体(frmLogin)作为系统的启动窗体,用于验证用户是否合法,运行时界面如图3-3所示。
图3-3 用户登录
方法:
窗体上两个文本框分别用于输入用户名和密码,其中密码文本框的内容用“*”显
示。
在窗体上添加一个ADO数据控件,设Visible=False,将其与数据库连接,用SQL
语句将记录源与数据库中的“用户”表绑定。
单击“确定”按钮后,查询“用户”表中是否有相符的用户名和密码,若不符,提
示重新输入,焦点返回文本框。如果3次输入错误,退出系统。若输入正确,将用户名和用户权限保存在全局变量中,显示系统主窗体,卸载本窗体。 单击“取消”按钮,退出系统。
注意:保存用户名和用户权限需要建立一个标准模块(Module1),用Public关键字声明两个全局变量,将“用户登录”窗体运行时输入的用户名和用户权限存入全局变量中,以供其他模块调用。
(三)设计系统主窗体
系统主窗体(frmMain)作为学生信息管理系统的主界面,如图3-4所示。
图3-4 主窗体
窗体中菜单结构如表3-7。
表3-7 菜单结构
主菜单 系统 学籍管理 课程管理 成绩管理 帮助 菜单项 添加用户 添加学籍信息 添加课程 输入成绩 关于 删除用户 修改学籍信息 修改课程 修改成绩 更改权限 查询学籍信息 修改密码 退出系统 查询成绩
方法:
单击某一菜单项时,显示对应窗体。
只有用户权限为“管理员”的用户才有权使用“系统”菜单中的“添加用户”、“删
除用户”和“更改权限”三个菜单项的功能。因此,应在窗体加载时根据保存在全局变量中的用户权限确定是否显示这三个菜单项。
(四)学籍管理模块
“学籍管理”菜单下有三个菜单项:添加学籍信息、修改学籍信息和查询学籍信息。 1. 添加学籍信息
单击“添加学籍信息”菜单项后显示“添加学籍信息”窗体(frmAddEss),运行时界面如图3-5所示。
图3-5 添加学籍信息
方法:
窗体上的文本框分别用于输入学号、姓名和出生日期,组合框用于选择性别。 在窗体上添加一个ADO数据控件,设Visible=False,将其与数据库连接,用SQL
语句将记录源与数据库中的“学籍”表绑定。
单击“确认添加”按钮后,查询数据库“学籍”表中是否有相同的学号,若有,提
示该学号已存在,重新输入,焦点返回学号文本框。如果无相同学号,将学号、姓名、性别和出生日期添加到数据库“学籍”表中,卸载本窗体。
注意:在向数据库添加记录前,应判断数据是否合法,如:学号应为数字(可用
IsNumeric函数判断),出生日期应为日期型数据(可用IsDate函数判断),各文本框均不应空白。
单击“退出”按钮,卸载本窗体。 2. 修改学籍信息
单击“修改学籍信息”菜单项后显示“修改学籍信息”窗体(frmModiEss),运行时界面如图3-6所示。
(a) 浏览状态 (b) 修改状态
图3-6 修改学籍信息
方法:
在窗体上添加两个ADO数据控件,分别命名为adoEdit和adoGrade,将其与数据
库连接,用SQL语句将adoEdit的记录源与数据库中的“学籍”表绑定,设Align=2。设adoGrade的Visible=False,其记录源采用动态绑定方式,通过查询语句生成临时记录集,与学籍表同步更新。
“修改记录”框架的文本框分别用于显示和修改学号、姓名及出生日期,将它们的
DataSource均设为ADO数据控件,DataField分别与学号、姓名及出生日期字段绑定。组合框分别用于选择性别和班级,与ADO数据控件及对应字段绑定。
“选择班级”框架中的简单组合框(Style = 1)用于选择班级,筛选拟修改记录的
范围。
在窗体加载时,应将“修改记录”框架中各文本框和组合框锁定为只读
(Locked=True),并将“更新数据”和“取消修改”按钮设置为无效,其他按钮有效。 在“修改记录”按钮的单击事件中,解除对各文本框和组合框的锁定以便允许修改,
并将“修改记录”按钮设为无效,其他按钮有效。
单击“更新数据”按钮,执行记录集的Update方法确认修改(应注意检查数据的
合法性),并重新将各文本框和组合框锁定为只读,各按钮恢复为在窗体加载时状态。若修改了学号,成绩表中需作相应修改。
单击“取消修改”按钮,执行记录集的CancelUpdate方法取消修改,并重新将各文
本框和组合框锁定为只读,各按钮恢复为在窗体加载时状态。 单击“删除记录”按钮,执行Delete方法删除记录,同时删除成绩表中的相应记录。 单击“退出”按钮,卸载本窗体。 3. 查询学籍信息
单击“查询学籍信息”菜单项后显示“查询学籍信息”窗体(frmQueryEss),界面如图3-7所示。
(a) 全部显示 (b) 多条件复合查询
图3-7 查询学籍信息
方法:
在窗体上添加一个ADO数据控件,设Visible=False,将其与数据库连接,用SQL
语句将记录源与数据库中的“学籍”表绑定。
在窗体上添加一个DataGrid控件,设AllowUpdate=False。 框架中的两个文本框分别用于输入学号和姓名。
框架中的两个组合框分别用于选择或输入性别和班级。
在“查询”按钮的单击事件中,根据复选框的选中状态判断查询条件,是单一查询
还是复合查询,然后根据文本框和组合框中的内容,用SQL语句的模糊查询、多条件复合查询功能生成记录集,为ADO数据控件的RecordSource属性赋值,并且将DataGrid控件与ADO数据控件绑定。
在“全部”按钮的单击事件中,用SQL语句将学籍表中的全部记录构成记录集,
为ADO数据控件的RecordSource属性赋值,并且将DataGrid控件与ADO数据控件绑定。
单击“退出”按钮,卸载本窗体。
(五)课程管理模块
“课程管理”菜单下有两个菜单项:添加课程和修改课程。 1. 添加课程
单击“添加课程”菜单项后显示“添加课程”窗体(frmAddCourse),运行时界面如图3-8所示。
图3-8 添加课程
方法:
窗体上的文本框分别用于输入课程编号和课程名称。
在窗体上添加一个ADO数据控件,设Visible=False,将其与数据库连接,用SQL
语句将记录源与数据库中的“课程信息”表绑定。添加一个DataGrid控件,与ADO数据控件绑定,用于显示现有课程,设AllowUpdate=False。
单击“确认添加”按钮后,查询数据库“课程信息”表中是否有相同的课程编号,
若有,提示该课程编号已存在,重新输入,焦点返回课程编号文本框。如果无相同的课程编号,将课程编号和课程名称添加到数据库“课程信息”表中,卸载本窗体。 注意:在向数据库添加记录前,应判断数据是否合法:课程编号应为数字(可用
IsNumeric函数判断),各文本框均不应空白。 单击“退出”按钮,卸载本窗体。 2. 修改课程
单击“修改课程”菜单项后显示“修改课程”窗体(frmModiCourse),运行时界面如图3-9所示。
图3-9 修改课程
方法:
在窗体上添加一个ADO数据控件,将其与数据库连接,用SQL语句将记录源与数
据库中的“课程信息”表绑定。设Align=2。
窗体上的文本框分别用于显示和修改课程编号和课程名称,将它们的DataSource均
设为ADO数据控件,DataField分别与课程编号及课程名称字段绑定。 对文本框的锁定处理和各按钮的处理与“修改学籍信息”相似。
(六)成绩管理模块
“成绩管理”菜单下有3个菜单项:输入成绩、修改成绩和查询成绩。 1. 输入成绩
单击“输入成绩”菜单项后显示“输入成绩”窗体(frmInGrade),运时界面如图3-10所示。
图3-10 输入成绩
方法:
在窗体上添加四个ADO数据控件,均设Visible=False,名称分别为adoNoName、
adoInGrade、adoAdd和adoOldGrade,将其与数据库连接。设adoInGrade的LockType属性为4(批更新模式)。用SQL语句将adoAdd的记录源与数据库中的“成绩”表绑定。
框架中的组合框用于选择班级和课程,Style属性均为2(下拉式列表框)。窗体加
载时查询学籍表中的班级和课程信息表中的课程填充组合框的列表项。
添加两个DataGrid控件,名称分别为dgdGrade和dgdInGrade。程序运行时分别动
态地与adoOldGrade和adoInGrade绑定,用于显示现有成绩和输入成绩。
当用户选择了班级和课程后,用SQL语句生成当前班级、课程已有成绩记录集,
为ADO数据控件adoOldGrade的RecordSource属性赋值,并将DataGrid控件dgdGrade与ADO数据控件adoOldGrade绑定。根据用户所选班级构成学号姓名记录集,为ADO数据控件adoNoName的RecordSource属性赋值,同时将ADO数据控件adoInGrade与临时表绑定,并将临时表清空。查询已有成绩记录集和学号姓名
记录集,将当前课程尚无成绩的学号姓名加入临时表,将DataGrid控件dgdInGrade与ADO数据控件adoInGrade绑定,为输入成绩作准备。此时用户可以在DataGrid控件中连续输入多人的成绩。
单击“确认输入”按钮后,将临时表中的学号、分数以及课程组合框中的课程名称
追加到与ADO数据控件adoAdd绑定的成绩表中。
单击“取消”按钮,调用adoInGrade记录集的CancelBatch方法取消更新。 单击“退出”按钮,卸载本窗体。 2. 修改成绩
单击“修改成绩”菜单项后显示“修改成绩”窗体(frmModiGrade),运行时界面如图3-11所示。
图3-11 修改成绩
方法:
在窗体上添加两个ADO数据控件,分别命名为adoEdit和adoNoName,将其与数
据库连接,设Visible=False,其记录源均采用动态绑定方式,通过查询语句生成临时记录集。
“选择班级”框架中的组合框用于选择班级。“选择学生”框架中的DataGrid控件
dgdNoName用于显示当前班级学生在成绩表中已有成绩的学生学号和姓名。“当前记录”框架中的两个文本框用作提示。“修改成绩”框架中的组合框用于选择课程,文本框用于显示和修改分数。
当用户在班级组合框选择班级后,用SQL语句从学籍表和成绩表中筛选出当前班
级学生在成绩表中已有成绩的学生学号和姓名,显示在DataGrid控件dgdNoName中。
当用户在DataGrid控件dgdNoName中选择学生后,将其学号和姓名显示在“当前
记录”框架中的文本框中,同时查询成绩表中当前学生已有成绩的课程名称,填充到课程组合框中。
当用户在课程组合框中选择课程时,将该课程的分数显示在成绩文本框中。 对各控件的锁定处理与“修改学籍信息”相似。 3. 查询成绩
界面设计与“查询学籍信息”相似,如图3-12所示。
图3-12 查询成绩
“查询”和“全部”按钮的单击事件的处理与“查询学籍信息”相似,注意查询结果来自“学籍”和“成绩”两个表。
(七)系统模块
“系统”菜单下有5个菜单项:添加用户、删除用户、更改权限、修改密码和退出。 1. 添加用户
单击“添加用户”菜单项后显示“添加用户”窗体(frmUser),运行时界面如图3-13所示。
图3-13 添加用户
方法:
窗体上的文本框分别用于输入用户名和密码,其中输入和确认密码的文本框的内容
用“*”显示。
在窗体上添加一个ADO数据控件,设Visible=False,将其与数据库连接,用SQL
语句将记录源与数据库中的“用户”表绑定。
单击“确认”按钮后,查询数据库“用户”表中是否有相同的用户名和密码,若有,
提示该用户已存在,重新输入,焦点返回用户名文本框。如果无同名用户,将用户名和密码添加到数据库“用户”表中,并设默认权限为“普通”,用MsgBox语句提示添加用户成功。
单击“退出”按钮,卸载本窗体。 2. 删除用户
单击“删除用户”菜单项后显示“删除用户”窗体(frmDelUser),运行时界面如图3-14所示。
图3-14 删除用户
方法:
在窗体上添加一个ADO数据控件,设Visible=False。将其与数据库连接,用SQL
语句将记录源与数据库中的“用户”表绑定。设LockType = adLockBatchOptimistic(批更新模式,以备用户取消删除)。 在窗体上添加一个DataGrid控件,用于显示和选择用户表中的记录,设AllowUpdate
= False(不允许用户直接修改控件中的内容),将该控件与ADO数据控件绑定。 在窗体上添加一个框架,名称为fraDel,内含三个命令按钮。 单击“删除用户”按钮后,判断被选中的用户名,若为“Admin”,提示不允许删除
该用户。若选中了其他用户,询问是否删除,如果回答“是”,用记录集的Delete方法删除该记录。
单击“取消删除”按钮后,用记录集的CancelBatch方法取消删除操作。 单击“退出”按钮,卸载本窗体。
3. 更改权限
“更改权限”与“删除用户”的窗体界面相似,为了减少程序中的窗体数目,复用代码,将两项功能设计为共用一个窗体(frmDelUser)。设计时和运行时界面如图3-15所示。
(a) 设计时界面 (b) 运行时界面
图3-15 更改权限
方法:
在“删除用户”窗体上添加一个框架,名称为fraModi,设置其宽度和高度与框架
fraDel相同。在框架中添加一个用于选择权限的组合框(含有“普通”和“管理员”两个列表项)和两个命令按钮。窗体加载时使两个框架的位置重合。
在主窗体单击“删除用户”或“更改权限”菜单项时,根据被选中的菜单项修改
frmDelUser窗体的标题。在frmDelUser窗体的激活事件(Activate)中,根据窗体标题,显示对应的框架,隐藏另一个框架。
单击“确认修改”按钮后,将选择权限组合框中被选中的权限赋予用户表中当前记
录的“权限”字段。
将两个框架中的“退出”按钮设为控件数组,共用一个单击事件。 4. 修改密码
单击“修改密码”菜单项后显示“修改密码”窗体(frmModiPass),运行时界面如图3-16所示。
图3-16 修改密码
单击“确认”按钮后,根据保存在全局变量中的用户名查询用户表,将当前用户的新密码存入“用户”数据库。
(八)帮助模块
在“关于”菜单项的单击事件中用MsgBox语句显示本程序的版本号和版权信息,如图3-17所示。
图3-17 版本信息
(九)关于标准模块
在标准模块中主要是声明一些供本模块和其他模块使用的全局变量(如用于保存用户名和用户权限的变量)。对于各模块经常用到的一些程序段,亦可将其编制成子过程或函数,用Public关键字在标准模块中声明为公用过程。例如,本程序中有多个窗体需要用组合框选择班级,将填充组合框中班级列表项的程序段编制成一个公用过程,以组合框对象作为参数,即可实现代码的复用。
二、程序参考代码
(一)用户登录窗体
'用户登录窗体frmLogin Option Explicit
Dim Rs As ADODB.Recordset '定义记录集变量
Private Sub cmdCancel_Click() Unload Me End Sub
Private Sub cmdOk_Click()
Static intErr As Integer '静态变量累加出错次数 adoUser.Refresh '刷新记录集(关键语句) Set Rs = adoUser.Recordset '设置记录集变量 '检查用户名(利用记录集的Find方法,不区分大小写) Rs.Find \"用户名='\" & txtUserID.Text & \"'\" If Not Rs.EOF Then '若用户名正确 '检查密码
If Rs(\"密码\") = txtPassword.Text Then '若密码正确 gstrUser = txtUserID.Text '存用户名 If Rs(\"权限\") = \"管理员\" Then '存用户权限 gblnPurview = True Else
gblnPurview = False End If
frmMain.Show '显示主窗体 Unload Me '卸载本窗体 Else '若密码错误 intErr = intErr + 1 '错误数+1
If intErr = 3 Then '若出错3次,退出系统 Set Rs = Nothing Unload Me
Else '若出错不足3次,重新输入
MsgBox \"密码输入错误,请重新输入!\ With txtPassword '焦点返回密码框 .SelStart = 0
.SelLength = Len(.Text) .SetFocus End With End If End If
Else '若用户名错误 intErr = intErr + 1 '错误数+1
If intErr = 3 Then '若出错3次,退出系统 Set Rs = Nothing Unload Me
Else '若出错不足3次,重新输入 MsgBox \"用户名输入错误,请重新输入!\ With txtUserID '焦点返回用户框 .SelStart = 0
.SelLength = Len(.Text) .SetFocus End With End If End If End Sub
Private Sub Form_Initialize() ChDrive App.Path ChDir App.Path End Sub
Private Sub Form_Load() '窗体加载
cmdOk.Default = True '“确定”按钮为回车键缺省按钮 Dim sql As String
sql = \"SELECT * FROM 用户\" 'SQL语句用于创建动态记录集 adoUser.RecordSource = sql '设置记录源为动态记录集 End Sub
(二)系统主窗体
'主窗体frmMain Option Explicit
Private Sub Form_Initialize() '窗体初始化 ChDrive App.Path '设当前路径 ChDir App.Path
Me.WindowState = vbMaximized
Call MySize '调整控件位置 End Sub
Private Sub Form_Load()
'根据用户权限确定是否显示用户管理各菜单项 mnuAddUser.Visible = gblnPurview mnuDelUser.Visible = gblnPurview mnuModiPurview.Visible = gblnPurview
Call CreateConnection '调用标准模块中的过程建立连接 End Sub
Private Sub Form_Resize() '窗体改变大小
If Me.WindowState = vbMinimized Then Exit Sub If Me.Width < 6000 Then Me.Width = 6000 If Me.Height < 5000 Then Me.Height = 5000 Call MySize '调整控件位置 Me.Refresh End Sub
Private Sub mnuAbout_Click() '关于
MsgBox Space(6) & \"学生信息管理系统\" & Space(6) & vbCr & vbCr & Space(9) & \"版本: 1.0\"
End Sub
Private Sub mnuAddCourse_Click() '添加课程 frmAddCourse.Show Me.Hide End Sub
Private Sub mnuAddUser_Click() '添加用户 frmUser.Show Me.Hide End Sub
Private Sub mnuDelUser_Click() '删除用户 frmDelUser.Caption = \"删除用户\" frmDelUser.Show Me.Hide End Sub
Private Sub mnuExit_Click() '退出 Unload Me End Sub
Private Sub Form_Unload(Cancel As Integer) '主窗体卸载 On Error GoTo Quit Dim i As Integer Set pubCnn = Nothing
'在窗体集合中循环并卸载每个窗体。
For i = Forms.Count - 1 To 0 Step -1 Unload Forms(i) Next Exit Sub Quit:
End '出错时强制退出
End Sub
Private Sub mnuInputGrade_Click() '输入成绩 frmInGrade.Show Me.Hide End Sub
Private Sub mnuModiCourse_Click() '修改课程信息 frmModiCourse.Show Me.Hide End Sub
Private Sub mnuModiEss_Click() '修改学籍信息 frmModiEss.Show Me.Hide End Sub
Private Sub mnuModiGrade_Click() '修改成绩 frmModiGrade.Show Me.Hide End Sub
Private Sub mnuModiPurview_Click() frmDelUser.Caption = \"更改用户权限\" frmDelUser.Show Me.Hide End Sub
Private Sub mnuNew_Click() '添加学籍信息 frmAddEss.Show Me.Hide End Sub
Private Sub mnuPassWord_Click() '修改密码 frmModiPass.Show Me.Hide End Sub
Private Sub mnuQueryEss_Click() '查询学籍信息 frmQueryEss.Show Me.Hide End Sub
Private Sub mnuQueryGrade_Click() '查询成绩信息
frmQueryGrade.Show Me.Hide End Sub
Private Sub MySize() '自定义过程,窗体改变大小时调整控件位置 Dim FW As Long
Line1.X1 = 0: Line1.X2 = Me.ScaleWidth Line2.X1 = 0: Line2.X2 = Me.ScaleWidth FW = Me.ScaleWidth * 0.98
Shape1.Left = (FW - Shape1.Width) \\ 2 Shape2.Left = (FW - Shape2.Width) \\ 2 + 96 Label1.Left = (FW - Label1.Width) \\ 2 Label2.Left = (FW - Label2.Width) \\ 2 End Sub
(三)学籍管理模块
1. 添加学籍信息
'添加学籍信息窗体frmAddEss Option Explicit
Private Sub cboClass_LostFocus() '班级组合框失去焦点时检查列表,添加新项 Call NewClassItem(cboClass) '调用标准模块中的过程 End Sub
Private Sub cmdExit_Click() '退出 Unload Me End Sub
Private Sub cmdOk_Click() '确认添加 '各文本框若为空白,提示重新输入 If Trim$(txtSID.Text) = \"\" Then MsgBox \"请输入学号!\ txtSID.SetFocus Exit Sub End If
If Trim$(txtName.Text) = \"\" Then MsgBox \"请输入姓名!\ txtName.SetFocus Exit Sub End If
If Trim$(txtBorn.Text) = \"\" Then
MsgBox \"请输入出生日期!\ txtBorn.SetFocus Exit Sub End If
If Trim$(cboClass.Text) = \"\" Then
MsgBox \"请选择或输入班级!\ cboClass.SetFocus Exit Sub End If
adoAdd.Refresh '刷新记录集(关键语句) '检查是否有重复学号(利用记录集的Find方法)
adoAdd.Recordset.Find (\"学号='\" & txtSID.Text & \"'\") If Not adoAdd.Recordset.EOF Then '若已有该学号 MsgBox \"学号重复,请重新输入!\ Call FocusBack(txtSID) '焦点返回学号框 Exit Sub End If
If Not IsDate(txtBorn.Text) Then '出生日期若非日期型,重新输入 MsgBox \"出生日期应按日期格式(yyyy-mm-dd)输入!\ Call FocusBack(txtBorn) '焦点返回出生日期框 Exit Sub Else '若日期格式正确
txtBorn.Text = Format(txtBorn.Text, \"yyyy-mm-dd\") '转换为4位年份 With adoAdd.Recordset
.AddNew '添加记录 '为各字段赋值
.Fields(0) = Trim$(txtSID.Text) '学号 .Fields(1) = Trim$(txtName.Text) '姓名 .Fields(2) = Trim$(cboSex.Text) '性别
.Fields(3) = Trim$(txtBorn.Text) '出生日期 .Fields(4) = Trim$(cboClass.Text) '班级 .Update '更新数据库 End With
MsgBox \"学籍信息已成功添加!\ End If End Sub
Private Sub Form_Load() '窗体加载 Dim sql As String
sql = \"SELECT * FROM 学籍\" 'SQL语句用于创建记录集(源) adoAdd.RecordSource = sql '设置记录源 adoAdd.Refresh
Call AddClassItem(cboClass) '调用标准模块中的过程填充班级组合框 End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载 frmMain.Show '显示主窗体
End Sub
Private Sub txtSID_KeyPress(KeyAscii As Integer) '学号文本框 '按键非数字或回删键,取消
If Not IsNumeric(Chr(KeyAscii)) And KeyAscii <> 8 Then KeyAscii = 0 End If End Sub
2. 修改学籍信息
'修改学籍信息窗体frmModiEss Option Explicit
Dim sNo As String '存学号
Private Sub adoEdit_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) '移动记录指针时显示当前记录位置/总记录数 adoEdit.Caption = \"Record: \" & _
CStr(adoEdit.Recordset.AbsolutePosition) & _ \"/\" & adoEdit.Recordset.RecordCount End Sub
'若班级组合框处于允许编辑状态,失去焦点时检查列表,添加新项 Private Sub cboClass_Click()
If cboClass.Locked = True Then Exit Sub Call NewClassItem(cboClass) End Sub
Private Sub cboSelClass_Click() '单击选择班级组合框 Dim sqlN As String Dim strClass As String
strClass = cboSelClass.Text '获取班级名称
If strClass = \"全部\" Then strClass = \"%\" '利用通配符%可包括全体学生 sqlN = \"SELECT * FROM 学籍 WHERE 班级 like '\" _ & strClass & \"' ORDER BY 学号\" '根据所选班级重新打开记录集 adoEdit.RecordSource = sqlN adoEdit.Refresh End Sub
Private Sub cmdCancel_Click() '取消 With adoEdit.Recordset .CancelUpdate '取消更新 .MoveNext
.MovePrevious End With
Call MyLock(True) End Sub
Private Sub cmdDelect_Click() '删除 Dim Response As Integer
Response = MsgBox(\"删除当前记录吗?\询问\") If Response = vbYes Then With adoEdit.Recordset .Delete .MoveNext
If .EOF And .RecordCount > 0 Then .MoveLast End With
'删除成绩表中的相应记录 Dim sqlG As String
sqlG = \"SELECT * FROM 成绩 WHERE 学号='\" & Trim$(txtSID.Text) & \"'\" adoGrade.RecordSource = sqlG adoGrade.Refresh
With adoGrade.Recordset If .RecordCount > 0 Then .MoveFirst Do Until .EOF .Delete .MoveNext Loop End If End With
MsgBox \"删除成功。\提示\" End If End Sub
Private Sub cmdEdit_Click() '修改 sNo = Trim$(txtSID.Text)
Call MyLock(False) '用于输入信息的控件解锁 End Sub
Private Sub cmdExit_Click() Unload Me End Sub
Private Sub cmdUpdate_Click() '更新 On Error Resume Next '各输入框若为空白,提示重新输入
If Trim(txtSID.Text) = \"\" Then
MsgBox \"请输入学号!\ txtSID.SetFocus Exit Sub End If
If Trim(txtName.Text) = \"\" Then MsgBox \"请输入姓名!\ txtName.SetFocus Exit Sub End If
If Trim(txtBorn.Text) = \"\" Then
MsgBox \"请输入出生日期!\ txtBorn.SetFocus Exit Sub End If
If Trim$(cboClass.Text) = \"\" Then
MsgBox \"请选择或输入班级!\ cboClass.SetFocus Exit Sub End If
If Not IsDate(txtBorn.Text) Then '出生日期若非日期型,重新输入 MsgBox \"出生日期应按日期格式(yyyy-mm-dd)输入!\ With txtBorn .SelStart = 0
.SelLength = Len(.Text) .SetFocus End With Else '若日期格式正确
txtBorn.Text = Format(txtBorn.Text, \"yyyy-mm-dd\") '转换为4位年份 adoEdit.Recordset.Update '更新数据库
If Err = -2147467259 Then '该错误号为主键重复错误 adoEdit.Recordset.CancelUpdate
MsgBox \"学号重复,请重新输入!\ Call FocusBack(txtSID) '焦点返回学号框 Exit Sub End If
'若修改了学号,成绩表中需作相应修改 If Trim$(txtSID.Text) <> sNo Then Dim sqlG As String
sqlG = \"SELECT * FROM 成绩 WHERE 学号='\" & sNo & \"'\" adoGrade.RecordSource = sqlG adoGrade.Refresh
With adoGrade.Recordset If .RecordCount > 0 Then
.MoveFirst Do Until .EOF
.Fields(\"学号\") = Trim$(txtSID.Text) .MoveNext Loop End If End With End If
MsgBox \"学籍信息已成功修改!\ Call MyLock(True) '锁定 End If End Sub
Private Sub Form_Initialize() ChDrive App.Path ChDir App.Path End Sub
Private Sub Form_Load() '窗体加载
Call MyLock(True) '锁定相关控件 Call AddClassItem(cboClass) '填充班级组合框 Call AddClassItem(cboSelClass) '填充选择班级组合框 cboSelClass.AddItem \"全部\"
cboSelClass.ListIndex = cboSelClass.NewIndex End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
'自定义过程:锁定/解锁用于输入的控件
Private Sub MyLock(ByVal bLock As Boolean) txtSID.Locked = bLock 'True txtName.Locked = bLock 'True txtBorn.Locked = bLock 'True cboSex.Locked = bLock 'True cboClass.Locked = bLock 'True
cboSelClass.Locked = Not bLock 'False
cmdEdit.Enabled = bLock 'True
cmdCancel.Enabled = Not bLock 'False cmdUpdate.Enabled = Not bLock 'False cmdDelect.Enabled = bLock 'True
adoEdit.Enabled = bLock 'True End Sub
3. 查询学籍信息
'查询学籍信息窗体frmQueryEss Option Explicit Dim sql As String
Private Sub chkQuery_Click(Index As Integer) '选中复选框时,焦点移至输入控件 If chkQuery(Index).Value = vbUnchecked Then Exit Sub Select Case Index Case 0
txtNo.SetFocus Case 1
txtName.SetFocus Case 2
cboSex.SetFocus Case 3
cboClass.SetFocus End Select End Sub
Private Sub cmdAll_Click() '全部显示 'SQL查询语句
sql = \"SELECT 学号,姓名,性别,Format(出生日期,'yyyy-m-d') \" & _ \"As 出生日期,班级 FROM 学籍 ORDER BY 学号\" Adodc1.RecordSource = sql '生成记录集 Adodc1.Refresh '刷新 Set DataGrid1.DataSource = Adodc1 End Sub
Private Sub cmdExit_Click() Unload Me End Sub
Private Sub cmdQuery_Click() '查询 Dim sql1 As String Dim i As Integer Dim sqlA(3) As String
'字符串数组存放各种查询条件,下标与复选框控件数组索引对应。 ' SQL 语句中使用 Like 运算符、% 通配符可实现模糊查询。 sqlA(0) = \"学号 Like '%\" & Trim$(txtNo.Text) & \"%'\" sqlA(1) = \"姓名 Like '%\" & Trim$(txtName.Text) & \"%'\" sqlA(2) = \"性别 = '\" & Trim$(cboSex.Text) & \"'\"
sqlA(3) = \"班级 Like '%\" & Trim$(cboClass.Text) & \"%'\"
sql1 = \"\" '用于存放 SQL 语句中 WHERE 子句的条件 '循环遍历各查询条件复选框
For i = 0 To chkQuery.Count - 1
If chkQuery(i).Value = vbChecked Then '若某复选框被选中, If sql1 = \"\" Then '若只有一个复选框被选中, sql1 = sqlA(i) '利用字符串数组加入一个条件; Else '若有多个复选框被选中,
sql1 = sql1 & \" AND \" & sqlA(i) '用 AND 运算符加入多个条件。 End If End If Next
'退出循环后,若条件字符串为空,说明未选中任何复选框, '执行“全部”按钮单击事件过程的语句,显示全部记录。 If sql1 = \"\" Then Call cmdAll_Click Exit Sub End If
'SELECT 语句 + WHERE 子句的条件字符串形成完整的 SQL 语句
sql = \"SELECT 学号,姓名,性别,Format(出生日期,'yyyy-m-d') \" & _ \"As 出生日期,班级 FROM 学籍 WHERE \" & sql1 & \" ORDER BY 学号\"
Adodc1.RecordSource = sql '刷新Adodc1 Adodc1.Refresh
If Adodc1.Recordset.BOF Then '若记录集为空
MsgBox \"对不起,没有您所要查找的记录。\ Exit Sub End If
Set DataGrid1.DataSource = Adodc1 '重新绑定数据网格控件 End Sub
Private Sub Form_Load()
'窗体加载后在网格控件中显示所有学生信息 Call cmdAll_Click
DataGrid1.AllowUpdate = False '禁止修改网格控件的内容
Call AddClassItem(cboClass) '调用标准模块中的过程填充班级组合框 End Sub
Private Sub Form_Unload(Cancel As Integer)
frmMain.Show End Sub
(四)课程管理模块
1. 添加课程
'添加课程窗体frmAddCourse Option Explicit Dim sql As String
Private Sub cmdCancel_Click() '退出 Unload Me End Sub
Private Sub cmdOk_Click() '各文本框若为空白,提示重新输入
If Trim$(txtCourseNo.Text) = \"\" Then MsgBox \"请输入课程编号!\ txtCourseNo.SetFocus Exit Sub End If
If Trim$(txtCourseName.Text) = \"\" Then MsgBox \"请输入课程名称!\ txtCourseName.SetFocus Exit Sub End If
'检查是否有重复课号(利用记录集的Find方法) Adodc1.Refresh
Adodc1.Recordset.Find (\"课号='\" & txtCourseNo.Text & \"'\") If Not Adodc1.Recordset.EOF Then '若已有该课号 MsgBox \"课程编号重复,请重新输入!\ With txtCourseNo '焦点返回课号框 .SelStart = 0
.SelLength = Len(.Text) .SetFocus End With Exit Sub End If
With Adodc1.Recordset
.AddNew '添加记录 '为各字段赋值
.Fields(0) = Trim$(txtCourseNo.Text) '课号 .Fields(1) = Trim$(txtCourseName.Text) '课名 .Update '更新数据库 .Requery '重新查询 End With
Set DataGrid1.DataSource = Adodc1 '更新网格 txtCourseNo.Text = \"\" txtCourseName.Text = \"\" txtCourseNo.SetFocus
MsgBox \"课程信息已成功添加!\End Sub
Private Sub Form_Load()
sql = \"SELECT * FROM 课程信息 ORDER BY 课号\" 'SQL语句用于创建动态记录集 Adodc1.RecordSource = sql '设置记录源为动态记录集 With DataGrid1
Set .DataSource = Adodc1 .AllowUpdate = False .Columns(0).Width = 1000 End With End Sub
Private Sub Form_Unload(Cancel As Integer) frmMain.Show '显示主窗体 End Sub
2. 修改课程
'修改课程窗体frmModiCourse Option Explicit
Private Sub adoEdit_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) '显示当前记录位置/总记录数
adoEdit.Caption = \"Record: \" & _
CStr(adoEdit.Recordset.AbsolutePosition) & _ \"/\" & adoEdit.Recordset.RecordCount End Sub
Private Sub cmdCancel_Click() '取消 With adoEdit.Recordset .CancelUpdate '取消更新 .MoveNext .MovePrevious End With
Call MyLock(True) End Sub
Private Sub cmdDelect_Click() '删除 Dim Response As Integer
Response = MsgBox(\"删除当前记录吗?\询问\") If Response = vbYes Then With adoEdit.Recordset .Delete .MoveNext
If .EOF Then .MoveLast End With End If End Sub
Private Sub cmdEdit_Click() '修改 Call MyLock(False) End Sub
Private Sub cmdExit_Click() Unload Me End Sub
Private Sub cmdUpdate_Click() '更新 On Error Resume Next
'各文本框若为空白,提示重新输入
If Trim$(txtCourseNo.Text) = \"\" Then MsgBox \"请输入课程编号!\ txtCourseNo.SetFocus Exit Sub End If
If Trim$(txtCourseName.Text) = \"\" Then MsgBox \"请输入课程名称!\ txtCourseName.SetFocus Exit Sub End If
adoEdit.Recordset.Update '更新数据库
If Err = -2147467259 Then '该错误号为主键重复错误 MsgBox \"课程编号重复,请重新输入!\ With txtCourseNo '焦点返回课号框 .SelStart = 0
.SelLength = Len(.Text) .SetFocus End With Exit Sub End If
MsgBox \"课程信息已成功修改!\
Call MyLock(True) '锁定 End Sub
Private Sub Form_Initialize() ChDrive App.Path ChDir App.Path End Sub
Private Sub Form_Load() Call MyLock(True) End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
Private Sub MyLock(ByVal bLock As Boolean) '自定义过程:锁定/解锁用于输入的控件 txtCourseNo.Locked = bLock 'True txtCourseName.Locked = bLock 'True cmdEdit.Enabled = bLock 'True
cmdCancel.Enabled = Not bLock 'False cmdUpdate.Enabled = Not bLock 'False adoEdit.Enabled = bLock 'True End Sub
(五)成绩管理模块
1. 输入成绩
'输入成绩窗体frmInGrade Option Explicit
Private Sub cboClass_Click() '班级组合框
If Trim$(cboCource.Text) = \"\" Then Exit Sub Call GetOldGrade '获取已有成绩 Call MakeTempTable '生成临时表 cmdOk.Enabled = True End Sub
Private Sub cboCource_Click() '课程组合框 If Trim$(cboClass.Text) = \"\" Then Exit Sub Call GetOldGrade '获取已有成绩 Call MakeTempTable '生成临时表 cmdOk.Enabled = True
End Sub
Private Sub cmdCancel_Click() '取消
If adoInGrade.Recordset Is Nothing Then Exit Sub adoInGrade.Recordset.CancelBatch End Sub
Private Sub cmdExit_Click() '退出 Unload Me End Sub
Private Sub cmdOk_Click() '确认输入 Dim Rp As Integer
Rp = MsgBox(\"“确认输入”后将无法取消,是否继续?\提示\")
If Rp = vbNo Then Exit Sub cmdOk.Enabled = False '将临时表中的数据追加到成绩表中 With adoInGrade.Recordset
If .RecordCount = 0 Then Exit Sub .MoveFirst Do Until .EOF
'注意对数据库中NULL值的判断,VB表达式与SQL表达式不同 If Not IsNull(.Fields(\"分数\")) Then adoAdd.Recordset.AddNew
adoAdd.Recordset(\"学号\") = .Fields(\"学号\").Value adoAdd.Recordset(\"课程\") = cboCource.Text adoAdd.Recordset(\"分数\") = .Fields(\"分数\").Value adoAdd.Recordset.Update End If .MoveNext Loop End With
'延时,以便完成数据库后台更新 Dim sngWait As Single sngWait = Timer
Do Until Timer - sngWait > 1# fraWait.Visible = True DoEvents Loop
fraWait.Visible = False
MsgBox \"添加成绩成功。\
Call cboCource_Click '刷新控件 End Sub
Private Sub Form_Load() '窗体加载
'填充课程组合框列表。该记录集仅在窗体加载时使用一次, '因此借用添加成绩的 ADO 数据控件
adoAdd.RecordSource = \"SELECT * FROM 课程信息\" adoAdd.Refresh
With adoAdd.Recordset Do Until .EOF
cboCource.AddItem .Fields(\"课程\").Value .MoveNext Loop End With
Call AddClassItem(cboClass) '填充班级组合框 cmdOk.Enabled = False
'打开成绩表
adoAdd.RecordSource = \"SELECT * FROM 成绩\" adoAdd.Refresh
'设输入成绩(临时表)记录集为批更新模式
adoInGrade.LockType = adLockBatchOptimistic End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
Private Sub GetOldGrade() '自定义过程:获取已有成绩并显示 Dim sql As String
'生成当前班级、课程已有成绩记录集
sql = \"SELECT 成绩.学号 AS 学号,学籍.姓名,分数 \" _ & \" FROM 成绩,学籍 WHERE 成绩.学号=学籍.学号\" _ & \" AND 成绩.课程='\" & cboCource.Text & \"'\" _ & \" AND 学籍.班级='\" & cboClass.Text & \"'\" adoOldGrade.RecordSource = sql adoOldGrade.Refresh '设置DataGrid控件 With dgdGrade
Set .DataSource = adoOldGrade .Columns(0).Width = 1200 .Columns(1).Width = 1200
.AllowUpdate = False End With End Sub
Private Sub MakeTempTable() '自定义过程:生成临时表并显示 Dim sql As String
adoInGrade.RecordSource = \"SELECT * FROM 临时\" adoInGrade.Refresh
'删除临时表中的记录
With adoInGrade.Recordset
'用记录集的Delete方法(客户端游标只能删除当前记录) Do While .RecordCount > 0 .MoveFirst .Delete Loop
.UpdateBatch End With
'根据所选班级构成学号姓名记录集
sql = \"SELECT 学号, 姓名 FROM 学籍 \" _
& \" WHERE 班级='\" & cboClass.Text & \"'\" adoNoName.RecordSource = sql adoNoName.Refresh
'将当前课程尚无成绩的学号姓名加入临时表,为输入成绩作准备 With adoNoName.Recordset Do Until .EOF
If adoOldGrade.Recordset.RecordCount > 0 Then '关键语句 adoOldGrade.Recordset.MoveFirst End If
adoOldGrade.Recordset.Find \"学号='\" & .Fields(\"学号\").Value & \"'\" If adoOldGrade.Recordset.EOF Then adoInGrade.Recordset.AddNew
adoInGrade.Recordset(\"学号\") = .Fields(\"学号\").Value adoInGrade.Recordset(\"姓名\") = .Fields(\"姓名\").Value End If .MoveNext Loop
adoInGrade.Recordset.UpdateBatch End With
'设置DataGrid控件
With dgdInGrade
Set .DataSource = adoInGrade .AllowUpdate = True
.Columns(0).Locked = True '锁定学号、姓名 .Columns(1).Locked = True .Columns(0).Width = 1100 .Columns(1).Width = 1100
If adoInGrade.Recordset.RecordCount > 0 Then .Col = 2 .Row = 0 .SetFocus End If End With End Sub
2. 修改成绩
'修改成绩窗体frmModiGrade Option Explicit
Dim strGrade As String
'在“选择学生”数据网格中选择学生时,显示当前记录内容
Private Sub adoNoName_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
If adoNoName.Recordset.BOF Or adoNoName.Recordset.EOF Then txtNo.Text = \"\" txtName.Text = \"\" txtGrade.Text = \"\" Exit Sub End If
'显示当前学号、姓名
txtNo.Text = adoNoName.Recordset(\"学号\").Value txtName.Text = adoNoName.Recordset(\"姓名\").Value
'查询成绩表中当前学生的各科成绩 Dim sql As String
sql = \"SELECT * FROM 成绩 WHERE 学号='\" & txtNo.Text & \"'\" adoEdit.RecordSource = sql adoEdit.Refresh '填充课程组合框 cboCourse.Clear
With adoEdit.Recordset Do Until .EOF
cboCourse.AddItem .Fields(\"课程\").Value
.MoveNext Loop End With
If cboCourse.ListCount > 0 Then cboCourse.ListIndex = 0 Else
txtGrade.Text = \"\" End If End Sub
Private Sub cboClass_Click() '单击班级组合框 Dim sqlN As String
'DISTINCT 关键字过滤重复记录
sqlN = \"SELECT DISTINCT 成绩.学号 AS 学号,姓名 \" _ & \" FROM 成绩,学籍 \" _
& \" WHERE 学籍.学号=成绩.学号 AND 班级 ='\" _ & cboClass.Text & \"' ORDER BY 成绩.学号\" '打开记录集
adoNoName.RecordSource = sqlN adoNoName.Refresh
'设置数据网格控件 With dgdNoName
Set .DataSource = adoNoName .Columns(0).Width = 1100 .Columns(1).Width = 1100 End With End Sub
Private Sub cboCourse_Click() '单击课程组合框
If Trim$(txtNo.Text) = \"\" Or Trim$(cboCourse.Text) = \"\" Then txtGrade.Text = \"\" Exit Sub Else
With adoEdit.Recordset '显示分数
If .RecordCount > 0 Then .MoveFirst .Find \"课程='\" & cboCourse.Text & \"'\" If .EOF Then Exit Sub
txtGrade.Text = .Fields(\"分数\").Value End With End If End Sub
Private Sub cmdCancel_Click() '取消 txtGrade.Text = strGrade Call MyLock(True) End Sub
Private Sub cmdDelete_Click() '删除
If Trim$(txtNo.Text) = \"\" Or Trim$(cboCourse.Text) = \"\" Then Exit Sub Dim Response As Integer
Response = MsgBox(\"删除当前记录吗?\询问\") If Response = vbYes Then With adoEdit.Recordset .Delete .Update
'延时,以便完成数据库后台更新 Dim sngWait As Single sngWait = Timer
Do Until Timer - sngWait > 1# fraWait.Visible = True DoEvents Loop
fraWait.Visible = False
If .RecordCount = 0 Then
MsgBox \"成绩表中已无该学生的成绩。\提示\" Else
MsgBox \"成绩删除成功。\提示\" End If
adoNoName.Refresh
dgdNoName.Columns(0).Width = 1100 dgdNoName.Columns(1).Width = 1100 End With End If
Call MyLock(True) End Sub
Private Sub cmdEdit_Click() '修改
If Trim$(txtNo.Text) = \"\" Or Trim$(cboCourse.Text) = \"\" Then Exit Sub strGrade = txtGrade.Text '暂存当前成绩 Call MyLock(False) '成绩框解锁 Call FocusBack(txtGrade) '焦点返回 End Sub
Private Sub cmdExit_Click() '退出 Unload Me End Sub
Private Sub cmdUpdate_Click() '更新 '成绩框若为空白,提示重新输入
If Trim$(txtGrade.Text) = \"\" Then
MsgBox \"请输入成绩!若无成绩,请将该记录删除。\提示\" Call cmdCancel_Click txtGrade.SetFocus Exit Sub End If '更新
With adoEdit.Recordset
.Fields(\"分数\").Value = Val(txtGrade.Text) .Update End With
MsgBox \"成绩修改成功。\
Call MyLock(True) '锁定 End Sub
Private Sub Form_Load() '窗体加载 Call MyLock(True) '锁定相关控件 Call AddClassItem(cboClass) '填充班级组合框 fraWait.Top = 1200 fraWait.Left = 1600
dgdNoName.AllowUpdate = False End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
'自定义过程:锁定/解锁相关控件
Private Sub MyLock(ByVal bLock As Boolean) txtGrade.Locked = bLock 'True=分数锁定 cboClass.Locked = Not bLock 'False=班级解锁 cboCourse.Locked = Not bLock 'False=课程解锁
cmdEdit.Enabled = bLock 'True=修改按钮有效 cmdCancel.Enabled = Not bLock 'False=取消按钮无效
cmdUpdate.Enabled = Not bLock 'False=更新按钮无效 dgdNoName.Enabled = bLock 'True End Sub
Private Sub txtGrade_KeyPress(KeyAscii As Integer) '成绩框按键 '按键非数字或回删键,取消
If Not IsNumeric(Chr(KeyAscii)) And KeyAscii <> 8 Then KeyAscii = 0 End If End Sub
3. 查询成绩
'查询成绩窗体frmQueryGrade Option Explicit
Dim sql As String '存SQL语句
Private Sub chkQuery_Click(Index As Integer) '选中复选框时,焦点移至输入控件 If chkQuery(Index).Value = vbUnchecked Then Exit Sub Select Case Index Case 0
txtNo.SetFocus Case 1
txtName.SetFocus Case 2
cboCourse.SetFocus Case 3
cboClass.SetFocus End Select End Sub
Private Sub cmdAll_Click() 'SQL查询语句
sql = \"SELECT 成绩.学号 AS 学号,姓名,课程,分数,班级 \" & _
\" FROM 成绩,学籍 WHERE 成绩.学号=学籍.学号 ORDER BY 成绩.学号\" Adodc1.RecordSource = sql '生成记录集,刷新 Adodc1.Refresh
Set DataGrid1.DataSource = Adodc1 End Sub
Private Sub cmdExit_Click() '退出 Unload Me End Sub
Private Sub cmdQuery_Click() '查询 Dim sql1 As String
Dim i As Integer Dim sqlA(3) As String
'字符串数组存放各种查询条件,下标与复选框控件数组索引对应。 ' SQL 语句中使用 Like 运算符、% 通配符可实现模糊查询。
sqlA(0) = \" 成绩.学号 Like '%\" & Trim$(txtNo.Text) & \"%'\" sqlA(1) = \" 姓名 Like '%\" & Trim$(txtName.Text) & \"%'\" sqlA(2) = \" 课程 = '\" & Trim$(cboCourse.Text) & \"'\" sqlA(3) = \" 班级 Like '%\" & Trim$(cboClass.Text) & \"%'\"
sql1 = \"\" '用于存放 SQL 语句中 WHERE 子句的条件 '循环遍历各查询条件复选框
For i = 0 To chkQuery.Count - 1
If chkQuery(i).Value = vbChecked Then '若某复选框被选中, If sql1 = \"\" Then '若只有一个复选框被选中, sql1 = sqlA(i) '利用字符串数组加入一个条件; Else '若有多个复选框被选中,
sql1 = sql1 & \" AND \" & sqlA(i) '用 AND 运算符加入多个条件。 End If End If Next
'退出循环后,若条件字符串为空,说明未选中任何复选框, '执行“全部”按钮单击事件过程的语句,显示全部记录。 If sql1 = \"\" Then Call cmdAll_Click Exit Sub End If
'SELECT 语句 + WHERE 子句的条件字符串形成完整的 SQL 语句 sql = \"SELECT 成绩.学号 AS 学号,姓名,课程,分数,班级 \" & _ \" FROM 成绩,学籍 WHERE 成绩.学号=学籍.学号 AND \" _ & sql1 & \" ORDER BY 成绩.学号\"
Adodc1.RecordSource = sql '刷新Adodc1 Adodc1.Refresh
If Adodc1.Recordset.BOF Then '若记录集为空
MsgBox \"对不起,没有您所要查找的记录。\ Exit Sub End If
Set DataGrid1.DataSource = Adodc1 '重新绑定数据网格控件
End Sub
Private Sub Form_Load() '窗体加载
'填充课程组合框,分组子句(GROUP BY)筛选重复课程 sql = \"SELECT 课程 FROM 成绩 GROUP BY 课程 \" _ & \" HAVING 课程<>NULL AND 课程<>''\" Adodc1.RecordSource = sql Adodc1.Refresh
With Adodc1.Recordset Do Until .EOF
cboCourse.AddItem .Fields(\"课程\").Value .MoveNext Loop End With
'填充班级组合框
Call AddClassItem(cboClass) '调用标准模块公有过程 DataGrid1.AllowUpdate = False '禁止修改网格控件的内容 End Sub
Private Sub Form_Unload(Cancel As Integer) frmMain.Show End Sub
(六)系统模块
1. 添加用户
'添加用户窗体frmUser Option Explicit
Private Sub cmdExit_Click() Unload Me End Sub
Private Sub cmdOk_Click() '确认 '检查各文本框是否为空
If Trim$(txtUserName.Text) = \"\" Then MsgBox \"请输入用户名!\ txtUserName.SetFocus Exit Sub End If
If Trim$(txtPassword1.Text) = \"\" Then MsgBox \"请输入密码!\ txtPassword1.SetFocus Exit Sub End If
If Trim$(txtPassword2.Text) = \"\" Then MsgBox \"请确认密码!\ txtPassword2.SetFocus Exit Sub End If
'检查两次输入密码是否一致
If Trim$(txtPassword1.Text) <> Trim$(txtPassword2.Text) Then MsgBox \"确认密码错误,请重新输入!\ With txtPassword2 .SetFocus .SelStart = 0
.SelLength = Len(.Text) End With Exit Sub End If
'SQL语句作为ADO控件的记录源
Adodc1.RecordSource = \"SELECT * FROM 用户 WHERE 用户名='\" txtUserName.Text & \"'\"
Adodc1.Refresh
With Adodc1.Recordset
If .BOF Then '检查是否有同名用户,若无,添加,若有,重新输入 .AddNew
.Fields(0) = Trim$(txtUserName.Text) .Fields(1) = Trim$(txtPassword1.Text) .Fields(2) = \"普通\" '默认权限为普通用户 .Update
MsgBox \"添加用户成功!\ Else
MsgBox \"此用户已存在!\ With txtUserName '焦点返回用户框 .SetFocus .SelStart = 0
.SelLength = Len(.Text) End With Exit Sub End If End With End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
2. 删除用户及更改权限
'删除用户、更改权限共用窗体frmDelUser
& Option Explicit
Private Sub cmdCancel_Click() '取消删除 adoUser.Recordset.CancelBatch adoUser.Refresh End Sub
Private Sub cmdDelete_Click() '删除按钮
If UCase$(adoUser.Recordset(\"用户名\")) = \"ADMIN\" Then MsgBox \"不能删除“Admin”用户。\提示\" Exit Sub End If
Dim intRsp As Integer Dim strQst As String
strQst = \"删除用户“\" & adoUser.Recordset(\"用户名\") & \"”吗?\" intRsp = MsgBox(strQst, vbQuestion + vbYesNo, \"询问\") If intRsp = vbYes Then
adoUser.Recordset.Delete '不执行更新操作,可以取消删除 End If End Sub
Private Sub cmdExit_Click(Index As Integer) Unload Me End Sub
Private Sub cmdValidate_Click() '确认对权限的修改 adoUser.Recordset(\"权限\") = cboPurview.Text End Sub
Private Sub Form_Activate() '窗体激活时 If Me.Caption = \"删除用户\" Then fraDel.Visible = True fraModi.Visible = False Else
fraDel.Visible = False fraModi.Visible = True End If End Sub
Private Sub Form_Load() '窗体加载
fraModi.Left = fraDel.Left '设置框架位置 fraModi.Top = fraDel.Top
With adoUser
.LockType = adLockBatchOptimistic '批更新模式,以备用户取消删除 .RecordSource = \"SELECT * FROM 用户 \" .Refresh End With
dgdUser.AllowUpdate = False '不允许修改DataGrid控件中显示的记录 Set dgdUser.DataSource = adoUser End Sub
Private Sub Form_Unload(Cancel As Integer)
adoUser.Recordset.UpdateBatch '窗体卸载时对删除或更改权限操作进行更新 frmMain.Show End Sub
3. 修改密码
'修改密码窗体frmModiPass Option Explicit
Private Sub cmdExit_Click() Unload Me End Sub
Private Sub cmdOk_Click() '确认 '检查各文本框是否为空
If Trim$(txtPassword1.Text) = \"\" Then MsgBox \"请输入新密码!\ txtPassword1.SetFocus Exit Sub End If
If Trim$(txtPassword2.Text) = \"\" Then MsgBox \"请确认新密码!\ txtPassword2.SetFocus Exit Sub End If
'检查两次输入密码是否相同
If Trim$(txtPassword1.Text) <> Trim$(txtPassword2.Text) Then MsgBox \"确认密码错误,请重新输入!\ With txtPassword2 .SetFocus .SelStart = 0
.SelLength = Len(.Text) End With Exit Sub End If
With Adodc1 '修改密码
.RecordSource = \"SELECT * FROM 用户 WHERE 用户名='\" & gstrUser & \"'\" .Refresh
.Recordset(\"密码\") = txtPassword1.Text .Recordset.Update End With
MsgBox \"密码修改成功!\End Sub
Private Sub Form_Unload(Cancel As Integer) '窗体卸载时 frmMain.Show End Sub
(七)标准模块
'标准模块Module1(Stud1.bas) Option Explicit
Public gstrUser As String '全局变量存用户名 Public gblnPurview As Boolean '全局变量存用户权限 Public pubCnn As New ADODB.Connection '全局连接对象供各模块使用
'建立连接
Public Sub CreateConnection()
pubCnn.CursorLocation = adUseClient
pubCnn.Open \"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Stud97.mdb\" End Sub
'填充班级组合框。参数为组合框对象变量
Public Sub AddClassItem(cboX As ComboBox) Dim rsTmp As New ADODB.Recordset '临时记录集
'过滤重复记录和空字段 '方法1:利用 GROUP BY 子句
' rsTmp.Open \"SELECT 班级 FROM 学籍 GROUP BY 班级 \" & _ \" HAVING 班级<>NULL AND 班级<>''\ pubCnn, adOpenStatic, adLockOptimistic
'方法2:利用 DISTINCT 关键字
rsTmp.Open \"SELECT DISTINCT 班级 FROM 学籍 \" & _ \" WHERE 班级<>NULL AND 班级<>''\ pubCnn, adOpenStatic, adLockOptimistic
'在组合框中添加班级 cboX.Clear
Do Until rsTmp.EOF
cboX.AddItem rsTmp(\"班级\")
rsTmp.MoveNext Loop
Set rsTmp = Nothing End Sub
'焦点返回文本框并反显内容。参数为文本框对象变量。 Public Sub FocusBack(txtX As TextBox) With txtX
.SelStart = 0
.SelLength = Len(.Text) .SetFocus End With End Sub
'班级组合框失去焦点时检查列表,若用户输入了新班级,添加新项
Public Sub NewClassItem(cboX As ComboBox) '参数为组合框对象变量 Dim i As Integer
Dim blnOld As Boolean '班级名称存在标志 Dim sNew As String
blnOld = False
sNew = Trim$(cboX.Text) '取用户在组合框输入的班级名称
For i = 0 To cboX.ListCount - 1 '若列表中已有该班级,设置标志,退出循环 If cboX.List(i) = sNew Or sNew = \"\" Then blnOld = True Exit For End If Next
If blnOld = False Then '若列表中无该班级名称,添加 cboX.AddItem sNew End If End Sub
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务