补充2,ADO+Access实现图书馆管理信息系统图书管理系统是一个常见的信息管理系统(MIS),典型的图书管理系统包括会员管理、书籍管理、借书、续借、丢失及赔偿等功能。本章将详细分析一个完整的图书管理系统的实施过程,包括需求分析、系统框架、系统建模、数据库建模、程序实现和系统维护等。
2.1 技术要点本章的知识要点可以分成两个部分,一个是系统分析层次的知识点,一个是程序员层次的知识点。对一个完整的系统来说,这两个方面是必不可少的,而更加重要的是系统分析这个层次,只有系统分析做好了,程序模块设计和代码编写才能够做得更好。本章主要介绍以下知识点:
图书馆管理系统的整个管理流程
图书馆管理系统的数据库设计控件动态绑定技术:介绍在数据库字段比较多的时候,如何使用控件数组及控件动态绑定到数据集技术,减少在显示数据时的大量重复代码。
数据敏感控件DataCombo的使用技术:介绍使用少量代码利用DataCombo控件显示数据表中某字段存在的信息的技术。
DataReport报表组件使用技术:介绍快速报表组件的使用技巧及动态绑定报表到数据集的技术。
ADO组件使用技术及技巧:介绍如何通过Connection对象连接后端数据库,使用Recordset对象实现对数据表的添加、修改、删除、查询技术。
公用窗体技术:介绍如何使用一个窗体提供几种主要业务,便于控件和窗体的共用,减少编程强度。
模拟Data控件技术:介绍使用4个按钮控件和1个标签(Label)控件模拟出Data控件的使用效果。
其他高级技术。
2.2 系统概况图书管理系统是一套功能完整、操作简便的图书管理及借书管理软件,包括图书管理系统、书籍管理系统、员工管理系统、会员管理系统、借书系统、罚款支付系统、系统设置与维护7大功能,实现了书籍及借书的自动管理。
图书管理系统可广泛适用于中小型图书馆和资料室。
2.2.1软件配置操作系统:Windows 98中文版、Windows 2000中文版、Windows XP中文版或更高;
数据库选择:Visual Access 2000;
开发平台:Visual Basic 6.0。
2.2.2硬件配置
CPU:Pentiun II 266或更高;
内存:64M或以上;
硬盘:2G以上;
扫描仪:扫描精度300dpi以上显示器:VGA或更高;
外设:报表打印机等。
2.3 需求分析需求分析是成功实施一个管理系统的基础,只有弄清楚客户的需求,才能真正开发出满足客户需求的管理信息系统,也才能够真正让整个系统发挥其相应的作用。接下来就针对图书管理系统的总体需求做分析,在实际开发过程中,可以在本系统需求分析中继续完善。
2.3.1 总体功能要求
在经过对图书管理流程进行详细了解与分析后,可以看出一个功能完整的图书管理系统必须包几个管理系统。
(1)图书信息管理系统考虑到图书馆书籍的特殊性,图书信息有其特殊的层次结构,如图2.1所示。
图2-1 图书信息的树状结构
往往由一些书籍(Titles)组成主题(Subjects),而每一书籍在图书馆中又有若干副本(书本,即Books)。因此,图书管理系统中包括主题信息管理(包括主题信息的添加、修改、删除及查找操作)、书籍信息管理(包括书籍信息的添加、.修改、删除及查询操作)、书本信息管理(包括书本信息的添加、删除及查询操作)。
(2)员工信息管理系统
这个管理系统包括图书馆工作人员基本信息的添加、修改、删除及查询功能。
(3)会员信息管理系统
这个管理系统包括会员信息的添加、修改、删除及查询功能。
(4)借书管理系统
这个管理系统包括借书、还书、预订书籍等功能。
(5)罚款管理系统这个管理系统包括丢失书籍罚款、会员支付罚款等功能。
(6)系统设置系统在这个系统中,可以设置会员最大借书数量、会员最大预订书数量、会员费、会员资格持续时间等系统参数。
(7)用户登录系统
用户分为三类:管理员、图书馆工作人员和会员,不同的用户根据不同的密码及用户类型登录,具有不同的权限。
(8)查询系统
分为书本查询和会员查询,可进行多个条件的组合查询,可进行精确和模糊查询。
(9)用户管理系统
可添加或删除用户,更改用户密码,变更用户身份类型等。
系统的功能需求可用图2-2来表示。
图2-2系统功能需求
2.3.2性能的需求
(1)精度要求图书管理系统对精度要求较低,仅需满足整型数据输入、存储和输出即可。
(2)时间特性要求在软件方面,响应时间、更新处理时间都要求比较快且迅速,以满足要求。
(3)灵活性当用户需求,如操作方式、运行环境、结果精度、数据结构与其他软件接口等发生变化时,设计的软件要求能做适当调整。
(4)规模适用于中小规模图书馆及资料室的图书管理工作。
2.4数据库设计及配置
2.4.1数据库设计数据库设计对于一个信息管理系统的顺利开发和运行是十分重要的,其目标为结构合理、易于维护、查询便捷、冗余信息少等。
本系统的数据库由8张表组成:Subjects(主题信息表)、Titles(书籍信息表)、Books(书本信息表)、Members(会员信息表)、Employees(员工信息表)、Fine(罚款支付信息表)、GlobalVariables (系统配置信息表)和Users(用户信息表)。它们之间的关系如图2-3所示。

图2-3关系图
下面对数据表进行逐一介绍。
Subjects表存储主题信息,其结构如表2.1所示。
表2—1 主题信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
Subject
文本
50
是
有(无重复)
是
主题名
IssueDays
数字
整型
出借期限
NoOfBooks
数字
整型
该主题下书籍数目
FjneCharge
数字
单精度型
罚款费用(每天)
ReverseCharge
数字
单精度型
预订费用
Titles表中存储书籍的基本信息,其结构如表2.2所示。
表2—2 书籍信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
TitleID
文本
50
是
有(无重复)
是
书籍编号
Subject
文本
50
所属主题
Author
文本
50
作者
Title
文本
50
书籍名称
Price
数字
单精度型
价格
Quantity
数字
整型
数量
AddOn
文本
50
附加信息
Books表中存储书本的基本信息,其结构如表2.3所示。
字段名
类型
大小
必填字段
索引
是否主键
意 义
TitleID
文本
50
是
所属书籍编号
BookID
文本
50
是
有(无重复)
是
书本编号
IsIn
是/否
是否在图书馆中
TypeIssue
是/否
范本出借
Condition
文本
50
书本状况
MemberID
文本
50
借阅会员编号
ReserveId
文本
50
预订会员编号
ReturnDate
日期/时间
归还日期
IssueCount
数字
整型
借出次数
Members表中存储会员基本信息,其结构如表2—4所示。
表2—4 会员信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
MemmberId
文本
50
是
有(无重复)
是
会员编号
DateOfJoining
日期/时间
加入日期
DateOfExpire
日期/时间
会员资格过期日期
FiestName
文本
50
姓
LastName
文本
50
名
BooksInHand
数字
整型
当前借书数量
FineBal
数字
单精度型
罚款金额
Address
文本
50
地址
Tel
文本
50
电话号码
Email
文本
50
Email地址
Employees表中存储员工基本信息,其结构如表2-5所示。
表2—5 员工信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
EmployeeId
文本
50
是
有(无重复)
是
员工编号
FirstName
文本
50
姓
LastName
文本
50
名
Address
文本
50
地址
Tel
文本
50
电话号码
Email
文本
50
Email地址
fine表中存储会员罚款支付信息,其结构如表2—6所示。
表2—6 罚款支付信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
MemberId
文本
50
是
有(无重复)
是
会员编号
FineAmount
数字
单精度型
支付罚款金额
PayDate
日期/时间
支付日期
GlobalVariables表中存储系统配置信息,其结构如表2-7所示。
表2-7 系统配置信息表
字段名
类型
大小
必填字段
索引
是否主键
意 义
TotallssueBooks
数字
整型
是
最大借书数量
RenewalCounter
数字
整型
是
最大续借数量
MaxFineBal
数字
单精度型
是
最大罚款额度
MembershipDuration
数字
整型
是
会员资格持续时间
MembershipFee
数字
单精度型
是
会费
RenewalFees
数字
单精度型
是
续借费用
Users表中存储用户信息,其结构如表2—8所示。
表2—8 用户信息表字段名
类型
大小
必填字段
索引
是否主键
意 义
UserName
文本
50
是
有(无重复)
是
用户名
UserPassword
文本
50
是
用户密码
UserType
数字
整型
是
用户类型
2.4.2数据库建立本例使用的后端数据库是Microsoft Access 2000,数据库及其表的建立比较简单,可参考前面相关内容,在此不多叙述。
2.5 系统程序实现
2.5.1设计概况为了让读者对本系统有一个大致了解,首先列举出本程序包含的窗体和模块及说明。窗体信息如下:
frmLogin(系统登录窗体):对用户名、用户密码、用户类型进行验证。
MDIForm1(程序主窗体):将系统提供的各种功能集中呈现于用户面前。
frmSubiects(主题信息管理窗体):提供对书籍主题信息的添加、修改、删除、浏览、查询等功能。
frmTitles(书籍信息管理窗体):提供书籍基本信息的添加、修改、删除、浏览、查询等功能。
frmBooks(书本信息管理窗体):提供对书本基本信息的添加、修改、删除、浏览、查询等功能。
frmMembers(会员信息管理窗体):提供对会员基本信息的管理功能,如添加会员、删除会员、修改会员信息、查询特定会员等。
frmEmployees(员工信息管理窗体):提供对员工基本信息的管理功能,如添加员工、删除员工、修改员唐息、查询特定员工等。
frmlssue(业务窗体):本窗体实现的功能比较多,如借阅书籍、还书、续借书籍、丢失书籍、赔款、预订书籍等。它也是本系统的最重要的窗体,大部分图书管理的业务逻辑均存在于这个窗体中。
frmOptions(系统配置窗体):提供对系统的一些配置选项,如会员最大借书数量、会员最大预定数量、最大罚款金额、会员资格持续时间、会员费用、会员续办费用等。
frmFindBook(书籍查询窗体):按书籍编号、书籍名称、作者、主题、价格等进行精确或模糊查询。
frmFindMember(会员查询窗体):按会员编号、姓、名、电话、地址、email等进行精确或模糊查询。
frmUser(用户管理窗体):提供用户添加、删除、更改密码、更改用户类型的管理功能。
frmAbout(关于窗体):提供软件的名称、版本、版权、作者、维护等信息。
以上介绍的是程序的重要窗体,其中frmSubjects、frmTitles、frmBooks、frmMembers和frmEmployee均是信息管理系统的标准窗体设计,具有一定相似性和代表性,可以依照这两个窗体的模式编写出适合其它信息系统的管理窗口。
还有一个部分即模块文件,具体为:
m.bas(主模块):主要功能为将系统配置信息从GlobalVariables表中读入系统。
在阅读下面的具体程序以前,可先了解每个窗体的大致功能,这对了解整个程序的开发实施是非常有益的。在后面的具体程序实现中,由于篇幅的限制,不会时所有的代码都进行详细分析,而只是针对关键的模块和技术进行介绍。
2.5.2系统登录窗体
1,登录窗体的功能系统登录模块是由系统登录窗体(frmLogin)构成,界面如图2-4所示。
本系统是一个基于不同用户的系统。在本系统中有3类不同的用户:管理人员、图书馆工作人员和会员。因此,在系统启动时,需要显示一个登录窗口,以供用户选择不同类型的身份登录,然后根据不同的用户身份,来显示不同的功能。

图2-4 frmLogin窗体的设计示意图
2.登录窗体的设计登录窗体的主要控件及其属性如表2-9所示。
表2-9 登录窗体主要控件及其属性设置
控件
名称
属性设置
Form
frmLogin
BorderStyle属性设为3,Caption属性设为“请登录”
Frame
fraLogin
Caption属性设为“登录”
Label
lblLabels
Caption属性设为“用户名:”,Index属性为0
TextBox
txtUser
Text属性设为空
Label
lblLabels
Caption属性为“口令:”,Index属性为l
TextBox
txtPwd
Text属性设为空
Label
lblLabels
Caption属性为“选择身份:”,Index属性为2
ComboBox
cboUserType
Style属性为“2-Dropdown List”
CommandButton
cmdOK
Caption属性设为“确定”,Default属性为True
CommandButton
cmdCancel
Caption属性设为“取消”,Cancel属性为False
3.窗体的工作流程/方式系统开始运行时,首先会登录窗体。由于本窗体是一个面向多用户的系统,不同的用户在使用统时,将会拥有不同的功能。登录窗体的作用就是确定当前使用系统的用户的类型。
当窗体运行时,用户首先要在用户名和口令这两个文本框中输入其用户名和口令,然后在身份组合框中选择不同的身份(管理人员、图书馆工作人员和会员)。
在窗体的Load事件中,首先就是需要将用户的3种不同的身份添加到cboUserType中,以供用户选择其身份之用。在“确定”按钮的Click事件响应中,程序将会根据用户输入的用户名和口令,及其选择的用户身份,在数据库中的Users表中查找对应的用户。在Users中,“用户名”字段对应用户输入的用户名,“用户密码”字段对应用户输入的口令,“用户类型”字段对应用户所选择的身份。
·如果在UserList表中找到了对应的用户,则退出登录窗体,并进入到MDI主窗体,并根据不同的用户身份,来向用户开放不同的功能。
·如果在Users表中没有找到对应的用户,则提示用户再次输入,如果超过3次,还不能找到用户,则表示用户无权使用本系统,并退出系统。
4.编写窗体代码
(1)本系统需要打开数据库及记录集,以及根据不同的用户来显示不同的功能,需要添加全局性变量和过程。因此在标准模块m.bas中添加变量和如下:
Public cnn As New ADODB.Connection '数据库连接对象
Public g_sql As String '要执行的SQL语句
Public rs As New ADODB.Recordset '记录集对象
Public g_Usertype As Integer '用户类型
Public g_userName As String '用户名
Public Sub openDatabase()
cnn.Open "provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
App.Path & "\library.mdb;Persist Security Info=False"
'打开与数据库的连接
End Sub
(2)在frmLogin窗体模块中,处理Form的Load事件。在该事件响应中,初始化 cboUserType的内容,代码如下:
Private Sub Form_Load()
Call openDatabase
cboUserType.Clear
cboUserType.AddItem "管理员",0
cboUserType.AddItem "图书馆工作人员",1
cboUserType.AddItem "借阅者",2
cboUserType.ListIndex = 0
txtUser.Text = ""
txtPwd.Text = ""
End Sub
(3)在frmLogin窗体中,处理cmdOK的Click事件。在该事件响应中,验证用户所输入的用户名、口令和身份是否匹配。代码如下:
Private Sub cmdOK_Click()
If Trim(txtUser.Text) = "" Or Trim(txtPwd.Text) = "" Then
MsgBox "请先输入用户名及其密码!",vbInformation,"注意"
Exit Sub
End If
'取得用户类型和用户名,保存在标准模块m.bas的全局变量'g_userType和g_userName中
g_Usertype = cboUserType.ListIndex
g_userName = txtUser.Text
'根据用户名及密码在数据库中搜索
Dim rs1 As New ADODB.Recordset
rs1.Open "select * from Users where UserName='" & _
Trim(txtUser.Text) & "' and userpassword='" & _
Trim(txtPwd.Text) & "' and UserType=" & _
g_Usertype,cnn,adOpenDynamic,adLockOptimistic
'用户名密码错误次数,超过3次,则退出系统
Static count As Integer
If rs1.EOF Then '登录失败
MsgBox "对不起,无此用户或者密码不正确或者用户类型不正确!_
请重新输入!",vbInformation,"错误"
txtUser.SetFocus
count = count + 1
If count >= 3 Then
MsgBox "您无权操作本系统!再见!",vbCritical,"无权限"
Unload Me
'关闭数据库连接
cnn.Close
End If
Else '登录成功
MsgBox "登录成功!欢迎使用本系统!",vbInformation,"欢迎"
Unload Me
MDIForm1.Show
End If
End Sub
(4)在frmLogin窗体中,处理cmdCancel的Click事件。
Private Sub cmdCancel_Click()
cnn.Close
'关闭数据库连接
Unload Me
End Sub
2.5.3系统主界面
1.窗体的功能主窗体(MDIForm1)的设计采用多文档(MDI)技术(在工程资源管理器中鼠标右键点击当前工程,然后在“插入”中选择,MDI窗体”,就可以创建MDIForm对象设置主窗体)。一个工程中主窗体是唯一的,多文档界面子窗体的MDIChid属性为True,如下介绍的主题信息管理窗体(frmSubjects),书籍信息管理窗体(frmTitles)、书本信息管理窗体(frmBooks)、会员信息管理窗体(frmMembers)和员工信息管理窗体(frmEmployees)都是MDI子窗体,打开此类窗体使用的是Show函数。再设置主窗体的WindowsState属性为wsMaximized,主窗体以最大化方式显示。
系统的主窗体MDIForm1如图2-5所示。

图2-5 系统主界面
2.菜单项系统功能模块的调用是通过主界面的菜单实现的,系统菜单设计如表2-10。
表2-10 主菜单设计
标 题
名 称
功 能
数据库(&D)
mnuDB
…主题信息管理
mnuSubjects
调用书籍主题管理模块
…书籍信息管理
mnuTitles
调用书籍信息管理模块
…书本信息管理
mnuB00ks
调用书本信息管理模块
…会员信息管理
mnuMembers
调用会员信息管理模块
…员工信息管理
mnuEmployees
调用员工信息管理模块
…配置
mnuOptions
调用系统配置模块
管理(&M)
mallTrallSaCtions
…借出书籍
mnuIssue
本菜单和接下来的5个菜单都调用业务窗体(业务模块),但实现不同功能
…续借书籍
munRenewal
同上
…归还书籍
munReturn
同上
…预订书籍
mtmRes
同上
…丢失书籍
munMiss
同上。
…购买书籍
munCharge
同上。
…支付罚款
munPayfine
同上
查询(&F)
mnuFind
…书本查询
mnuBookFind
调用书本查询模块
…会员查询
mnuMemFind
调用会员查询模块
报表(&R)
munReports
…罚款支付表
munFineReport
打印罚款支付表
…罚款平衡表
munFineBal
打印会员罚款平衡表
…丢失书籍表
munMissBook
打印丢失书籍表
用户管理(&U)
mnuUser
调用用户管理模块
关于(&H)
mnuAbout
关于本软件
退出(&E)
mnuExit
退出系统
3.窗体的工作流程/方式
该窗体被作为系统中众多窗体的父窗体,其主要功能是提供用户所要使用的菜单项,不同身份的用户,其所能使用的菜单项也是不同的。
在本窗体的Load事件中,首先将会恢复上一次系统窗体退出时所处的位置,然后根据不同的用户身份,来使相应的菜单项可见。
4.核心代码分析主窗体的代码并不复杂,主要是进行各个功能的导航。系统调用各个功能模块的代码主要是将相应窗体显示出来,在此不多介绍。下面主要介绍主窗体对功能窗体(frmIssue)的修改和调用,以使其实现多种功能。代码如下:
(1)MDIForm的Load事件,首先还原上一次运行时窗体最后的位置,然后根据用户不同的身份来设置各个菜单的可视性。
Private Sub MDIForm_Load()
'取得上次退出时窗体的位置,并且将当前窗体的位置还原
Me.Left = GetSetting(App.Title,"Settings","MainLeft",1000)
Me.Top = GetSetting(App.Title,"Settings","Maintop",1000)
Me.Width = GetSetting(App.Title,"Settings","MainWidth",1000)
Me.Height = GetSetting(App.Title,"Settings","MainHeight",1000)
'根据不同的身份,确定不同的菜单的可用性
Select Case g_Usertype
Case 0,'管理员
mnuDB.Visible = True
mnuTransactions.Visible = True
mnuFind.Visible = True
mnuReports.Visible = True
mnuUser.Visible = True
mnuAbout.Visible = True
mnuExit.Visible = True
Case 1,'图书馆工作人员
mnuDB.Visible = False
mnuTransactions.Visible = True
mnuFind.Visible = True
mnuUser.Visible = False
mnuReports.Visible = True
mnuAbout.Visible = True
mnuExit.Visible = True
Case 2,'会员
mnuDB.Visible = False
mnuTransactions.Visible = False
mnuFind.Visible = True
mnuReports.Visible = False
mnuUser.Visible = False
mnuAbout.Visible = True
mnuExit.Visible = True
End Select
End Sub
MDIForm的Unload事件,保存窗体的位置。
Private Sub MDIForm_Unload(Cancel As Integer)
'在注册表中保存窗体退出时的位置
If Me.WindowState <> vbMinimized Then
SaveSetting App.Title,"Settings","MainLeft",Me.Left
SaveSetting App.Title,"Settings","Maintop",Me.Top
SaveSetting App.Title,"Settings","MainWidth",Me.Width
SaveSetting App.Title,"Settings","Mainheight",Me.Height
End If
End Sub
(3)各个菜单项的Click事件。特别注意对frmIssue窗体的修改和调用。
Private Sub mnuExit_Click()
Unload Me
cnn.Close
frmLogin.Show '重新返回登录界面
End Sub
Private Sub mnuOptions_Click()
frmOptions.Show
End Sub
Private Sub mnuMembers_Click()
frmMembers.Show
End Sub
Private Sub mnuSubjects_Click()
frmSubjects.Show
End Sub
Private Sub mnuTitles_Click()
frmTitles.Show
End Sub
Private Sub mnubookFind_Click()
frmFindBook.Show
End Sub
Private Sub mnuMemFind_Click()
frmMemFind.Show
End Sub
Private Sub mnuPayfine_Click()
frmpayfine.Show
End Sub
Private Sub mnuUser_Click()
frmUser.Show
End Sub
Private Sub mnuMissBook_Click()
MissReport.Show
End Sub
Private Sub mnuFineBal_Click()
FineReport.Show
End Sub
Private Sub mnuFineReport_Click()
FineBalReport.Show
End Sub
'购买书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnucharge_Click()
frmIssue.cmdLendBook.Visible = False
frmIssue.cmdReserve.Visible = False
frmIssue.cmdMiss.Visible = False
frmIssue.cmdreturn.Visible = False
frmIssue.cmdRenewal.Visible = False
frmIssue.cmdcharge.Visible = True
frmIssue.Caption = "购买书籍"
frmIssue.Show
End Sub
'借阅书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnuIssue_Click()
frmIssue.cmdLendBook.Visible = True
frmIssue.cmdReserve.Visible = False
frmIssue.cmdMiss.Visible = False
frmIssue.cmdreturn.Visible = False
frmIssue.cmdRenewal.Visible = False
frmIssue.cmdcharge.Visible = False
frmIssue.Caption = "借阅书籍"
frmIssue.Show
End Sub
'丢失书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnuMiss_Click()
frmIssue.cmdLendBook.Visible = False
frmIssue.cmdReserve.Visible = False
frmIssue.cmdMiss.Visible = True
frmIssue.cmdreturn.Visible = False
frmIssue.cmdRenewal.Visible = False
frmIssue.cmdcharge.Visible = False
frmIssue.Caption = "丢失书籍"
frmIssue.Show
End Sub
'续借书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnuRenewal_Click()
frmIssue.cmdLendBook.Visible = False
frmIssue.cmdReserve.Visible = False
frmIssue.cmdMiss.Visible = False
frmIssue.cmdreturn.Visible = False
frmIssue.cmdRenewal.Visible = True
frmIssue.cmdcharge.Visible = False
frmIssue.Caption = "续借书籍"
frmIssue.Show
End Sub
'预订书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnuRes_Click()
frmIssue.cmdLendBook.Visible = False
frmIssue.cmdReserve.Visible = True
frmIssue.cmdMiss.Visible = False
frmIssue.cmdreturn.Visible = False
frmIssue.cmdRenewal.Visible = False
frmIssue.cmdcharge.Visible = False
frmIssue.Caption = "预订书籍"
frmIssue.Show
End Sub
'归还书籍菜单的单击事件响应代码
'注意其中对frmIssue的修改
Private Sub mnuReturn_Click()
frmIssue.cmdLendBook.Visible = False
frmIssue.cmdReserve.Visible = False
frmIssue.cmdMiss.Visible = False
frmIssue.cmdreturn.Visible = True
frmIssue.cmdRenewal.Visible = False
frmIssue.cmdcharge.Visible = False
frmIssue.Caption = "归还书籍"
frmIssue.Show
End Sub
代码仅仅是将某种业务不需要的按钮隐藏,而诸如显示书本信息等内容的控件实现了重用,减少了代码量。
主窗体还包括对报表的初始化和调用功能,这些功能的实现代码在介绍报表时已经介绍。
2.5.3主题信息管理模块主题信息管理模块主要是由主题信息管理窗体(frmSubjects)构成,界面如图2-6所示。

图2-6主题信息管理实现的功能如下:
(1)对书籍的主题信息的管理(数据存储在数据库Library表Subjects中),包括添加主题信息、编辑主题信息、删除主题信息等。
(2)对书籍主题信息的浏览。它提供了一个导航条,用来向前、向后移动浏览信息。
(3)对特定主题信息的搜索操作,搜索符合指定条件(搜索某个字段为特定值的所有记录,如Subject为Computers的所有记录)的书籍主题信息。
这些功能的代码:略
2.5.4书籍信息管理模块书籍信息管理模块主要是由书籍信息管理窗体(frmTitles)构成,界面如图2-7所示。

图2-7书籍信息管理实现的功能如下:
(1)对书籍信息的管理(数据存储在数据库Library表Titles中),包括添加书籍信息、编辑书籍信息、删除书籍信息等。
(2)对书籍信息的浏览。它提供了一个导航条,用来向前、向后移动浏览信息。
(3)对特定书籍信息的搜索操作,搜索符合指定条件(搜索某个字段为特定值的所有记录,如Title为C++的所有记录)的书籍信息。
本模块的代码和主题信息管理模块(frmSubjects)的代码非常类似。有所不同的是此处的主题信息是需要从已有的主题信息中选择。为实现此功能,应用了一个Combo控件将现有的主题信息显示出来:
程序代码:略
2.5.5书本信息管理模块书本信息管理模块主要是由书本信息管理窗体(frmBooks)构成。
实现的功能如下:
(1)对书本信息的管理(数据存储在数据库Library表Books中),包括添加书本信息、编辑书本信息、删除书本信息等。
(2)对书本信息的浏览。它提供了一个导航条,用来向前、向后移动浏览信息。
(3)对特定书本信息的搜索操作,搜索符合指定条件(搜索某个字段为特定值的所有记录,如BookId为B0001的所有记录)的书本信息。
本模块的代码和书籍信息管理模块(frmTitles)的代码非常类似。同样使用了Combo控件以显示当前存在的书籍信息,并指定当前书本所属的书籍。
2.5.6会员信息管理模块会员信息管理模块由会员信息管理窗体(frmMembers)构成,界面如图2—8所示。

图2-8会员信息管理实现的功能如下:
(1)对会员信息的管理(数据存储在数据库Library表Members中),包括添加会员、编辑会员信息、删除会员等。
(2)对会员信息的浏览。它提供了一个导航条,用来向前、向后移动浏览信息。
(3)对特定会员信息的搜索操作。搜索符合指定条件(搜索某个字段为特定值的所有记录,如MemberId为M0001的所有记录)的会员信息。
本模块的代码和主题信息管理模块的代码非常类似,均是对一个数据库表格(这里是Members)的添加、编辑、删除、查询工作。但由于会员信息的特殊性,在添加会员时需要自动生成会员加入时间、会员资格持续对间、当前所借书籍数和由于交纳会员费所产生的账户欠款。
代码:略
2.5.7员工信息管理模块员工信息管理模块由员工信息管理窗体(frmEmployees)构成。
实现的功能如下:
(1)对员工信息的管理(数据存储在数据库Library表Employees中),包括添加员工、编辑员工信息、删除员工等。
(2)对员工信息的浏览。它提供了一个导航条,用来向前、向后移动浏览信息。
(3)对特定员工信息的搜索操作,搜索符合指定条件(搜索某个字段为特定值的所有记录,如EmployeeId为E10001的所有记录)的员工信息。
本模块的代码和主题信息管理模块的代码非常类似,在此不多介绍。
2.5.8借书管理模块借书管理模块由借书管理窗体(frmIssue)构成,界面如图2-9所示。

图2-9借书管理借书管理窗体是本系统最重要的业务窗体,它实现了图书管理工作中大部分业务功能,主要有借出书籍、归还书籍、续借书籍、预订书籍、购买书籍、遗失书籍等。下面将对这些业务进行分别介绍。
(1))借书业务当用户填写好会员编号和书本编号,单击“借书”按钮后,系统将对当前会员的账户欠款情况、当前借书情况及当前书本的库存情况、出借情况和预订情况进行判断,确定此会员可否借出此书,然后将借出情况分别更新至书本信息表(Books)和会员信息表(Members)中,完成借书业务。
代码:略
(2))还书业务当用户填写好会员编号和书本编号,单击“还书”按钮后,系统将判断会员是否曾借出本书;然后判断书籍是否已超出原定归还日期,若超期,则需要支付罚款;然后更新书本信息表(Books)和会员信息表(Members),完成还书业务。
代码:略
(3)续借书籍业务当用户填写好会员编号和书本编号,单击“续借书籍”按钮后,系统将判断会员是否已借出当前书本、借书是否超期、是否超出续借期限以确定会员是否能续借本书;然后更新书本信息表(Books),完成续借书籍业务。
代码:略
(4)预定书籍业务若欲借书籍已被其他人借出,则可以预定书籍,当其他人归还后,只有预定此书的人才能借出它。
当用户填写好会员编号和书本编号,单击“预定书籍”按钮后,系统将判断图书馆是否有此书籍,若有则无须预定;然后判断此书是否被别人预定,若没有其他预定者则更新书本信息表(Books),完成预定书籍业务。
代码:略
(5)丢失书籍赔偿业务当用户填写好会员编号和书本编号,单击“丢失书籍”按钮后,系统将判断会员是否借出本书;然后对会员进行罚款,将罚款数额更新到会员帐户中(更新Members表),完成丢失书籍赔偿业务。
(6)购买书籍业务当用户填写好会员编号和书本编号,单击“购买书籍”按钮后,系统将查询当前书本的价格,并扣除会员帐户(Members表)相应余额,完成购买书籍业务。
2.5.9系统配置模块系统配置模块由系统配置窗体(frmOptions)构成,界面如图2—10所示。

图2—10系统配置本模块对系统的一些参数进行设置,并将这些参数存储到数据库中(表GlobalVariables),主要代码如下:
Private Sub cmdOK_Click()
'对标准模块m.bas的有关系统变量赋值
totalIssueBooks = Text1(0).Text
renewalCounter = Text1(1).Text
MaxFineBal = Text1(2).Text
MembershipDuration = Text1(3).Text
MembershipFee = Text1(4).Text
renewalFees = Text1(5).Text
'写入表GlobalVariables中
g_sql = "select * from GlobalVariables"
rs.Open g_sql,cnn,adOpenDynamic,adLockOptimistic
For i = 0 To 5
rs.Fields(i) = Text1(i).Text
Next i
rs.Update
'系统配置模块只允许执行一次
MDIForm1.mnuOptions.Enabled = False
Unload Me
End Sub
2.5.10欠款支付模块欠款支付模块由欠款支付窗体(frmPayFine)构成,界面如图2—11所示。

图2—11欠款支付本模块是用来支付会员帐户中的欠款的,会员帐户被清零。主要代码:略
2.5.12创建用户管理模块
1.窗体模块的功能
本系统是一个多用户的系统,为了便于管理这些用户,因此需要创建用户管理模块。用户管理模块的主要作用在于对当前系统中的用户进行管理,添加或者删除用户,更改用户密码,变更用户的身份类型等。
用户管理模块有3个窗体组成:用户管理主窗体、密码窗体和用户身份选择窗体。用户管理主窗体用于显示用户列表,供用户选择下一步操作;密码窗体用于添加用户时输入用户密码,或者用于变更当前用户的密码;用户身份选择窗体用于添加用户时选择用户身份,或者用于变更当前的用户身份。
2.窗体界面的设计
(1)用户管理主窗体(frmUser)
用户管理的主窗体命名为frmUser窗体,其界面如图2-12。
窗体fimUser的主要控件及其属性如表2—11所示。

图2-12 frmUser的界面设计示意图表2-11窗体fimUser的主要控件及其属性控件
名称
属性设置
Form
frmUser
BorderStyle属性设为1,MDIChild属性设为True,Caption为“用户管理”
Label
lblUserType
Caption属性设为“用户类型:”
ComboBox
cboUserType
Style属性设为“2-Dropdown List”
Label
lblUserList
Caption属性设为“用户列表:”
ListBox
lstUser
CommandButton
lblAddUser
Caption属性设为“添加用户”
CommandButton
lblDeleteUser
Caption属性设为“删除用户”
CommandButton
cmdChangePwd
Caption属性设为“改变密码”
CommandButton
cmdChangeType
Caption属性设为“更改用户类型”
CommandButton
cmdClose
Caption属性设为“关闭”
(2) 密码窗体(frmPassword)
密码窗体命名为frmPassword,其界面设计如图2-13。

图2-13 frmPassword的界面设计示意图窗体frmPassword的主要控件及其属性设置如表2—12所示。
表2—12 frmPassword窗体主要控件及其属性设置控件
名称
属性设置
Form
frmPassword
BorderStyle属性设为4,Caption属性为“密码”
Label
lblPwd
Caption属性设为“输入密码:”,Index属性为0
TextBox
txtPwd
Text属性设为空,Index属性为0
Label
lblPwd
Caption属性设为“确定密码:”,Index属性为l
TextBox
txtPwd
Text属性设为空,Index属性为1
CommandButton
cmdOK
Caption属性设为“确定”,Default属性为True
CommandButton
cmdCancel
Caption属性设为“取消”,Cancel属性为False
(3)用户身份选择窗体(frmUserType)
用户身份选择窗体命名为frmUserType,其界面如图2-14所示。

图2-14 frmUserType的界面设计示意图
窗体frmUserType的主要控件及其属性设置如表2—13所示。
表2-13 frmUserType窗体主要控件及其属性设置控件
名称
属性设置
Form
frmUserType
BorderStyle属性设为4,Caption属性为“用户类型”
Frame
fraUserType
Caption属性设为“请选择用户类型:”
OptionButton
optUserType
Caption属性为“管理人员”,Index属性为0
OptionButton
optUserType
Caption属性为“图书馆工作人员”,Index属性为1
OptionButton
optUserType
Caption属性为“会员”,Index属性为2
CommandButton
cmdOK
Caption属性设为“确定”,Default属性为True
CommandButton
cmdCancel
Caption属性设为“取消”,Cancel属性为False
3.窗体的工作流程/方式用户管理模块有几个窗体所共同组成。在用户管理模块中,首先将会显示当前系统中的用户列表,此时用户有两个可能的操作:添加用户,或者选择用户然后进行下一步操作。
(1)添加用户
如果操作人员要添加用户,则首先要输入用户名,然后输入用户的密码,最后选择用户的类型(管理人员、图书馆工作人员或者会员)。如果添加用户成功,则返回到用户列表,等待下一个操作。
(2)选择用户
如果操作人员选择了某个用户,则可以对某个用户进行删除、修改密码和更改用户类型这3种操作。
用户管理模块的流程如图2—15所示。
图2-15用户管理模块的流程
4.主要代码:略
2.5.13书本查询模块
1.设计界面按书籍编号、书籍名称、作者、主题、价格等进行精确或模糊查询。
根据功能,该窗体的运行界面如图2-16。

图2-16书本查询
2.窗体代码
(1)Form的load事件
Private Sub cleartext()
txtBookId.Text = ""
txtTitle.Text = ""
txtTitleId.Text = ""
txtAuthor.Text = ""
txtsubject.Text = ""
txtPrice.Text = ""
End Sub
Private Sub Form_Load()
Call cleartext
End Sub
(2)“开始查找”按钮的Click事件
Private Sub cmdFind_Click()
'保存设置的查询条件
Dim strcon(6) As String
Dim strsql As String
'获得查询条件,根据是否选中“执行模糊查询”复选框分别进行查询条件的设置
'获得书本编号查询条件
If txtBookId.Text <> "" Then
If chkMoHu.Value = 1 Then
strcon(1) = " BookId like '%" & txtBookId.Text & "%'"
Else
strcon(1) = " BookId ='" & txtBookId.Text & "'"
End If
Else
strcon(1) = ""
End If
'获得书籍名称查询条件
If txtTitle.Text <> "" Then
If chkMoHu.Value = 1 Then
strcon(2) = " Title like '%" & txtTitle.Text & "%'"
Else
strcon(2) = " Title ='" & txtTitle.Text & "'"
End If
Else
strcon(2) = ""
End If
'获得书籍编号查询条件
If txtTitleId.Text <> "" Then
If chkMoHu.Value = 1 Then
strcon(3) = " Titles.TitleId like '%" & txtTitleId.Text & "%'"
Else
strcon(3) = " titles.TitleId ='" & txtTitleId.Text & "'"
End If
Else
strcon(3) = ""
End If
'获得作者查询条件
If txtAuthor.Text <> "" Then
If chkMoHu.Value = 1 Then
strcon(4) = " Author like '%" & txtAuthor.Text & "%'"
Else
strcon(4) = " Author ='" & txtAuthor.Text & "'"
End If
Else
strcon(4) = ""
End If
'获得书籍主题查询条件
If txtsubject.Text <> "" Then
If chkMoHu.Value = 1 Then
strcon(5) = " Subject like '%" & txtsubject.Text & "%'"
Else
strcon(5) = " Subject ='" & txtsubject.Text & "'"
End If
Else
strcon(5) = ""
End If
'获得书籍价格查询条件,价格无法模糊查询
If txtPrice.Text <> "" Then
strcon(6) = " Price =" & Val(txtPrice.Text) & ""
Else
strcon(6) = ""
End If
'根据查询条件进行查询SQL语句的设置
If strcon(1) = "" And strcon(2) = "" And strcon(3) = "" And strcon(4) = "" And strcon(5) = "" And strcon(6) = "" Then
strsql = "select Books.BookId as 书本编号,Titles.Title as 书籍名称,Titles.TitleId as 书籍编号,Titles.Author as 作者,Titles.Subject as 所属主题,Titles.Price as 书籍价格,Books.IsIn as 是否在图书馆 from Books,Titles where Books.TitleId=Titles.TitleId"
Else '具有查询条件
strsql = "select Books.BookId as 书本编号,Titles.Title as 书籍名称,Titles.TitleId as 书籍编号,Titles.Author as 作者,Titles.Subject as 所属主题,Titles.Price as 书籍价格,Books.IsIn as 是否在图书馆 from Books,Titles where Books.TitleId=Titles.TitleId"
For i = 1 To 6
If strcon(i) <> "" Then
strsql = strsql + " and " + strcon(i)
End If
Next i
End If
'设置Adodc控件
Adodc1.ConnectionString = "provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\library.mdb;Persist Security Info=False"
Adodc1.RecordSource = strsql
Adodc1.Refresh
End Sub
(3)“清空”按钮的Click事件
Private Sub cmdClear_Click()
Call cleartext
End Sub
(4)“关闭”按钮的Click事件
Private Sub cmdClose_Click()
Unload Me
End Sub
2.5.14会员查询模块与书本查询模块类似,在此不多叙述。
2.5.15报表打印模块报表打印模块由3张报表构成:会员欠款一览表(FineBalReport)、欠款支付表(FineReport)和书籍丢失情况表(MissReport),分别如图2—17、2-18、2-19所示。

图2—17会员欠款一览表

图2—18欠款支付表

图2-19书籍丢失情况表有关系统的报表的设计在此不多叙述。