由系,而于每个数据库的功能界定的非常详细,因此每个数据库中的表存在着联除了用来建立关系的个别字段以外,数据库中也不存在许多表存储相同数据的情况,在最简化方面,所有字段都尽量拆分成最小单元,并采用合适的VFP字段数据类型。比如说像性别,专兼职这样的字段就采用逻辑型字段,既限定了输入形式,又节省了存储空间。至于还原成直观文字的工作,则交由程序部分完成。
在定义各个数据库表之间的关系以后,我还为物资管理库和教学管理库建立了参照完整性。建立参照完整性涉及到生成一系列规则,以便在输入或删除记录时,能保持已定义的表间关系。如果实施了参照完整性规则,Visual FoxPro可以确保:
当主表中没有关联记录时,记录不得添加到相关表中。
主表的值不能改变,若这个改变将导致相关表中出现孤立记录。
若某主表记录在相关表中有匹配记录,则该主表记录不能删除。
而要实现上述性能,只需要在VFP参照完整性生成器(RI)中选择相应选项就行了,十分的简单。而我也在后面的工作中通过程序实现了同样的功能,至少需要20行程序左右,而且很可能会出错,从这里就可以看出使用RI生成器的简洁性。而且使用RI生成器为数据库生成规则时,VFP把生成的代码作为触发器保存在存储过程中,在打开数据库中,它们便自动加载在内存中,因此即使不通过程序而直接对数据库进行操作,也会受到上述完整性规则的限制,这项功能的重要行我将在以后提及
由于数据库设计部分准备充分,表和字段以及表间关系的制定比较合理,为后来的工作打下了良好的基础。
2. 系统模型设计
对于VFP来说,完成一套数据库管理系统,绝大部分时间都用来完成这套系统的表单部分。表单是用户查看和修改数据的界面,它还提供了丰富的对象集,能响应用户(或系统)事件,这样就能使用户尽可能方便和直观的完成信息管理工作。因此,对于系统模型的设计实际上就是表单的确定。下面就是系统的流程图:
为了实现密码验证功能,我在表单中加入了一个包含了两个页面的页框,上图就是这个页框的第一个页面,为了避免用户直接选择第二个页面,因此将该页框的TABS属性设置为.F.,这样页框的选项卡就不可见,只有通过程序才能第二个页面。
该表单的数据环境中包括一个自由表(PASS.DBF),包括两个字段,用户和密码,当用户在用户和密码文本框中输入完毕并点击了“确定“键以后,将调用“确定”按钮的CLICK事件响应函数。首先在表中进行定位,如果找到字段“用户”与用户文本框中相同的记录,就再检验密码是否也相同。如果不同或者找不到记录,则系统属性TIMES自加1,TIMES是用来控制重试次数的,它在系统生成时自动置0。当TIMES=3时系统就自动退出,以免有人尝试次数过多。
当用户和密码全都正确时,则通过执行thisform.pageframe1.activepage=2将页框的当前活动页设为第二页面,如下所示:
相同的记录,即在显示一个仪器的详细状况时,将它的所有附件也同时列出来,方便了用户的查看。
一对多关系在带来方便的同时,也有一些不足,那就是在使用一对多关系的数据环境中,一旦对父表使用SET ORDER命令进行重新排序,那么一对多关系将被破坏。所以我在系统的其他部分中尝试使用了别的方法,同样达到了一对多显示的效果,后面再详细介绍。
表单最下方按钮组的前四个按钮提供了仪器设备表的一般的记录指针移动功能。“详细查询”按钮调用仪器查询页,“添加”和“删除”调用仪器设备表修改页。“删除”则将仪器设备表的当前记录删除。“退出”将退出当前表单,回到主表单。“打印”将调用报表YQSB1,打印YQSB表的当前记录和附件表中的相关纪录。
VFP的报表可以在报表生成器中和报表设计器生成。报表生成器与表单生成器十分类似,通过选择数据源来指定打印的内容。而在报表设计器中可以进一步调节各个控件的位置,通过简单的操作产生精美的报表。在程序中通过REPORT FORM命令就可以调用已经建立好的报表。
在表单右下方的按钮组中,“附件查询”将调用附件查询页,“附件添加”将调用附件修改页。表单右面的按钮组中,“借出”和“归还”都将调用仪器借用页。
在物资管理页中,控件的显示属性不是不变的,而是随着数据表当前记录的变化而变化。比如说当指针指向表中第一个记录时,“|<”和“<”按钮的enable属性应该变为.F.,即不可点击;仅当该记录已被删除时标签“已删除”的VISIBLE属性才会是.T.等等。这些属性的设置可以在每次会导致表单显示属性变化的程序中分别设置,但是那样程序的可读性较差,而且会有很多重复,因此我在表单中创建了一个表单方法程序DIS,将所有与显示有关的程序集中到一起,而每次需要对表单更新时都调用DIS,这样凡是与显示有关的全都在DIS中进行设置, 使程序的可读性得到了提高.另外,在表单中“未借出”及其后面包含两个按钮的按钮组的状态是与FUJIAN表有关的,我建立名为JY的表单方法程序,对FUJIAN表进行扫描,当满足条件yqbh=thisform.yqbh1.text1.value and empty(alltrim(ghrq))时,代表仪器已借出,否则代表未借出,相应的设置标签控件和按钮组控件的属性。再在 DIS中使用JY,使得表单每次刷新时那两个控件也会随之刷新。