实验室管理系统
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
密 惠 保
提要
1. 目的:建立一个实验室管理系统
2. 技术背景:
VFP系统
Microsoft Visual FoxPro6.0关系型数据库系统是微软公司1998年推出的具有强大功能的数据库管理系统.使用VFP可以使组织数据、定义数据库规则和建立应用程序等工作变得简单易行。另外,利用可视化的设计工具和向导,可以快速创建表单、查询和报表。因此 VFP是制作各种专业化数据库应用程序的有利工具。
3. 成果:成功建立了一套实验室管理系统。
4. 关键字:VFP,SQL,数据库,实验室管理系统。 内容来自think58 [来源:http://think58.com]
目录
首页 ……………………………………………………………………..1
中文提要…………………………………………………………………2
英文提要…………………………………………………………………3
目录………………………………………………………………………4
序言………………………………………………………………………5
相关技术介绍……………………………………………………………6
系统设计…………………………………………………………………9
系统实现………………………………………………………………..13
附录……………………………………………………………………..28
参考文献………………………………………………………………..45
致谢……………………………………………………………………..46
think58
[版权所有:http://think58.com]
系统设计
一套数据库管理系统是否完善是与它的前期设计的密不可分的,因此我在系统设计工作投入的精力也占了相当大的比重.我认为 VFP的系统设计工作可以分为两大部分:数据库设计和系统模型的设计。前者是后者的基础,也直接影响着最后生成的系统的性能。下面我就分开介绍一下:
1. 数据库的设计
数据库设计是将现实世界中的信息,根据数据库的组织结构约束,表现在计算机中,其关键问题是确定表的结构并为之建立索引。数据库应用系统的设计与普通应用系统的设计的很大差别就是前者更注重数据模型的设计。如果数据组织的得当,就能把数据库设计得相当灵活,可以用很多方法组合和提供数据。结合我的工作经历,我觉得可以把数据库设计分为如下几个步骤: think58
需求分析:VFP数据库设计的第一步就是明确数据库的目的和如何使用,必须准确的了解用户需求(包括数据和处理)。通过需求分析可以得到整个数据库的概念模型。如果这一步没有做好,可能会导致整个系统的返工重做。
结构设计:包括表的设计和表中字段的设计。将概念模型变为VFP的数据模型,分类放入表中,并根据表中数据的不同属性并选取相应的VFP字段类型建立字段。在建立字段的过程我觉得特别应当注意以下几点:
每个字段直接和表的主题相关,尽量不要在多个表中重复相 同的信息。
不要包含可推导或计算得到的数据,他们可以在程序中很容易的得到,不需要额外占用存储空间。
收集全所需的所有信息。不要等到进行程序设计时再回头来修改,增加格外工作量。
以最小的逻辑单位来存储信息。如果一个字段中包含很多信息,以后要想获得单独信息就很困难,应该尽量把信息分解成比较小的逻辑单位。
确定关系:Visual FoxPro是一个关系型数据库,在每个独立表中存储的数据都存在关系。可以定义表之间的关系,而Visual FoxPro可以利用这些关系来查找有联系的信息。表之间有三种关系:一对多关系,多对多关系和多对一关系。在一对多关系中,表A中的一个字段,在表B中可以有多个记录与之相对应。一对多关系也是比较常用的关系。在Visual FoxPro 6的数据库设计器中,可以通过简单的拖放来建立关系。 think58
设计优化:在完成以上3个步骤以后,应该再研究一下设计方案,检查可能存在的缺陷,如:数据的分类是否合理、字段是否与表的主题相关、是否有些字段对很多记录不适用,在那里保持空白等等。当确定了要做的修改以后,就可以修改表和字段,来完善方案。
在我这次的工作当中,由于我本人对实验室的管理工作并不熟悉,因此崔老师对数据库的用途和要求作出了规定。另外在听取其他老师的意见后,我将实验室管理的日常工作分为了6个部分,并根据这6个部分建立了6个数据库:教学管理库、经费管理库、物资管理库、人员管理库、实验室管理库以及器材管理库。
教学管理库主要存储本学期在实验室上课的课程信息。包括3个表:教材表、实验计划统计表和课程表(JXSYJC,JXSYTJ,JXGLKCB)。
经费管理库主要储存实验室的经费支出情况,包含一个表:经费管理表(JFGL).
物资管理库主要存储实验室有编号的主要仪器及其附件的信息,包括3个表:附件表,借用表和仪器设备表(FUJIAN,JIEYONG,YQSB)。
人员管理库主要存储实验室人员信息,包括两个表:实验室工作人员表和实验室工作人员培训计划表。
实验室管理库主要记录每个实验使用仪器的情况,包含一个表:实验室仪器表(SYSYQ)。 [来源:http://think58.com]
器材管理库主要记录那些没有编号的器材的信息,包含2个表:器材管理表和器材领用表(QCGL,QCLYB)。
由系,而于每个数据库的功能界定的非常详细,因此每个数据库中的表存在着联除了用来建立关系的个别字段以外,数据库中也不存在许多表存储相同数据的情况,在最简化方面,所有字段都尽量拆分成最小单元,并采用合适的VFP字段数据类型。比如说像性别,专兼职这样的字段就采用逻辑型字段,既限定了输入形式,又节省了存储空间。至于还原成直观文字的工作,则交由程序部分完成。
在定义各个数据库表之间的关系以后,我还为物资管理库和教学管理库建立了参照完整性。建立参照完整性涉及到生成一系列规则,以便在输入或删除记录时,能保持已定义的表间关系。如果实施了参照完整性规则,Visual FoxPro可以确保:
当主表中没有关联记录时,记录不得添加到相关表中。
主表的值不能改变,若这个改变将导致相关表中出现孤立记录。
若某主表记录在相关表中有匹配记录,则该主表记录不能删除。
而要实现上述性能,只需要在VFP参照完整性生成器(RI)中选择相应选项就行了,十分的简单。而我也在后面的工作中通过程序实现了同样的功能,至少需要20行程序左右,而且很可能会出错,从这里就可以看出使用RI生成器的简洁性。而且使用RI生成器为数据库生成规则时,VFP把生成的代码作为触发器保存在存储过程中,在打开数据库中,它们便自动加载在内存中,因此即使不通过程序而直接对数据库进行操作,也会受到上述完整性规则的限制,这项功能的重要行我将在以后提及 think58
[资料来源:http://www.THINK58.com]
由于数据库设计部分准备充分,表和字段以及表间关系的制定比较合理,为后来的工作打下了良好的基础。
系统实现
从上面的系统模型中可以看出,这个数据库管理系统按照所操作的数据源的不同可以分成6个部分,加上一开始的密码确认部分一共是7部分。在对每一部分的功能及实现方法加以说明之前,先简单介绍一下VFP表单的生成和对数据访问的控制。
VFP有功能强大的表单生成向导和表单设计器,使得生成和设计表单的工作变得快速而且简洁。VFP的表单生成向导可以生成多种样式的对指定数据源进行操作的表单,一般包括与指定数据源绑定的文本框以及常用按钮组,如果是使用一对多表单生成向导话,还会包含与子表绑定的表格控件。而在VFP的表单生成器我们可以处理下列内容:
表单中不同类型的对象。
与表单相关联的数据。
顶层表单或子表单。
能一起操作的多个表单。
基于自定义模板的表单。
表单设计器中通过简单的拖放操作就可以完成控件定位和显示属性控制操作,这在直接用程序编程时是一件非常麻烦的工作。另外值得一提的在表单设计器的数据环境中可以直接为表单添加或移去数据表或视图,并指定它们之间的关系。在我的工作中,都是将表单生成向导和表单设计器结合使用,这样确实节省了很多时间。
为了能够一次使用多个表,在VFP中引入了工作区这个概念。一个工作区就是一个编号区域,它标识一个已打开的表。VFP总共可以开启32767个工作区,然而一次仅可以处理一个工作区,所有命令仅对当前的工作区有效,若要使用其他工作区必须使用切换工作区指令。当使用USE命令打开第一个数据表时,作用区为第一工作区,在打开第二个数据表则置于第二工作区,以此类推。也可以使用USE [表文件名] IN [工作区号],指定要开启哪一个工作区。而要选择工作区,则使用命令SELECT [工作区],如果之前使用了USE [表文件名] ALIAS [表别名]指定了表的别名,那么也可以使用SELECT [表别名]来选择工作区。因为第二种方法比较直观,因此在应用程序中通常通过使用该数据区的表的别名来标识。在表单中,表别名是在表单设计器的数据环境中指定的。 本文来自think58 [来源:http://think58.com]
除了工作区以外,VFP还通过数据工作期自动为表单或表单集的每个实例提供一个独立的工作环境。一个数据工作期是指表单、表单集或报表使用的当前动态工作环境。每个数据工作期包含了它自己一组工作区,这些工作区包括在工作区中打开的表、标索引以及表之间的关系。数据工作期主要适用于网络系统中,由于这次我做的是一个个人桌面系统,因此就不再对其详细介绍了。
下面我就开始对这套实验室管理系统进行详细的说明:
1. 系统首页部分
系统首页是进入系统的第一个页面,它所实现的功能是密码确认以及系统导航。其中启动系统时最先出现的页面如下所示:
为了实现密码验证功能,我在表单中加入了一个包含了两个页面的页框,上图就是这个页框的第一个页面,为了避免用户直接选择第二个页面,因此将该页框的TABS属性设置为.F.,这样页框的选项卡就不可见,只有通过程序才能第二个页面。
该表单的数据环境中包括一个自由表(PASS.DBF),包括两个字段,用户和密码,当用户在用户和密码文本框中输入完毕并点击了“确定“键以后,将调用“确定”按钮的CLICK事件响应函数。首先在表中进行定位,如果找到字段“用户”与用户文本框中相同的记录,就再检验密码是否也相同。如果不同或者找不到记录,则系统属性TIMES自加1,TIMES是用来控制重试次数的,它在系统生成时自动置0。当TIMES=3时系统就自动退出,以免有人尝试次数过多。 [资料来源:http://think58.com]
当用户和密码全都正确时,则通过执行thisform.pageframe1.activepage=2将页框的当前活动页设为第二页面,如下所示:
内容来自think58 [资料来源:http://www.THINK58.com]
页面2的功能有两个,一个是系统导航,由此可以调用系统的其他6个部分,另一项功能就是修改密码。当点击了“修改密码”按钮以后,就会出现如下界面:
可以看到,与密码修改相关的控件:按钮组,文本框和标签都被我放到一个容器控件中,这样所有控件是否在表单上显示都会受到容器控件的VISIBLE 属性的控制,因此程序中只需要对容器控件的VISIBLE属性进行操作就可以了,比一个一个的修改控件的VISIBLE属性要方便了很多。这个容器控件的VISIBLE属性默认为.F.,只有当点击了“修改密码”按钮以后它们才会变成可视,而密码修改完毕后再将该容器控件的VISIBLE设为.F.。
2. 物资管理部分
物资管理部分包括6个表单,是对物资管理库中的3个表运行进行操作的。其首页是物资管理页,如下图所示。
物资管理页中的数据操作涉及到物资管理库中全部3个表,因此生成该表单时我是用了一对多表单生成向导。父表是仪器设备表(YQSB),子表是附件表(FUJIAN),借用表中的数据由于不需要显示,因此可以不和仪器设备表建立临时关系,仅需加入到表单的数据环境中就行了。表单中的文本框是与仪器设备表中各字段绑定的,而下面的表格则是和附件表绑定。为了防止用户误操作对数据表做出修改,因此所有的文本框和表格都是只读的。而对数据表进行操作的功能将在专门的表单中提供,物资管理页主要提供的是数据表的浏览功能。 think58
[来源:http://www.think58.com]
所谓的一对多表单,就是在表单的数据环境中包含了2个或两个以上的数据表,并且用SET RELATION命令在表之间建立了临时关系,临时关系使用两个表间相同的字段,子表的记录指针会随着父表的记录指针移动,这样,便允许当在关系中“一”方(或父表)选择一个记录时,会自动去访问表关系中“多”方(或子表)的相关记录。显然,这一特性在显示多个表数据时是非常有用的。在这个表单中我是将仪器设备表作为父表,将附件表作为子表,临时关系使用两个表中都存在的YQBH字段,该字段唯一确定一个仪器记录。因此在文本框中显示仪器设备表中某一记录各字段的详细情况时,在表格控件中将自动显示在附件表所有YQBH与之相同的记录,即在显示一个仪器的详细状况时,将它的所有附件也同时列出来,方便了用户的查看。
一对多关系在带来方便的同时,也有一些不足,那就是在使用一对多关系的数据环境中,一旦对父表使用SET ORDER命令进行重新排序,那么一对多关系将被破坏。所以我在系统的其他部分中尝试使用了别的方法,同样达到了一对多显示的效果,后面再详细介绍。
表单最下方按钮组的前四个按钮提供了仪器设备表的一般的记录指针移动功能。“详细查询”按钮调用仪器查询页,“添加”和“删除”调用仪器设备表修改页。“删除”则将仪器设备表的当前记录删除。“退出”将退出当前表单,回到主表单。“打印”将调用报表YQSB1,打印YQSB表的当前记录和附件表中的相关纪录。 本文来自think58
VFP的报表可以在报表生成器中和报表设计器生成。报表生成器与表单生成器十分类似,通过选择数据源来指定打印的内容。而在报表设计器中可以进一步调节各个控件的位置,通过简单的操作产生精美的报表。在程序中通过REPORT FORM命令就可以调用已经建立好的报表。
在表单右下方的按钮组中,“附件查询”将调用附件查询页,“附件添加”将调用附件修改页。表单右面的按钮组中,“借出”和“归还”都将调用仪器借用页。
在物资管理页中,控件的显示属性不是不变的,而是随着数据表当前记录的变化而变化。比如说当指针指向表中第一个记录时,“|<”和“<”按钮的enable属性应该变为.F.,即不可点击;仅当该记录已被删除时标签“已删除”的VISIBLE属性才会是.T.等等。这些属性的设置可以在每次会导致表单显示属性变化的程序中分别设置,但是那样程序的可读性较差,而且会有很多重复,因此我在表单中创建了一个表单方法程序DIS,将所有与显示有关的程序集中到一起,而每次需要对表单更新时都调用DIS,这样凡是与显示有关的全都在DIS中进行设置, 使程序的可读性得到了提高.另外,在表单中“未借出”及其后面包含两个按钮的按钮组的状态是与FUJIAN表有关的,我建立名为JY的表单方法程序,对FUJIAN表进行扫描,当满足条件yqbh=thisform.yqbh1.text1.value and empty(alltrim(ghrq))时,代表仪器已借出,否则代表未借出,相应的设置标签控件和按钮组控件的属性。再在 DIS中使用JY,使得表单每次刷新时那两个控件也会随之刷新。 本文来自think58 [资料来源:http://THINK58.com]
仪器设备表的记录数目比较多,因此仅仅提供“前一个”、“后一个”、“第一个”、“最后一个”这样简单的记录指针移动功能很难满足用户的浏览要求,因此我制作了专门对仪器设备表进行查询操作的仪器查询页,如下图所示:
在仪器查询页的上半部是与YQSB表绑定的表格控件。而下半部则是用户输入查询条件的区域。可以看到在用户输入区域包括3个下来列表框。之所以采用下拉列表框是因为仪器名称(YQMC)、型号(XH)和规格(GG)三个字段是比较常用的查询项,并且它们在数据表中是大量重复的,不同项的并不多,同时也为了规范查询条件的输入。以YQMC下拉列表框为例,它的ROWSOURCETYPE设为SQL语句,ROWSOURCE即控件数据值的源设为“SELECT DISTINCT XH FROM YQSB INTO CURSOR TEMP2”,这样就从仪器设备表中把所有不同XH字段选择出来作为下拉列表框的值。为了进一步规范输入条件,我还为每个下拉列表框编辑了INTERACTIVECHANGE事件响应函数,当其中一个下拉列表框的值被改变了以后,另外两个下拉列表框数据源的值将会被重新设定,与已选定的下拉列表框的值相对应,然后用REQUERY函数更新。另外为了清除下拉列表框的选择,我为每个下拉列表框设置了“清空”按钮,将它的VALUE置为’’。而“全部清空”则将清除用户所有输入,将表单恢复到初始状态。
[资料来源:http://THINK58.com]
表单的查询功能在“查询”按钮的事件响应函数中实现的。在该函数中,对所有供用户输入查询条件的控件进行判断,如果有用户输入,则在变量TIAOJIAN中加入该控件对应的查询语句,最后将变量TIAOJIAN作为SET FILTER FOR的条件语句。SET FILTER命令使用来暂时筛选数据,而不生成专门的筛选索引,它可以接受任何一个有效的VFP逻辑表达式作为筛选条件,在表中只有满足筛选条件的记录才可以访问,所有访问表的命令都遵守SET FILTER条件。而筛选条件语句之所以用FOR而不用TO,是为了配合RUSHMORE技术加速数据访问,我将在后面的系统优化部分中再详细介绍。
仪器查询页使用物资管理页数据环境中别名为YQSB的工作区,因此两个表单的记录指针是指向相同记录的。当查询结束后,在表格中选择想要进行操作的记录,点击“退出”按钮,则退出该表单回到物资管理页,由于“退出”按钮的CLICK事件响应函数中包含对物资管理页的DIS函数的调用,因此返回后物资管理页将显示刚刚在仪器查询页中所选定记录的详细情况。
当我们选定了记录后,就要对它进行操作了。其中添加和修改操作都是在同一个表单中进行的。下图就是仪器设备表修改页的界面:
考虑到数据的安全性,一般浏览用的表单中的文本控件都是只读的,而将涉及到数据表操作的添加和修改功能集中到一个表单上。而同样是出于安全性以及操作的方便性的考虑,我决定使用缓冲技术。 copyright think58 [资料来源:THINK58.com]
如果将更新数据直接放到基表中,会造成这样一个结果,如果修改有错,就不能回滚,即不能回头。为了在更新过程中保护数据,我使用了缓冲技术。使用了缓冲技术以后,只有发出TABLEUPDATE更新命令以后,新值才会覆盖旧值。如果发出TABLEEVERT命令,则会取消这次操作,基表的值不会改变。
VFP提供记录缓冲和表缓冲,由于在我的系统中,一次只对一个记录进行操作,因此采用记录缓冲。事实上,缓冲技术主要是用于像网络那样的多用户环境的。借助该技术,可以很容易的检测比解决数据更新操作中所遇到的冲突:当前记录被复制到一个由VFP进行管理的内存或磁盘区域,其他用户仍然可以同时访问原来的记录。当离开该记录或以编程方式更新该记录时,VFP将准备锁定该记录,确认其他用户没有作修改,然后写入编辑结果。根据锁定方式:VFP的缓冲还可以分为保守式和开放式,他们决定了一个或多个记录何时被锁定,何时被解锁以及解锁方式。由于我的系统是单用户环境,因此不会有冲突的问题。使用缓冲主要是利用它对数据的保护功能。而本系统的所有对数据表修改和添加操作都使用了缓冲技术。
在仪器设备表修改页这个表单中,我定义了MODE属性,来确定表单是被用来执行添加操作还是修改操作。MODE属性在表单的INIT事件响应函数中被赋值。这是由于使用DO FORM WITH在表单间传递的参数必须在被调用表单的INIT事件响应函数中被接受。如果表单执行修改操作,那么在修改完成后点击“存储”按钮将会保存退出。如果表单执行添加操作,那么点击“存储”按钮将会保存当前记录,并在表的末尾再次添加一条空白记录,即允许用户连续添加,直到点击“完成”按钮才退出表单。 [来源:http://www.think58.com]
在用户在仪器设备表中添加了一条记录并存储成功以后,将会出现提示是否为该记录添加附件。如果用户选择是,则先调用附件修改页,当用户完成附件操作以后,再返回仪器设备表修改页表单,继续仪器设备表的添加操作。在实现这项功能时,我遇到一个问题,那就是在“存储”的CLICK事件响应函数中调用附件修改页表单后,程序会继续执行下去,而不会暂时停止等待附件修改页表单退出后在继续执行。最后我发现上述功能的实现不是由仪器设备修改页表单控制,而是附件修改页表单的WINDOWTYPE控制,将其设为1-模式,则会实现上述功能。
物资管理页、仪器查询页和仪器设备表修改页三个表单基本实现了对仪器设备表的操作。而附件表的操作由附加查询页和附件修改页完成。这两个表单如下图所示:
其中附件查询页表单主要是用来浏览和查找想要进行操作的记录,并对其进行操作。该表单生成时,仅显示仪器设备表当前记录所对应的附件记录。用户也可以自行修改查询条件进行其他查询。
我们看到提供记录添加功能的按钮并不在本表单上,而是在物资管理表上,这是因为我考虑到数据的完备性,仅当在仪器设备表中存在的记录才有可能添加附件。在附件修改页中可以看到,如果该表单是实现添加功能,则与YQBH字段关联的文本框控件是只读的,不可更改。即在物资管理表上点击“附件添加”按钮只能为仪器设备表中的当前记录添加附件,这样做的目的就是为了保证数据库的完备性,类似的设计在前面还有。比如说在仪器设备表修改页中,如果表单进行的是修改操作,就会自动记录仪器编号字段的值,如果修改以后发现仪器编号字段的值被改变了,就会提醒用户将要对FUJIAN表和JIEYONG表的相应值进行修改,是否继续,如果用户选择继续那么就要先修改FUJIAN表和JIEYONG表的相应值。最后再对YQSB进行更新。之所以采用这些设计,仅仅是为了作一个对比。事实上,这些工作完全可以由数据库的参照完整性规则来实行。由这些繁琐的步骤就可以看出数据库设计的重要性以及使用数据库RI生成器的简洁性。
[资料来源:http://THINK58.com]
物资管理部分的另一项功能就是进行仪器的借还管理,这是通过物资管理页和仪器借用页共同完成的。在选定了要借出或归还的仪器后,在物资管理页中点击“借用”或“归还”按钮(哪一个按钮可以点击是由物资管理页中JY函数控制的),就会调用仪器借用页,如下图所示:
该表单生成时会依据是借用操作还是归还操作自动在与借用日期字段或归还日期字段关联的文本框中填入当天日期,另外提供了“打印”按钮来打印打印借用单。
最后我再谈一下为什么我使用表单而不使用表单集。可以看出,物资管理部分中各个表单的数据彼此关联,在一些表单中的操作会影响到其他表单。这时就要在一个表单中调用其他表单的属性或函数,又或者在多个表单中要进行数据的传递,那么这时最先想到的方法就是使用表单集。表单集中包含多个表单,作为一组处理。表单集有以下特点:
可同时显示或隐藏表单集中的全部表单。
可以可视的模式调整多个表单以控制它们的相对位置。
因为表单集中所有表单都是在单个.SCX文件中用单独的数据环境定义的,可自动的同步改变多个表单中的记录指针。
在表单集中若要引用其他表单的属性或函数只需要采用如下引用THISFORMSET.所要引用表单名.属性名(函数名)就可以了。非常的简洁。 think58.com [资料来源:http://think58.com]
但是表单集也存在着一个严重不足,那就是表单集中的表单不能自建属性和方法,而在我前面的介绍中可以看到,像物资管理页中的DIS、JY方法,以及修改页中的MODE属性,这些属性和方法都是十分重要的,它们在系统的运行中时必不可少的,如果没有他们的存在,很多功能都实现不了,因此我仍决定使用表单。而这时我就要解决表单间数据的传递以及对象的引用。
VFP中可以在调用表单时传递参数,使用的命令是DO FORM [表单名] WITH [参数列表]。然后在被调用表单的INIT事件响应函数中接收参数,把它们赋给该表单的公共变量或属性,从而完成数据的传递。
另外通过查询资料,我还找到了一个不属于任何表单的VFP系统变量_SCREEN,通过它的的属性FORMCOUNT和FORMS以及如下程序,我可以遍历在VFP主窗口中的所有表单,直接使用其方法或属性。
for i=1 to _screen.formcount
if _screen.forms[i].caption="要引用表单名 "
_screen.forms[i].方法名
_screen.forms[i].属性名
endif
endfor
采用以上两种方法,基本上就可以实现与表单集类似的效果,满足程序设计的要求。但是这样也有它的不足之处,一个是需要的代码较多,而且也不利于项目的管理。因此在工作使用表单集比较好还是使用表单比较好并不一定,应根据需求以及其实情况来确定。 copyright think58 [来源:http://think58.com]
物资管理部分是在这次工作中最先完成的部分,它的功能也最齐全。其他部份的很多功能都是类似的,因此我就不一一详细介绍了,而只介绍与之不同的部分。 [来源:http://www.think58.com]
参考文献
翁正科 《Visual FoxPro 6数据库开发教程》 清华大学出版社 2000年8月第一版
Microsoft Corporation 《Visual FoxPro 6.0中文版程序员指南》 北京希望电脑公司 1998年8月第一版
Microsoft Corporation 《Visual FoxPro 6.0中文版语言参考手册》北京希望电脑公司 1991年1月第一版
毛一心 《中文版 Visual FoxPro 6.0 应用及实例集锦》 人民邮电出版社 1999年11月第一版 think58好,好think58 [资料来源:http://think58.com]
上一篇:VC398 手机信息管理系统论文
下一篇:VC377 指纹识别系统论文