美章网 精品范文 物理模型论文范文

物理模型论文范文

前言:我们精心挑选了数篇优质物理模型论文文章,供您阅读参考。期待这些文章能为您带来启发,助您在写作的道路上更上一层楼。

物理模型论文

第1篇

1前言随着计算机技术和人类社会经济的发展,对于纺织服装业CAD/CAM的应用要求也越来越高,二维服装CAD系统已经不能满足要求,人们迫切希望借助计算机完成一些更加实用的三维功能。若能直接将二维服装CAD系统设计的衣片,在计算机上真实地模拟出穿在人体上的效果,便可以帮助设计师直接在计算机上进行着装效果检查、服装裁剪片缝合检查等工作。这样就可大大提高服装从设计阶段到生产阶段间的效率,具有非常重要的实用价值。要通过计算机实现这一功能,有两个关键的问题必须解决:1)建立合适的织物变形模型;2)选择高效而实用的碰撞检测算法。

研究织物变形仿真的方法通常分为三类:几何的、物理的和混合的(几何和物理方法的混合)。纯几何的造型方法很难反映织物的物理特性,因此基于物理的方法研究,近年来已占据了主导地位。在织物变形物理仿真模型中[1],按比拟织物结构的方式又可分为两大类:1)离散质点型模型:比较典型的有Feynma等建立的质点网格模型、Breen等建立的粒子模型和XProvot等建立的弹簧质点模型;2)连续介质型模型:比较典型的有Terzopoulos等建立的弹性变型模型、Liling等建立的空气动力模型、Aono建立的波传播模型、Collier等建立的有限元模型等。

以上的织物变形物理仿真模型,由于其建模的原理和方法不尽相同,因此,它们适用于不同的应用场合有其各自的优缺点。

我们结合设计虚拟穿衣功能的实际,认为XProvot所建立的弹簧质点模型,模型简单,易于计算机实现,在模拟衣片复杂的动态变形过程时,能够取得比较真实的模拟效果和较快的模拟速度。

在模拟三维服装穿在人体上的真实效果时,会遇到大量的碰撞现象:衣片同人模之间以及衣片自身间的一种相互渗透和穿越。只有很好地解决了渗透和穿越的问题,才能逼真地完成虚拟穿衣的模拟过程。因此,碰撞检测是整个模拟过程的关键。碰撞检测非常耗时,最简单的碰撞检测算法是对两个碰撞体中的所有基本几何元素(通常为三角形)进行两两相交测试。

现有的碰撞检测算法大致可划分为两大类:空间分解法(spacedecomposition),和层次包围盒法(hierarchicalboundingvolumes)。前者是将整个虚拟空间划分成相等体积的小单元格,只对占据同一单元格或相邻单元格的几何对象进行相交测试。比较典型的方法有八叉树和BSP树。层次包围盒法的核心思想是利用体积略大而几何特性简单的包围盒将复杂几何对象包裹起来,在进行碰撞检测时,首先进行包围盒之间相交测试,只有包围盒相交时,才对其所包裹的对象,做进一步求交计算。在构造碰撞体的包围盒时,若引入树状层次结构,可快速剔除不发生碰撞的元素,减少大量不必要的相交测试,从而提高碰撞检测效率。比较典型的包围盒类型有沿坐标轴的包围盒AABB(axisalignedboundingboxes),包围球(sphere),方向包围盒OBB(orientedboundingbox)等。

在本文中,我们充分利用了AABB层次包围盒法的优势,同时在构建静态人模的AABB树时,又借助层次空间分解法中子空间在空间排列上的有序性和相关性的思想,将缝合衣片的相对位置同人模自身的结构信息相结合,灵活地构造人模AABB树,这样减少了需相交测试的元素,从而提高了碰撞检测的效率。

2织物的变形模型

2.1织物变形模型的描述

我们建立的织物变形模型是以XProvot的弹簧质点模型作为基础,将织物设想为一个个质点集合,质点间相互关系归结为质点间的弹簧作用。其中弹簧分为三类:结构弹簧、剪切弹簧和弯曲弹簧,具体构成如图1所示。图1织物模型离散成规则网格

1)结构弹簧:在质点Pij和Pi+1,j间,以及Pij和Pi,j+1间的弹簧为结构弹簧,结构弹簧是为了保持质点间初始状态时的距离。

2)剪切弹簧:在质点Pij和Pi+1,j+1间,以及Pi+1,j和Pi,j+1间的弹簧为剪切弹簧。剪切弹簧是为了防止织物在自身平面过渡和不真实的变形,而给织物的一个剪切刚性。3)弯曲弹簧:在质点Pij和Pi+2,j间,以及Pij和Pi,j+2间的弹簧为弯曲弹簧,弯曲弹簧是为了防止织物弯曲。2.2质点的位移在缝合衣片过程中,衣片上所有质点因受力而产生一定的位移,质点位移我们选用Nowton运动定律来描述:F外力(i,j)+F内力(i,j)=ma(i,j)其中,m是质点P(i,j)的质量。在本文中,我们假定布料是各向均质的,因此,质点的质量可由衣片总质量除以质点总数得到,a(i,j)是该点加速度,F外力(i,j)是该点所受的外力,F内力(i,j)是该点所受的内力。为了简化模型,在我们三维服装CAD系统中,只考虑两种外力:缝合力和重力。可以用以下公式来表示:F外力(i,j)=F缝合力(i,j)+F重力(i,j)

在衣片缝合过程中,为了将不同的衣片缝在一起,我们在衣片对应缝合边上加载缝合力。在模型中,缝合力被定义成对应缝合点之间距离的线性函数。对两个缝合点pi,j和qi,j间的缝合力,可以按如下公式计算:F缝合力(i,j)=CsDis(pi,j,qi,j)Npi,j-qi,j式中Cs为缝合力系数,该系数与织物的缝合性能有关,通常,较难变形的布料采用较大的缝合力系数;Dis(pi,j,qi,j)表示两缝合点pi,j和qi,j间的距离;Npi,j-qi,j表示从pi,j点指向qi,j点的单位方向矢量。为了获得较真实的仿真效果,我们在变形模型中考虑了衣片所受的重力。质点所受的重力可按如下公式计算:F重力(i,j)=mi,jg式中mi,j为质点pi,j的质量。在弹簧质点模型中,唯一考虑的弹性内力是弹簧的弹性变形力,由于采用的是理想的弹簧质点系统,可以利用胡克(Hooke)定律来计算弹簧的弹性变形力:F内力(i,j)=-∑(k,l)∈Rk(Pi,jPk,l-Pi,jPk,l0Pi,jPk,lPi,jPk,l)其中,k是弹簧的弹性变形系数,R是P(i,j)邻点的集合,Pi,jPk,l0表示质点P(i,j)与质点P(k,l)之间的原始距离,弹簧的弹性变形系数k可以?谰菟∮弥锏牟牧闲阅懿问呷范ā?/P>

2.3织物变形模型的求解我们选择显式欧拉方法来求解织物变形模型。求解公式如下:ai,j(t+t)=1mi,jFi,j(t)Vi,j(t+t)=Vi,j(t)+tai,j(t+t)Pi,j(t+t)=Pi,j(t)+tVi,j(t+t)其中,Fi,j是质点P(i,j)所受所有力的合力,mi,j(t)是质点P(i,j)的质量,ai,j(t)、Vi,j(t)和Pi,j(t)分别是质点P(i,j)在时间t的加速度,速度和位置。t是系统选定的时间步长。

3基于AABB树层次包围盒的碰撞检测

3.1建立AABB树一个碰撞体的AABB被定义为包含该碰撞体,且边平行于坐标轴的最小六面体。因此,描述一个AABB,仅需六个标量。在构造AABB包围盒时,需沿着碰撞体局部坐标系统的轴向(X,Y,Z)来构造,所以所有的AABB包围盒具有一致的方向。

AABB树是基于AABB的二叉树,按照由上至下的递归细分方式构造生成的。在每一次递归过程中,要求取最小的AABB,需沿所选择的剖分面将碰撞体分为正负两半,并将所对应的原始几何元素(如三角面)分别归属正、负两边,整个递归过程类似于空间二叉剖分,只是每次剖分的对象是AABB,而不是空间区域。递归细分一直要进行到每一个叶子节点只包容一个原始几何元素为止,所以具有n个原始几何元素的AABB树具有n-1个非叶子节点和n个叶子节点。对于剖分面的选择,在本文中,选择垂直AABB的最长轴,且平分该轴的平面。经试验证明,这种方式,在大多数情况下的算法复杂度仅为O(nlogn),较其它的剖分面选择方法有了极大的提高。至于原始几何元素的归属则应依据几何元素的重心P在最长轴上的投影坐标。若投影坐标大于剖分面的坐标(mid),则在剖分面的正向,否则在负向,如图2所示。图2三角面归属负区域,因为其质心投影坐标小于剖分面的基准坐标

3.2AABB的相交判断AABB间的相交测试比较简单,两个AABB相交当且仅当它们在三个坐标轴上的投影区间均相交。通过投影,我们即将三维求交问题转化为一维求交问题。而对一维求交问题,我们则采用SAT(SeparatingAxesTest)[2]法。因SAT无需求交计算,只需比较两个包围盒分别在三个轴向上投影的重叠情况,即可得出相交测试结果,非常简单。现以在一个轴向上的投影情况为例说明:图3AABBs在X轴向相交判断。

设A,B为两包围盒,X为投影轴,CA,CB分别为A,B的中心点,PA,PB为点CA,CB在X上的投影。RA,RB分别为包围盒A,B在X上的投影。若RA+RB

PAPB,(如图3所示)则在轴向X上A和B不相交,反之在轴向X上A和B邻接或相53第5期高成英等:虚拟穿衣中织物模型的建立和碰撞检测的处理交。当包围盒A,B在三条轴向上的投影均相交时,则A,B相交。定义AABB的六个最大最小值分别确定了它在三个坐标轴上的投影区间,因此AABB间的相交测试最多只需六次比较运算,非常简单快速。

3.3AABB树的更新当衣片移动、旋转后,需要对AABB进行更新,根据定义AABB的6个最大最小值的组合,可以得到AABB的8个顶点,对这8个顶点进行相应的旋转和平移变化,并根据变化后的顶点计算新的AABB。当衣片发生变形时,需要重新计算AABB树中发生变形了的叶结点的AABB,再利用变形叶节点的新AABB来重新计算它们父节点的AABB。这种计算必须严格按照从下到上的方式进行。父节点AABB的具体求法为:令(Xmax1,Xmin1,Ymax1,Ymin1,Zmax1,Zmin1)和(Xmax2,Xmin2,Ymax2,Ymin2,Zmax2,Zmin2)分别是两个变形叶结点的AABB,则父结点的AABB即为(max(Xmax1,Xmax2),min(Xmin1,Xmin2),max(Ymax1,Ymax2),min(Ymin1,Ymin2),max(Zmax1,Zmax2),min(Zmin1,Zmin2),只需6次比较运算就完成一个结点的更新,其效率远远高于重新构造AABB包围盒树。

3.4基于AABB树的碰撞检测算法基于AABB树碰撞检测算法的核心是通过有效地遍历这两棵树,以确定在当前位置下,两个碰撞体的某些部分是否发生碰撞,这是一个双重递归遍历的过程。算法描述如下:step1:分别为人模和衣片构造AABB树。step2:人模的AABB树的根结点遍历衣片的AABB树。如果发现人模AABB树的根结点的包围盒与衣片AABB树内部结点的包围盒不相交,则停止向下遍历;如果遍历能到达衣片AABB树的叶节点,再用该叶节点遍历人模AABB树。如果能到达人模AABB树的叶节点,则进一步进行基本几何元素间的相交测试。step3:检测基本几何元素间是否相交。3.5自碰撞检测在衣片缝合过程中,除了衣片同人模之间的碰撞外,由于衣片的动态变形,使得衣片与衣片自身间也有碰撞现象,因此必须进行进一步的自相交检测。在系统设计中,我们利用三角形表面曲率来简化计算。当邻近三角形法线的夹角较小时,它们不可能发生碰撞,只有当夹角超过阈值,才有可能碰撞。我们为每个三角形建立它的临近三角形列表,通过判断每个三角形的所有邻近区域的三角形表面曲率,来排除大部分不可能相交的情况,从而简化了计算。

4虚拟穿衣的具体实现步骤

(1)读入二维服装CAD系统设计的衣片

(2)选择所有需要缝合衣片的对应的缝合边

(3)将二维衣片离散并形成初始的弹簧质点系统a)将衣片离散成规则四边域网格,再将四边域网格的对角线相连,形成规则三角形网格的弹簧质点系统。三角形的顶点形成质点,三角形的边形成相应的弹簧。衣片的三角化,正是为方便地建立衣片的AABB树;b)按质点间的相应关系,加入各种弹力。在离散衣片时,需特别注意的是在(2)中所选择的对应缝合边的长度一定要相等,且当衣片离散化时,在对应缝合边上的原始几何元素(这里为三角形)的个数也应相同。若在(2)中所选择的对应缝合边长度不等,或原始几何元素个数不同时,系统将需做一些预处理:将其中一条缝合边的所有信息删除,将另一条缝合边的相应信息赋给它。

(4)将衣片交互式地放置在人体模型附近的初始位置在该步骤中,首先,给每一缝合衣片赋一个别名(系统自定义的标准别名:左前片,右前片,左后片,右后片等),根据每一衣片的别名,衣片被自动地放置在人体模型附近的相应初始位置上。

(5)分别为人模和衣片建立AABB树本文中所涉及的两个碰撞体,分别为人模和衣片,其中人模在整个动态模拟过程中为静态的,因此,只需在初始化时构造一次AABB树即可。为了进一步提高碰撞检测的效率,我们在构造人模的AABB树时,应根据(4)中得到的缝合衣片别名,结合人模的几何结构,灵活构造人模的AABB树。例如:假设我们在(4)中,得到衣片分别为:左前片,右前片,左后片,右后片。我们即可知,将要缝合的为一件四片裁剪片的上衣,所以在构造人模的AABB树,我们只取人模上半身数据来构造人模的AABB,具体层次结构如图4所示。在进行人模和衣片间碰撞检测时,根据衣片的别名分别进行局部检测,(例如:左前片,就只需和人模AABB树第三层最左边的结点,左前半身的AABB进行碰撞检测)有效地减少了需要碰撞检测的元素。系统根据所缝合的衣片不同,建立的人模AABB树亦不相同。图4人模的AABB树层次结构图

(6)动态变形模型的计算根据衣片的缝合信息,我们在衣片的对应缝合边上加载缝合力。在缝合力、重力和衣片上各质点间内部弹力的共同作用下,二维衣片将逐步变形,并逐渐被缝合在一起,整个缝合过程是一个动态的迭代过程。在动态迭代过程中,要同时进行大量的人模—衣片间,及衣片—衣片间的碰撞检测处理,并给出相应碰撞响应(当有碰撞现象发生时,要重新调整碰撞点处的位置,避免发生穿越和渗透)的处理。缝合过程结束后,便可以得到缝合好的三维服装穿在静态人模上的效果。

5结束语实验证明,本文所采用的织物变形模型———弹簧质点模型,模型简单,能够较真实地反映虚拟环境下的织物特性。所采用的基于AABB的层次包围盒碰撞检测算法,除了AABB层次包围盒自身在碰撞检测上的较高性能外,算法还从以下几方面提高了碰撞的检测效率:

1)将缝合衣片的相对位置同人模自身的结构信息相结合,灵活地构造人模AABB树,减少了人模和衣片之间不可能相交元素碰撞检测的次数;

2)AABB包围盒的相交判断中,采用SAT方法进行包围盒之间的交叠判断,降低了算法的复杂度,提高算法效率。

3)衣片之间的碰撞判断,利用了每个三角形相邻区域的三角形表面曲率来简化求交判断。

第2篇

软件开发过程包括需求分析,系统分析与设计,编码测试过程等。而构建复杂多变的系统,难度主要体现在需求分析过程。需求分析人员通过与用户沟通,获得详细全面的需求描述,即与系统相关的“问题域”;系统分析师需要理解用户想要的系统、评估权衡不同的解决方案,即与系统相关的“求解域”。面向对象的方法把“问题域”与“求解域”的建模活动合二为一。“问题域”首先被建模成一组对象和关系,然后系统用这个模型来表达它操纵的现实世界的概念。比如中煤平朔劳保物资发放系统中员工资金账户对象,就表示现实生活中,员工在领用劳保时专有的一个虚拟钱包;员工资金账户操作记录对象,表示劳保管理人员对员工的虚拟钱包存款或扣款。“求解域”也被建模为对象。面向对象中使用了数据抽象、信息隐藏或封装、继承和分段加工等,对象和类就是对现实世界的一种抽象,对象和类中封装了相关的属性和方法,通过对象与对象之间的信息交互,来实现软件的功能。UML(UnifiedModelingLanguage)统一建模语言,是一套优秀的面向对象建模设计语言。为系统分析设计提供模型架构。包括功能模型、对象模型、动态模型。中煤平朔劳保物资发放系统的系统分析与设计通过UML中的UseCase(用例图),Class框图(类图),和Sequence(顺序图)来实现。

二、系统建模

(一)功能模型开发软件的初期阶段,需求分析人员与用户经过反复地沟通,了解用户详细的需求,并且对需求的规格定义达成共识,落实到具体的文档形式。UML技术中的用例模型-Use管理二一四•十二企业管理Case(用例图)为解决建模问题提供了标准的可视化表示法和面向对象的建模语言。用例模型描述了系统的整体功能需求,使开发人员站在软件使用人员的角度,从系统宏观上理解系统的功能。以确保在后期开发中,真实系统不会偏离用户的需求。用例图主要是刻画整个系统功能和环境约束,它由一组用例、执行者、执行者与用例间的关系以及用例间的关系组成。一个用例就是系统一个功能单元。根据用户需求,确定系统的边界,中煤平朔劳保物资发放系统的外部执行者可分成四个角色(Actors):系统管理员、卡务管理人员、采购计划管理人员、仓库管理人员,然后根据角色的使用功能确定用例。系统管理员是系统的全局角色,除执行基础数据管理以及其他角色的管理模块之外,还负责系统权限设置、系统数据备份和恢复、系统相关参数设置等。行政单位设置用例是企业内部按照等级划分和按照不同职责划分的各级部门基本信息的增加、删除和修改功能。工种设置用例是企业按生产劳动性质来划分的种类基本信息的增加、删除和修改。岗位设置用例是企业内部在特定的时间段内,由特定的人或小组所担负某项任务的组织基本信息的增加、删除和修改。员工岗位任职设置用例是在具体的岗位中指派特定的员工基本信息的增加、删除和修改。用例图同时划分了清晰的系统权限。岗位权限设置用例说明系统的权限由岗位来划分,不同的员工登录系统后,会根据其岗位权限来确定系统的使用权限。基础数据用例图如图1所示。卡务管理人员是在信息卡逐步代替手工单据、票据的制作、保管下应运而生的一类角色。卡务管理人员负责系统软件与卡信息的交互,即读取芯片卡内信息录入软件或将系统数据设置到芯片卡中。单位资金账户和员工资金账户是系统为企业内部开设的虚拟钱包,作为部门或员工领取劳保品的一种电子货币形式。单位资金往来明细和员工资金往来明细中记录了资金的存入和消费。采购计划管理员角色因物资的需求计划而设立。工矿企业的工种科目种类繁多、岗位职务分类复杂;员工领取劳保品的标准各不相同;并且物资类别丰富多样等诸多原因加大了制定物资需求计划的难度。物资类别用例和物资标准品种用例是采购计划管理员对物资的分类管理和别名管理。供应标准是企业根据一定的原则为员工领取劳保用品所指定的发放标准。供应标准明细用例和供应标准品种用例进一步说明了发放标准中的详细信息。采购计划管理员在设置特定的时间段内,根据员工的供应标准和供应标准明细生成领料计划及领料计划明细。采购计划用例图如图3所示。仓库管理人员负责入库、盘点、调库、发放,以及实时查看仓库库存和库存变动情况。系统管理员可以增设仓库信息,指派相应的仓库管理员。仓库管理员接收供货商的物资,执行入库操作。仓库管理员可以对仓库执行调库操作。可以实时查看库存情况,盘点库存的盈亏。在物资发放上仓库人员采取按计划发放和零售发放两种方式。库存、发放管理用例图如图4所示。用例描述模板描述了角色和系统交互的事件流。卡务管理员资金账户明细管理,包括添加、修改、删除三个用例描述。添加员工资金账户明细的用例描述,如表1所示。

(二)静态模型Class框图(类图)是UML建模中的一个基本要素,类图用于描述系统中类的静态结构,描述了类、接口、协作以及它们之间的关系。主要内容包括类、接口、协作、依赖(一个类使用另一个类)、泛化(一个类是另一个类的特殊化)、实现(一个类是另一个类的实现)和关联关系(彼此之间存在联系)。类的组成包括类的名称、类的属性和方法。图5和图6表示了基础数据类图和采购计划管理的类图,以及类之间的关联。行政单位是企业内部划分的主管部门,可以根据上下级别划分成二级行政单位和三级行政单位等;工种是根据劳动管理需要,以企业的专业分工和劳动组织基本状况为依据进行的划分;岗位是企业根据具体的劳动强度、劳动环境和技术要求而进行的划分,比如:同样是司机,对于170吨重型卡车司机和普通司机的技术要求是不同的,同时样是管钳工,对于井上管钳工和井下管钳工的作业环境、安全要求是大不相同的。不同的岗位就决定了福利、奖励的差异。供应标准及供应标准明细是企业为员工发放福利所制定的供应标准。供应标准依据是员工的岗位制定,企业还可以根据行政单位、工种、岗位供应类别及员工岗位任职来制定供应标准,这样就要求系统设计适应需求的变动。领料计划是由计划管理员定期制定的,包括计划的起始和结束时间,领料计划明细是根据领料记录信息与供应标准计算得出,包括物品的使用起始时间,使用结束时间,可领数量等。图7表示了卡务管理的类图。卡作为卡务管理中的核心部分,包含了卡的基本信息和卡的设置参数,以及卡的类型。卡的类型有两种:单位卡和个人卡。单位卡用于单位资金账户的操作,因此每个行政单位至少具备一个单位资金账户,单位资金账户明细反映了单位资金账户的上账记录和消费记录。个人卡用于员工资金账户的操作,每位员工至少具备一个员工资金账户,员工资金账户明细反映了员工资金账户的上账记录和消费记录。图8表示了库存、发放管理的类图。入库单、入库单明细反映了仓库库存的入库操作,出库单出库明细反映了仓库库存的出库操作,仓库库存反映了当前库存的实时情况。根据需求在实际发放中分为两种发放形式,一种是计划发放形式,另一种是零售形式。领料单反映了员工在某一阶段内的领料状态,领料单明细反映了某一阶段内该员工可以领用的物品及数量,领料记录反映了已经领用的信息。销售单销售明细反映了零售方式的员工领用情况。

(三)动态模型Sequence(顺序图),描述的是参与者与对象之间的时间交互顺序。顺序图是对用例图的细化和扩展。参与者通过软件完成一项特定的功能,需要与相关的类产生交互,所有参与类都要产生自己的实例,并提供相应的方法,对象调用其他类的方法是按照时间顺序排序的,在图上是以从左到右的方向显示,同时每一次调用都要有反馈消息。图9表示了采购计划管理员生成某阶段的领用计划用例的系统工作顺序图。其中生成领用计划的是采购计划管理员。它首先向领料计划类对象发送生成计划消息,领料计划类对象通过调用自己的方法检查当前的计划是否已经生成,如果未生成,领料计划类对象会调用行政单位类的方法获取相关的行政单位信息,行政单位类对象调用岗位类方法获得相关的岗位信息,岗位类对象调用供应标准类的方法获得相关的供应标准信息;岗位类对象调用员工岗位任职类的方法获取相关的员工岗位任职,员工岗位任职类对象调用员工的方法获取员工的信息。根据供应标准信息为每个员工生成领用计划。

三、结束语

第3篇

“服务型高校行政管理模式”的内涵可以通过以下四个方面分析,即管理观念、管理职能、体制结构和服务对象。首先,从管理观念角度分析。要将服务师生、服务教学的观念贯穿到日常的行政管理工作中,将教师和学生的角色从被管理者转变为服务的对象,强化“管理即是服务”的意识;其次,从管理职能角度分析。高校服务型行政管理职能的侧重点应体现在两个方面,即实现从权力型机关向责任型机关的转变,以及提升对服务职能的认识,摒弃行政本位,以教学科研为中心;再次,从体制结构角度分析。一方面,采用扁平的组织机构来代替传统的金字塔结构,合并职能相近的机关部门。另一方面,提高学校制度政策制定的参与性和民主化;最后,从服务对象角度分析。高校所具有的人才培养及教学科研的基本职能决定了高校行政部门服务的对象是学生和教师,因此,应以师生为本,为其创造良好的平台和环境,推动教育事业的发展。高校服务型行政管理模式归纳起来具有以下四个特征:

第一,强调服务意识。坚持“以师生为本”的理念,将服务视为学校管理模式的核心价值观和行政管理机构的首要职责,一切从师生的需求出发,为师生的利益着想,明确师生的主体地位和作用。在实际工作中,努力实现和维护好师生的根本利益,协调好各方面的利益关系,做到“教育以育人为本、以学生为主体,办学以人才为本、以教师为主体”。

第二,鼓励参与并及时回应。鼓励参与指的是在涉及有关学校发展与建设的问题上,服务型行政管理模式鼓励相关人员参与。学校决策不再仅由少数领导干部讨论决定,而是要广泛听取师生、家长及其他相关机构的意见与建议,让他们充分而自由地参与到学校决策中来;与鼓励参与相对应的是强调回应性。针对相关人员提出的意见和建议,建立科学有效的沟通回应机制,以保证畅通无阻的沟通与交流。

第三,体现公开与公正。在新时期高校服务型行政管理模式下,学校行政部门要及时将重要工作信息如学校重大决策、制度调整和管理活动向师生、家长及其他相关机构公布,做到管理的公开和公正。师生、家长等相关人员有权对学校的服务质量进行监督。

第四,倡导尊重与平等。服务型高校管理模式倡导尊重个体,强调平等。在日常行政管理工作中,管理人员要严格遵循勤奋务实的工作原则,努力与师生形成一种互相尊重、彼此平等的关系,营造和谐的工作氛围。在管理决策过程中,行政部门应充分考虑并积极维护师生员工的合法权益,使每位师生都能平等地享受学校资源,使学校教育发展的成果惠及全体师生。

二、目前中国高校行政管理的现状及存在的问题

近年来,在全国构建“服务型政府”的大背景下,高校行政管理工作的服务意识不断增强,行政管理体制改革不断向前推进,但由于中国高校始终没有完全摆脱传统的行政管理模式,时至今日仍然存在一些弊端和问题,主要表现在以下几个方面:

(一)管理机构过度膨胀

中国高校在内部管理上一直采用从学校、学院、教研室到教师这种自上而下层层管理的形式,即金字塔式的组织机构。这种科层制的组织机构会产生两个方面的负面影响:一是由于各部门功能不断细化和权限不断缩小使行政部门岗位越设越多,导致机构膨胀,行政效率不高。二是由于中国高校行政管理人员是按照政府机关的人员编制设置的,从科员到处级、局级逐级建构,每个部门至少有两到三名行政人员,随着行政机构的不断膨胀,行政管理人员的队伍也越来越大。

(二)管理制度不完善

一方面,缺乏实际有效的法律制度保障。中国现行的教育法律体系是自20世纪80年代开始建立的,以《中华人民共和国宪法》为基础,先后制订了《学位条例》、《义务教育法》、《高等教育法》等教育法律、法规,它们构成了中国现行教育法律制度的基本框架。但这其中及后续出台的相关法律法规涉及行政管理的内容较少且空泛,实际工作中难以参照执行,使行政人员在执行或决策中随意性增大,难以形成公开透明的制度环境。另一方面,很多高校忽视与行政管理制度联系密切的监督和信息反馈等民主制度建设,使得师生、家长及相关机构脱离了涉及高校重要决策制定的过程,不利于建立“以人为本”的新时期高校服务管理模式。

(三)管理机制不健全

首先,人才引进机制不完善。高校不仅需要有一支高水平的师资队伍,还要有一支高素质的行政管理队伍。从专业素质看,大多数行政管理人员都不是来自管理专业,没有经过系统的高等教育基础理论和现代高校管理知识的学习,不具备系统的知识理论框架,在日常工作中不讲方式方法,影响了工作效率。从年龄结构看,由于对高校行政管理工作仍保持着传统的认识,即科技含量低、创新空间小、自我提升慢等,专业青年人才不愿加入到这个队伍中来,致使整个行政管理队伍人才出现断层。其次,激励机制欠缺。目前,全国各高校发放工资、奖金、福利等大多是以科研成果来划分等级,由于工作性质原因行政人员不可能在科研方面有太多成果,因此获得奖励的机会很少,导致行政人员缺乏工作积极性,工作效率受到影响。

三、构建高校服务型管理模式的主要措施

解决传统高校行政管理模式中出现的问题,推动新时期高校服务型管理模式的建立,是中国高校内部管理体制改革的重要任务,具体要从转变管理观念、精简管理机构、完善体制机制三个方面入手。

(一)转变和提升服务理念

在全国构建“服务型政府”的大背景下,高校应开始转变并不断提升行政服务理念,将以人为本作为日常工作的出发点,将保证高校师生的利益作为工作核心,树立和维护以服务为根本、尊重与合作并存的理念,真正做到将为师生提供的便利化服务扩展到最大范围。坚持“以师生为本”的服务理念,需要行政管理人员在日常工作中具体做到以下两点:第一,明确定位,包括对自身的定位和工作对象的定位。行政管理人员应深刻理解高校行政管理工作的性质、职能和作用,摆脱自身官本位思想的束缚,站在服务者的角度协助师生处理好日常事务工作。第二,把握好思路和方法,寻求以师生为本的有效的高校行政管理工作方式方法,切实转变工作作风。

(二)精简机构

建立扁平式的组织结构科学合理的组织结构不仅搭建出了新时期高校服务型行政管理模式的主体框架,还为提高行政工作效率和服务质量打下了坚实基础。科学和合理的组织结构是指扁平式的组织结构,即改变传统多层级的金字塔式组织结构,减少过多的中间层行政部门和行政人员职位,使行政组织逐渐趋向简约化和扁平化。这种扁平式的组织结构具有管理层次少、管理成本低、管理跨度大、信息传递速度快且准确度高等特点,促进行政管理工作效率不断提高。

(三)建立并完善管理机制

第4篇

    在外语教学中的应用和对外语教学的启示

    1、充分关注学生的认知差异。

    设计任务教学时安排任务活动要层层推进,逐步提高学生的语言运用能力,在运用中由浅入深。例如,在牛津高中英语的教学中,我每模块的每个单元都有一个任务型教学活动,根据不同的教学内容设计不同的教学活动。要把“学生带任务的学习”落到实处,教师要改变教学观念,从准备到点拨的过程中,教师必须使学生明确学习意识,做到鼓励学生大胆的使用英语。通过任务型教学实践,我发现学生对这种教学方法产生极大的兴趣,使学生能在参与活动过程中,通过自己的创造和别人合作共同完成交际任务。

    2、划分小组,合理搭配小组成员。

    使学生能够根据自己的学习情况,自主探究,进一步锻炼学习英语的语言能力和创新实践能力,又让学生学以致用。活动中要注意到学生个体差异,因此,要合理搭配小组成员。根据不同问题,小组成员可多可少,有时让大家自行解决分组,完成任务。加强学生的活动,并能及时给予个别辅导。经过几年的任务型教学实践,我认为,任务型教学不仅提高了学生的听说读写的语言运用能力,而且培养了学生的研究实践能力,在英语教学中有很大作用。倡导任务型教学模式,不仅表现在学生在课堂内容的学习参与上,而且在完成任务的过程中,达到知识的积累,技能的训练,能力的发展。第二部分:以牛津高中英语第四模块第一单元TASK板块为例,探讨高中英语课中的任务型教学模式。根据本节课的写作目的即为公司的ChocoLocoBar写一则广告的最终目标,在课开始的时候,迎合许多学生喜欢音乐的兴趣爱好,我在网上找到了学生喜欢吃的德芙巧克力的音乐广告,虽然学生可能没有听过,但能够激发学生的兴趣,通过歌曲赏析和辨析来训练学生的听的能力。然后通过对德芙广告的中英文广告标语的介绍和在网上找到的市场调查数字报告自然导入,帮助学生复习分数,小数和百分数的表达方式,并提醒学生注意小数点后的数字的正确读法并对数据变化的各种表达方式如增加、减少、变化、范围和限度通过条形图表的形式出现,形式相对新颖,让学生在读图中自然而然的学会各种数字的句子表达方式,然后再进行该部分的词块总结呈现。在第二次听力活动前,让学生用以上相关词块进行句子翻译练习,学生四人小组操练,老师将一张有六句中文句子的练习纸发给每个小组,由一人说出中文句子,其他三人抢译。由复习与总结如何说各种各样的数字到用所学词块进行翻译练习,此时学生们已经对听力内容中所要涉及到的句型比较熟悉,接着适时进行听力练习。听力任务过程中,适时地停顿让学生有时间思考各个数字的表达和书写,然后再抽取个别同学汇报答案,这种做法提高了最后答案的正确度,也提高了课堂的效率。在此基础上帮助学生掌握连词的用法,训练学生能够有条理地陈述自己的观点,提高学生口头表达能力,要求学生结对练习对话,通过同桌做采访的活动,鼓励学生应用所学表达方式和不同的句子结构陈述理由,表达观点,有利于提高学生的口头表达能力。然后帮助学生辨别不同形式的句子并要求连线以辩识不同形式句子的能力,再通过阅读书上三则广告并总结广告中所阅读到的广告用语词块,有意识地让学生进行写作模仿,并为一些基础薄弱的学生提供了写作模版和任务,保证每个学生都有了写作的素材,而基础好的学生可以自行发挥,广告文章的写作也就水到渠成。最后要求学生用自己最有说服力的图片和语言向全班同学展示和推销自己的广告产品。在整个教学活动中,教师是导演、咨询者和参与者,学生则是活动主体,学生的任务是开放型的。每个环节都有明确的任务,方便各个层次学生的学习。与之前的教学活动相比,该教学难度降低,但能保证各个层次学生的不同层度的提升。学生以小组为单位进行讨论有利于培养学生的合作精神。学生个体的活动则给整个课堂增添了一抹抹亮色,学生回答精准之处无不增添了学生的英语学习兴趣。

第5篇

1前言随着计算机技术和人类社会经济的发展,对于纺织服装业CAD/CAM的应用要求也越来越高,二维服装CAD系统已经不能满足要求,人们迫切希望借助计算机完成一些更加实用的三维功能。若能直接将二维服装CAD系统设计的衣片,在计算机上真实地模拟出穿在人体上的效果,便可以帮助设计师直接在计算机上进行着装效果检查、服装裁剪片缝合检查等工作。这样就可大大提高服装从设计阶段到生产阶段间的效率,具有非常重要的实用价值。要通过计算机实现这一功能,有两个关键的问题必须解决:1)建立合适的织物变形模型;2)选择高效而实用的碰撞检测算法。

研究织物变形仿真的方法通常分为三类:几何的、物理的和混合的(几何和物理方法的混合)。纯几何的造型方法很难反映织物的物理特性,因此基于物理的方法研究,近年来已占据了主导地位。在织物变形物理仿真模型中[1],按比拟织物结构的方式又可分为两大类:1)离散质点型模型:比较典型的有Feynma等建立的质点网格模型、Breen等建立的粒子模型和XProvot等建立的弹簧质点模型;2)连续介质型模型:比较典型的有Terzopoulos等建立的弹性变型模型、Liling等建立的空气动力模型、Aono建立的波传播模型、Collier等建立的有限元模型等。

以上的织物变形物理仿真模型,由于其建模的原理和方法不尽相同,因此,它们适用于不同的应用场合有其各自的优缺点。

我们结合设计虚拟穿衣功能的实际,认为XProvot所建立的弹簧质点模型,模型简单,易于计算机实现,在模拟衣片复杂的动态变形过程时,能够取得比较真实的模拟效果和较快的模拟速度。

在模拟三维服装穿在人体上的真实效果时,会遇到大量的碰撞现象:衣片同人模之间以及衣片自身间的一种相互渗透和穿越。只有很好地解决了渗透和穿越的问题,才能逼真地完成虚拟穿衣的模拟过程。因此,碰撞检测是整个模拟过程的关键。碰撞检测非常耗时,最简单的碰撞检测算法是对两个碰撞体中的所有基本几何元素(通常为三角形)进行两两相交测试。

现有的碰撞检测算法大致可划分为两大类:空间分解法(spacedecomposition),和层次包围盒法(hierarchicalboundingvolumes)。前者是将整个虚拟空间划分成相等体积的小单元格,只对占据同一单元格或相邻单元格的几何对象进行相交测试。比较典型的方法有八叉树和BSP树。层次包围盒法的核心思想是利用体积略大而几何特性简单的包围盒将复杂几何对象包裹起来,在进行碰撞检测时,首先进行包围盒之间相交测试,只有包围盒相交时,才对其所包裹的对象,做进一步求交计算。在构造碰撞体的包围盒时,若引入树状层次结构,可快速剔除不发生碰撞的元素,减少大量不必要的相交测试,从而提高碰撞检测效率。比较典型的包围盒类型有沿坐标轴的包围盒AABB(axisalignedboundingboxes),包围球(sphere),方向包围盒OBB(orientedboundingbox)等。

在本文中,我们充分利用了AABB层次包围盒法的优势,同时在构建静态人模的AABB树时,又借助层次空间分解法中子空间在空间排列上的有序性和相关性的思想,将缝合衣片的相对位置同人模自身的结构信息相结合,灵活地构造人模AABB树,这样减少了需相交测试的元素,从而提高了碰撞检测的效率。

2织物的变形模型

2.1织物变形模型的描述

我们建立的织物变形模型是以XProvot的弹簧质点模型作为基础,将织物设想为一个个质点集合,质点间相互关系归结为质点间的弹簧作用。其中弹簧分为三类:结构弹簧、剪切弹簧和弯曲弹簧,具体构成如图1所示。图1织物模型离散成规则网格

1)结构弹簧:在质点Pij和Pi+1,j间,以及Pij和Pi,j+1间的弹簧为结构弹簧,结构弹簧是为了保持质点间初始状态时的距离。

2)剪切弹簧:在质点Pij和Pi+1,j+1间,以及Pi+1,j和Pi,j+1间的弹簧为剪切弹簧。剪切弹簧是为了防止织物在自身平面过渡和不真实的变形,而给织物的一个剪切刚性。3)弯曲弹簧:在质点Pij和Pi+2,j间,以及Pij和Pi,j+2间的弹簧为弯曲弹簧,弯曲弹簧是为了防止织物弯曲。2.2质点的位移在缝合衣片过程中,衣片上所有质点因受力而产生一定的位移,质点位移我们选用Nowton运动定律来描述:F外力(i,j)+F内力(i,j)=ma(i,j)其中,m是质点P(i,j)的质量。在本文中,我们假定布料是各向均质的,因此,质点的质量可由衣片总质量除以质点总数得到,a(i,j)是该点加速度,F外力(i,j)是该点所受的外力,F内力(i,j)是该点所受的内力。为了简化模型,在我们三维服装CAD系统中,只考虑两种外力:缝合力和重力。可以用以下公式来表示:F外力(i,j)=F缝合力(i,j)+F重力(i,j)

在衣片缝合过程中,为了将不同的衣片缝在一起,我们在衣片对应缝合边上加载缝合力。在模型中,缝合力被定义成对应缝合点之间距离的线性函数。对两个缝合点pi,j和qi,j间的缝合力,可以按如下公式计算:F缝合力(i,j)=CsDis(pi,j,qi,j)Npi,j-qi,j式中Cs为缝合力系数,该系数与织物的缝合性能有关,通常,较难变形的布料采用较大的缝合力系数;Dis(pi,j,qi,j)表示两缝合点pi,j和qi,j间的距离;Npi,j-qi,j表示从pi,j点指向qi,j点的单位方向矢量。为了获得较真实的仿真效果,我们在变形模型中考虑了衣片所受的重力。质点所受的重力可按如下公式计算:F重力(i,j)=mi,jg式中mi,j为质点pi,j的质量。在弹簧质点模型中,唯一考虑的弹性内力是弹簧的弹性变形力,由于采用的是理想的弹簧质点系统,可以利用胡克(Hooke)定律来计算弹簧的弹性变形力:F内力(i,j)=-∑(k,l)∈Rk(Pi,jPk,l-Pi,jPk,l0Pi,jPk,lPi,jPk,l)其中,k是弹簧的弹性变形系数,R是P(i,j)邻点的集合,Pi,jPk,l0表示质点P(i,j)与质点P(k,l)之间的原始距离,弹簧的弹性变形系数k可以依据所选用织物的材料性能参数曲线确定。

2.3织物变形模型的求解我们选择显式欧拉方法来求解织物变形模型。求解公式如下:ai,j(t+t)=1mi,jFi,j(t)Vi,j(t+t)=Vi,j(t)+tai,j(t+t)Pi,j(t+t)=Pi,j(t)+tVi,j(t+t)其中,Fi,j是质点P(i,j)所受所有力的合力,mi,j(t)是质点P(i,j)的质量,ai,j(t)、Vi,j(t)和Pi,j(t)分别是质点P(i,j)在时间t的加速度,速度和位置。t是系统选定的时间步长。

3基于AABB树层次包围盒的碰撞检测

3.1建立AABB树一个碰撞体的AABB被定义为包含该碰撞体,且边平行于坐标轴的最小六面体。因此,描述一个AABB,仅需六个标量。在构造AABB包围盒时,需沿着碰撞体局部坐标系统的轴向(X,Y,Z)来构造,所以所有的AABB包围盒具有一致的方向。

AABB树是基于AABB的二叉树,按照由上至下的递归细分方式构造生成的。在每一次递归过程中,要求取最小的AABB,需沿所选择的剖分面将碰撞体分为正负两半,并将所对应的原始几何元素(如三角面)分别归属正、负两边,整个递归过程类似于空间二叉剖分,只是每次剖分的对象是AABB,而不是空间区域。递归细分一直要进行到每一个叶子节点只包容一个原始几何元素为止,所以具有n个原始几何元素的AABB树具有n-1个非叶子节点和n个叶子节点。对于剖分面的选择,在本文中,选择垂直AABB的最长轴,且平分该轴的平面。经试验证明,这种方式,在大多数情况下的算法复杂度仅为O(nlogn),较其它的剖分面选择方法有了极大的提高。至于原始几何元素的归属则应依据几何元素的重心P在最长轴上的投影坐标。若投影坐标大于剖分面的坐标(mid),则在剖分面的正向,否则在负向,如图2所示。图2三角面归属负区域,因为其质心投影坐标小于剖分面的基准坐标

3.2AABB的相交判断AABB间的相交测试比较简单,两个AABB相交当且仅当它们在三个坐标轴上的投影区间均相交。通过投影,我们即将三维求交问题转化为一维求交问题。而对一维求交问题,我们则采用SAT(SeparatingAxesTest)[2]法。因SAT无需求交计算,只需比较两个包围盒分别在三个轴向上投影的重叠情况,即可得出相交测试结果,非常简单。现以在一个轴向上的投影情况为例说明:图3AABBs在X轴向相交判断。

设A,B为两包围盒,X为投影轴,CA,CB分别为A,B的中心点,PA,PB为点CA,CB在X上的投影。RA,RB分别为包围盒A,B在X上的投影。若RA+RB

PAPB,(如图3所示)则在轴向X上A和B不相交,反之在轴向X上A和B邻接或相53第5期高成英等:虚拟穿衣中织物模型的建立和碰撞检测的处理交。当包围盒A,B在三条轴向上的投影均相交时,则A,B相交。定义AABB的六个最大最小值分别确定了它在三个坐标轴上的投影区间,因此AABB间的相交测试最多只需六次比较运算,非常简单快速。

3.3AABB树的更新当衣片移动、旋转后,需要对AABB进行更新,根据定义AABB的6个最大最小值的组合,可以得到AABB的8个顶点,对这8个顶点进行相应的旋转和平移变化,并根据变化后的顶点计算新的AABB。当衣片发生变形时,需要重新计算AABB树中发生变形了的叶结点的AABB,再利用变形叶节点的新AABB来重新计算它们父节点的AABB。这种计算必须严格按照从下到上的方式进行。父节点AABB的具体求法为:令(Xmax1,Xmin1,Ymax1,Ymin1,Zmax1,Zmin1)和(Xmax2,Xmin2,Ymax2,Ymin2,Zmax2,Zmin2)分别是两个变形叶结点的AABB,则父结点的AABB即为(max(Xmax1,Xmax2),min(Xmin1,Xmin2),max(Ymax1,Ymax2),min(Ymin1,Ymin2),max(Zmax1,Zmax2),min(Zmin1,Zmin2),只需6次比较运算就完成一个结点的更新,其效率远远高于重新构造AABB包围盒树。

3.4基于AABB树的碰撞检测算法基于AABB树碰撞检测算法的核心是通过有效地遍历这两棵树,以确定在当前位置下,两个碰撞体的某些部分是否发生碰撞,这是一个双重递归遍历的过程。算法描述如下:step1:分别为人模和衣片构造AABB树。step2:人模的AABB树的根结点遍历衣片的AABB树。如果发现人模AABB树的根结点的包围盒与衣片AABB树内部结点的包围盒不相交,则停止向下遍历;如果遍历能到达衣片AABB树的叶节点,再用该叶节点遍历人模AABB树。如果能到达人模AABB树的叶节点,则进一步进行基本几何元素间的相交测试。step3:检测基本几何元素间是否相交。3.5自碰撞检测在衣片缝合过程中,除了衣片同人模之间的碰撞外,由于衣片的动态变形,使得衣片与衣片自身间也有碰撞现象,因此必须进行进一步的自相交检测。在系统设计中,我们利用三角形表面曲率来简化计算。当邻近三角形法线的夹角较小时,它们不可能发生碰撞,只有当夹角超过阈值,才有可能碰撞。我们为每个三角形建立它的临近三角形列表,通过判断每个三角形的所有邻近区域的三角形表面曲率,来排除大部分不可能相交的情况,从而简化了计算。

4虚拟穿衣的具体实现步骤

(1)读入二维服装CAD系统设计的衣片

(2)选择所有需要缝合衣片的对应的缝合边

(3)将二维衣片离散并形成初始的弹簧质点系统a)将衣片离散成规则四边域网格,再将四边域网格的对角线相连,形成规则三角形网格的弹簧质点系统。三角形的顶点形成质点,三角形的边形成相应的弹簧。衣片的三角化,正是为方便地建立衣片的AABB树;b)按质点间的相应关系,加入各种弹力。在离散衣片时,需特别注意的是在(2)中所选择的对应缝合边的长度一定要相等,且当衣片离散化时,在对应缝合边上的原始几何元素(这里为三角形)的个数也应相同。若在(2)中所选择的对应缝合边长度不等,或原始几何元素个数不同时,系统将需做一些预处理:将其中一条缝合边的所有信息删除,将另一条缝合边的相应信息赋给它。

(4)将衣片交互式地放置在人体模型附近的初始位置在该步骤中,首先,给每一缝合衣片赋一个别名(系统自定义的标准别名:左前片,右前片,左后片,右后片等),根据每一衣片的别名,衣片被自动地放置在人体模型附近的相应初始位置上。

(5)分别为人模和衣片建立AABB树本文中所涉及的两个碰撞体,分别为人模和衣片,其中人模在整个动态模拟过程中为静态的,因此,只需在初始化时构造一次AABB树即可。为了进一步提高碰撞检测的效率,我们在构造人模的AABB树时,应根据(4)中得到的缝合衣片别名,结合人模的几何结构,灵活构造人模的AABB树。例如:假设我们在(4)中,得到衣片分别为:左前片,右前片,左后片,右后片。我们即可知,将要缝合的为一件四片裁剪片的上衣,所以在构造人模的AABB树,我们只取人模上半身数据来构造人模的AABB,具体层次结构如图4所示。在进行人模和衣片间碰撞检测时,根据衣片的别名分别进行局部检测,(例如:左前片,就只需和人模AABB树第三层最左边的结点,左前半身的AABB进行碰撞检测)有效地减少了需要碰撞检测的元素。系统根据所缝合的衣片不同,建立的人模AABB树亦不相同。图4人模的AABB树层次结构图

(6)动态变形模型的计算根据衣片的缝合信息,我们在衣片的对应缝合边上加载缝合力。在缝合力、重力和衣片上各质点间内部弹力的共同作用下,二维衣片将逐步变形,并逐渐被缝合在一起,整个缝合过程是一个动态的迭代过程。在动态迭代过程中,要同时进行大量的人模—衣片间,及衣片—衣片间的碰撞检测处理,并给出相应碰撞响应(当有碰撞现象发生时,要重新调整碰撞点处的位置,避免发生穿越和渗透)的处理。缝合过程结束后,便可以得到缝合好的三维服装穿在静态人模上的效果。

5结束语实验证明,本文所采用的织物变形模型———弹簧质点模型,模型简单,能够较真实地反映虚拟环境下的织物特性。所采用的基于AABB的层次包围盒碰撞检测算法,除了AABB层次包围盒自身在碰撞检测上的较高性能外,算法还从以下几方面提高了碰撞的检测效率:

1)将缝合衣片的相对位置同人模自身的结构信息相结合,灵活地构造人模AABB树,减少了人模和衣片之间不可能相交元素碰撞检测的次数;

2)AABB包围盒的相交判断中,采用SAT方法进行包围盒之间的交叠判断,降低了算法的复杂度,提高算法效率。

3)衣片之间的碰撞判断,利用了每个三角形相邻区域的三角形表面曲率来简化求交判断。

第6篇

【关键词】人性化护理服务模式探讨

随着经济和社会的发展进步,以人为本、充分倡导尊重人格,满足人的需求,人与社会和谐发展成为当今社会发展的主旋律。同时,人们的健康观念不断更新,人们认识到人体和环境是相互联系、相互制约的统一体,疾病的形成是复杂的、由多种因素决定,疾病的治疗和预防也需要立体的综合措施。在医疗服务中,强调以人和健康为中心,关注人的价值和需求成为举足轻重的重要环节,患者不但需要获得满意的诊疗,而且还有精神、心理上的舒适、安慰,治疗上的参与、选择和多元化的服务需求[1]。而人性化护理恰恰是实现这一目标的最好手段和方式,这是社会进步引发护理模式改革的必然结果,是社会对护理工作提出的必然要求。在临床护理工作中如何应用人性化护理模式,如何及时发现和满足住院病人的心理需求,如何实施人性化的护理服务,本文对上述问题进行探讨。

1病人的需求

1.1病人的护理需求人们患病时,从自己熟悉的社会环境走进陌生的医院,从家庭社会的多种角色变为病人。住院后,病人非常关注自己的诊治医生、责任护士、科室主任和护士长;希望尽快进行检查治疗并知道自己的检查结果;希望了解疾病的治疗效果;希望知道治疗疾病所需的总费用;希望亲人的陪护以及与护理人员沟通交流;希望护士的技术娴熟;希望住院的环境安全舒适等。

1.2病人的心理需求人们患病后,心理方面会产生焦虑、恐惧、孤独等心理问题,从而产生一系列的心理需求。

1.2.1焦虑恐惧心理害怕疾病不能治愈,经常处于惊恐不安的紧张状态,有的甚至吃不下饭,睡不着觉,精神压力很大。这时,他们希望医务人员多关心他们,给他们讲解疾病的相关知识,指导他们如何配合治疗。

1.2.2孤独心理人们患病后进入医院这个新的环境,这里的环境及医护人员对他们而言都是陌生的,他们会感到茫然,无所适从,很容易产生失落感,他们希望有亲人的陪护,希望医务人员多与他们谈心,尽量缩短与医务人员之间的距离。

2满足病人的需求

2.1营造人性化的环境医院和病房应努力营造一种充满人情味的、尽可能体现家庭式的温馨和舒适的环境。一切本着方便病人,从细微之处入手。

2.2将人性化融入护理过程我们的医疗对象首先是“人”,其次才是“病”。因此我们首先要尊重、理解、关怀病人。从入院那一刻起,我们就要把病人当作一个需要帮助的弱势群体来关注,帮助他们尽快熟悉环境及周围的人;对他们提出的问题耐心解答;多与他们沟通交流,给予他们足够的心理支持与心理疏导,帮助他们树立战胜疾病的信心;刻苦学习,提高专业水平,以娴熟的技术服务病人。

3人性化护理服务的方法和措施

3.1确立服务质量标准根据人文精神和健康新概念来调整、确定护理质量评价标准,强化对护理人员服务主动性和体现人文关怀等内容的评价指标,建立住院病人需求分析制度,出院病人跟踪随访调查制度以及护理服务质量讲评分析制度,将病人对服务是否满意作为评价的重要标准,将病人的需要和期望转化为质量要求和质量标准。

3.2培养人文精神、强化礼仪修养培养人文精神,除了丰富专业知识外,还要不断丰富社会学、人文学、伦理学、心理学、公共关系、行为科学、语言学等方面的知识,养成良好的性格,形成健康向上的精神面貌,以人文精神推动人文服务。强化礼仪修养,打造礼仪化的护理服务。护士礼仪是指护士在职业活动中所应遵守的行为准则[2]。优雅的外在形象、过硬的护理技术、负责的工作态度、良好的沟通技巧是做好礼仪化的护理服务内在要求。一是基本礼仪,包括言谈、举止、仪容、服饰、个人和公共卫生等,做到语言文明、举止得当、行为规范、仪容整洁、服饰得体、庄重大方、和蔼可亲;二是职业礼仪,主要指掌握医学知识、遵守规章制度、制定工作计划、了解患者病情、加强护患沟通、保护患者隐私、注重心理治疗等。

3.3营造人文氛围,优化就医环境努力营造医院的人文氛围,使患者能感受到无处不在的人性化服务。一是营造人文化的医院环境,医院建设生态化、园林化,让患者有亲临大自然的感觉;二是建设人性化的基础设施,基础设施以方便、舒适、美观、实用为准则,让患者在诊疗期间既有舒适感,又有亲切归属感;三是营造浓厚的文化氛围,温馨化、艺术化、人性化的布局和装饰,根据就诊人群的不同彰显不同的文化特色,体现出对患者的热情和关注;四是就医流程人性化,通过导医、分诊、全程、便民及特色服务,营造舒适、温馨、便捷的就医环境,良好的就医秩序,科学的就医流程,最大限度地缩短患者就医时间,提供优质的、人性化诊疗服务。

3.4努力提高护理艺术水平护理艺术的核心是研究和掌握病人的心理,做到因人而思、因人而护,根据病人的不同情况和不同需求制定不同的护理计划,实施不同的护理措施[3]。我们不但要充分掌握护理学的基本知识,还要学习心理学、人文学科、社会学、操作技能,获得专科护理的专门技术和方法,成为一个有道德素养和艺术修养的护理人员,能够掌握病人的不同心理状态,消除病人的思想顾虑,用高超的护理艺术完成不同的特色护理。

3.5加强职业道德建设,规范服务行为一是要热爱本职工作,忠诚护理事业,倡导奉献精神;二是把病人的利益放在首位,对病人尽职尽责;三是增强服务意识,提高为病人服务的自觉性,对诊治工作密切配合,对患者的生活精心照料;四是工作严谨,认真观察病情,防范差错事故;五是严格规章制度,遵守操作规程,规范服务行为。牢固树立制度、规程就是质量和生命的理念,严格规范服务行为;六是加强技术培训,提高技术水平。

3.6健康教育人性化、个性化每个人不仅存在身体和心理的不同,更有年龄、职业、信仰、生活习惯、文化程度等不同[4]。要针对不同的人实施不同的护理方法,不仅要讲解与疾病相关的知识,还要针对其存在的心理和社会问题进行分析和开导,使患者得到及时、科学的健康指导,能够在疾病的各个阶段获得相关的健康知识并逐步培养、建立良好的卫生行为方式及健康的心理状态,在获得良好治疗的同时,运用相关健康和卫生知识去更好地维护健康。

3.7服务方法多样化、服务内容层次化一是开展全程服务,将服务过程涵盖院前、院中、院后的全过程;二是坚持服务内容层次化,能够对有着不同服务需求的病人提供不同的服务;三是推行非专业服务后勤化、市场化,使医务人员全身心地投入专业服务;四是努力使服务质量最优化,强化人员素质培养、技能提高,不断完善质量监控和质量评价体系;五是推进服务方式亲情化,对病员做到无微不至的关怀和呵护,使病人感到亲人般的温暖;六是坚持服务过程公开化,强化服务的监督作用,增强服务内容的透明度。

4评价

医院通过大力倡导人文关怀服务模式,一是大力推进了医院文化建设,全面提升了医院的社会形象,势必赢得良好的社会形象和社会效益;二是在社会树立起良好的职业形象和良好的品牌形象,从而提高医院的信誉度,提升医院综合竞争力;三是有利于在全社会逐步形成以人为本的氛围,有利于人性、爱心、亲情的体现,有利于弘扬社会美德,有利于社会的发展和文明程度的提高,有利于促进社会和谐建设;四是使人与社会的适应性不断增强,人的生活质量得到提高,健康知识不断丰富,健康意识不断增强;五是强化了护士的人文观念,提高了护士的思想道德水准、知识水平和服务能力,使护士的综合素质得到了很大提高,有助于医疗护理服务质量的全面提高和持续改进。

【参考文献】

[1]周君.未来趋势——护理人性化服务[J].中国医院管理,2003,23(12):48.

[2]戴晓阳.护理心理学[M].北京:人民卫生出版社,1999:109-110.

第7篇

一、问题的提出

长期以来,企业忽视出资者权益的维护,利益过分向经营者和职工倾斜,资本遭受严重侵蚀,资产流失惊人。长此以往,企业将难以为继。对此,许多学者进行了深入研究,并取得突破性进展。尤其是财务分层管理框架以及出资者财务论和经营者财务论的提出,为上述问题的解决及企业财务管理体制的完善提供了新的思路和广阔的制度空间。推动出资者财务和经营者财务理论在实践中的具体应用,对于实现财务根本职能,保证财务改革的正确方向,推动现代企业制度的建立,具有重大的现实意义。然而,财务管理分层框架强调不同立场(出资者和经营者)的财务目标和权责利关系,把企业财务分解开来,这对于企业财务管理模式和有效的财务运行机制的建立产生了许多困难。因此,能否把出资者财务目标内化为经营者财务的有效约束,出资者如何通过经营者财务达到其财务目标,以及经营者如何在出资者的财务约束下经营,成为财务改革的关键。本文试图对此作一探讨,以求抛砖引玉。

二、维护出资者权益是现代企业财务的基石

众所周知,公司制是现代企业制度的主要形式,我们不妨选取公司制企业作为分析样本。在公司法人治理结构中,通过多层次的关系,从激励与监督、权责利对等、信息的交流等方面,形成一个相互制约、有效降低成本、提高决策效率的组织体系。那么,股东(出资者)如何行使其所有权?如何保证股东目标的实现?在实现股东目标的过程中,董事会将通过何种机制来保证经营者目标不偏离股东目标?如何使得经营者有充分的激励机制来发挥其人力资本优势,同时保证对经营者的有效监督?这些问题的解决是建立现代企业财务的关键。财力分层管理框架以及出资者财务论和经营者财务论对这些问题提出了很好的解决思路,但是对于一个企业来说,出资者和经营者不能建立两套制度而各行其是,他们必须通过有效的财务管理模式的建立,以促进出资者财务目标和经营者财务目标的同时实现。或者说,建立一种有效的财务管理模型,这种财务管理模式必须能够把出资者财务目标内化为经营者的目标,并保证这些目标的顺利实现。

所谓模式的建立,其实质是有关制度的建立,建立有效的财务管理模式,就是要建立一套保证出资者与经营者共同实现其财务目标的制度,而要建立这套制度,必须首先找到出资者财务和经营者财务所共同依赖的基石。出资者出资,是为了实现出资增值。经营者之所以能够经营出资者出资,是因为依法事先承诺对出资者的财产责任,即保证出资的保值增值。因此,出资者财务和经营者财务统一出资者出资的保值增值,而增值又以保值为基础。所以维护出资者权益,实现出资的保值增值,是有效的企业财务管理模式建立的基石,是企业财务的首要任务和职能,对于建立产权明晰、权责分明、政企分开、管理科学的现代企业制度,具有至关重要的意义。所谓出资者权益通常指“企业所有者对企业净资产的要求权或所有权”,即出资者出资所代表的权益。维护出资者权益是现代企业财务的首要任务和职能,是现代企业财务的基石;基于出资者权益维护的企业财务管理模式,才是适应现代企业制度的财务模式,是保证出资者财务目标和经营者财务目标共同实现的载体;有效地保障出资者权益,是真正建立起现代企业制度的首要标志。

三、基于出资者权益维护的财务管理模式及其特征

基于出资者权益维护的财务管理模式,本文称之为出资者权益维护型的财务管理模式。所谓出资者权益维护型的财务管理模式,是指企业财力提供的信息和生成信息的过程必须建立在出资者权益维护的基础上,或者说是以出资者权益维护作为整个财务会计系统运行的主线和指导。其精神实质在于:在市场经济条件下,企业作为一个“受托责任”的法人财产实体,经营者是在为完成出资者所赋予的“受托责任”而工作,这样出资者投入本金的维护、经营过程的风险控制以及通过利润来增长出资者权益,就构成了企业财务管理的目标,即实现出资者权益的最大化。甚至整个企业的管理都是围绕“股东财富最大化(出资者权益最大化)”而展开。也就是说,企业的经营管理,就是“维持良好的财务状况,实现收益性和流动性的统一,注重企业的持续发展壮大,来保证实现出资者权益的最大化”。要做到这一点,企业在获得净收益前,其出资者权益必须得到充分的维护和保持,即保全出资者是确定利润的前提。

出资者权益维护型的财务管理模式有以下基本特征:

(一)服从或服务于资本运营目标是出资者维护型的财务管理模式的根本任务。从经济学意义上看,资本运营泛指以资本增值为目的的经营活动,与单纯生产型和生产经营型对比,资本运营的基本特点是围绕资本保值增值而进行经营管理,把资本收益作为管理的核心,以财务管理为导向,生产经营管理服从资本收益目标。因此,企业经营管理的重点是资本存量管理、资本增量管理、资本配置管理等,供、产、销管理及一般的筹资、投资管理要从属于资本保值增值的资本运营目标。财务管理也应以资本的保值增值为目标,出资者权益维护型的财务管理模式正是以资本运营目标作为根本任务的。

(二)保全出资者权益是确定收益(利润)的前提。企业经营的目标归根结底是为了创造收益(利润),财务管理不仅要为企业创造尽可能多的收益服务,而且必须能够正确地计量收益。要正确地计量收益,必须以保全出资者权益为前提,划清本利的界限。然而在现实操作中,由于物价变动、经济生活的不确定性、主观因素以及其他原因,往往使出资者权益不能得到有效的维护,从而导致现实存在的诸多问题,甚至陷于恶性循环,严重阻碍了财务管理目标的实现。出资者权益维护型的财务管理模式,要求采取一切可能的措施,保证出资者权益得以有效维护,保证收益计量的科学、准确,从而保证财务管理职能的真正实现。

(三)以严格的管理制度作为该模式有效运转的保证。现代企业制度下,所有权与经营权发生分离。两权分离往往存在激励不相容、信息不对称、责任不对等等问题,尤其我国现阶段尚未真正建立起现代企业制度,这些问题表现的更为突出。资产经营者以出资者的出资从事生产经营活动,出资者投放资本的目的是谋求资本收益最大化,而这必须通过资产经营者的生产经营活动才能达成。但事实上,资产经营者很可能损害出资者权益,如将资产据为己有或拱手送人,导致出资者资产流失。或者经营不负责任,导致低效或无效经营,使出资者资产发生损失。为此,出资者权益维护型的财务管理模式以建立有效的激励机制和严格的监督约束机制作为保障,从而形成了该模式的重要特征之一。

四、实行出资者权益维护型的财务管理模式是我国企业的现实选择

正如前文所述,在现代企业制度下,企业是一个拥有法人财产权的经济实体,决定了我国企业要树立市场观念,谨慎经营,努力维护出资者权益,保证企业的长期生存和发展能力;目前严重困扰我国企业发展的各种现实问题,迫使我国企业必须采用出资者权益维护型的财务管理模式。

首先,现代企业制度已经赋予了企业自主经营、自我发展、自担风险的管理机制,企业经营的目标必须从单纯的利益最大化走向出资者权益最大化(资产保值增值),企业的出资者权益将成为制约企业的根本动力,企业经营者的任免和是非功过的评价主要由出资者来进行,企业经营的最终目标将是出资者权益的维护和增长。我国已经开始推行以“国有资产保值增值率”为主要指标的考核指标体系。这就为出资者权益维护型的财务管理模式的实施奠定了宏观基础。

其次,出资者权益维护型的财务管理模式,不仅是建立现代企业制度的需要,同时它反映了与企业有利害关系各方共同利益的要求。企业作为一个独立的经济实体,其生存和发展只能取决于自身再生产能力的维持,否则只能走向萎缩乃至破产,再生产能力的维持强烈要求出资者权益的保全;企业管理当局同样关注出资者权益维护问题,因为在现代企业制度下,企业出资者与经营者之间规范的委托关系,使得企业管理当局的管理能力、荣誉与应得报酬将维系于企业生存与发展,这就促使他们重视出资者权益维护,以便确保自身的长远利益;现代企业制度下,企业出资者投资办企业,其根本目的在于扩大所拥有的财富,而其中最为起码的要求则是保证其出资的安全与完整,因而他们是其权益维护的最大支持者;债权人向企业提供信用,势必要求企业拥有足够的偿债能力,足够的偿债能力源自于企业足够的出资者权益;国家(政府)更要求出资者权益维护,企业全面坚持和贯彻出资者权益维护原则,保证其自身的长期生存与发展能力,这样国家将在诸多方面受益,因为企业确保了长期生存与发展能力,自然就为国民经济的持续稳定与繁荣打下了坚实的基础,而且为国家中长期发展培植了资源,有助于解决就业问题。

五、出资者权益维护型的财务管理模式构造

(一)树立牢固的资本运营观念,保证资本保值增值的正确考核。借鉴我国国有资资本保值增值考核指标体系,对企业资本保值增值进行考核。我国国有资本主要考核指标如下:

国有资本保值增值率=期末所有者权益/期初所有者权益×100

如果国有资产保值增值率>=1,则实现了国有资本的保值增值;

如果国有资本保值增值率<1,则意味着国有资本受到侵蚀。

可以看出,考察国有资本的保值增值,采用期初、期末所有者权益对比的方法,说明考察资本保值增值,重点在于考察出资者权益的增减。因此,建立出资者权益维护型的财务管理模式,首先就要树立这种资本运营观念,强调出资者权益的维护和保持,进行科学的资本运营,保证资本保值增殖目标的真正实现。

(二)建立科学的收益(利润)观念,建立健全定期资产评估制度。前已指出,出资者权益在会计账册中以资产负债表上资产总额和负债总额的差数来表现。资产负债表借方的资产可以看作“正资产”,贷方负债可以看作“负资产”,即担负的经济义务或责任,出资者权益则以净资产表现。各类企业的出资者,其持有的利益不是资产总额,而是净资产的期末余额。出资者权益维护理论创立伊始便与收益密切相关。收益,它代表的是某一主体在一定期间内经营活动的净成果。从会计文献来看,一般都将收益(利润)定义为收入和费用之间的差额。但在界定其具体内容时,存在两种不同的观点,一是本期营业观,将当期的收入减去为实现这些收入所发生的费用(成本)即为收益。用公式表示如下:

AI[t2]=R[t2]—C[t]

其中,AI[t2]表示第二期的会计收益;

R[t2]表示第二期的收入;

C[t]表示第二期的费用(成本)。

另一观点是总括收益观,即期末净资产减去期初净资产的差额。公式为:

AI[t2]-NA[t2]—NA[t1]+D[t2]

其中,NA[t2]表示第二期期末的净资产;

NA[t1]表示第二期期末的净资产;

D[t2]表示第二期的资本分配(股利)。

按照出资者权益维护理论的要求,收益的定义应当采用总括收益观,即收益应被定义成企业净资产的增值,换言之,只有在净资产保值基础上的增值才能被看成是真正的收益。这一定义较之本期营业观下的“以收抵支的差额”或“一定时期内经营成果的货币表现”的说法当然要科学的多,它真正揭示了收益的本质,同时也为财务会计是确认和计量收入、费用、资产、负债指明了方向。建立出资者权益维护型的财务管理模式,坚持总括收益观实乃必要。其实,相比而言,说总括收益观更为科学,还因为它具有更广泛的应用前景,如它能更好地用于金融资产的计量。因此,应建立健全定期资产评估制度。在评估中应以资产的现时成本为计量标准,特别应重视以资抵债后的资产净值,并以此计算当期收益,超过这一程度的利润分配意味着对出资者权益的侵耗,应采取果断措施加以制止。

(三)全面贯彻资本保全原则。物价变动是市场经济的伴随现象,持续剧烈的物价变动使出资者权益的保全面临着严峻的考验。出资者权益维护型的财务管理模式要求全面贯彻资本保全理论。在该种模式下,出资者权益的保全是确定收益的前提。任何一项权益都有资产相对应,出资者权益用净资产表示,净资产的计量即为出资者权益的计量。构成会计计量模式的因素有三:计量对象、计量属性和计量单位。计量因素的各种组合产生了不同的会计计量模式。不同的计量模式,出资者权益的量度和收益的确定都有区别,因而就产生了保全出资者权益的几种观点,主要包括出资者权益的货币资本保全观、出资者权益的稳值货币保全观和出资者权益的实物保全观三种,各种出资者权益保全观都规定了各自的资本保全要求。要正确分析各种出资者权益保全观的优缺点,根据实际情况选用合理的方法保全出资者权益,防止补偿不足,全面实现资本保全。具体地说,物价变动轻微时期,财务核算的原则和方法的选择应有所偏重,以便基本解决成本的补偿问题;当物价变动达到一定幅度之后,应该综合采用出资者权益保全措施,以便追求全面的资本维护。

(四)创造条件,促进谨慎性原则充分应用的。出资者权益维护型的财务管理模式,要求企业在获得净利前必须使其资本得到充分维护,体现在财务运作中,就要求必须在认真遵守权责发生制和配比原则的同时,全面推行谨慎性原则。谨慎性原则,又称稳健性原则,是指企业为了克服市场经济固有的不确定性给企业的生产经营带来的种种风险,当某一经济事项在会计上有两种或两种以上的方法可供选择,并且每一种方法都具有相同的理论上和逻辑上的正确性时,通常选择避免高估资产和收益与低估负债的会计方法,谨慎性原则是会计适应经济环境发展的结果。1992—1993年的我国会计改革中部分地引入了谨慎性原则,开始允许采用存货的后进先出法、应收账款坏账准备、固定资产加速折旧等方法来强化资本维护,确为我国会计的一大进步。但是我国会计准则和现行会计制度中谨慎性原则的应用程度还偏低,距离出资者权益维护的要求和客观需要还存在不足。笔者认为,应进一步创造条件,充分应用谨慎性原则,并建议采取以下具体措施:(1)对有价证券和存货采用“成本与市价孰低”规则进行计价;(2)将快速折旧法和直线折旧法均作为企业选择折旧方法的备选方案,并尽可能缩短折旧年限;(3)允许企业根据自身经营特点采用“账龄分析法”计提坏账准备;(4)递延资产与无形资产的摊销应尽可能缩短摊销年限;(5)对企业发生的产品维修担保、法律诉讼等或有负债进行揭示;(6)审慎地确定支出补偿内容与额度、合理划分期间费用与制造成本;(7)收入的确认要严格核查其应具备的各项条件或标准。

第8篇

(1.湘潭大学法学院,湖南 湘潭 411105;2.湘潭县人民法院,湖南 湘潭 411228)

【摘要】由于法律法规及司法解释的规定较为混杂,导致我国房屋登记案件的审理过程中,人民法院在处理民行交叉问题的时候做法各异,主要有先民后行、先行后民及一并审理等三种模式。借鉴国外先进模式,我国房屋登记案件中民行交叉问题的处理应选择一元制模式,这是我国一元制司法体制的要求,民事诉讼与行政诉讼的不断融合使然,能够获得我国司法实践的支持。

关键词 房屋登记;民行交叉;模式

作者简介:刘峰(1973—),男,湖南湘潭人,湘潭大学法学院2012级法律硕士,湘潭县人民法院审判委员会委员、审判员。

房屋登记行为兼具私法属性与公法属性的复合性特征,使得民事关系和行政关系在登记中相互交错,也导致民事争议和行政争议交叉问题在房屋登记案件中大量出现。由于有关立法、司法解释对我国房屋登记案件中民行交叉问题处理的规定较为模糊,大多是原则性的规定,且各个规定之间还存在相互冲突之处。这就导致房屋登记案件的审理中,采取何种模式处理民行交叉的矛盾和冲突成为审判实践中的棘手问题。

1我国司法实践中房屋登记案件民行交叉问题处理模式现状

审判实践中,人民法院审理房屋登记案件,对民行交叉问题的处理模式主要有以下三种:首先是先民后行模式,就是在审理房屋登记案件过程中,涉及民事争议与行政争议交叉的问题时,应当先处理民事争议,然后再处理行政争议;其次是先民后行模式,就是在审理房屋登记案件过程中,涉及民事争议与行政争议交叉的问题时,应当先处理行政争议,然后再处理民事争议;再次是一并审理模式,就是通过一个诉讼将房屋登记案件中的民行交叉问题一并处理。

房屋登记案件民行交叉问题先行后民及先行后民的处理模式有其合理性,但也存在着明显的缺陷,其缺陷除主要是诉讼中止后难以恢复、中止诉讼在法律依据上的欠缺、造成当事人诉累及浪费有限的司法资源。而一并审理模式通过民事诉讼与行政诉讼的融合解决房屋登记案件中的民行交叉问题,对于克服先行后民及先行后民处理模式存在的缺陷具有重大的实践意义。但在我国现行的司法审判体制下,也存在程序衔接等一些难以克服的问题。

2域外房屋等不动产登记案件民行交叉问题处理模式考察

考察世界各国关于房屋等不动产登记的立法例,房屋等不动产登记案件民行交叉问题处理的立法模式主要有法国的二元制模式、英国的一元制模式及日本的当事人模式三种模式。

一是法国的二元制模式。法国在房屋等不动产登记案件的审理中,属于私法性质的当事人之间的争议问题,由普通法院根据民事诉讼程序的有关规定进行审理。普通法院的法官在案件审理中,发现属于公法性质的不动产登记行为的合法性问题影响民事争议的解决,则会交由行政法院通过行政诉讼程序进行评价并作出裁判。

二是英国的一元制模式。在英国,房屋等不动产登记行政行为、民事主体之间的关系等在原则上均由同一法律进行调整,出现矛盾纠纷则统一由普通法院依据一般的民事诉讼程序规则进行审理。在审理中涉及房屋等不动产登记行政行为的,一般不对其进行司法审查,而由普通法院直接进行审查。

三是日本的当事人模式。对于房屋等不动产登记案件民行交叉问题的处理,日本采取当事人模式,即通过当事人诉讼的方式进行解决。根据日本《行政案件诉讼法》的规定,针对行政机关的房屋等不动产登记行政行为,当事人可以以行政行为涉及的另一方作为被告向法院提起诉讼,此时,行政机关也必须参加诉讼,不过其参加诉讼的身份不是原告,也不是被告,而是第三人。

3我国房屋登记案件中民行交叉问题处理模式的应然选择

他山之石,可以攻玉。借鉴英国的一元制模式和日本的当事人模式,我国房屋登记案件中民行交叉问题的处理应选择一元制模式,即通过一个诉讼,由同一审判组织对房屋登记案件中的民事争议和行政争议一并处理,这是彻底解决房屋登记案件中民行交叉问题的最佳对策。

首先,我国一元制司法体制的要求。在我国一元制司法体制下,不存在英美法系中独立的普通法院与行政法院,人民法院内部对民事审判权和行政审判权的划分,完全是根据矛盾纠纷的不同特点在法院内部所做的安排,不管是民事审判还是行政审判,都是在人民法院的统一主持下代表国家行使审判权,各审判庭没有独立的主体资格,不能以自己的名义独立对外作出裁判。在人民法院,法官也不存在民事审判法官与行政审判法官的严格区分,其在人民法院内部是可以根据工作的需要进行流动的。

其次,这是民事诉讼与行政诉讼的不断融合使然。民事诉讼与行政诉讼除了部分要素不能相互取代之外,二者在审判过程中的大部分程序是相通的。在诉讼程序进程中,民事诉讼与行政诉讼的各自所特有的要素也存在相互融合的趋势。房屋登记案件中,民行交叉问题处理的中心焦点是理顺当事人之间民事争议所涉及的民事权利义务关系,以此确定合理的诉讼程序。而人民法院对于房屋登记行为的审查,主要目的还是要解决民事争议,这也是司法实践的目的之所在。因此,司法制度的构建上,以一次性彻底解决矛盾纠纷为司法目标,通过科学合理地优化整合审判资源,在法院内部共享审判力量,由同一审判组织通过一个诉讼对房屋登记案件中的民行交叉问题作出处理,是完全可行的。

再次,能够获得我国司法实践的支持。事实上,司法实践中已存在由同一审判组织对民事行政相关联纠纷案件一并审理的先例,2002年5月,最高院针对北京市高院请示所作的批复(法[2002]117号)指出,知识产权审判庭可以对人民法院受理的涉及专利权或者注册商标专用权的民事诉讼中的不服专利复审委员会裁定提起的行政诉讼一并审理。正在修改的《行政诉讼法》也已注意到房屋登记等案件中的民行交叉问题,并在2014年8月审议的草案(二次审议稿)中规定了行政争议与民事争议的一并审理,具体体现在草案的第63条。

参考文献

[1][法]让·里韦罗,让·瓦利纳.法国行政法[M].鲁仁,译.北京:商务印书馆,2008:729.

[2]马怀德.行政诉讼原理[M].北京:北京法律出版社,2003:29-35.

[3]李战,蒋文玉.论我国民事行政关联案件诉讼程序之重构:确立民事行政交叉案件审理的一体化模式[J].河北法学,2014(2).

第9篇

关键词 :产业结构调整与升级;偏离-份额模型;经济增长

改革开放以来,武汉市的经济一直保持稳定快速发展的良好态势。“十一五”以来,2005-2012 年武汉市的GDP 增加了3.58倍。这个数字高于同期全国累计同比增长率,为全国经济持续增长做出了极大贡献,发挥了武汉市作为中部地区中心城市的示范作用。但近年来武汉市经济增长步伐明显减缓,呈现增长乏力的疲软态势。虽然在全球经济危机大背景下,武汉市的发展难以独善其身,但武汉市自身的产业结构确实存在许多问题和弊端。所以,找出其中的短板和瓶颈,提出相应的有建设性的对策建议,为经济增长提供强劲的动力支持已是当务之急。

一、武汉市产业结构发展的现状与特点

三大产业对经济增长率贡献的背后是产业产值的增加和产业结构调整与升级。武汉市产业结构在经济发展过程中不断调整和优化,但由于种种原因,最终结果并不如人意。

1.第一产业占比不断下降,生产方式比较落后

武汉市第一产业比重波动较小,除在2011年到2012年略微有所上升外,在其他年份都持续小幅下降。内部结构不断优化,但主要生产经营方式还是以传统的为主。产业化水平较低,投入产出率低,难以满足市场多样化需求,不利于收入的增加。传统的农业贡献了第一产业的大部分产值,农村居民家庭人均纯收入中农业占比近四分之三,而林、牧、畜业的发展明显力度不够,未能充分利用丰富的水资源和湿地资源的优势,发展特色农业。

2.第二产业占比略微上升,内部轻重工业比重失衡

第二产业比重呈轻微振荡,总体略微有所上升。从2005 年的45.57% 升至2012 年的48.22%。工业占据了第二产业产值的绝大部分,一般在82%以上。但内部轻重工业比例严重失调,呈现明显的重工业化,以汽车、钢铁、冶金、石油化工为主导产业,却以资源过度使用及环境污染为代价。造成不可逆转的对环境的破坏,产业选择重合度较高,利润空间被压缩,工业低水平结构性等矛盾突出。致使地方性产能过剩,虽然在短期内可以保证短期较高的产值,但难以为继。同时,轻工业的发展被严重忽视,不仅损失了大量的产值,也割断了一、二产业间的联系,使产业关联度过低,联动效果不佳。

3.第三产业占比振荡变化,新兴产业发展不足

第三产业的比重呈现先升后降的态势,从2005年的49.57%一路升至2010年的51.44%,而后便出现小幅下降,直至2012年的48.02%。在第三产业的比重总体偏低的情况下,发展速度滞后,而第三产业大多是劳动密集型产业,较低的水平使得原本就供过于求的劳动力市场的就业形势更为严峻。内部结构也局限于传统的商务服务业、仓储业和运输服务业,经营方式落后,竞争力低下,发展空间小,而具有“三高”特征的金融、信息、软件、旅游等新兴服务业发展力度不足,导致武汉市第三产业的总体发展情况不佳,难以形成竞争力。

从总体看,武汉市的二、三产业产值占比95%以上,是经济增长的强劲推动力(见表一)。产业结构不断优化,内部结构日趋合理。但与上海、北京等城市进行类比后,不难发现武汉市产业结构调整和优化的速度和深度还差强人意。武汉市第二产业比重严重偏高(占比50%以上),第三产业发展明显不足。产业结构升级的速度远远落后于东部发达地区。不合理的产业结构导致了市场要素价格的扭曲,对资源的有效配置极为不利。也使得武汉市与东部地区的差距越来越明显,并且过度偏重工业的发展模式,致使产业结构发展的协调性和关联度不高。

由此可知,在武汉市产业结构不断调整和优化过程中,确实存在制约经济快速发展的弊端和问题。为确保要素的合理流动,资源的更好配置,总体效益的不断提升,经济的持续增长,产业结构调整与升级必须提到议事日程上来。同时,产业结构调整与升级是一项涉及风险和外部性的创新活动,在路径选择时必须深思熟虑,考虑周全。

二、基于偏离-份额模型对武汉市产业结构的实证研究和分析

偏离-份额分析法是把区域经济的变化看成一个动态过程,以其所在地区或整个国家的经济发展为参照系,将区域自身经济总量在某一时期的变动分解为份额、结构偏离分量和竞争力偏离三个分量,说明区域经济发展和衰退的原因,评价区域经济结构优劣和自身竞争力的强弱,找出区域具有相对竞争优势的产业门类,进而确定区域未来经济发展的合理方向和产业结构调整的原则。

本文选取了目标区域武汉市及其所在大区域湖北省2005—2012年的国内生产总值(GDP)、第一、二、三产业产值,将数据的单位换算为亿元,基于偏离-份额模型,计算得到武汉市各个产业的偏离-份额数据(见表二)。

1.对武汉市各产业的份额偏离的分析

整体上来看,武汉市各产业的份额份量具有相同特征:第三产业最大,第二产业次之,第一产业最小。随着时间的推移,武汉市各产业的份额分量呈现稳步增长的良好态势。但也不难看出,发展的同时差距也在逐步显现:二、三产业的增长速度明显快于第一产业,且份额分量之和远远大于第一产业。第二、三产业的份额分量相当,差异较小,说明武汉市经济整体水平处于工业化和服务业并进的阶段。

2.对武汉市各产业的产业结构偏离的分析

从纵向时间序列上看,武汉市第一产业的产业结构分量一直为负数,且绝对值不断增加,表明第一产业结构不太合理,层次低下,阻碍了武汉市经济的发展。第二产业的产业结构分量除2007年为-4.18外,总体上为正值,且保持增长趋势,说明武汉市第二产业结构整体优化程度较高,对经济发展的促进作用明显,并且促进作用在逐步强化。第三产业的产业结构分量在2006-2007年为正值,促进了经济发展,但在2008 年后发生逆转,2008-2012年内一直保持为负值,且其绝对值还在不断增加,严重阻碍了经济的健康发展,产生了负面的影响。从截面上进行分析可知,虽然总体上武汉市产业结构份量总量为正,但也存在很多不和谐因素,需要予以重视。每年均有两个不合理的产业结构抑制了经济的增长,这些结构未能自行调整,反而进一步加剧。因此,武汉市产业结构确实存在许多不合理和不协调问题,产业结构调整与优化势在必行。

3.对武汉市产业竞争力偏离的分析

第一产业竞争力除在2006 年为0.44 和2012 年为12.76 外,其他年份一直为负,竞争力不断下降。第二产业竞争力除在2007年具有0.14微弱竞争优势外,在其他年份一直为负,竞争力严重不足。第三产业在开始的2006-2007 年里,其竞争力为负,难以与其他产业抗衡。但在接下来的年份中,竞争力呈上升态势,得到显著提高,市场占有率极大提升。总的来说,武汉市的三大产业,在近些年内,除第三产业的竞争力略有上升外,第一、二产业竞争力不断下降。因此,调整和优化第一、二产业的结构,提升竞争力已是当务之急。

综上所述,武汉市产业结构的主要问题表现在第一产业占比过高,内部结构较为单一,投入产出低,整体效率水平低下;第二产业占比总体上较为合理,整体发展较好,但以重工业为主的发展模式导致产业同构现象明显,资源配置不合理,规模效应较低,缺乏竞争力;第三产业的占比有待提高,内部结构急需完善,技术含量有待提升,对人才的吸纳能力需要。

三、武汉市产业结构调整和升级的对策建议

1.兼顾质量和效益,推进农业产业化,实现农产品多样化和特色化

武汉市自然资源得天独厚,水资源极为充足。由于第一产业发展模式单一,以传统的水稻、小麦、玉米和大豆为主,未能充分发挥好比较优势,种植水生经济作物,发展渔业和养殖业。今后,应在原有单个家庭承包责任制基础上,加快土地扭转,鼓励多样化合作;改变传统的种植模式,使水面动、植物生产互补,实现水陆“双赢”;按照市场需求,丰富农产品的种类,提高农作物的经济价值和附加值,带动关联的食品加工制造业的发展。

2.统筹发展轻重工业,集约发展主导产业,大力培育优势产业

在大力发展制造业基调下,第二产业整体发展状况良好。但由于“重型化”较为明显,产值主要是由汽车、钢铁、冶金、石化等重型工业贡献的,不仅对资源依赖性较强,而且是以牺牲环境为代价的。所以,需要通过平衡轻重工业的比重,保持产业内的良性互动。作为主导产业的重工业应通过产业集聚,加强对资源的整合,实现集约发展;通过技术创新提升企业对工业“三废”的处理能力,发展循环经济,提高资源的利用效率;针对产业中的国有比重过大的问题,应加快国有企业改革进程,使经营体制更灵活。并通过加强与周边地区的合作与交流,比如,针对作为主导产业的汽车行业,发挥与襄阳、十堰、宜昌等地区的产业联动作用,实现规模经济,实现共同协调发展;对具有优势的烟草、食品、纺织等轻工业应加大扶持力度,使其能在服务于农产业的基础上,形成完善的产业链,创造值得信赖的品牌,增强产业竞争力。

3.利用区位优势,发展生产业,重视新兴科技产业

第三产业总体规模不大,具有明显的结构缺陷。由于以传统的餐饮和商贸零售服务为主,金融、信息、咨询、物流、旅游等生产业发展严重不足。首先,武汉市应增强发展第三产业意识,在发展工业的同时兼顾第三产业;其次,武汉市位于中国的中部腹心部位,水陆空交通枢纽完备,具有明显的区位优势。应大力发展物流产业;同时,应通过大力发展旅游文化产业,弘扬武汉具有特色的汉味文化和历史文化古迹;最后,武汉东湖地区是中国较大的智力密集区,集聚了大批高校,科研实力雄厚。应做好产学研对接,充分提升自主创新能力,大力发展新兴科技产业。

四、对武汉市产业结构调整与升级的研究结论与展望

基于对产业结构调整研究的结论和武汉市产业结构的现状,利用偏离-份额模型对产业结构进行实证分析,我们得出武汉市产业结构具有第一产业占比过高,结构单一,缺乏竞争力;第二产业占比较为合理,但以“重型化”为主,同构现象明显,内部亟待升级;第三产业占比有待提高,应发展新兴服务业的结论。并从三大产业的角度,对武汉市产业结构调整与升级给出了第一产业兼顾质量和效益,推进农业产业化,实现农产品的多样化和特色化;第二产业统筹发展轻重工业,集约发展主导产业,大力培育优势产业;第三产业整合利用区位优势,发展生产业,重视新兴科技产业的对策建议。

参考文献

[1]陈朔, 冯素杰.产业结构优化升级中几个问题的国际经验和启示: 以日本、韩国和我国台湾地区为例[J].经济问题探索,2008(3).

[2]戴瑾.产业结构与就业结构的实证分析:以湖北省为考察对象[J].社会科学论坛,2010(15).

[3]马艳华, 魏辅轶.产业结构调整理论研究综述[J].山西财经大学学报,2011(11).

[4]徐勇,丁悦.产业演进比较与武汉产业结构高级化选择[J].统计与决策,2011(16).

[5]李武军,黄炳南.基于偏离一份额分析法的中部地区产业结构研究[J].经济经纬,2010(6).

第10篇

本系统主要完成对图书仓库的库存管理,包括图书入库、出库、库存,员工信息,供应商信息以及密码管理等六个方面。系统可以完成对各类信息的浏览、查询、添加、删除、修改、报表等功能。

系统的核心是入库、库存和出库三者之间的联系,每一个表的修改都将联动的影响其它的表,当完成入库或出库操作时系统会自动地完成库存的修改。查询功能也是系统的核心之一,在系统中即有单条件查询和多条件查询,也有精确查询和模糊查询,系统不仅有静态的条件查询,也有动态生成的条件查询,其目的都是为了方便用户使用。系统有完整的用户添加、删除和密码修改功能,并具备报表打印功能。

系统采用Microsoft Office中的Access 2000来设计数据库,并使用当前优秀的开发工具—Delphi 6.0 ,它有着最为灵活的数据库结构,对数据库应用有着良好的支持。

论文主要介绍了本课题的开发背景,所要完成的功能和开发的过程。重点的说明了系统设计的重点、设计思想、难点技术和解决方案。

关键字:数据库,SQL语言,Delph 6,数据库组件,仓库管理

目 录

第一章 引言 ……………………………………………………………………………1

1.1 课题来源 ……………………………………………………………………1

1.2 开发工具的选择 ……………………………………………………………2

1.3 所做的主要工作 ……………………………………………………………3

第二章 数据库概论 ……………………………………………………………………4

2.1 数据库的发展 ………………………………………………………………4

2.1.1 数据库的发展 …………………………………………………………4

2.1.2 数据库阶段的特点 ……………………………………………………5

2.1.3 数据库技术 ……………………………………………………………6

2.2 数据库理论基础 ……………………………………………………………7

2.2.1 数据库模型 ……………………………………………………………7

2.2.2 数据库体系结构

……………………………………………………10

2.2.3 数据的独立性 ………………………………………………………11

2.2.4 范式 …………………………………………………………………11

2.3 SQL语言基础 ……………………………………………………………13

2.3.1 SQL简介 ……………………………………………………………13

2.3.2 SQL查询

……………………………………………………………13

2.3.3 SQL数据更新

………………………………………………………14

第三章数据库开发工具 ……………………………………………………………16

3.1 Delphi 6.0 简介 ……………………………………………………………16

3.2 Delphi 6.0 控件 ……………………………………………………………17

3.2.1 ADO数据访问组件 …………………………………………………17

3.2.2 数据控制类DataControl

……………………………………………18

3.2.3 数据访问类DataAccess

……………………………………………18

3.2.4 SQL语言在Delphi中的应用

………………………………………19

3.3 Access 简介

………………………………………………………………21

第四章 系统总体设计 ………………………………………………………………23

4.1 系统需求分析

……………………………………………………………23

4.2 系统概要设计

……………………………………………………………25

4.2.1 系统结构设计

………………………………………………………25

4.2.2 数据库设计

…………………………………………………………27

4.2.2.1 ER图设计 ……………………………………………………27

4.2.2.2 数据库表格设计………………………………………………29

4.3系统详细设计………………………………………………………………34

第五章 系统应用程序设计 …………………………………………………………37

5.1 系统窗体模块组成…………………………………………………………37

5.2 数据模块窗体设置…………………………………………………………38

5.3 主窗体功能模块的实现……………………………………………………39

5.4 入库、出库窗体模块的实现………………………………………………43

5.5 查询功能的实现……………………………………………………………51

5.6 系统登陆窗体模块的实现…………………………………………………52

5.7 用户管理功能的实现………………………………………………………54

5.7.1 用户管理主窗体 ……………………………………………………54

5.7.2 密码修改窗体模块的实现

…………………………………………54

5.7.3 用户注册窗体模块的实现

…………………………………………55

5.7.4 用户注销窗体模块的实现

…………………………………………57

结束语 …………………………………………………………………………………59

致谢 ……………………………………………………………………………………60

参考文献 ………………………………………………………………………………61

第一章

引 言

§1.1 课题来源

随着社会经济的迅速发展和科学技术的全面进步,计算机事业的飞速发展,以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期。随着经济文化水平的显著提高,人们对生活质量及工作环境的要求也越来越高。书籍做为人类的精神食粮,在现代社会中越来越受到重视,大量的书籍出现在市场上,人们有了各种各样不同的选择。与此同时,为了管理大量的图书,图书仓库也大量的出现,仓库的管理问题也就提上了日程。随着图书的大量增加,其管理难度也越来越大,如何优化仓库的日常管理也就成为了一个大众化的课题。

在计算机飞速发展的今天,将计算机这一信息处理利器应用于仓库的日常管理已是势必所然,而且这也将为仓库管理带来前所未有的改变,它可以带来意想不到的效益,同时也会为企业的飞速发展提供无限潜力。采用计算机管理信息系统已成为仓库管理科学化和现代化的重要标志,它给企业管理来了明显的经济效益和社会效益。主要体现在:

极大提高了仓库工作人员的工作效率,大大减少了以往入出存流程繁琐,杂乱,周期长的弊端。

基于仓库管理的全面自动化,可以减少入库管理、出库管理及库存管理中的漏洞,可以节约不少管理开支,增加企业收入。

仓库的管理的操作自动化和信息的电子化,全面提高了仓库的管理水平。

随着我国改革开放的不断深入,经济飞速的发展,企业要想生存、发展,要想在激烈的市场竞争中立于不败之地,没有现代化的管理是万万不行的,仓库管理的全面自动化、信息化则是其中极其重要的部分。为了加快仓库管理自动化的步伐,提高仓库的管理业务处理效率,建立仓库管理系统已变得十分心要。

入库、库存、出库还是现在企业图书仓库管理的常规基本模式,虽然,最近又出现了很多新的管理模式,如:基于零库存思想的沃尔玛特管理方式,但这些新的思想在中国大部分企业的管理中还是难以实现的。所以如何设计好仓库管理系统,尽可能地减少仓库管理的重复性和低效性就成为当前最为重要的问题。图书仓库管理的核心是入库、库存和出库之间的联系,如何处理好三者之间的关系是系统最为关键的部分。另外,员工信息和供应商信息管理也是仓库管理中一个必不可少的部分,它提供着与入库和出库相关的地一些信息,使得整个系统更加完整,更加实用。

通过对仓库管理日常工作的详细调查,搜集了大量的资料,从系统结构的组织,功能的实现,技术的要求以及可行性等多方面进行考虑,认为本课题是一个适应现今图书仓库管理需求的计算机信息管理系统,具有一定的实际开发价值和使用价值。

§1.2 开发工具的选择

自Java诞生以来,随着Internet技术的普及和应用需求的变化,以第四代语言为主的应用开发产品发生了较大的变化,它们不仅已成为人们开发应用的开发工具,而且很多产品已发展成为一种强有力的应用开发环境。这些新型的开发工具通常以一种集成软件包的形式提供给开发人员,被称为Studio(工作室)或Suite(程序组)。例如,微软的Visual Studio 6.0,Borland公司的Delphi 6.0等数据库辅助开发工具。

现在,市场上可以选购的应用开发产品很多,流行的也有数十种。目前在我国市场上最为流行、使用最多、最为先进的可用作企业级开发工具的产品有:

Microsoft公司的Visual Basic 6.0版

Microsoft公司的Visual C++6.0版

Borland公司的Delphi 6.0版

在目前市场上这些众多的程序开发工具中,有些强调程语言的弹性与执行效率;有些则偏重于可视化程序开发工具所带来的便利性与效率的得高,各有各的优点和特色,也满足了不同用户的需求。然而,语言的弹性和工具的便利性是密不可分的,只有便利的工具,却没有弹性的语言作支持,许多特殊化的处理动作必需要耗费数倍的工夫来处理,使得原来所标榜的效率提高的优点失去了作用;相反,如果只强调程语言的弹性,却没有便利的工具作配合,会使一些即使非常简单的界面处理动作,也会严重地浪费程序设计师的宝贵时间。

而Delphi是一个非常理想选择。Delphi 6 是操作系统中快速应用开发环境的最新版本。它也是当前Windows平台上第一个全面支持最新Web服务的快速开发工具。无论是企业级用户,还是个人开发者,都能够利用Delphi 6 轻松、快捷地构建新一代电子商务应用。Delphi 6 是惟一支持所有新出现的工业标准的RAD环境,包括XML(扩展标记语言)/XSL(可扩展样式语言),SOAP(简单对象存取协议)和WSDL(Web服务器描述语言)等。

Delphi 6 是可视化的快速应用程序开发语言,它提供了可视化的集成开发环境,这一环境为应用程序设计人员提供了一系列灵活而先进的工具,可以广泛地用于种类应用程序设计。在Delphi 6 的集成开发环境中,用户可以设计程序代码、运行程序、进行程序错误的调试等,可视化的开发方法降低了应用程序开发的难度。Delphi的基础编程语言是具有面向对象特性的Pascal语言,即Object Pascal 。Object Pascal具有代码稳定、可读性好、编译速度快等优点,并将面向对象的概念移植到了Pascal语言中,使这种基础语言有了新的发展空间。

使用Delphi 6.0 ,我们几乎可以作任何事情,还可以撰写种各种类型的应用程序,动态链接库(DLL)、CON、或CORBA对象,CGI/ISAPI程序,Microsoft Back Office应用程序。程序的规模小到简单的个人数据库应用,大到复杂的企业的多层次分布式系统,都可以使用Delphi进行开发,其友好的集成开发界面,可视化的双向开发模式,良好的数据库应用支持高效的程序开发和程序运行,备受广大程序开发人员的好评。尤其是Delphi对数据库应用的强大支持,大大提高了数据库应用软件开发的效率,缩短了开发周期,深受广大数据库应用程序设计人员的喜爱。Delphi为数据库应用开发人员提供了丰富的数据库开发组件,使数据库应用开发功能更强大,控制更灵活,编译后的程序运行速度更快。

§1.3 本文所做工作

引言部分介绍了本系统的课题来源以及对数据库开发工具的选择。

第二章介绍了数据库的发展,关系数据库,数据库体系结构,并系统介绍了SQL语言,为设计和理解应用程序做了铺垫。

第三章系统介绍了Delphi 6.0及其部分控件,SQL语言在Delphi 6.0中的应用,以及Access等。

第四章是本文的主体,按照软件工程的要求,从需求分析开始,经过概要设计最后到详细设计,完成对整个系统的设计。

第五章根据第四章的设计结果利用Access 2000和Delphi 6.0进行了具体的窗体和应用程序设计。

总结部分介绍了设计体会和编程体会,并指出了系统设计中的不足和改进的方向

转贴于 第二章

数据库概论

§2.1

数据库的发展

数据库处理在信息系统的研究中一直是非常重要的主题,然而,近年来,随着World Wide Web(WWW)的猛增及Internet技术的迅速发展,使得数据库技术之时成为最热门技术之一。数据库技术能使Internet应用超越具有早期应用特点的简单的。同时,Internet技术提供了一种向用户数据库内容的标准化的访问方法。这些技术没有脱离经典数据库技术的要求。它们只是加重了数据库技术的重要性。

数据库的设计和开发及包括艺术有包括工程。理解用户的需求,然后,把它们转变为有效的数据库设计是一个艺术过程。把设计转变为实际的数据库,并且这些数据库带有功能完备、高效能的应用,是一个工程过程。

数据库的目的是帮助人们跟踪事务。经典的数据库应用涉及诸如订单、顾客、工作、员工、学生、电话之类的项,或其它数据量较大、需要密起关注的事务。最近,由于数据库的普及,数据库技术已经被应用到了新的领域,诸如用于Internet的数据库或用于公司内联网的数据库。数据库也被越来越多地应用于生成和维护多媒体应用程序上。

计算机的数据处理应用,首先要把大量的信息以数据形式存放在存储器中。存储器的容量、存储速率直接影响到数据管理技术的发展。从1956年生产出第一台计算机到现在,存储器的发展,为数据库技术提供了良好的物质基础。

使用计算机以后,数据处理的速度和规模,无论是相对于手工方式,还是机械方式,都有无可比拟的优势。通常在数据处理中,计算是比较简单的而数据的管理却比较复杂。数据管理是指数据的收集、整理、组织、存储、维护、检索、传送等操作,这部分操作是数据处理业务的基本环节,而且是任何数据处理业务中必不可少的共有部分。数据管理技术的优劣,将直接影响数据处理的效率。

2.1.1 数据库的发展

数据管理技术的发展,与硬件(主要是外存)、软件、计算机应用的范围有密切的联系。数据管理技术的发展经过三个阶段:人工管理阶段、文件系统阶段和数据库阶段。

人工管理阶段和文件系统阶段都有着相当多的缺陷,诸如数据冗余性 ,数据不一致性以及数据联系弱等等。也正是由于这些原因,促使人们研究新的数据管理技术,从而产生了数据库技术。

20世纪60年代末发生的三件大事,层次模型IMS系统的推出、关于网状模型DBTG报告的发表以及关于关系模型论文的连续发表标志着数据管理技术进入数据库阶段。进入70年代以后,数据库技术得到迅速发展,开发了许多有效的产品并投入运行。数据库系统克服了文件系统的缺陷,提供了对数据更高级更有效的管理。

当进入数据库阶段后,随着数据管理规模一再扩大,数据量急剧增加,为了提高效率,开始时,人们只是对文件系统加以扩充,在应用文件中建立了许多辅助索引,形成倒排文件系统。但这并不能最终解决问题。在20世纪60年代末,磁盘技术取得重要进展,具有数百兆容量和快速存取的磁盘陆续进入市场,成本也不高,为数据库技术的产生提供了良好的物质条件。

2.1.2 数据库阶段的特点

(1)减少数据的重复(Redundancy can be reduced)

当在一个非数据库系统当中,每一个应用程序都有属于他们自己的文件,由于无法有系统建立的数据,因此常常会造成存储数据的重复与浪费。例如:在一家公司当中,人事管理程序与工资管理程序或许都会使用到职员与部门的信息或文件,而我们可以运用数据库的方法,把这两个文件整理起来,以减少多余的数据,过度地占用存储空间。

(2)避免数据的不一致(Inconsistency can avoid)

本项的特色,可以说是延伸前项的一个特点,要说明这样的一个现象,我们可以从下面这个实例来看:若是在同一家公司当中,职员甲在策划部门工作,且职员甲的记录同时被存放在数据库的两个地方,而数据库管理系统却没有对这样重要的情况加以控制,当其中一条数据库被修改时,便会造成数据的不一致,但是,对于一个健全的数据库管理系统而言,将会对这样的情况加以控制,但有时并不需要刻意消除这种情形,应当视该数据库的需求与效率来决定。

(3)数据共享(Data shared)

对于数据共享的意义,并不是只有针对数据库设计的应用程序,可以使用数据库中的数据,对于其他撰写好的应用程序,同样可以对相同数据库当中的数据进行处理,进而达到数据共享的目的。

(4)强化数据的标准化(Standard can be enforced)

由数据库管理系统,对数据做出统筹性的管理,对于数据的格式与一些存储上的标准进行控制,如此一来,对于不同的环境的数据交换(Data Interchange)上将有很大的帮助,也能提高数据处理的效率。

(5)实践安全性的管理(Security restriction can be applied)

通过对数据库完整的权限控制,数据库管理者可以确认所有可供用户存取数据的合法途径渠道,并且可以事先对一些较重要或关键性的数据进行安全检查,以确保数据存取时,能够将任何不当损毁的情形降至最低。

(6)完整性的维护(Integrity can be maintained)

所谓完整性的问题,就是要确认某条数据在数据库当中,是正确无误的。正如(2)所述,若是无法控制数据的不一致性,便会产生完整性不足的问题,所以,我们会发现,当数据重复性高的时候,数据不完整的情形也会增加,当然,若是数据库的功能完整,将会大大地提高数据完整性,也会增加数据库的维护能力与维护简便性。

(7)需求冲突会获得平衡(Conflicting requirements can be balance)

在一个较大型的企业当中,用户不同的需求,往往会造成系统或数据库在设计上的困扰,但是一个合适的数据库系统,可以通过数据库管理员的管理,将会有效地整理各方面的信息,对于一些较重要的应用程序,可以适时地提供较快速的数据存取方法与格式,以平衡多个用户在需求上的冲突。

上述七个方面构成了数据库系统的主要特征。这个阶段的程序和数据间的联系可用下图表示: 2.1.3 数据库技术

从文件系统发展到数据库系统是信息处理领域的一个重大变化。在文件系统阶段,人们关注的中心问题是系统功能的设计,因而程序设计处于主导地位,数据只起着服从程序需要的作用。在数据库方式下,信息处理观念已为新体系所取代,数据占据了中心位置。数据结构的设计成为信息系统首先关心的问题,而利用这些数据的应用程序设计则退居到以既定的数据结构为基础的外围地位。

目前世界上已有数百万个数据库系统在运行,其应用已经深入到人类社会生活的各个领域,从企业管理、银行业务、资源分配、经济预测一直到信息检索、档案管理、普查统计等。并在通信网络基础上,建立了许多国际性的联机检索系统。我国20世纪90年代初在全国范围内装备了12个以数据库技术为基础的大型计算机系统,这些系分布在邮电、计委、银行、电力、铁路、气象、民航、情报、公安、军事、航天和财税等行业。

数据库技术还在不断的发展,并且不断地与其它计算机技术相互渗透。数据库技术与网络通信技术相结合,产生了分布式数据库系统。数据库技术与面向对象技术相结合,产生了面向对象数据库系统。

在数据库技术中有四个名词,其概念应该分清。

(1)数据库(database,DB):DB是统一管理的相关数据的集合。DB能为各种用户共享,具有最小冗余度,数据间联系密切,而又有较高的数据独立性。

(2)数据库管理系统(Database Management System,DBMS):DBMS是位于用户与操作系统之间的一层数据管理软件,为用户或应用程序提供访问DB的方法,包括DB的建立、查询、更新及各种数据控制。DBMS总是基于某种数据模型,可以分为层次型、网状型、关系型和面向对象型DBMS。

(3)数据库系统(Database System,DBS):DBS是实现有组织地、动态地存储大量关联数据,方便多用户访问的计算机软件、硬件和数据资源组成的系统,即采用了数据库技术的计算机系统。

(4)数据库技术:这是一门研究数据库的结构、存储、管理和使用的软件学科。数据库技术是操作系统的文件系统基础上发展起来的。而DBMS本身要在操作系统的支持下才能工作。数据库不仅用到数据结构的知识,而且丰富了数据结构的内容。在关系数据库中要用到集合论、数理逻辑的理论。因此,数据库技术是一门综合性较强的学科。

§2.2数据库理论基础

2.2.1 数据库模型

从20世纪50年代中期开始,计算机的应用由科学研究部门逐步扩展到企业、行政部门。至60年代,数据处理成为计算机的主要应用。数据库技术作为数据管理技术,是计算机软件领域的一个重要分支,产生于60年代末。现已形成相当规模的理论体系和实用技术。

模型是对现实世界的抽象。在数据库技术中,我们用模型的概念描述数据库的结构与语义,对现实世界进行抽象,表示实体类型及实体间联系的模型称为“数据模型” 。

目前广泛作用的数据模型可分为两种类型。

一种是独立于计算机系统的模型,完全不涉及信息在系统中的表示,只是用来描述某个特定组织所关心的信息结构,这类模型称为“概念数据模型” 。要领模型用于建立信息世界的数据模型,强调其语义表达功能,应该概念简单、清晰,易于用户理解,它是现实世界的第一层抽象,是用户和数据库设计人员之间进行交流的工具。这一其中著名的模型是“实体联系模型” 。

另一种数据模型是直接面向数据库的逻辑结构,它是现实世界的第二层抽象。 这类模型涉及到计算机系统和数据库管理系统,又称为“结构数据模型” 。例如,层次、网状、关系、面向对象等模型。这类模型有严格的形式化定义,以便于在计算机系统中实现。

(1)层次模型。用树型结构表示实体类型及实体间联系的数据模型。树的结点是记录类型,每个非根结点有且只有一个父结点。上一层记录类型和下一层记录类型间联系是1∶N联系。

层次模型的特点是记录之间的联系通过指针实现,查询效率较高。但层次模型有两个缺点:一是只能表示1∶N联系,虽然有多种辅助手段实现了M∶N联系,但都较复杂,用户不易掌握,二是由于树型结构层次顺序的严格和复杂,引起数据的查询和更新操作也很复杂,因此,编写应用程序也很复杂。

(2)网状模型。用有向图结构表示实体类型及实体间联系的数据模型。。1969年DBTG报告提出的数据模型是网状模型的主要代表。有向图中的结点是记录类型,有向边表示从箭尾一端的记录类型到箭头一端的记录类型间联系是1∶N联系。

网状模型的特点:记录之间联系通过指针实现,M∶N联系也容易实现(每个M∶N联系可拆成两个1∶N联系),查询效率较高。网状模型的缺点是编写应用程序比较复杂,程序员必须熟悉数据库的逻辑结构。由于层次系统和网状系统的应用程序编制比较复杂,因此,从20世纪80年代中期起,其市场已被关系系统所取代。但是使用这两种模型建立起的许多数据库仍然在正常运转,只是在外层加了个关系数据库语言的接口。网状模型有许多成功的产品,20世纪70年代的产品大部分网状系统,例如,Honeywell公司的IDS/Ⅱ、HP公司的IMAGE/3000、Burroughs公司的DMSⅡ、Umivac公司的DMS1100、Cullinet公司的IDMS、Cimcom公司的TOTAL等

(3)关系模型。关系模型的主要是用二维表格结构表达实体集,用外键表示实体间联系。关系模型是由若干个关系模式组成的集合。关系模式相当于前面提到的记录类型,它的实例称为关系,每个关系实际上是一张二维表格。

关系模型和层次、网状模型的最大判别是用关键码而不是用指针导航数据,表格简单用户易懂,编程时并不涉及存储结构,访问技术等细节。关系模型是数学化模型。SQL语言是关系数据库的标准化语言,已得到了广泛的应用。20世纪70年代对关系数据库的研究主要集中在理论和实验系统的开发方面。80年代初才形成产品,但很快得到广泛的应用和普及,并最终取代了层次、网状数据库产品。现在市场上典型的关系DBMS产品有DB2、ORACLE、SYBASE、INFORMIX和微机型产品Foxpro、Access等。

关系模型和网状、层次模型的最大区别是:关系模型用表格数据而不是通过指针链来表示和实现实体间联系。关系模型的数据结构简单、易懂。只需用简单的查询语句就可对数据库进行操作。

关系模型是数学化的模型,可把表格看成一个集合,因此集合论、数理逻辑等知识可引入到关系模型中来。关系模型已是一个成熟的有前途的模型,已得到广泛应用。

(4)面向对象模型。目前,关系数据库的使用已相当普遍,但是,现实世界中仍然存在着许多含有复杂数据结构的应用领域,例如,CAD数据、图形数据等,而关系模型在这方面的处理能力就显得力不从心。因此,人们需要更高级的数据库技术来表达这类信息。面向对象的概念最早出现在程序设计语言中,随后迅速渗透到计算机领域的每一个分支。面向对象数据库是面向对象概念与数据库技术相结合的产物。

面向对象模型能完整地描述现实世界的数据结构,具有丰富的表达能力,但模型相对较复杂,涉及的知识面也广,因此面向对象数据库尚未达到关系数据库那样的普及程度。

2.2.2 数据库体系结构

数据库的体系结构分三级:内部级(internal),概念级(conceptual)和外部级(external)。这个三级结构有时也称为“三级模式结构”,或“数据抽象的三个级别”,最早是在1971年通过的DBTG报告中提出,后来收入在1975年的美国ANSI/SPARC报告中。虽然现在DBMS的产品多种多样,在不同的操作系统支持下工作,但是大多数系统在总的体系结构上都具有三级模式的结构特征。从某个角度看到的数据特性称为“数据视图”(data view)。

外部级最接近用户,是单个用户所能看到的数据特性。单个用户使用的数据视图的描述称为“外模式”。

概念级涉及到所有用户的数据定义,是全局的数据视图。全局数据视图的描述称为“概念模式”。

内部级最接近于物理存储设备,涉及到实际数据存储的结构。物理存储数据视图的描述称为“内模式”。

数据库的三级模式结构是数据的三个抽象级别。它把数据的具体组织留给DBMS去做,用户只要抽象地处理数据,而不必关心数据在计算机中的表示和存储,这样就减轻了用户使用系统的负担。

三级结构之间往往差别很大,为了实现这三个抽象级别的联系和转换,DBMS在三级结构之间提供两个层次的映象(mappings):外模式/模式映象,模式/内模式映象。此处模式是概念模式的简称。

2.2.3 数据的独立性

由于数据库系统采用三级模式结构,因此系统具有数据独立性的特点。在数据库技术中,数据独立性是指应用程序和数据之间相互独立,不受影响。数据独立性分成物理数据独立性和逻辑数据独立性两级。

(1)物理数据独立性

如果数据库的内模式要进行修改,即数据库的存储设备和存储方法有所变化,那么模式/内模式映象也要进行相当的修改,使概念模式尽可能保持不变。也就是对内模式的修改尽量不影响概念模式,当然,对于外模式和应用程序的影响更小,这样,我们称数据库达到了物理数据独立性。

(2)逻辑数据独立性

如果数据库的概念模式要进行修改,譬如增加记录类型或增加数据项,那么外模式/模式映象也要进行相应的修改,使外模式尽可能保持不变。也就是对概念模式的修改尽量不影响外模式和应用程序,这样,我们称数据库达到了逻辑数据独立性。

现有关系系统产品均提供了较高的物理独立性,而对逻辑独立性的支持尚有欠缺,例如,对外模式的数据更新受到限制等。

2.2.4 范式

建立起一个良好的数据指标体系,是建立数据结构和数据库的最重要的一环。一个良好的数据指标体系是建立DB的必要条件,但不是充分条件。我们完全可以认为所建指标体系中的一个指标类就是关系数据库中的一个基本表,而这个指标类下面的一个个具体指标就是这个基本表中的一个字段。但如果直接按照这种方式建库显然还不能算最佳。对于指标体系中数据的结构在建库前还必须进行规范化的重新组织。

在数据的规范化表达中,一般将一组相互关联的数据称为一个关系(relation),而在这个关系下的每个数据指标项则被称为数据元素(data element),这种关系落实到具体数据库上就是基本表,而数据元素就是基本表中的一个字段(field)。规范化表达还规定在每一个基本表中必须定义一个数据元素为关键字(key),它可以唯一地标识出该表中其它相关的数据元素。在规范化理论中表是二维的,它有如下四个性质:

在表中的任意一列上,数据项应属于同一个属性(如图中每一列都存放着不同合同记录的同一属性数据)。

表中所有行都是不相同的,不允许有重复组项出现(如图中每一行都是一个不同的合同记录)。

在表中,行的顺序无关紧要(如图中每行存的都是合同记录,至于先放哪一个合同都没关系)。

在表中,列的顺序无关紧要,但不能重复(如图中合同号和合同名谁先谁后都没关系,但二者不可重复或同名)。

在对表的形式进行了规范化定义后,数据结构还有五种规范化定义,定名为规范化模式,称为范式。在这五种范式中,一般只用前三种,对于常用系统就足够了。而且这五种范式是“向上兼容”的,即满足第五范式的数据结构自动满足一、二、三、四范式,满足第四范式的数据结构自动满足第一、二、三范式,……,依此类推。

第一范式(first normal form,简称1st NF)就是指在同一表中没有重复项出现,如果有则应将重复项去掉。这个去掉重复项的过程就称之为规范化处理。在本文所讨论的开发方法里,1st NF实际上是没有什么意义的。因为我们按规范化建立的指标体系和表的过程都自动保证了所有表都满足1st NF。

第二范式(second normal form,简称 2nd NF)是指每个表必须有一个(而且仅一个)数据元素为主关键字(primary key),其它数据元素与主关键字一一对应。例如,在图l9.7中如果我们将合同号定义为主关键字(其它数据元素中的记录数据都有可能重名,故不能作为主关键字),故只要知道了一个合同记录的合同号,就可以唯一地在同一行中找到该合同的任何一项具体信息。通常我们称这种关系为函数依赖(functional depEndence)关系。即表中其它数据元素都依赖于主关键字,或称该数据元素唯一地被主关键字所标识。

第三范式(third normal form,简称 3rd NF)就是指表中的所有数据元素不但要能够唯一地被主关键字所标识,而且它们之间还必须相互独立,不存在其它的函数关系。也就是说对于一个满足了 2nd NF的数据结构来说,表中有可能存在某些数据元素依赖于其它非关键宇数据元素的现象,必须加以消除。

为防止数据库出现更新异常、插入异常、删除异常、数据冗余太大等现象,关系型数据库要尽量按关系规范化要求进行数据库设计。

§2.3 SQL语言基础

2.3.1 SQL简介

用户对数据库的使用,是通过数据库管理系统提供的语言来实现的。不同的数据库管理系统提供不同的数据库语言。关系数据库管理系统几乎都提供关系数据库标准语言——SQL。

SQL 的全称是Structured Query Language,即结构化查询语言。SQL语句可以从关系数据库中获得数据,也可以建立数据库、增加数据、修改数据。1986年ANSI采用SQL语言作为关系数据库系统的标准语言,后被国际化标准组织(ISO)采纳为国际标准。SQL语言使用方便、功能丰富、简洁易学,是操作数据库的工业标准语言,得到广泛地应用。例如关系数据库产品DB2、ORACLE等都实现了SQL语言。同时,其它数据库产品厂家也纷纷推出各自的支持SQL的软件或者与SQL的接口软件。这样SQL语言很快被整个计算机界认可。

SQL语言是一种非过程化语言,它一次处理一个记录集合,对数据提供自动导航。SQL语言允许用户在高层的数据结构上工作,而不对单个记录进行操作。SQL语言不要求用户指定数据的存取方法,而是使用查询优化器,由系统决定对指定数据存取的最快速手段。当设计者在关系表上定义了索引时,系统会自动利用索引进行快速检索,用户不需知道表上是否有索引或者有什么类型的索引等细节。

SQL语言可以完成许多功能,例如:

查询数据

在数据库表格中插入、修改和删除记录

建立、修改和删除数据对象

控制对数据和数据对象的存取

确保数据库的一致性和完整性等

2.3.2 SQL查询

数据查询是关系运算理论在SQL语言中的主要体现,SELECT 语句是SQL查询的基本语句,当我们在对一个数据库进各种各样的操作时,使用的最多的就是数据查询,在以SQL为基础的关系数据库中,使用的最多的就是SELECT查询语句。

SELECT语句的完整句法如下:

SELECT 目标表的列名或列表达式序列

FROM 基本表和(或)视图序列

[WHERE 行条件表达式]

[GROUP BY 列名序列]

[HAVING 组条件表达式]

[ORDER BY列名 [ASC│DEAC]…]

我在SELECT语句中还使用了大量的保留字和通配符以进行各种各样的条件查询。在系统中有大量的查询按钮,其使用了大量的查询语句,而且这些查询语句大部分使用的是模糊查询,所以大量的使用了模式匹配符LIKE(判断值是否与指定的字符通配格式相符)。在包含LIKE的查询语句中可以使用两个通配符:%(百分号):与零个或多个字符组成的字符串匹配;_(下划线):与单个字符匹配。系统中的条件判断往往包含多个条件,这时就需要使用逻辑运算符NOT、AND、OR(用于多条件的逻辑连接),谓词ALL以及保留字DISTINCT等等。做为SELECT语句还有很多的使用方法,这里就不再叙述。

2.3.3 SQL数据更新

使用数据库的目的是为了有效地管理数据,而数据的插入、删除和修改则是必不可少的一个功能。在本系统中就大量地使用了数据插入、删除和修改这三种操作,现做一个简单地介绍。

数据插入

往数据库的基本表中插入数据使用的是INSERT语句,其方式有两种:一种是元组值的插入,另一种是查询结果的插入。在本系统中使用的是前一种方式,其句法如下:

INSERT INTO 基本表名(列表名)VALUES(元组值)

数据删除

往数据库的基本表中删除数据使用的是DELETE语句,其句法如下:

DELETE FROM 基本表名 [WHERE 条件表达式]

在些作一点说明,删除语句实际上是“SELECT * FROM 基本表名 [WHERE 条件表达式]”和DELETE操作的结合,每找到一个元组,就把它删除。此外,DELETE语句只能从一个基本表中删除元组,WHERE子句中条件可以嵌套,也可以是来自几个基本表的复合条件。

数据修改

当需要修改基本表中元组的某些列值时,可以用UPDATE语句实现,其句法如下:

UPDATE基本表名

SET列名=值表达式[,列名=值表达式…]

[WHERE条件表达式]

在Delphi中使用SQL语句是很方便的,一般来说,都是通过TQuery组件来使用SQL语言的。有一点要进行说明,虽然通过TQuery组件来使用SQL语言很方便,但考虑到自己对不同组件的理解程度、个人习惯以及其它各个方面,在本系统中我采用的是ADO组件来对数据库进行操作。最简单的方法比如在TADOQuery组件的SQL属性中就可以键入SQL语句,至于详细的使用方法在后面进行介绍。

转贴于 第三章

数据库开发工具

§3.1 Delphi 6.0 简介

Delphi类可以粗略地分成两部分:一部分是组件类,这些组件类通常以某种方式出现在组件面板上,当用户从组件面板上点取一个类的图标后,在程序中就自动生成了该类的对象(非可视组件除外);另一部分是功能类,这此功能类的对象通常出现在程序代码中,起着不可代替的作用,但是这些功能类在组件面板上是找不到的。在Delphi中,每一个类的祖先都是Tobject类,整个类的层次结构就像一棵倒挂的树,在最顶层的树根即为Tobject类。这样,按照面向对象编程的基本思想,就使得用户可用Tobject类这个类型代替任何其它类的数据类型。实际上在Delphi的类库中,Tobject类派生出了为数相当众多的子类,它们形成了一个庞大的体系,通常情况下,如果不自行开发组件,就不必了解整个类的体系结构,只用到类层次树的叶结点就足够了。

凡是做过程序开发的人都知道从来没有单纯的数据应用程序,也就是说,数据库应用程序必须和用户界面(可以是图形界面,也可以是命令接口)元素相结合,只讲界面或只讲数据库本身都构不成数据库应用程序,因而用Delphi 6.0开发数据库应用程序就隐含着界面开发。Delphi6中的VCL组件可用图3-1来说明。组件在Delphi程序的开发中是最显眼的角色。大家知道,在编写程序时一般都开始于在组件面板上选择组件并定义组件间的相互作用。但也有一些组件不在组件面板上,例如Tform和Tapplication(典型的非可视组件)。组件是Tcomponents派生出来的子类,可以流的形式存放在DFM文件中,具有事件和Publish属性。

窗口组件类是窗口化的可视化组件类,在Delphi的类库中占有最大的份额。在实际编程中,窗口组件类的对象都有句柄,可以接受输入焦点和包含其它组件。

图形组件与窗口组件并列,是另一大类组件。图形组件不是基于窗口的,因而不能有窗口句柄,不能接受输入焦点和包含其它组件。从图8-43中可以看出,图形组件的基类是TgraphicControl,在实际编程中,它们必须寄生于它们的宿主——窗口组件类的对象,由它们的拥有者负责其显示,而且它们还能触发一些和鼠标活动相关的事件。图形控件最典型的例子是Tlabel和TspeedButton。由此可以看出图形组件的功能很弱,有读者会问图形组件的用处何在呢?其实使用图形组件的最大好处在于节省资源,正是因为它们的功能较弱,所以使用的系统资源就要少。在一个应用程序中,如果能在不影响其功能的前提下合理大量地使用图形组件,将会大减少程序对系统资源的消耗。

非可视组件是与可视组件相并列的另一类组件,非可视组件在程序运行中是不可见的(除各种对话框组件之外,事实上有人认为对话框组件不能归入非可视组件,应该是另一种介于可视与非可视之间的组件)。

§3.2 Delphi 6.0 控件

用Delphi6开发数据库应用,重点是和各种数据库组件打交道,当然也要使用其它的一些组件,现在就我在系统设计中所使用的重要组件给与简单介绍。

3.2.1 ADO数据访问组件

ADO数据对象(Active Data Objects)实际是一种提供访问各种数据类型的链接机制。ADO设计为一种极简单的格式,通过ODBC的方法同数据库接口中,可以使用任何一种ODBC数据源,即不止适合于SQL Server、Oracle、Access等数据库应用程序,也适合于Excel表格、文本文件、图形文件和无格式的数据文件。ADO是基于OLE-DB之上的技术,因此ADO通过其内部的属性和方法提供统一的数据访问接口方法。ADO使您的客户端应用程序能够通过OLE DB提供访问和操作在数据库服务器中的数据。ADO支持用于建立C/S和Web的应用程序的主要功能。其主要优点是易于使用、高速度、低内存支出和占用磁盘空间较少。ADO同时具有远程数据服务(RDS)功能,通过RDS可以在一次往返过程中实现将数据从服务器移动到客户端应用程序和Web页、在客户端对数据进行处然后将更新结果返回服务器的操作。

Delphi 6.0继续对Microsoft的ADO访问能力的支持。这种能力是通过一组新组件实现的,这些组件是在企业版的ADO组件页中,在组件面版的ADO页上可以找到这些组件。利用在前面章节提到的TdataSet抽象类,ADO组件可以不通过BDE而直接实现ADO连接。这意味着只需要很少的代码就可以实现该连接并且性能得到提高。

利用ADO数据访问组件,可以只使用ADO结构与数据库取得联系并对其中的数据进行操作,而在这些过程中完全不需要使用BDE。大多数的ADO连接和数据集组件都是与基于BDE的连接和数据集组件相类似的。TADOConnection组件与基于BDE的应用程序中的Tdatabase组件类似。TADOTable与Ttable,TADOQuery与Tquery,以及TADOStoreProc和TstoredProc之间都具有这种类似的对应关系。使用这些ADO组件的方式与我们常使用的数据访问组件(基于BDE)都有许多相同之处。TTADODataSet没有直接的BDE对应组件,但它提供了许多与Ttable和Tquery相同的功能。同样,TADOCommand也没有相对应的BDE组件,它是在Delphi/ADO环境中完成特定功能的组件。Delphi 6.0通过ADO数据集访问组件,可以不借助BDE数据引擎而是通过微软的OLEDB来访问更为广泛的数据库中的数据。ADO数据集访问组件与常用的数据访问组件是并列的关系。

在系统中我主要使用的是ADOTablet和ADOQuery两个组件。

3.2.2 数据控制类DataControl

数据控制类负责数据库数据的显示,并把用户对数据的修改传回。这里的绝大多数组件,如DBText, DBEdit, DBMemo, DBImage, DBListBox, DBComboBox, DBCheckBox, DBRadioGroup, DBLookupListBox, DBLookupCombox, DBCtrGrid的功能和对应的非数据感知组件相同,如TEdit框,TRadioGroups单选按钮组等,只不过在显示数据库数据时要用而已。

在系统中主要使用数据网格控件DBGrid和数据库导航器控件DBNavigator。

3.2.3 数据访问类DataAccess

数据库应用系统中数据访问是一个首要问题,包括单用户和 C/S系统,都必须联系一些数据库和数据表文件。Delphi 6 提供了专门用于数据访问的基类控件。主要包括数据源控件DataSource、客户数据集控件ClientDataSet、数据集提供器控件DataSetProvider等等。

Tdatabase:当一个基于BDE的数据库应用程序需要一个永久数据库连接时,需要定制向一个数据库服务器的连接时,需要事务控制和特殊的数据库别名时就得用到Tdatabase对象。特别是当连接到一个远程的SQL数据库服务器时,如果要利用BDE进行数据库事务处理,那么,TDatabase对象的威力就体现出来了。在一个应用程序中为每一个数据库连接显示的声明Tdatabase对象要根据需要而定,不是必需的。对一个数据库连接,如果没有显示的声明并实例化TDatabase对象,系统就会产生一个带有默认属性的TDatabase对象。

TdataSource对象用于在DataSet对象(包括Tquery,TstoredProc,Ttable等)和数据感知组件之间提供一个连接的纽带,以便在窗体上显示数据库中的数据,在数据库中导航定位与编辑数据集中的数据。如果一个DataSet对象中的数据想在数据感知组件中显示和修改,它就必须和TdataSource对象相联系。同样,一个数据感知组件如果想和数据源相联系以便显示和操纵数据,就必须以TDataSource对象为中介。

用Delphi6作数据库应用开发概括来说如下:先利用数据存取组件和实际的数据库建立连接,并用Tsession对象和Tdatabase对象管理这些连接。然后以Tdatasource对象为中介,用数据感知组件向用户显示数据库的内容并接受用户的查询和修改等操作。

3.2.4 SQL语言在Delphi中的应用

在Delphi中使用SQL语言非常方便,一般来说,都是通过Tquery组件来使用SQL语言的。可以在TQuery组件的SQL属性中设置SQL语句。设计程序时,在该组件的属性对话框中选择SQL属性,单击带省略号的按钮,就可以打开String List Editor对话框,然后我们就可以在对话框中添加SQL语句。还可以使用Delphi的SQL Builder来自动生成SQL语句,这样可以避免手工编写SQL而可能造成的语法错误。

静态SQL语句在程序设计时便已固定下来,它不包含任何参数和变量。

动态SQL语句,也被称作参数化的语句,在其中间包含着表示字段名或表名的参数,例如下面的语句是一条动态SQL语句:

Select * From Students Where StudentCode =: StudentCode;

其中的变量StudentCode便是一个参数变量,它由一个冒号引导,在程序运行过程中,必须要为该参数赋值,该条SQL语句才能正确执行,每次运行应用程序时可以为该参数变量赋予不同的值。为参数赋值有三种方法:

①根据参数在SQL语句中出现的顺序,设置TQuery部件的Params属性值为参数赋值。

②直接根据SQL语句中各参数的名字,调用ParamByName方法来为各参数赋值。

③将TQuery部件的DataSource属性设置为另一个数据源,这样将另一个数据源中与当前TQuery部件的SQL语句中的参数名相匹配的字段值赋给其对应的参数。利用这种方法也能实现所谓的连接查询,创建主要—明细型数据库应用。

在程序运行过程中,要想设置TQuery部件的SQL属性,必须首先调用Close方法,关闭TQuery部件,然后再调用Clear方法清除SQL属性中现存的SQL命令语句, 最后再调用Add方法为SQL属性设置新的SQL命令语句。例如:

Query1.Close {关闭Query1)

Query1.SQL.Clear {清除SQL属性中的SQL命令语句}

Query1.SQL.Add(‘Select * From Students‘);

Query1.SQL.Add(‘ Where Name ="Lucy" ‘);

在为TQuery部件设置SQL属性时调用Close方法总是很安全的,如果TQuery部件已经被关闭了,调用Close方法时不会产生任何影响。在应用程序中为SQL属性设置新的SQL 命令语句时,必须要调用Clear方法以清除SQL属性中现存的SQL命令语句,如果不调用Clear方法,便调用Add方法向SQL属性中设置SQL命令语句,那么新设置的SQL命令语句会追加在现存SQL命令语句后面, 在程序运行时常常会出现出乎意料的查询结果甚至程序无法运行下去。

在这里要特别注意的,一般情况下TQuery部件的SQL属性只能包含一条完整的SQL语句,它不允许被设置成多条SQL语句。当然有些数据库服务器也支持在TQuery部件的SQL属性中设置多条SQL语句,只要数据库服务器允许这样,我们在编程时可以为 SQL 属性设置多条SQL语句。

在为TQuery部件设置完SQL属性的属性值之后,也即编写好适当的SQL程序之后,可以有多种方式来执行SQL程序。

在设计过程中,设置完TQuery部件的SQL属性之后将其Active属性的值置为True, 这样便可以执行SQL属性中的SQL程序,如果应用中有与TQuery部件相连的数据浏览部件( 如TDDGrid TDBEdit等)那么在这些数据浏览部件中会显示SQL程序的执行结果。

在应用程序运行过程中,通过程序调用TQuery部件的Open方法或ExecSQL 方法可以执行其SQL属性中的SQL程序。Open方法和ExecSQL方法是不一样的。Open方法只能用来执行SQL语言的查询语句(Select命令), 并返回一个查询结果集,而ExecSQL方法还可以用来执行其它常用的SQL语句(如INSERT, UPDATE, DELETE等命令),例如:

Query1.Open (这样会返回一个查询结果集)

如果调用Open方法,而没有查询结果时,会出错。此时应该调用ExecSQL 方法来代替Open方法。如:

Query1.ExecSQL (没有返回结果)

当然在设计应用程序时,程序设计人员是无法确定TQuery部件中的SQL 语句是否会返回一个查询结果的。对于这种情况应当用Try…Except模块来设计程序。在 Try 部分调用Open方法,而在Except部分调用ExceSQL方法,这样才能保证程序的正确运行。

Delphi中用ADOQuery来使用SQL语句同样十分方便。在ADOQuery组件中首先通过ConnectionString属性值来联接数据源,然后就通过双击SQL…属性值来写入SQL语句。在Delphi中调用数据库,就可以调用ADOQuery组件,通过修改其中的SQL…属性中的SQL语句来实现对数据库的各项操作。

值得注意的是,ADOQuery组件只有在激活的情况下才可以被正确地使用,这样就提出了一个问题,也就是说,在每次修改ADOQuery组件的SQL…属性时都必须先行进行关闭,待清除掉SQL…中所有的SQL语句后才可以添加新的SQL语句。而且,在每一次修改完成以后,还应该记得重新将ADOQuery激活。其它的使用方法与TTQuery有许多的相似之处。

§3.3 Access 简介

建立一个数据库我们有多种选择,现在市场上有各种各样的数据库,而且每一种数据库都有其自身的特点,不能说哪一种更好,只能在其中寻找一种能更好地适应系统需求、更好地满足用户的要求以及适应开发人员的习惯。在本系统中,做为图书仓库管理系统是一个比较小的应用系统,它所产生和处理的数据量也比较小。因此,没有必要使用像SQL Server和Oracle这样的大型数据库。我首先想到的数据库是Borland公司的Paradox数据库。另外,Microsoft Office中的Access数据库在计算机上的应用比较普及,是开发小型数据库系统的比较理想的选择,所以,在本系统中我选择了Access数据库。

Access做为一个数据库管理系统,它被集成在Microsoft Office中。Access数据库处理的基本结构,采取关系型数据库模式。与其他的数据库系统相比,Access更加简单易学,一个普通的计算机用户可以很快地掌握它。Access 2000的功能十分强大,利用它可以方便地实现对信息保存、维护、查询、统计、打印、交流、,而且它可以十分方便地与Office其他组件交流数据,这些功能对一个一般用户而言已经足够了。

转贴于 第四章 系统总体设计

软件系统的总体设计大约要经历可行性分析和项目开发计划,需求分析,概要设计,详细设计,编码,测试以及维护等七个阶段。可行性分析和项目开发计划在前面已经叙述,下面所要做的是进行软件需求分析,概要设计和详细设计。编码过程将在下一节论述,而测试和维护过程不在本文叙及。

§4.1 系统需求分析

在经过前一阶段的分析之后,我确定了我的开发课题为图书仓库管理。现在所要做的是要准确定义系统必须做什么以及系统必须具备的功能。

软件需求分析中我采用结构化分析方法(Structured Analysis,简称SA),SA是面向数据流进行需求分析的方法,像所有的软件分析方法(如面向对象分析方法、IDEF方法等等)一样,SA也是一种建模活动,它使用简单易读的符号,根据软件内部数据传递、变换的关系,自顶向下逐层分解,描绘满足功能要求的软件模型。

在系统中我采用数据流图(DFD)这种半形式化的描述方式表达需求。它是一种功能模型,以图形的方式描绘数据在系统中流动和处理的过程,只反映系统必须完成的逻辑功能。它有四种基本图形符号:

:箭头,表示数据流;

〇:圆或椭圆,表示加工;

:双杠,表示数据存储;

:方框,表示数据的源点或终点。

为了表达较为复杂问题的数据处理过程,用一张数据流图是不够的,要按照问题的层次结构进行逐步分解,并以一套分层的数据流图反映这种结构关系。在这里我一共使用了三层数据流图,即顶层图,0层图和1层图(也是底层图)。

在多层数据流图中,顶层流图仅包含一个加工,它代表被开发系统,它的输入流是该系统的输入数据了,输出流是该系统的输出数据;底层流图是指其加工不需要再做分解的数据流图,中间层流图表示对其上层父图的细化,它的每一步加工可能继续细化成子图。

经过对系统的分析首先得到系统的顶层DFD,如下: 一步细化得到系统的0层DFD,如下:

再进一步细化每一个数据加工功能,得到系统的1层DFD图。

在这里只给出有关入库管理和出库管理的1层数据流图,它们是系统的关鍵部分,也是主要的部分。通过以上对数据流图的分析之后,我们已大体地了解了系统的功能和目标,接下来所要做的就是系统功能模块的划分和数据库的设计,也就是系统的概要设计。

§4.2 系统概要设计

在软件需求分析阶段,搞清楚了软件“做什么”的问题,形成了目标系统的逻辑模型。现在我们所要做的就是要把软件“做什么”的逻辑模型变换为“怎么做”的物理模型,即着手实现软件的需求。首先,我们需要描述的是系统的总的体系结构。

4.2.1 系统结构设计

系统的概要设计中最重要的就是系统的模块化。模块化是指解决一个复杂问题时自项向下逐层把软件系统划分成若干个模块的过程。每个模块完成一个特定的功能,所有的模块按某种方法组织起来,成为一个整体,完成整个系统所要求的功能。

将系统划分为多个模块是为了降低软件系统的复杂性,提高可读性、可维护性,但模块的划分不能是任意的,应尽量保持其独立性。也就是说,每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单,即尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。

在系统的概要设计中我采用结构化设计(Structure Design,简称SD),SD以需求分析阶段产生的数据流图DFD为基础,按一定的步骤映射成软件结构。我首先将整个系统化分为几个小问题,小模块,在系统中,我设计了用户管理、库存管理、入库管理、出库管理、员工管理和供应商管理6个小模块。然后,进一步细分模块,添加细节。比如,用户管理我又将其分为用户注册、用户注销、密码修改;库存管理分为库存记录查询、库存记录修改、库存记录打印等等。

以下就是系统的结构图:(在这里为了表达方便我将结构图分开来表达。)

在得到系统的第一层功能模块图后,经过进一步地细化,得一系统的子功能模块图:

4.2.2 数据库设计

在信息世界中,信息从客观事物出发流经数据库,通过决策机构最后又回到客观世界,信息的这一循环经历了三个领域:信息世界,数据世界,现实世界。现实世界的事物反映到人的头脑中,人的大脑对它有个认识过程,经过分析(选择、命名、分类等)进入信息世界。这些信息再进一步加工、编码,然后进数据世界,而软件系统的开发工作需要考虑这两个方面的问题,也就是要考虑系统开发所需要的数据,以及如何对这些数据进行操作。这两个问题贯穿了整个软件系统的开发过程,这也就是数据库的设计问题,软件设计的一个核心。

4.2.2.1 ER图设计

在系统设计的开始,我首先考虑的是如何用数据模型来数据库的结构与语义,以对现实世界进行抽象。目前广泛使用的数据模型可分为两种类型,一种是独立于计算机系统的“概念数据模型”,如“实体联系模型”;另一种是直接面向数据库逻辑结构的“结构数据模型”。在本系统中我采用“实体联系模型”(ER模型)来描述数据库的结构与语义,以对现实世界进行第一次抽象。ER模型直接从现实世界抽象出实体类型及实体间联系,然后用ER图来表示数据模型。它有两个明显的优点:接近于人的思维,容易理解;与计算机无关,用户容易接受。但ER模型只能说明实体间语义的联系,不能进一步说明详细的数据结构,它只是数据库设计的第一步。

ER图是直观表示概念模型的工具,它有四个基本成分:

矩形框,表示实体类型(考虑问题的对象)。

菱形框,表示联系类型(实体间的联系)。

椭圆形框,表示实体类型和联系类型的属性。对于关键码的属性,在属性名下划一横线。

直线,联系类型与其涉及的实体类型之间以直线连接。

本系统为图书仓库管理,主要管理图书的入库、出库以及库存等事项。仓库根据需要可以查询图书供应商的信息,同时还需要了解在入库和出库中员工的参与情况。依据仓库管理的实际情况,考虑了多方面的因素以后,确定系统的ER图如下:

(为了表达的方便,在这里我没有在一张图上表达出所有的关系,而是用一张总体ER图,和几张实体属性关系图来表达数据库的结构。)

在该数据库中,我设计了三个实体,分别是库存、员工和供应商以及两个联系类型入库和出库。在本系统中库存是核心,也是基本,没有了库存其它的也就没有什么意义了。员工记录的添加是考虑到责任问题,也就是说,在仓库管理的实际运用中,出现了责任不清的现象,特别是由于仓库的进出图书数量都比较大时产生了一系列问题,所以在设计数据库时,我特别考虑到这一点,加入了员工记录这一实体。供应商信息的添加主要出于对图书来源问题的思考。通过添加供应商信息可以比较清楚地了解图书的进货渠道,从图书的质量到供应商的信誉都可以进行了解,同时可以为以后的图书进购提供一定有用的信息。

入库联系类型将库存信息、供应商信息和员工信息联系在一起,可以方便地实现三个实体之间的联接,而出库联系类型则将库存信息和员工信息较好地联接起,同时这两个联系类型又都具有各自特有的属性。

下面就是各实体及联系类型的属性图:(带#号的属性为关键字段)4.2.2.2 数据库表格设计

在完成系统的ER图之后,需要将ER模型转化为关系模型,也就是说,要设计出数据库所需要的表格。在这里,我选用的是关系数据库。因为关系数据库中的二维表格可以很清楚地描述数据之间的联系。

在这里不得不提到一个概念——范式。其实在上一节的ER图设计中,已经运用了范式的思想,不仅如此,在数据库的表格设计中更离不开范式的思想,它是数据库设计的基础,如果不注意这个问题将会导致一系列问题的出现。

我在系统中定义的表格都严格地按照范式的思想和要求去完成,数据库中的所有表格都达到了三范式的要求。根据系统ER图,针对本系统的特点,在对所搜集的数据进行规范化之后,定义了如下六张表格,分别是库存信息表,入库信息表,出库信息表,员工信息表,供应商信息表和密码信息表。通过对这六张表格的操作可以较好地完成系统设计的各项功能,六张表格之间有着不同程度的联系。(说明:在以下数据表中,K代表主键,#代表外键,字段值不为空。)

BookRecord 表(库存信息表)

字段名称 数据类型 说明

K BookID 数字 图书编号

BookName 文本 图书名

Author 文本 作者

Publisher 文本 出版社

PubDate 日期/时间 出版日期

Price 货币 价格

BookType 文本 图书类型

Number1 数字 库存数量

Addation 文本 备注

图4.13 库存信息表

库存信息表主要用于记录仓库中现存放的所有图书的详细信息,包括图书编号、书名、作者、出版社、图书类型等有关图书的各类信息,它即是该数据库的主表,也是系统主界面的主要内容。

在该表中图书编号是主键,它按图书入库的先后次序来编写,每当有图书入库,系统自动给出图书编号,这样我们按图书编号来查找图书是比较方便的。考虑到编号比较难于记忆,所以使用了出版社和图书类型两个字段,在系统中我提供了出版社和图书类型的分类查找,而且全部采用自动生成,每当系统中有新的出版社类型和图书类型,弹出菜单会自动添中新类型,这样就可以比较方便地实现按出版社和按图书类型查找。此外,库存数量也是一个比较关键的字段,该字段是在系统初始化时就给定的,每当有图书入库或出库操作,系统就会自动修改图书的库存数量,以保持数据的一致性。做为备注有一点说明,我的数据库中备注的数据类型是文本,而不是备注类型,主要考虑到该字段的长度并不大,而且在Delphi中文本数据类型的处理也比较方便一点。

Employee 表(员工信息表)

字段名称 数据类型 说明

K EmployeeID 数字 员工编号

EmployeeName 文本 员工姓名

Sex 文本 性别

BornDate 日期/时间 出生日期

Grade 文本 职称

WorkDate 日期/时间 工作日期

Telephone 文本 联系电话

Address 文本 联系地址

图4.14 员工信息表

员工信息表主要用于记录有关员工的各类信息,包括姓名、职称、出生日期、联系电话、联系地址等。它主要用来为系统提供员工的有关信息,因为在系统中,入库和出库操作均与员工有着一定的联系,在查询入库信息和出库信息时,有时需要查找有关此项记录有关的员工信息,在系统中我是通过入库记录与员工记录(出库记录和员工记录)之间的联接查询来完成的。另外,作为一个仓库也有必要了解其所属员工的一些基本情况,以便查询。

Shopkeeper 表(供应商信息表)

字段名称 数据类型 说明

K ShopkeeperID 数字 供应商编号

ShopkeeperName 文本 供应商姓名

Address 文本 地址

PostNo 数字 邮编

OfficePhone 文本 办公电话

HomePhone 文本 住宅电话

Email 文本 E-mail

PayType 文本 付款方式

图4.15 供应商信息表

供应商信息表主要用于记录有关供应商的各类信息,包括姓名、地址、电话、付款方式等。它主要用来为系统提供供应商的有关信息,在系统中入库记录是与供应商记录相联系的,通过入库记录可以查找相关的供应商信息。在供应商信息中,考虑当实际情况,我特别加入了Email和付款方式这两个字段,因为在当今信息世界中,多种多样的通讯方式和多种多样的付款方式是必然的,是数据库中必须与以记录。

InRecord 表(入库信息表)

字段名称 数据类型 说明

K InID 数字 入库编号

# BookID 数字 图书编号

# EmployeeID 数字 员工编号

# ShopkeeperID 数字 供应商编号

Number 数字 入库数量

BuyDate 日期/时间 入库日期

图4.16 入库信息表

OutRecord 表(出库信息表)

字段名称 数据类型 说明

K OutID 数字 出库编号

# BookID 数字 图书编号

# EmployeeID 数字 员工编号

Number2 数字 出库数量

OutDate 日期/时间 出库日期

图4.17 出库信息表

入库信息表主要用于记录有关入库的详细信息,包括入库数量、入库日期以及图书、员工、供应商三方的编号,以便查询。出库信息表主要用于记录有关出库的详细信息,包括出库数量、出库日期以及图书、员工的编号。出库信息表和入库信息表一样,其实它们都属于联系类型,系统通过这两个表可以联接上其它的表为用户提供多种条件的联接查询。值得提出的一点是入库记录和出库记录的添加不仅仅是单表操作,由于它们都与库存记录相联系,所以,无论您是添中入库记录还是添加出库记录,都必须同时修改库存记录,以保持数据的一致性,否则将引发系统出错而这些我都让其在系统中自动完成。无论您是添加入库记录,还是添加出库记录,系统都将自动修改库存中图书的数量,而且,在您出库的数量大于库存数量时,系统还会自动提示错误,这样就可以防止一定错误的发生。

在入库信息表和出库信息表中我还定义了几个外键,它提供了一种表示几个关系联系的方法。比如,系统中通过在入库信息表中定义的外键 BookID、EmployeeID和ShopkeeperID可以将库存信息表、员工信息表和供应商信息表联系在一起,从而方便地实现联接查询,而且,引入外键的定义是实体完整性约束的一个主要方面。

Key 表(密码信息表)

字段名称 数据类型 说明

K KeyName 文本 用户姓名

KeyNo 文本 用户密码

图4.18 密码信息表

密码信息表主要用于记录所有的用户名和用户密码。它是在用户登陆时用来确定用户和密码的正确性,以防止非法用户登陆。

通过以上设计已经完成了系统的概要设计,当我们有了系统的功能模块图和数据库之后,就需要着手去实现每一个模块,为每一个功能设计程序流程图,这也就是系统的详细设计。

§4.3 系统详细设计

在前面的概要设计中,已将系统划分为多个模块,并将它们按照一定的原则组装起来,同时确定了每个功能及模块之间的外部接口。现在所要做的就是确定每个模块具体执行过程,也可以说是“过程设计”。

在处理过程设计时我采用的是结构化程序设计(简称SP)方法。需要指出的是系统的详细设计并不是指具体的编程序,而是将概要设计阶段产生的系统功能模块图细化成很容易产生程序的图纸。因此详细设计的结果基本决定了最终程序的质量。为软件的质量,延长软件的生存期,软件的可测试性、可维护性提供重要的保障。详细设计的目标不仅是逻辑上正确地实现每个模块的功能,还应使设计出的处理过程清晰易读。

由前一阶段产生的系统功能模块图,我为系统的主要部分设计了如下程序流程图:通过以上步骤,基本上完成了对整个系统的总体设计,接下来所要做的就是软件的编码工作。系统总体设计的好坏直接影响着下一步工作,只有在这一阶段设计出好的模块图和程序流程图,才能更有利于编码,产生好的软件系统。

第五章 系统应用程序设计

§5.1 系统窗体模块组成

§5.2 数据模块窗体的设置

在编写数据库应用程序时,经常要遇到这样的情况,即好多组件、窗体同时访问相同的数据源,如果为每一个组件或者窗体都设置一个数据源将是十分耗时的工件,而且要保证这些数据源的确是相同的也需花一番功夫。那么,能不能将这些数据源集中管理,最好是做成一个统一的模块,需要时就将该模块引入而不必直接操作数据源本身呢?数据模块(DataModule)是解决这个问题最好的答案。简单说来,数据模块是用来集中管理数据源的一个窗体,该窗体可被需要的地方随时引入。

图5.2给出了本程序的数据模块(datamoduleform)窗体图,除报表窗体外所有的数据存取组件和数据源组件都在此数据模块中进行了定义。值得一提的是,设置了数据库Database组件,该组件引入了系统所需的唯一的数据库tsxs,Database组件的DatabaseName属性设置为tsckgl。tsxs数据库已在ODBC配置程序中进行了设置。其他的数据存取组件都是基于此数据库组件创建的,这样做的好处是,当数据库的别名或者其他信息改变之后,只需修改Tdatabase组件的AliasName属性即可。

另外,在本系统的数据模块窗体图中,我大多采用的AODQuery组件而没有采用BDE组,这主要是基于对ADO组件的了解。在Delphi的学习中我对ADO组件了解的更加清楚,使用也较BDE更为熟练,而且,ADO组件的功能也较BDE更为强大,所以在这里大多采用ADO组件来进行数据库联接。同时我也使用了BDE组件中的Table,因为在某些时候BDE有着其自身特有的优越性。 主窗体功能模块的实现

file://主窗体程序代码

public

file://在程序的起始部分,定义快捷按钮点击事件

Procedure Popup1Handler(Sender:Tobject);

Procedure Popup2Handler(Sender:TObject);

**********************************************************************

procedure Tmainform.Popup1Handler(Sender: TObject);

begin

file://快捷按钮1(点“按出版社分类”按钮产生)的点击事件

with datamoduleform.MainQuery do

begin

file://打开数据模块窗体的MainQuery,对BookRecord表进行操作

close;

file://关闭MainQuery

SQL.Clear;

file://清除SQL属性中的SQL命令语句

SQL.Add(‘select * from BookRecord where Publisher=:Pub‘); file://添加新的SQL语句

Parameters.ParamByName(‘Pub‘).Value:=(Sender as TMenuItem).Caption;

open;

file://重新打开MainQuery

end;

end;

**********************************************************************

procedure Tmainform.SpeedButton1Click(Sender: TObject);

Var s1,s2,s3,s4,s5 :String;

file://设立5个变量以方便实现模糊查询

begin

file://主窗口库存查询按钮事件

with datamoduleform.MainQuery do

begin

close;

SQL.Clear;

SQL.Add(‘select * from BookRecord‘);

SQL.Add(‘where BookID Like :BookID and BookName Like :Name and Author Like :Author and Publisher Like :pub and BookType Like :BookType‘);

file://使用Like语句来实现模糊查询

if Edit1.Text‘‘ then s1:=‘%‘+Edit1.Text+‘%‘ else s1:=‘%‘;

Parameters.ParamByName(‘BookID‘).Value:=s1;

file://给变量s1赋值

if Edit2.Text‘‘ then s2:=‘%‘+Edit2.Text+‘%‘ else s2:=‘%‘;

Parameters.ParamByName(‘Name‘).Value:=s2;

file://给变量s2赋值

if Edit3.Text‘‘ then s3:=‘%‘+Edit3.Text+‘%‘ else s3:=‘%‘;

Parameters.ParamByName(‘Author‘).Value:=s3;

file://给变量s2赋值

if Edit4.Text‘‘ then s4:=‘%‘+Edit4.Text+‘%‘ else s4:=‘%‘;

Parameters.ParamByName(‘Pub‘).Value:=s4;

file://给变量s2赋值

if Edit5.Text ‘‘ then s5:=‘%‘+Edit5.Text+‘%‘ else s5:=‘%‘;

Parameters.ParamByName(‘BookType‘).Value:=s5;

file://给变量s2赋值

open;

if FieldValues[‘BookID‘]=NULL

file://判断是否找到记录

then begin

Messagedlg(‘没有找到你所需要的记录!‘,mtInformation,[mbOK],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit4.Text:=‘‘;Edit5.Text:=‘‘;

close;

SQL.Clear;

SQL.Add(‘select * from BookRecord‘);

file://这里相当于一个刷新功能

open;

end;end;

end;

**********************************************************************

procedure Tmainform.SpeedButton3Click(Sender: TObject);

begin

file://库存表刷新按钮事件

with datamoduleform.MainQuery do

begin

close;

SQL.Clear;

SQL.Add(‘select * from BookRecord‘);

open;

end;

end;

**********************************************************************

procedure Tmainform.SpeedButton11Click(Sender: TObject);

var PopupItem:TMenuItem;

begin

file://自动生成快捷按钮1的内容

with datamoduleform.BookQuery do

begin

file://从数据库中选择出版社类型

close;

SQL.Clear;

SQL.Add(‘select distinct Publisher from BookRecord‘);

open;

PopupMenu1:=TPopupMenu.Create(Self); file://自动生成快捷菜单

PopupMenu1.AutoHotkeys:=maManual;

file://自定义热键

while Not Eof do

begin

file://根据出版社内容生成菜单子项

PopupItem:=TMenuItem.Create(Self);

PopupItem.Caption:=FieldByName(‘Publisher‘).AsString;

PopupMenu1.Items.Add(PopupItem);

PopupItem.onClick:=Popup1Handler;

file://确定菜单子项的点击事件

Next;

end; end;

PopupMenu1.Popup(384,67);

file://在指定位置显示快捷菜单1

end;

**********************************************************************

procedure Tmainform.FormActivate(Sender: TObject);

begin

file://系统初始化,在进入mainform时自动添加数据源

mainform.DBGrid1.DataSource:=datamoduleform.MainSource;

mainform.DBNavigator1.DataSource:=datamoduleform.MainSource;

mainform.DBGrid2.DataSource:=datamoduleform.EmpSource;

mainform.DBNavigator2.DataSource:=datamoduleform.EmpSource;

mainform.DBGrid3.DataSource:=datamoduleform.ShopSource;

mainform.DBNavigator3.DataSource:=datamoduleform.ShopSource;

mainform.DBGrid4.DataSource:=datamoduleform.InSource;

mainform.DBNavigator4.DataSource:=datamoduleform.InSource;

mainform.DBGrid5.DataSource:=datamoduleform.OutSource;

mainform.DBNavigator5.DataSource:=datamoduleform.OutSource;

end;

**********************************************************************

procedure Tmainform.FormCreate(Sender: TObject);

begin

file://系统初始化,定义界面大小,以适应不同分辩率

Width:=800;Height:=600;

end;

**********************************************************************

procedure Tmainform.Timer1Timer(Sender: TObject);

begin

file://在状态栏显示时间

StatusBar1.Panels[2].Text:=DateToStr(Date);

StatusBar1.Panels[4].Text:=TimeToStr(Time);

end;

§5.4 入库、出库窗体模块的实现

图5.4 系统入库管理窗体

图5.5 系统出库管理窗体

procedure Tinoutform.SpeedButton4Click(Sender: TObject);

begin

file://入库管理查找按钮事件

with datamoduleform.BookQuery do

file://入库查询处理

begin

close;

SQL.Clear;

SQL.Add(‘select * from BookRecord where BookID=:BookID‘);

Parameters.ParamByName(‘BookID‘).Value:=Edit13.Text;

open;

if FieldValues[‘BookID‘]NULL

then

begin

Edit1.Text:=‘‘;

Edit1.ReadOnly:=true;Edit1.Color:=clMenu;

Edit6.Text:=FieldValues[‘BookName‘]; file://显示图书名

Edit6.ReadOnly:=true;Edit6.Color:=clMenu; file://设置显示框不可更改属性

Edit7.Text:=FieldValues[‘Author‘];

Edit7.ReadOnly:=true;Edit7.Color:=clMenu;

Edit8.Text:=FieldValues[‘Publisher‘];

Edit8.ReadOnly:=true;Edit8.Color:=clMenu;

Edit9.Text:=FieldValues[‘PubDate‘];

Edit9.ReadOnly:=true;Edit9.Color:=clMenu;

Edit10.Text:=FieldValues[‘Price‘];

Edit10.ReadOnly:=true;Edit10.Color:=clMenu;

Edit11.Text:=FieldValues[‘BookType‘];

Edit11.ReadOnly:=true;Edit11.Color:=clMenu;

Edit12.Text:=FieldValues[‘Number1‘];

Edit12.ReadOnly:=true;Edit12.Color:=clMenu;

If FieldValues[‘Addation‘]NULL

then Edit25.Text:=FieldValues[‘Addation‘]

else Edit25.Text:=‘‘;

Edit25.ReadOnly:=true;Edit25.Color:=clMenu;

end

else

begin

file://在没有查找到的情况下,清空所有显示框

Edit1.ReadOnly:=false;Edit1.Text:=‘‘;Edit1.Color:=clMenu;

Edit6.ReadOnly:=false;Edit6.Text:=‘‘;Edit6.Color:=clMenu;

Edit7.ReadOnly:=false;Edit7.Text:=‘‘;Edit7.Color:=clMenu;

Edit8.ReadOnly:=false;Edit8.Text:=‘‘;Edit8.Color:=clMenu;

Edit9.ReadOnly:=false;Edit9.Text:=‘‘;Edit9.Color:=clMenu;

Edit10.ReadOnly:=false;Edit10.Text:=‘‘;Edit10.Color:=clMenu;

Edit11.ReadOnly:=false;Edit11.Text:=‘‘;Edit11.Color:=clMenu;

Edit12.ReadOnly:=false;Edit12.Text:=‘‘;Edit12.Color:=clMenu;

Edit25.ReadOnly:=false;Edit25.Text:=‘‘;Edit25.Color:=clMenu;

MessageDlg(‘没有找到你所需要的记录!‘,mtInformation,[mbOK],0);

Edit13.Text:=‘‘;Edit13.SetFocus;

end;

end;

with datamoduleform.InQuery do file://自动入库编号的获取

begin

close;

SQL.Clear;

SQL.Add(‘select * from InRecord where InID>=All(select InID from InRecord)‘);

open;

file://找到入库编号中最大的一个

Edit26.ReadOnly:=false;

Edit26.Text:=FieldValues[‘InID‘]+1; file://最大的入库编号加1形成新的入库编号

Edit26.ReadOnly:=true;Edit26.Color:=clMenu; file://设置编号的不可更改性

end;

end;

**********************************************************************

procedure Tinoutform.SpeedButton1Click(Sender: TObject);

var s:integer;

begin

file://入库管理添加按钮事件

if Edit1.TextNULL

then MessageDlg(‘请输入完整的入库信息和图书信息,然后单击确定按钮。‘,

mtInformation,[mbok],0)

else begin

if (Edit2.Text=‘‘) or (Edit3.Text=‘‘) or (Edit4.Text=‘‘) or (Edit5.Text=‘‘)

then begin

MessageDlg(‘请输入完整的入库信息!‘,mtInformation,[mbok],0);

Edit2.SetFocus;

end

else begin

with datamoduleform.InQuery do

file://将找到的图书信息显示

begin

close;

SQL.Clear;

SQL.Add(‘insert into InRecord values(:InID,:BookID,:EmpID,:ShopID,

:Number,:InDate)‘); file://向入库信息表中插入记录

Parameters.ParamByName(‘InID‘).Value:=Edit26.Text; file://向Edit框取值

Parameters.ParamByName(‘BookID‘).Value:=Edit13.Text;

Parameters.ParamByName(‘EmpID‘).Value:=Edit2.Text;

Parameters.ParamByName(‘ShopID‘).Value:=Edit3.Text;

Parameters.ParamByName(‘Number‘).Value:=Edit4.Text;

Parameters.ParamByName(‘InDate‘).Value:=Edit5.Text;

execSQL;

end;

Edit12.ReadOnly:=False;

S:=StrToInt(Edit12.Text)+StrToInt(Edit4.Text); file://计算入库后库存图书数量

Edit12.Text:=IntToStr(s);

file://将修改后的库存图书数量显示

Edit12.ReadOnly:=true;

with datamoduleform.BookQuery do

file://修改库存记录中图书数量

begin

close;

SQL.Clear;

SQL.Add(‘update BookRecord set Number1=:Number where

BookID=:BookID‘);

Parameters.ParamByName(‘Number‘).Value:=s;

Parameters.ParamByName(‘BookID‘).Value:=Edit13.Text;

execSQL;

file://提交SQL语句

MessageDlg(‘记录已成功添加!‘,mtInformation,[mbOK],0);

Edit13.SetFocus;

end;

end;

end;

end;

**********************************************************************

procedure Tinoutform.SpeedButton2Click(Sender: TObject);

begin

file://入库管理确定按钮事件

if (Edit2.Text=‘‘) or (Edit3.Text=‘‘) or (Edit4.Text=‘‘) or (Edit5.Text=‘‘)

or (Edit6.Text=‘‘) or (Edit7.Text=‘‘) or (Edit8.Text=‘‘) or (Edit9.Text=‘‘)

or (Edit10.Text=‘‘) or (Edit11.Text=‘‘) or (Edit25.Text=‘‘)

then begin

file://判断输入信息的完整性

MessageDlg(‘请输入所需的全部入库信息!‘,mtInformation,[mbok],0);

Edit2.SetFocus;

end

else

begin

with datamoduleform.InQuery do

file://入库信息添加

begin

close;

SQL.Clear;

SQL.Add(‘insert into InRecord values(:InID,:BookID,:EmpID,:ShopID,

:Number,:InDate)‘);

file://向入库信息表中插入记录

Parameters.ParamByName(‘InID‘).Value:=Edit26.Text;

Parameters.ParamByName(‘BookID‘).Value:=Edit1.Text;

Parameters.ParamByName(‘EmpID‘).Value:=Edit2.Text;

Parameters.ParamByName(‘ShopID‘).Value:=Edit3.Text;

Parameters.ParamByName(‘Number‘).Value:=Edit4.Text;

Parameters.ParamByName(‘InDate‘).Value:=Edit5.Text;

execSQL;

end;

with datamoduleform.BookQuery do

begin

close;

SQL.Clear;

file://在完成入库信息的添加后,修改库存记录

SQL.Add(‘insert into BookRecord values(:BookID,:BookName,:Author,

:Publisher,:PubDate,:Price,:BookType,:Number,:Addration)‘);

Parameters.ParamByName(‘BookID‘).Value:=Edit1.Text;

Parameters.ParamByName(‘BookName‘).Value:=Edit6.Text;

Parameters.ParamByName(‘Author‘).Value:=Edit7.Text;

Parameters.ParamByName(‘Publisher‘).Value:=Edit8.Text;

Parameters.ParamByName(‘PubDate‘).Value:=Edit9.Text;

Parameters.ParamByName(‘Price‘).Value:=Edit10.Text;

Parameters.ParamByName(‘BookType‘).Value:=Edit11.Text;

Parameters.ParamByName(‘Number‘).Value:=Edit4.Text;

Parameters.ParamByName(‘Addration‘).Value:=Edit25.Text;

execSQL;

end;

MessageDlg(‘记录添加成功!‘,mtInformation,[mbok],0);

end;

end;

**********************************************************************

procedure Tinoutform.SpeedButton11Click(Sender: TObject);

begin

file://新书入库按钮事件

Edit13.Text:=‘‘;Edit13.Color:=clMenu;

with datamoduleform.InQuery do file://自动入库编号的获取

begin

close;

SQL.Clear;

SQL.Add(‘select * from InRecord where InID>=All(select InID from InRecord)‘);

open;

Edit26.Text:=FieldValues[‘InID‘]+1;

Edit26.ReadOnly:=true;Edit26.Color:=clMenu;

end;

with datamoduleform.BookQuery do

file://自动图书编号的获取

begin

close;

SQL.Clear;

SQL.Add(‘select * from BookRecord where BookID>=All(select BookID from BookRecord)‘);

file://找到库存图书编号中最大的一个

open;

Edit1.ReadOnly:=false;

Edit1.Text:=FieldValues[‘BookID‘]+1; file://显示自动生成的图书编号

Edit1.ReadOnly:=true;Edit1.Color:=clMenu;

end;

Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit4.Text:=‘‘;Edit5.Text:=‘‘;

Edit6.ReadOnly:=false;Edit6.Text:=‘‘;Edit6.Color:=clWindow;

Edit7.ReadOnly:=false;Edit7.Text:=‘‘;Edit7.Color:=clWindow;

Edit8.ReadOnly:=false;Edit8.Text:=‘‘;Edit8.Color:=clWindow;

Edit9.ReadOnly:=false;Edit9.Text:=‘‘;Edit9.Color:=clWindow;

Edit10.ReadOnly:=false;Edit10.Text:=‘‘;Edit10.Color:=clWindow;

Edit11.ReadOnly:=false;Edit11.Text:=‘‘;Edit11.Color:=clWindow;

Edit12.ReadOnly:=false;Edit12.Text:=‘‘;Edit12.Color:=clMenu;

Edit25.ReadOnly:=false;Edit25.Text:=‘‘;Edit25.Color:=clWindow;

end;

procedure Tinoutform.SpeedButton22Click(Sender: TObject);

var s:integer;

begin

file://出库管理确定按钮事件

if (Edit24.Text=‘‘) or (Edit27.Text=‘‘) or (Edit28.Text=‘‘)

then begin

MessageDlg(‘请输入完整的出库信息!‘,mtInformation,[mbok],0);

Edit24.SetFocus;

end

else begin

if Edit27.Text>Edit21.Text

file://检查出库数量是否小于库存数量

then begin

MessageDlg(‘库存中的图书数量不够!‘,mtInformation,[mbok],0);

Edit27.Text:=‘‘;Edit27.SetFocus;

end

else begin

with datamoduleform.OutQuery do

begin

close;

SQL.Clear;

SQL.Add(‘insert into OutRecord values(:OutID,:BookID,:EmpID,

:Number,:OutTime)‘);

file://添加出库记录

Parameters.ParamByName(‘OutID‘).Value:=Edit23.Text;

Parameters.ParamByName(‘BookID‘).Value:=Edit14.Text;

Parameters.ParamByName(‘EmpID‘).Value:=Edit24.Text;

Parameters.ParamByName(‘Number‘).Value:=Edit27.Text;

Parameters.ParamByName(‘OutTime‘).Value:=Edit28.Text;

execSQL;

end;

Edit21.ReadOnly:=False;

s:=StrToInt(Edit21.Text)-StrToInt(Edit27.Text); file://计算出库后库存图书数量

Edit21.Text:=IntToStr(s);

file://显示出库后库存图书数量

Edit21.ReadOnly:=True;

with datamoduleform.BookQuery do

begin

file://修改库存图书数量

close;

SQL.Clear;

SQL.Add(‘update BookRecord set Number1=:Number where BookID=:BookID‘);

Parameters.ParamByName(‘Number‘).Value:=s;

Parameters.ParamByName(‘BookID‘).Value:=Edit14.Text;

execSQL;

end;

MessageDlg(‘出库记录添加成功!‘,mtInformation,[mbok],0);

Edit14.Text:=‘‘;Edit14.SetFocus;

end;

end;

end;

§5.5 查询功能的实现

查询功能包括员工信息查询,供应商信息查询,入库信息查询和出库信息查询。由于每一个功能的实现都差不太多,而且其窗体也差不太多,所以在这里只给出员工信息查询窗体及其源代码。

图5.6 员工信息查询窗体

procedure Tfindempform.SpeedButton1Click(Sender: TObject);

Var s1,s2,s3 :String;

begin

file://员工记录查询窗体查找按钮事件

with datamoduleform.EmpQuery do

begin

close;

SQL.Clear;

SQL.Add(‘select * from Employee‘);

SQL.Add(‘where EmployeeID Like :EmpID and EmployeeName Like :Name and Grade Like :Grade‘);

file://实现模糊查询功能

if Edit1.Text‘‘ then s1:=‘%‘+Edit1.Text+‘%‘ else s1:=‘%‘;

Parameters.ParamByName(‘EmpID‘).Value:=s1;

if Edit2.Text‘‘ then s2:=‘%‘+Edit2.Text+‘%‘ else s2:=‘%‘;

Parameters.ParamByName(‘Name‘).Value:=s2;

if Edit3.Text‘‘ then s3:=‘%‘+Edit3.Text+‘%‘ else s3:=‘%‘;

Parameters.ParamByName(‘Grade‘).Value:=s3;

open;

if FieldValues[‘EmployeeID‘]NULL

then findempform.Close

file://在找到记录的情况下关闭查找窗口

else

begin

MessageDlg(‘没有找到你所需要的记录!‘,mtInformation,[mbOK],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit1.SetFocus;

close; SQL.Clear;

SQL.Add(‘select * from Employee‘);

file://刷新员工信息窗口

open;

end; end;

end;

§5.6 系统登陆窗体模块的实现

由于系统登陆窗体中有一幅彩图,在这里不便给出,而只给出了系统的实现。

var keyname: string; file://定义了一个全局变量,在key2中有调用

procedure Tkeyform.SpeedButton1Click(Sender: TObject);

var s:string;

file://登陆窗口登陆按钮事件

begin

if (Edit1.Text=‘‘) then begin

MessageDlg(‘清输入登陆姓名和密码!‘,mtInformation,[mbok],0);

Edit1.SetFocus;

end

else begin

datamoduleform.KeyTable.Active:=true;

if not datamoduleform.KeyTable.Locate(‘KeyName‘,Edit1.Text,[])

file://判断登陆名是否存在

then begin

MessageDlg(‘登陆名错误,请重新输入!‘,mtInformation,[mbok],0);

Edit1.Text:=‘‘; Edit1.SetFocus;

end

else begin

with datamoduleform.KeyQuery do

begin

close; SQL.Clear;

SQL.Add(‘select * from Key where KeyName=:KeyName‘);

Parameters.ParamByName(‘KeyName‘).Value:=Edit1.Text;

open;

s:=FieldValues[‘KeyNo‘];

end;

if sEdit2.Text file://判断登陆密码是否正确

then begin

MessageDlg(‘登陆密码错误,请重新输入!‘,mtInformation,[mbok],0);

Edit2.Text:=‘‘; Edit2.SetFocus;

end

else begin

keyname:=Edit1.Text;

keyform.Hide;

mainform.Show;mainform.WindowState:=wsMaximized;

end; end; end;

end;

§5.7 用户管理功能的实现

5.7.1 用户管理主窗体

图5.7 用户管理主窗体

5.7.2 密码修改窗体模块的实现

图5.8 密码修改窗体

procedure Tkey2form.SpeedButton1Click(Sender: TObject);

begin

file://密码修改窗口修改按钮事件

if (Edit1.Text=‘‘)or(Edit2.Text=‘‘)or(Edit3.Text=‘‘)

then begin

MessageDlg(‘请输入完整的信息。‘,mtInformation,[mbok],0);

Edit1.SetFocus;

end

else begin

if Not datamoduleform.KeyTable.Locate(‘KeyNo‘,Edit1.Text,[])

then begin

MessageDlg(‘原密码输入错误,不能修改新密码!‘,mtInformation,[mbok],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit1.SetFocus;

end

else begin

if Edit2.TextEdit3.Text

then begin

MessageDlg(‘两次密码输入不同,请重新输入新密码!‘,mtInformation,[mbok],0);

Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit2.SetFocus;

end

else begin

file://在数据库中修改密码

with datamoduleform.KeyQuery do

begin

close; SQL.Clear;

SQL.Add(‘update key set KeyNo=:KeyNo where KeyName=:KeyName‘);

Parameters.ParamByName(‘KeyName‘).Value:=keyname;

Parameters.ParamByName(‘KeyNo‘).Value:=Edit2.Text;

execSQL;

MessageDlg(‘密码修改成功!‘,mtInformation,[mbok],0);

key2form.Close;

end; end; end; end;

end;

5.7.3 用户注册窗体模块的实现

图5.9 用户注册窗体

procedure Tkey3form.SpeedButton1Click(Sender: TObject);

begin

file://用户注删窗口注删按钮事件

if (Edit1.Text=‘‘)or(Edit2.Text=‘‘)or(Edit3.Text=‘‘)

then begin

MessageDlg(‘请输入完整的信息!‘,mtInformation,[mbok],0);

Edit1.SetFocus;

end

else begin

if datamoduleform.KeyTable.Locate(‘KeyName‘,Edit1.Text,[])

file://判断用户名是否存在,系统不允许用户名重复

then begin

MessageDlg(‘用户名已存在,请输入新的用户名和密码!‘,

mtInformation,[mbok],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit1.SetFocus;

end

else begin

if Edit2.TextEdit3.Text

then begin

MessageDlg(‘您输入的两个密码不相同,请重新输入!‘,mtInformation,[mbok],0);

Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit2.SetFocus;

end

else begin

with datamoduleform.KeyQuery do

file://在数据库中添加该用户

begin

close;

SQL.Clear;

SQL.Add(‘insert into Key values(:KeyName,:KeyNo)‘);

Parameters.ParamByName(‘KeyName‘).Value:=Edit1.Text;

Parameters.ParamByName(‘KeyNo‘).Value:=Edit2.Text;

execSQL;

end;

MessageDlg(‘新用户添加成功,您可以继续添加用户,或按“取消”退出。‘,mtInformation,[mbok],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit3.Text:=‘‘;Edit1.SetFocus;

end; end; end;

end;

5.7.4 用户注销窗体模块的实现

图5.10 用户注销窗体

procedure Tkey4form.SpeedButton1Click(Sender: TObject);

var s:string;

begin

file://用户注销窗口注销按钮事件

if (Edit1.Text=‘‘)or(Edit2.Text=‘‘)

then MessageDlg(‘请输入完整的信息!‘,mtInformation,[mbok],0)

else begin

if Not datamoduleform.KeyTable.Locate(‘KeyName‘,Edit1.Text,[])

file://判断用户名是否存在,用户名必须存在,才可以删除

then begin

MessageDlg(‘您所输入的用户名不存在,请重新输入或按“取消”退出。‘,

mtInformation,[mbok],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit1.SetFocus;

end

else begin

with datamoduleform.KeyQuery do

begin

close;

SQL.Clear;

SQL.Add(‘select * from Key where KeyName=:KeyName‘);

Parameters.ParamByName(‘KeyName‘).Value:=Edit1.Text;

open;

s:=FieldValues[‘KeyNo‘];

end;

if sEdit2.Text file://判断该用户名下的密码是否正确

then begin

MessageDlg(‘您所输入的密码不正确,请重新输入或按“取消”退出。‘,

mtInformation,[mbok],0);

Edit2.Text:=‘‘;Edit2.SetFocus;

end

else begin

file://从数据库中删除该用户

with datamoduleform.KeyQuery do

begin

close;

SQL.Clear;

SQL.Add(‘delete from Key where KeyName=:KeyName‘);

Parameters.ParamByName(‘KeyName‘).Value:=Edit1.Text;

execSQL;

end;

MessageDlg(‘用户已成功删除,您可以继续删除用户,或按“取消”退出。‘,

mtInformation,[mbok],0);

Edit1.Text:=‘‘;Edit2.Text:=‘‘;Edit1.SetFocus;

end; end; end;

end;

结束语

本系统是一个面向小型图书企业,具有一定实用性的数据库信息管理系统。它主要完成对图书仓库的一系列管理,包括入库、出库、库存以及员工和供应商信息管理。本系统采用当前流行的面向对象的开发工具—Delphi来完成整个系统的设计,在数据库的设计上利用了Access的便利性和实用性。

本系统具有相当的实用功能。在查询方面,系统实现了多条件任意字段的模糊查询,同时在分类查询上实现了动态生成,系统可以自动识别用户不同的输入。在图书入库、出库和库存三者之间建立了良好的链接关系,某一部分地修改均会自动引发系统对与其相关的部分进行连锁修改。在用户管理方面,系统较好地实现了用户注册,用户注销和密码修改等各项功能。

系统在设计过程中不可避免地遇到了各种各样的问题,由于整个系统完全都是由个人设计的,有关Delphi许多细节问题都要靠自己去摸索,加之本人水平有限,并没有完全地理解Delphi的强大功能,而且还存在着许多不足之处。如:

受开发条件和开发时间的限制,本系统只利用了本地数据库Access,它同应用程序处于同一系统中,能存储的数据量也有一定限制,并没有发挥出Delphi其数据库方面的优势;

报表打印功能尚不够全面完善,不能实现动态报表;

在一些数据输入时没有及时的进行数据格式校验,不能保证数据输入的绝对正确性。

由于时间关系,系统功能实现不够完善,使用不是很方便,比如,没有实现多条记录的连锁删除和添加以及数据的导入功能。

这些都是需要完善的地方,该系统离实际使用也还有相当的距离,需要我进行不断地补充和完善。

通过本次毕业设计我学到了不少新的东西,也发现了大量的问题,有些在设计过程中已经解决,有些还有待今后慢慢学习。只要学习就会有更多的问题,有更多的难点,但也会有更多的收获。

考 文 献

[1] 郑荣贵、黄平、谷会东,Delphi 6.0数据库开发与应用,中科多媒体电子出版社,2002

[2] 伍俊良,Delphi 6控件应用实例教程,北京希望电子出版社,2002

[3] 卢国俊,Delphi 6数据库开发,电子工业出版社,2002

[4] 边萌,Delphi 编程起步,机械工业出版社,2002

[5] 伍俊良,Delphi 6课程设计案例精编,中国水利水电出版社,2002

第11篇

本系统主要完成对图书仓库的库存管理,包括图书入库、出库、库存,员工信息,供应商信息以及密码管理等六个方面。系统可以完成对各类信息的浏览、查询、添加、删除、修改、报表等功能。

系统的核心是入库、库存和出库三者之间的联系,每一个表的修改都将联动的影响其它的表,当完成入库或出库操作时系统会自动地完成库存的修改。查询功能也是系统的核心之一,在系统中即有单条件查询和多条件查询,也有精确查询和模糊查询,系统不仅有静态的条件查询,也有动态生成的条件查询,其目的都是为了方便用户使用。系统有完整的用户添加、删除和密码修改功能,并具备报表打印功能。

系统采用microsoft office中的access 2000来设计数据库,并使用当前优秀的开发工具—delphi 6.0 ,它有着最为灵活的数据库结构,对数据库应用有着良好的支持。

论文主要介绍了本课题的开发背景,所要完成的功能和开发的过程。重点的说明了系统设计的重点、设计思想、难点技术和解决方案。

关键字:数据库,sql语言,delph 6,数据库组件,仓库管理

目  录

第一章 引言 ……………………………………………………………………………1

1.1  课题来源 ……………………………………………………………………1

1.2  开发工具的选择  ……………………………………………………………2

1.3  所做的主要工作  ……………………………………………………………3

第二章 数据库概论 ……………………………………………………………………4

2.1  数据库的发展  ………………………………………………………………4

   2.1.1  数据库的发展 …………………………………………………………4

   2.1.2  数据库阶段的特点 ……………………………………………………5

   2.1.3  数据库技术 ……………………………………………………………6

2.2  数据库理论基础  ……………………………………………………………7

   2.2.1  数据库模型 ……………………………………………………………7

   2.2.2  数据库体系结构    ……………………………………………………10

   2.2.3  数据的独立性  ………………………………………………………11

   2.2.4  范式  …………………………………………………………………11

2.3  sql语言基础   ……………………………………………………………13

   2.3.1  sql简介  ……………………………………………………………13

   2.3.2  sql查询    ……………………………………………………………13

   2.3.3  sql数据更新    ………………………………………………………14

第三章数据库开发工具  ……………………………………………………………16

3.1  delphi 6.0 简介  ……………………………………………………………16

3.2  delphi 6.0 控件  ……………………………………………………………17

3.2.1  ado数据访问组件   …………………………………………………17

   3.2.2  数据控制类datacontrol    ……………………………………………18

   3.2.3  数据访问类dataaccess     ……………………………………………18

   3.2.4  sql语言在delphi中的应用    ………………………………………19

3.3  access 简介    ………………………………………………………………21

第四章 系统总体设计   ………………………………………………………………23

4.1 系统需求分析     ……………………………………………………………23

4.2 系统概要设计     ……………………………………………………………25

   4.2.1  系统结构设计    ………………………………………………………25

   4.2.2  数据库设计    …………………………………………………………27

       4.2.2.1  er图设计  ……………………………………………………27

       4.2.2.2  数据库表格设计………………………………………………29

4.3系统详细设计………………………………………………………………34

第五章 系统应用程序设计  …………………………………………………………37

5.1  系统窗体模块组成…………………………………………………………37

5.2  数据模块窗体设置…………………………………………………………38

5.3  主窗体功能模块的实现……………………………………………………39

5.4  入库、出库窗体模块的实现………………………………………………43

5.5  查询功能的实现……………………………………………………………51

5.6  系统登陆窗体模块的实现…………………………………………………52

5.7  用户管理功能的实现………………………………………………………54

   5.7.1  用户管理主窗体  ……………………………………………………54

5.7.2  密码修改窗体模块的实现    …………………………………………54

   5.7.3  用户注册窗体模块的实现    …………………………………………55

   5.7.4  用户注销窗体模块的实现    …………………………………………57

结束语 …………………………………………………………………………………59

致谢 ……………………………………………………………………………………60

参考文献 ………………………………………………………………………………61

第一章    引  言  

§1.1   课题来源

随着社会经济的迅速发展和科学技术的全面进步,计算机事业的飞速发展,以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期。随着经济文化水平的显著提高,人们对生活质量及工作环境的要求也越来越高。书籍做为人类的精神食粮,在现代社会中越来越受到重视,大量的书籍出现在市场上,人们有了各种各样不同的选择。与此同时,为了管理大量的图书,图书仓库也大量的出现,仓库的管理问题也就提上了日程。随着图书的大量增加,其管理难度也越来越大,如何优化仓库的日常管理也就成为了一个大众化的课题。

在计算机飞速发展的今天,将计算机这一信息处理利器应用于仓库的日常管理已是势必所然,而且这也将为仓库管理带来前所未有的改变,它可以带来意想不到的效益,同时也会为企业的飞速发展提供无限潜力。采用计算机管理信息系统已成为仓库管理科学化和现代化的重要标志,它给企业管理来了明显的经济效益和社会效益。主要体现在:

极大提高了仓库工作人员的工作效率,大大减少了以往入出存流程繁琐,杂乱,周期长的弊端。

基于仓库管理的全面自动化,可以减少入库管理、出库管理及库存管理中的漏洞,可以节约不少管理开支,增加企业收入。

仓库的管理的操作自动化和信息的电子化,全面提高了仓库的管理水平。

随着我国改革开放的不断深入,经济飞速的发展,企业要想生存、发展,要想在激烈的市场竞争中立于不败之地,没有现代化的管理是万万不行的,仓库管理的全面自动化、信息化则是其中极其重要的部分。为了加快仓库管理自动化的步伐,提高仓库的管理业务处理效率,建立仓库管理系统已变得十分心要。

入库、库存、出库还是现在企业图书仓库管理的常规基本模式,虽然,最近又出现了很多新的管理模式,如:基于零库存思想的沃尔玛特管理方式,但这些新的思想在

第二章    数据库概论

§2.1     数据库的发展

数据库处理在信息系统的研究中一直是非常重要的主题,然而,近年来,随着world wide web(/yingyongwengao/" target="_blank" title="">应用超越具有早期应用特点的简单的。同时,internet技术提供了一种向用户数据库内容的标准化的访问方法。这些技术没有脱离经典数据库技术的要求。它们只是加重了数据库技术的重要性。

数据库的设计和开发及包括艺术有包括工程。理解用户的需求,然后,把它们转变为有效的数据库设计是一个艺术过程。把设计转变为实际的数据库,并且这些数据库带有功能完备、高效能的应用,是一个工程过程。

数据库的目的是帮助人们跟踪事务。经典的数据库应用涉及诸如订单、顾客、工作、员工、学生、电话之类的项,或其它数据量较大、需要密起关注的事务。最近,由于数据库的普及,数据库技术已经被应用到了新的领域,诸如用于internet的数据库或用于公司内联网的数据库。数据库也被越来越多地应用于生成和维护多媒体应用程序上。

计算机的数据处理应用,首先要把大量的信息以数据形式存放在存储器中。存储器的容量、存储速率直接影响到数据管理技术的发展。从1956年生产出第一台计算机到现在,存储器的发展,为数据库技术提供了良好的物质基础。

使用计算机以后,数据处理的速度和规模,无论是相对于手工方式,还是机械方式,都有无可比拟的优势。通常在数据处理中,计算是比较简单的而数据的管理却比较复杂。数据管理是指数据的收集、整理、组织、存储、维护、检索、传送等操作,这部分操作是数据处理业务的基本环节,而且是任何数据处理业务中必不可少的共有部分。数据管理技术的优劣,将直接影响数据处理的效率。

2.1.1  数据库的发展

数据管理技术的发展,与硬件(主要是外存)、软件、计算机应用的范围有密切的联系。数据管理技术的发展经过三个阶段:人工管理阶段、文件系统阶段和数据库阶段。

人工管理阶段和文件系统阶段都有着相当多的缺陷,诸如数据冗余性 ,数据不一致性以及数据联系弱等等。也正是由于这些原因,促使人们研究新的数据管理技术,从而产生了数据库技术。

20世纪60年代末发生的三件大事,层次模型ims系统的推出、关于网状模型dbtg报告的发表以及关于关系模型论文的连续发表标志着数据管理技术进入数据库阶段。进入70年代以后,数据库技术得到迅速发展,开发了许多有效的产品并投入运行。数据库系统克服了文件系统的缺陷,提供了对数据更高级更有效的管理。

当进入数据库阶段后,随着数据管理规模一再扩大,数据量急剧增加,为了提高效率,开始时,人们只是对文件系统加以扩充,在应用文件中建立了许多辅助索引,形成倒排文件系统。但这并不能最终解决问题。在20世纪60年代末,磁盘技术取得重要进展,具有数百兆容量和快速存取的磁盘陆续进入市场,成本也不高,为数据库技术的产生提供了良好的物质条件。

2.1.2  数据库阶段的特点

(1)减少数据的重复(redundancy can be reduced)

当在一个非数据库系统当中,每一个应用程序都有属于他们自己的文件,由于无法有系统建立的数据,因此常常会造成存储数据的重复与浪费。例如:在一家公司当中,人事管理程序与工资管理程序或许都会使用到职员与部门的信息或文件,而我们可以运用数据库的方法,把这两个文件整理起来,以减少多余的数据,过度地占用存储空间。

(2)避免数据的不一致(inconsistency can avoid)

本项的特色,可以说是延伸前项的一个特点,要说明这样的一个现象,我们可以从下面这个实例来看:若是在同一家公司当中,职员甲在策划部门工作,且职员甲的记录同时被存放在数据库的两个地方,而数据库管理系统却没有对这样重要的情况加以控制,当其中一条数据库被修改时,便会造成数据的不一致,但是,对于一个健全的数据库管理系统而言,将会对这样的情况加以控制,但有时并不需要刻意消除这种情形,应当视该数据库的需求与效率来决定。                      

(3)数据共享(data shared)

对于数据共享的意义,并不是只有针对数据库设计的应用程序,可以使用数据库中的数据,对于其他撰写好的应用程序,同样可以对相同数据库当中的数据进行处理,进而达到数据共享的目的。

(4)强化数据的标准化(standard can be enforced)

由数据库管理系统,对数据做出统筹性的管理,对于数据的格式与一些存储上的标准进行控制,如此一来,对于不同的环境的数据交换(data interchange)上将有很大的帮助,也能提高数据处理的效率。

(5)实践安全性的管理(security restriction can be applied)

通过对数据库完整的权限控制,数据库管理者可以确认所有可供用户存取数据的合法途径渠道,并且可以事先对一些较重要或关键性的数据进行安全检查,以确保数据存取时,能够将任何不当损毁的情形降至最低。

(6)完整性的维护(integrity can be maintained)

所谓完整性的问题,就是要确认某条数据在数据库当中,是正确无误的。正如(2)所述,若是无法控制数据的不一致性,便会产生完整性不足的问题,所以,我们会发现,当数据重复性高的时候,数据不完整的情形也会增加,当然,若是数据库的功能完整,将会大大地提高数据完整性,也会增加数据库的维护能力与维护简便性。

(7)需求冲突会获得平衡(conflicting requirements can be balance)

在一个较大型的企业当中,用户不同的需求,往往会造成系统或数据库在设计上的困扰,但是一个合适的数据库系统,可以通过数据库管理员的管理,将会有效地整理各方面的信息,对于一些较重要的应用程序,可以适时地提供较快速的数据存取方法与格式,以平衡多个用户在需求上的冲突。

上述七个方面构成了数据库系统的主要特征。这个阶段的程序和数据间的联系可用下图表示: 2.1.3  数据库技术

从文件系统发展到数据库系统是信息处理领域的一个重大变化。在文件系统阶段,人们关注的中心问题是系统功能的设计,因而程序设计处于主导地位,数据只起着服从程序需要的作用。在数据库方式下,信息处理观念已为新体系所取代,数据占据了中心位置。数据结构的设计成为信息系统首先关心的问题,而利用这些数据的应用程序设计则退居到以既定的数据结构为基础的外围地位。

目前世界上已有数百万个数据库系统在运行,其应用已经深入到人类社会生活的各个领域,从企业管理、银行业务、资源分配、经济预测一直到信息检索、档案管理、普查统计等。并在通信网络基础上,建立了许多国际性的联机检索系统。我国20世纪90年代初在全国范围内装备了12个以数据库技术为基础的大型计算机系统,这些系分布在邮电、计委、银行、电力、铁路、气象、民航、情报、公安、军事、航天和财税等行业。

数据库技术还在不断的发展,并且不断地与其它计算机技术相互渗透。数据库技术与网络通信技术相结合,产生了分布式数据库系统。数据库技术与面向对象技术相结合,产生了面向对象数据库系统。

在数据库技术中有四个名词,其概念应该分清。

(1)数据库(database,db):db是统一管理的相关数据的集合。db能为各种用户共享,具有最小冗余度,数据间联系密切,而又有较高的数据独立性。

(2)数据库管理系统(database management system,dbms):dbms是位于用户与操作系统之间的一层数据管理软件,为用户或应用程序提供访问db的方法,包括db的建立、查询、更新及各种数据控制。dbms总是基于某种数据模型,可以分为层次型、网状型、关系型和面向对象型dbms。

(3)数据库系统(database system,dbs):dbs是实现有组织地、动态地存储大量关联数据,方便多用户访问的计算机软件、硬件和数据资源组成的系统,即采用了数据库技术的计算机系统。

(4)数据库技术:这是一门研究数据库的结构、存储、管理和使用的软件学科。数据库技术是操作系统的文件系统基础上发展起来的。而dbms本身要在操作系统的支持下才能工作。数据库不仅用到数据结构的知识,而且丰富了数据结构的内容。在关系数据库中要用到集合论、数理逻辑的理论。因此,数据库技术是一门综合性较强的学科。

§2.2数据库理论基础

2.2.1  数据库模型

从20世纪50年代中期开始,计算机的应用由科学研究部门逐步扩展到企业、行政部门。至60年代,数据处理成为计算机的主要应用。数据库技术作为数据管理技术,是计算机软件领域的一个重要分支,产生于60年代末。现已形成相当规模的理论体系和实用技术。

模型是对现实世界的抽象。在数据库技术中,我们用模型的概念描述数据库的结构与语义,对现实世界进行抽象,表示实体类型及实体间联系的模型称为“数据模型” 。

目前广泛作用的数据模型可分为两种类型。

一种是独立于计算机系统的模型,完全不涉及信息在系统中的表示,只是用来描述某个特定组织所关心的信息结构,这类模型称为“概念数据模型” 。要领模型用于建立信息世界的数据模型,强调其语义表达功能,应该概念简单、清晰,易于用户理解,它是现实世界的第一层抽象,是用户和数据库设计人员之间进行交流的工具。这一其中著名的模型是“实体联系模型” 。

另一种数据模型是直接面向数据库的逻辑结构,它是现实世界的第二层抽象。 这类模型涉及到计算机系统和数据库管理系统,又称为“结构数据模型” 。例如,层次、网状、关系、面向对象等模型。这类模型有严格的形式化定义,以便于在计算机系统中实现。

(1)层次模型。用树型结构表示实体类型及实体间联系的数据模型。树的结点是记录类型,每个非根结点有且只有一个父结点。上一层记录类型和下一层记录类型间联系是1∶n联系。

层次模型的特点是记录之间的联系通过指针实现,查询效率较高。但层次模型有两个缺点:一是只能表示1∶n联系,虽然有多种辅助手段实现了m∶n联系,但都较复杂,用户不易掌握,二是由于树型结构层次顺序的严格和复杂,引起数据的查询和更新操作也很复杂,因此,编写应用程序也很复杂。

(2)网状模型。用有向图结构表示实体类型及实体间联系的数据模型。。1969年dbtg报告提出的数据模型是网状模型的主要代表。有向图中的结点是记录类型,有向边表示从箭尾一端的记录类型到箭头一端的记录类型间联系是1∶n联系。

网状模型的特点:记录之间联系通过指针实现,m∶n联系也容易实现(每个m∶n联系可拆成两个1∶n联系),查询效率较高。网状模型的缺点是编写应用程序比较复杂,程序员必须熟悉数据库的逻辑结构。由于层次系统和网状系统的应用程序编制比较复杂,因此,从20世纪80年代中期起,其市场已被关系系统所取代。但是使用这两种模型建立起的许多数据库仍然在正常运转,只是在外层加了个关系数据库语言的接口。网状模型有许多成功的产品,20世纪70年代的产品大部分网状系统,例如,honeywell公司的ids/ⅱ、hp公司的image/3000、burroughs公司的dmsⅱ、umivac公司的dms1100、cullinet公司的idms、cimcom公司的total等

(3)关系模型。关系模型的主要是用二维表格结构表达实体集,用外键表示实体间联系。关系模型是由若干个关系模式组成的集合。关系模式相当于前面提到的记录类型,它的实例称为关系,每个关系实际上是一张二维表格。

关系模型和层次、网状模型的最大判别是用关键码而不是用指针导航数据,表格简单用户易懂,编程时并不涉及存储结构,访问技术等细节。关系模型是数学化模型。sql语言是关系数据库的标准化语言,已得到了广泛的应用。20世纪70年代对关系数据库的研究主要集中在理论和实验系统的开发方面。80年代初才形成产品,但很快得到广泛的应用和普及,并最终取代了层次、网状数据库产品。现在市场上典型的关系dbms产品有db2、oracle、sybase、informix和微机型产品foxpro、access等。

关系模型和网状、层次模型的最大区别是:关系模型用表格数据而不是通过指针链来表示和实现实体间联系。关系模型的数据结构简单、易懂。只需用简单的查询语句就可对数据库进行操作。

关系模型是数学化的模型,可把表格看成一个集合,因此集合论、数理逻辑等知识可引入到关系模型中来。关系模型已是一个成熟的有前途的模型,已得到广泛应用。

(4)面向对象模型。目前,关系数据库的使用已相当普遍,但是,现实世界中仍然存在着许多含有复杂数据结构的应用领域,例如,cad数据、图形数据等,而关系模型在这方面的处理能力就显得力不从心。因此,人们需要更高级的数据库技术来表达这类信息。面向对象的概念最早出现在程序设计语言中,随后迅速渗透到计算机领域的每一个分支。面向对象数据库是面向对象概念与数据库技术相结合的产物。

面向对象模型能完整地描述现实世界的数据结构,具有丰富的表达能力,但模型相对较复杂,涉及的知识面也广,因此面向对象数据库尚未达到关系数据库那样的普及程度。

2.2.2  数据库体系结构

数据库的体系结构分三级:内部级(internal),概念级(conceptual)和外部级(external)。这个三级结构有时也称为“三级模式结构”,或“数据抽象的三个级别”,最早是在1971年通过的dbtg报告中提出,后来收入在1975年的美国ansi/sparc报告中。虽然现在dbms的产品多种多样,在不同的操作系统支持下工作,但是大多数系统在总的体系结构上都具有三级模式的结构特征。从某个角度看到的数据特性称为“数据视图”(data view)。

外部级最接近用户,是单个用户所能看到的数据特性。单个用户使用的数据视图的描述称为“外模式”。

概念级涉及到所有用户的数据定义,是全局的数据视图。全局数据视图的描述称为“概念模式”。

内部级最接近于物理存储设备,涉及到实际数据存储的结构。物理存储数据视图的描述称为“内模式”。

数据库的三级模式结构是数据的三个抽象级别。它把数据的具体组织留给dbms去做,用户只要抽象地处理数据,而不必关心数据在计算机中的表示和存储,这样就减轻了用户使用系统的负担。

三级结构之间往往差别很大,为了实现这三个抽象级别的联系和转换,dbms在三级结构之间提供两个层次的映象(mappings):外模式/模式映象,模式/内模式映象。此处模式是概念模式的简称。

2.2.3  数据的独立性

由于数据库系统采用三级模式结构,因此系统具有数据独立性的特点。在数据库技术中,数据独立性是指应用程序和数据之间相互独立,不受影响。数据独立性分成物理数据独立性和逻辑数据独立性两级。

(1)物理数据独立性

如果数据库的内模式要进行修改,即数据库的存储设备和存储方法有所变化,那么模式/内模式映象也要进行相当的修改,使概念模式尽可能保持不变。也就是对内模式的修改尽量不影响概念模式,当然,对于外模式和应用程序的影响更小,这样,我们称数据库达到了物理数据独立性。

(2)逻辑数据独立性

如果数据库的概念模式要进行修改,譬如增加记录类型或增加数据项,那么外模式/模式映象也要进行相应的修改,使外模式尽可能保持不变。也就是对概念模式的修改尽量不影响外模式和应用程序,这样,我们称数据库达到了逻辑数据独立性。

现有关系系统产品均提供了较高的物理独立性,而对逻辑独立性的支持尚有欠缺,例如,对外模式的数据更新受到限制等。

2.2.4  范式

建立起一个良好的数据指标体系,是建立数据结构和数据库的最重要的一环。一个良好的数据指标体系是建立db的必要条件,但不是充分条件。我们完全可以认为所建指标体系中的一个指标类就是关系数据库中的一个基本表,而这个指标类下面的一个个具体指标就是这个基本表中的一个字段。但如果直接按照这种方式建库显然还不能算最佳。对于指标体系中数据的结构在建库前还必须进行规范化的重新组织。

在数据的规范化表达中,一般将一组相互关联的数据称为一个关系(relation),而在这个关系下的每个数据指标项则被称为数据元素(data element),这种关系落实到具体数据库上就是基本表,而数据元素就是基本表中的一个字段(field)。规范化表达还规定在每一个基本表中必须定义一个数据元素为关键字(key),它可以唯一地标识出该表中其它相关的数据元素。在规范化理论中表是二维的,它有如下四个性质:

在表中的任意一列上,数据项应属于同一个属性(如图中每一列都存放着不同合同记录的同一属性数据)。

表中所有行都是不相同的,不允许有重复组项出现(如图中每一行都是一个不同的合同记录)。

在表中,行的顺序无关紧要(如图中每行存的都是合同记录,至于先放哪一个合同都没关系)。

在表中,列的顺序无关紧要,但不能重复(如图中合同号和合同名谁先谁后都没关系,但二者不可重复或同名)。

在对表的形式进行了规范化定义后,数据结构还有五种规范化定义,定名为规范化模式,称为范式。在这五种范式中,一般只用前三种,对于常用系统就足够了。而且这五种范式是“向上兼容”的,即满足第五范式的数据结构自动满足一、二、三、四范式,满足第四范式的数据结构自动满足第一、二、三范式,……,依此类推。

第一范式(first normal form,简称1st nf)就是指在同一表中没有重复项出现,如果有则应将重复项去掉。这个去掉重复项的过程就称之为规范化处理。在本文所讨论的开发方法里,1st nf实际上是没有什么意义的。因为我们按规范化建立的指标体系和表的过程都自动保证了所有表都满足1st nf。

第二范式(second normal form,简称 2nd nf)是指每个表必须有一个(而且仅一个)数据元素为主关键字(primary key),其它数据元素与主关键字一一对应。例如,在图l9.7中如果我们将合同号定义为主关键字(其它数据元素中的记录数据都有可能重名,故不能作为主关键字),故只要知道了一个合同记录的合同号,就可以唯一地在同一行中找到该合同的任何一项具体信息。通常我们称这种关系为函数依赖(functional dependence)关系。即表中其它数据元素都依赖于主关键字,或称该数据元素唯一地被主关键字所标识。

第三范式(third normal form,简称 3rd nf)就是指表中的所有数据元素不但要能够唯一地被主关键字所标识,而且它们之间还必须相互独立,不存在其它的函数关系。也就是说对于一个满足了 2nd nf的数据结构来说,表中有可能存在某些数据元素依赖于其它非关键宇数据元素的现象,必须加以消除。

为防止数据库出现更新异常、插入异常、删除异常、数据冗余太大等现象,关系型数据库要尽量按关系规范化要求进行数据库设计。

§2.3 sql语言基础

2.3.1  sql简介

用户对数据库的使用,是通过数据库管理系统提供的语言来实现的。不同的数据库管理系统提供不同的数据库语言。关系数据库管理系统几乎都提供关系数据库标准语言——sql。

sql 的全称是structured query language,即结构化查询语言。sql语句可以从关系数据库中获得数据,也可以建立数据库、增加数据、修改数据。1986年ansi采用sql语言作为关系数据库系统的标准语言,后被国际化标准组织(iso)采纳为国际标准。sql语言使用方便、功能丰富、简洁易学,是操作数据库的工业标准语言,得到广泛地应用。例如关系数据库产品db2、oracle等都实现了sql语言。同时,其它数据库产品厂家也纷纷推出各自的支持sql的软件或者与sql的接口软件。这样sql语言很快被整个计算机界认可。

sql语言是一种非过程化语言,它一次处理一个记录集合,对数据提供自动导航。sql语言允许用户在高层的数据结构上工作,而不对单个记录进行操作。sql语言不要求用户指定数据的存取方法,而是使用查询优化器,由系统决定对指定数据存取的最快速手段。当设计者在关系表上定义了索引时,系统会自动利用索引进行快速检索,用户不需知道表上是否有索引或者有什么类型的索引等细节。

sql语言可以完成许多功能,例如:

查询数据

在数据库表格中插入、修改和删除记录

建立、修改和删除数据对象

控制对数据和数据对象的存取

确保数据库的一致性和完整性等

2.3.2  sql查询

数据查询是关系运算理论在sql语言中的主要体现,select 语句是sql查询的基本语句,当我们在对一个数据库进各种各样的操作时,使用的最多的就是数据查询,在以sql为基础的关系数据库中,使用的最多的就是select查询语句。

select语句的完整句法如下:

select 目标表的列名或列表达式序列

from   基本表和(或)视图序列

[where 行条件表达式]

[group by 列名序列]

[having 组条件表达式]

[order by列名 [asc│deac]…]

我在select语句中还使用了大量的保留字和通配符以进行各种各样的条件查询。在系统中有大量的查询按钮,其使用了大量的查询语句,而且这些查询语句大部分使用的是模糊查询,所以大量的使用了模式匹配符like(判断值是否与指定的字符通配格式相符)。在包含like的查询语句中可以使用两个通配符:%(百分号):与零个或多个字符组成的字符串匹配;_(下划线):与单个字符匹配。系统中的条件判断往往包含多个条件,这时就需要使用逻辑运算符not、and、or(用于多条件的逻辑连接),谓词all以及保留字distinct等等。做为select语句还有很多的使用方法,这里就不再叙述。

2.3.3  sql数据更新

使用数据库的目的是为了有效地管理数据,而数据的插入、删除和修改则是必不可少的一个功能。在本系统中就大量地使用了数据插入、删除和修改这三种操作,现做一个简单地介绍。

数据插入

往数据库的基本表中插入数据使用的是insert语句,其方式有两种:一种是元组值的插入,另一种是查询结果的插入。在本系统中使用的是前一种方式,其句法如下:

insert into 基本表名(列表名)values(元组值)

数据删除

往数据库的基本表中删除数据使用的是delete语句,其句法如下:

delete from 基本表名 [where 条件表达式]

在些作一点说明,删除语句实际上是“select * from 基本表名 [where 条件表达式]”和delete操作的结合,每找到一个元组,就把它删除。此外,delete语句只能从一个基本表中删除元组,where子句中条件可以嵌套,也可以是来自几个基本表的复合条件。

数据修改

当需要修改基本表中元组的某些列值时,可以用update语句实现,其句法如下:

update基本表名

set列名=值表达式[,列名=值表达式…]

[where条件表达式]

在delphi中使用sql语句是很方便的,一般来说,都是通过tquery组件来使用sql语言的。有一点要进行说明,虽然通过tquery组件来使用sql语言很方便,但考虑到自己对不同组件的理解程度、个人习惯以及其它各个方面,在本系统中我采用的是ado组件来对数据库进行操作。最简单的方法比如在tadoquery组件的sql属性中就可以键入sql语句,至于详细的使用方法在后面进行介绍。

第三章    数据库开发工具

§3.1 delphi 6.0 简介

delphi类可以粗略地分成两部分:一部分是组件类,这些组件类通常以某种方式出现在组件面板上,当用户从组件面板上点取一个类的图标后,在程序中就自动生成了该类的对象(非可视组件除外);另一部分是功能类,这此功能类的对象通常出现在程序代码中,起着不可代替的作用,但是这些功能类在组件面板上是找不到的。在delphi中,每一个类的祖先都是tobject类,整个类的层次结构就像一棵倒挂的树,在最顶层的树根即为tobject类。这样,按照面向对象编程的基本思想,就使得用户可用tobject类这个类型代替任何其它类的数据类型。实际上在delphi的类库中,tobject类派生出了为数相当众多的子类,它们形成了一个庞大的体系,通常情况下,如果不自行开发组件,就不必了解整个类的体系结构,只用到类层次树的叶结点就足够了。

凡是做过程序开发的人都知道从来没有单纯的数据应用程序,也就是说,数据库应用程序必须和用户界面(可以是图形界面,也可以是命令接口)元素相结合,只讲界面或只讲数据库本身都构不成数据库应用程序,因而用delphi 6.0开发数据库应用程序就隐含着界面开发。delphi6中的vcl组件可用图3-1来说明。组件在delphi程序的开发中是最显眼的角色。大家知道,在编写程序时一般都开始于在组件面板上选择组件并定义组件间的相互作用。但也有一些组件不在组件面板上,例如tform和tapplication(典型的非可视组件)。组件是tcomponents派生出来的子类,可以流的形式存放在dfm文件中,具有事件和publish属性。

窗口组件类是窗口化的可视化组件类,在delphi的类库中占有最大的份额。在实际编程中,窗口组件类的对象都有句柄,可以接受输入焦点和包含其它组件。

图形组件与窗口组件并列,是另一大类组件。图形组件不是基于窗口的,因而不能有窗口句柄,不能接受输入焦点和包含其它组件。从图8-43中可以看出,图形组件的基类是tgraphiccontrol,在实际编程中,它们必须寄生于它们的宿主——窗口组件类的对象,由它们的拥有者负责其显示,而且它们还能触发一些和鼠标活动相关的事件。图形控件最典型的例子是tlabel和tspeedbutton。由此可以看出图形组件的功能很弱,有读者会问图形组件的用处何在呢?其实使用图形组件的最大好处在于节省资源,正是因为它们的功能较弱,所以使用的系统资源就要少。在一个应用程序中,如果能在不影响其功能的前提下合理大量地使用图形组件,将会大减少程序对系统资源的消耗。

非可视组件是与可视组件相并列的另一类组件,非可视组件在程序运行中是不可见的(除各种对话框组件之外,事实上有人认为对话框组件不能归入非可视组件,应该是另一种介于可视与非可视之间的组件)。

§3.2 delphi 6.0 控件

用delphi6开发数据库应用,重点是和各种数据库组件打交道,当然也要使用其它的一些组件,现在就我在系统设计中所使用的重要组件给与简单介绍。

3.2.1  ado数据访问组件

ado数据对象(active data objects)实际是一种提供访问各种数据类型的链接机制。ado设计为一种极简单的格式,通过odbc的方法同数据库接口中,可以使用任何一种odbc数据源,即不止适合于sql server、oracle、access等数据库应用程序,也适合于excel表格、文本文件、图形文件和无格式的数据文件。ado是基于ole-db之上的技术,因此ado通过其内部的属性和方法提供统一的数据访问接口方法。ado使您的客户端应用程序能够通过ole db提供访问和操作在数据库服务器中的数据。ado支持用于建立c/s和web的应用程序的主要功能。其主要优点是易于使用、高速度、低内存支出和占用磁盘空间较少。ado同时具有远程数据服务(rds)功能,通过rds可以在一次往返过程中实现将数据从服务器移动到客户端应用程序和web页、在客户端对数据进行处然后将更新结果返回服务器的操作。

delphi 6.0继续对microsoft的ado访问能力的支持。这种能力是通过一组新组件实现的,这些组件是在企业版的ado组件页中,在组件面版的ado页上可以找到这些组件。利用在前面章节提到的tdataset抽象类,ado组件可以不通过bde而直接实现ado连接。这意味着只需要很少的代码就可以实现该连接并且性能得到提高。

利用ado数据访问组件,可以只使用ado结构与数据库取得联系并对其中的数据进行操作,而在这些过程中完全不需要使用bde。大多数的ado连接和数据集组件都是与基于bde的连接和数据集组件相类似的。tadoconnection组件与基于bde的应用程序中的tdatabase组件类似。tadotable与ttable,tadoquery与tquery,以及tadostoreproc和tstoredproc之间都具有这种类似的对应关系。使用这些ado组件的方式与我们常使用的数据访问组件(基于bde)都有许多相同之处。ttadodataset没有直接的bde对应组件,但它提供了许多与ttable和tquery相同的功能。同样,tadocommand也没有相对应的bde组件,它是在delphi/ado环境中完成特定功能的组件。delphi 6.0通过ado数据集访问组件,可以不借助bde数据引擎而是通过微软的oledb来访问更为广泛的数据库中的数据。ado数据集访问组件与常用的数据访问组件是并列的关系。

在系统中我主要使用的是adotablet和adoquery两个组件。

3.2.2  数据控制类datacontrol

数据控制类负责数据库数据的显示,并把用户对数据的修改传回。这里的绝大多数组件,如dbtext, dbedit,  dbmemo, dbimage, dblistbox, dbcombobox, dbcheckbox, dbradiogroup, dblookuplistbox, dblookupcombox, dbctrgrid的功能和对应的非数据感知组件相同,如tedit框,tradiogroups单选按钮组等,只不过在显示数据库数据时要用而已。

在系统中主要使用数据网格控件dbgrid和数据库导航器控件dbnavigator。

3.2.3  数据访问类dataaccess

数据库应用系统中数据访问是一个首要问题,包括单用户和 c/s系统,都必须联系一些数据库和数据表文件。delphi 6 提供了专门用于数据访问的基类控件。主要包括数据源控件datasource、客户数据集控件clientdataset、数据集提供器控件datasetprovider等等。

tdatabase:当一个基于bde的数据库应用程序需要一个永久数据库连接时,需要定制向一个数据库服务器的连接时,需要事务控制和特殊的数据库别名时就得用到tdatabase对象。特别是当连接到一个远程的sql数据库服务器时,如果要利用bde进行数据库事务处理,那么,tdatabase对象的威力就体现出来了。在一个应用程序中为每一个数据库连接显示的声明tdatabase对象要根据需要而定,不是必需的。对一个数据库连接,如果没有显示的声明并实例化tdatabase对象,系统就会产生一个带有默认属性的tdatabase对象。

tdatasource对象用于在dataset对象(包括tquery,tstoredproc,ttable等)和数据感知组件之间提供一个连接的纽带,以便在窗体上显示数据库中的数据,在数据库中导航定位与编辑数据集中的数据。如果一个dataset对象中的数据想在数据感知组件中显示和修改,它就必须和tdatasource对象相联系。同样,一个数据感知组件如果想和数据源相联系以便显示和操纵数据,就必须以tdatasource对象为中介。

用delphi6作数据库应用开发概括来说如下:先利用数据存取组件和实际的数据库建立连接,并用tsession对象和tdatabase对象管理这些连接。然后以tdatasource对象为中介,用数据感知组件向用户显示数据库的内容并接受用户的查询和修改等操作。

3.2.4  sql语言在delphi中的应用

在delphi中使用sql语言非常方便,一般来说,都是通过tquery组件来使用sql语言的。可以在tquery组件的sql属性中设置sql语句。设计程序时,在该组件的属性对话框中选择sql属性,单击带省略号的按钮,就可以打开string list editor对话框,然后我们就可以在对话框中添加sql语句。还可以使用delphi的sql builder来自动生成sql语句,这样可以避免手工编写sql而可能造成的语法错误。

静态sql语句在程序设计时便已固定下来,它不包含任何参数和变量。

动态sql语句,也被称作参数化的语句,在其中间包含着表示字段名或表名的参数,例如下面的语句是一条动态sql语句:

select  *  from  students  where studentcode =: studentcode;

其中的变量studentcode便是一个参数变量,它由一个冒号引导,在程序运行过程中,必须要为该参数赋值,该条sql语句才能正确执行,每次运行应用程序时可以为该参数变量赋予不同的值。为参数赋值有三种方法:

①根据参数在sql语句中出现的顺序,设置tquery部件的params属性值为参数赋值。

②直接根据sql语句中各参数的名字,调用parambyname方法来为各参数赋值。

③将tquery部件的datasource属性设置为另一个数据源,这样将另一个数据源中与当前tquery部件的sql语句中的参数名相匹配的字段值赋给其对应的参数。利用这种方法也能实现所谓的连接查询,创建主要—明细型数据库应用。

在程序运行过程中,要想设置tquery部件的sql属性,必须首先调用close方法,关闭tquery部件,然后再调用clear方法清除sql属性中现存的sql命令语句, 最后再调用add方法为sql属性设置新的sql命令语句。例如:

query1.close {关闭query1)

query1.sql.clear {清除sql属性中的sql命令语句}

query1.sql.add(‘select * from students‘);

query1.sql.add(‘ where name ="lucy" ‘);

在为tquery部件设置sql属性时调用close方法总是很安全的,如果tquery部件已经被关闭了,调用close方法时不会产生任何影响。在应用程序中为sql属性设置新的sql 命令语句时,必须要调用clear方法以清除sql属性中现存的sql命令语句,如果不调用clear方法,便调用add方法向sql属性中设置sql命令语句,那么新设置的sql命令语句会追加在现存sql命令语句后面, 在程序运行时常常会出现出乎意料的查询结果甚至程序无法运行下去。

在这里要特别注意的,一般情况下tquery部件的sql属性只能包含一条完整的sql语句,它不允许被设置成多条sql语句。当然有些数据库服务器也支持在tquery部件的sql属性中设置多条sql语句,只要数据库服务器允许这样,我们在编程时可以为 sql 属性设置多条sql语句。

在为tquery部件设置完sql属性的属性值之后,也即编写好适当的sql程序之后,可以有多种方式来执行sql程序。

在设计过程中,设置完tquery部件的sql属性之后将其active属性的值置为true, 这样便可以执行sql属性中的sql程序,如果应用中有与tquery部件相连的数据浏览部件( 如tddgrid tdbedit等)那么在这些数据浏览部件中会显示sql程序的执行结果。

在应用程序运行过程中,通过程序调用tquery部件的open方法或execsql 方法可以执行其sql属性中的sql程序。open方法和execsql方法是不一样的。open方法只能用来执行sql语言的查询语句(select命令), 并返回一个查询结果集,而execsql方法还可以用来执行其它常用的sql语句(如insert, update, delete等命令),例如:

query1.open (这样会返回一个查询结果集)

如果调用open方法,而没有查询结果时,会出错。此时应该调用execsql 方法来代替open方法。如:

query1.execsql (没有返回结果)

当然在设计应用程序时,程序设计人员是无法确定tquery部件中的sql 语句是否会返回一个查询结果的。对于这种情况应当用try…except模块来设计程序。在 try 部分调用open方法,而在except部分调用excesql方法,这样才能保证程序的正确运行。

delphi中用adoquery来使用sql语句同样十分方便。在adoquery组件中首先通过connectionstring属性值来联接数据源,然后就通过双击sql…属性值来写入sql语句。在delphi中调用数据库,就可以调用adoquery组件,通过修改其中的sql…属性中的sql语句来实现对数据库的各项操作。

值得注意的是,adoquery组件只有在激活的情况下才可以被正确地使用,这样就提出了一个问题,也就是说,在每次修改adoquery组件的sql…属性时都必须先行进行关闭,待清除掉sql…中所有的sql语句后才可以添加新的sql语句。而且,在每一次修改完成以后,还应该记得重新将adoquery激活。其它的使用方法与ttquery有许多的相似之处。

§3.3 access 简介

建立一个数据库我们有多种选择,现在市场上有各种各样的数据库,而且每一种数据库都有其自身的特点,不能说哪一种更好,只能在其中寻找一种能更好地适应系统需求、更好地满足用户的要求以及适应开发人员的习惯。在本系统中,做为图书仓库管理系统是一个比较小的应用系统,它所产生和处理的数据量也比较小。因此,没有必要使用像sql server和oracle这样的大型数据库。我首先想到的数据库是borland公司的paradox数据库。另外,microsoft office中的access数据库在计算机上的应用比较普及,是开发小型数据库系统的比较理想的选择,所以,在本系统中我选择了access数据库。

access做为一个数据库管理系统,它被集成在microsoft office中。access数据库处理的基本结构,采取关系型数据库模式。与其他的数据库系统相比,access更加简单易学,一个普通的计算机用户可以很快地掌握它。access 2000的功能十分强大,利用它可以方便地实现对信息保存、维护、查询、统计、打印、交流、,而且它可以十分方便地与office其他组件交流数据,这些功能对一个一般用户而言已经足够了。

第四章  系统总体设计

软件系统的总体设计大约要经历可行性分析和项目开发计划,需求分析,概要设计,详细设计,编码,测试以及维护等七个阶段。可行性分析和项目开发计划在前面已经叙述,下面所要做的是进行软件需求分析,概要设计和详细设计。编码过程将在下一节论述,而测试和维护过程不在本文叙及。

§4.1   系统需求分析

在经过前一阶段的分析之后,我确定了我的开发课题为图书仓库管理。现在所要做的是要准确定义系统必须做什么以及系统必须具备的功能。

软件需求分析中我采用结构化分析方法(structured analysis,简称sa),sa是面向数据流进行需求分析的方法,像所有的软件分析方法(如面向对象分析方法、idef方法等等)一样,sa也是一种建模活动,它使用简单易读的符号,根据软件内部数据传递、变换的关系,自顶向下逐层分解,描绘满足功能要求的软件模型。

在系统中我采用数据流图(dfd)这种半形式化的描述方式表达需求。它是一种功能模型,以图形的方式描绘数据在系统中流动和处理的过程,只反映系统必须完成的逻辑功能。它有四种基本图形符号:

:箭头,表示数据流;

〇:圆或椭圆,表示加工;

:双杠,表示数据存储;

:方框,表示数据的源点或终点。

为了表达较为复杂问题的数据处理过程,用一张数据流图是不够的,要按照问题的层次结构进行逐步分解,并以一套分层的数据流图反映这种结构关系。在这里我一共使用了三层数据流图,即顶层图,0层图和1层图(也是底层图)。

在多层数据流图中,顶层流图仅包含一个加工,它代表被开发系统,它的输入流是该系统的输入数据了,输出流是该系统的输出数据;底层流图是指其加工不需要再做分解的数据流图,中间层流图表示对其上层父图的细化,它的每一步加工可能继续细化成子图。

经过对系统的分析首先得到系统的顶层dfd,如下: 一步细化得到系统的0层dfd,如下:

再进一步细化每一个数据加工功能,得到系统的1层dfd图。

在这里只给出有关入库管理和出库管理的1层数据流图,它们是系统的关鍵部分,也是主要的部分。通过以上对数据流图的分析之后,我们已大体地了解了系统的功能和目标,接下来所要做的就是系统功能模块的划分和数据库的设计,也就是系统的概要设计。

§4.2   系统概要设计

在软件需求分析阶段,搞清楚了软件“做什么”的问题,形成了目标系统的逻辑模型。现在我们所要做的就是要把软件“做什么”的逻辑模型变换为“怎么做”的物理模型,即着手实现软件的需求。首先,我们需要描述的是系统的总的体系结构。

4.2.1  系统结构设计

系统的概要设计中最重要的就是系统的模块化。模块化是指解决一个复杂问题时自项向下逐层把软件系统划分成若干个模块的过程。每个模块完成一个特定的功能,所有的模块按某种方法组织起来,成为一个整体,完成整个系统所要求的功能。

 将系统划分为多个模块是为了降低软件系统的复杂性,提高可读性、可维护性,但模块的划分不能是任意的,应尽量保持其独立性。也就是说,每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单,即尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。

在系统的概要设计中我采用结构化设计(structure design,简称sd),sd以需求分析阶段产生的数据流图dfd为基础,按一定的步骤映射成软件结构。我首先将整个系统化分为几个小问题,小模块,在系统中,我设计了用户管理、库存管理、入库管理、出库管理、员工管理和供应商管理6个小模块。然后,进一步细分模块,添加细节。比如,用户管理我又将其分为用户注册、用户注销、密码修改;库存管理分为库存记录查询、库存记录修改、库存记录打印等等。

以下就是系统的结构图:(在这里为了表达方便我将结构图分开来表达。)

    在得到系统的第一层功能模块图后,经过进一步地细化,得一系统的子功能模块图:

4.2.2  数据库设计

在信息世界中,信息从客观事物出发流经数据库,通过决策机构最后又回到客观世界,信息的这一循环经历了三个领域:信息世界,数据世界,现实世界。现实世界的事物反映到人的头脑中,人的大脑对它有个认识过程,经过分析(选择、命名、分类等)进入信息世界。这些信息再进一步加工、编码,然后进数据世界,而软件系统的开发工作需要考虑这两个方面的问题,也就是要考虑系统开发所需要的数据,以及如何对这些数据进行操作。这两个问题贯穿了整个软件系统的开发过程,这也就是数据库的设计问题,软件设计的一个核心。

4.2.2.1  er图设计

在系统设计的开始,我首先考虑的是如何用数据模型来数据库的结构与语义,以对现实世界进行抽象。目前广泛使用的数据模型可分为两种类型,一种是独立于计算机系统的“概念数据模型”,如“实体联系模型”;另一种是直接面向数据库逻辑结构的“结构数据模型”。在本系统中我采用“实体联系模型”(er模型)来描述数据库的结构与语义,以对现实世界进行第一次抽象。er模型直接从现实世界抽象出实体类型及实体间联系,然后用er图来表示数据模型。它有两个明显的优点:接近于人的思维,容易理解;与计算机无关,用户容易接受。但er模型只能说明实体间语义的联系,不能进一步说明详细的数据结构,它只是数据库设计的第一步。

er图是直观表示概念模型的工具,它有四个基本成分:

矩形框,表示实体类型(考虑问题的对象)。

菱形框,表示联系类型(实体间的联系)。

椭圆形框,表示实体类型和联系类型的属性。对于关键码的属性,在属性名下划一横线。

直线,联系类型与其涉及的实体类型之间以直线连接。

本系统为图书仓库管理,主要管理图书的入库、出库以及库存等事项。仓库根据需要可以查询图书供应商的信息,同时还需要了解在入库和出库中员工的参与情况。依据仓库管理的实际情况,考虑了多方面的因素以后,确定系统的er图如下:

(为了表达的方便,在这里我没有在一张图上表达出所有的关系,而是用一张总体er图,和几张实体属性关系图来表达数据库的结构。)

在该数据库中,我设计了三个实体,分别是库存、员工和供应商以及两个联系类型入库和出库。在本系统中库存是核心,也是基本,没有了库存其它的也就没有什么意义了。员工记录的添加是考虑到责任问题,也就是说,在仓库管理的实际运用中,出现了责任不清的现象,特别是由于仓库的进出图书数量都比较大时产生了一系列问题,所以在设计数据库时,我特别考虑到这一点,加入了员工记录这一实体。供应商信息的添加主要出于对图书来源问题的思考。通过添加供应商信息可以比较清楚地了解图书的进货渠道,从图书的质量到供应商的信誉都可以进行了解,同时可以为以后的图书进购提供一定有用的信息。

入库联系类型将库存信息、供应商信息和员工信息联系在一起,可以方便地实现三个实体之间的联接,而出库联系类型则将库存信息和员工信息较好地联接起,同时这两个联系类型又都具有各自特有的属性。

下面就是各实体及联系类型的属性图:(带#号的属性为关键字段)4.2.2.2  数据库表格设计

在完成系统的er图之后,需要将er模型转化为关系模型,也就是说,要设计出数据库所需要的表格。在这里,我选用的是关系数据库。因为关系数据库中的二维表格可以很清楚地描述数据之间的联系。

在这里不得不提到一个概念——范式。其实在上一节的er图设计中,已经运用了范式的思想,不仅如此,在数据库的表格设计中更离不开范式的思想,它是数据库设计的基础,如果不注意这个问题将会导致一系列问题的出现。

我在系统中定义的表格都严格地按照范式的思想和要求去完成,数据库中的所有表格都达到了三范式的要求。根据系统er图,针对本系统的特点,在对所搜集的数据进行规范化之后,定义了如下六张表格,分别是库存信息表,入库信息表,出库信息表,员工信息表,供应商信息表和密码信息表。通过对这六张表格的操作可以较好地完成系统设计的各项功能,六张表格之间有着不同程度的联系。(说明:在以下数据表中,k代表主键,#代表外键,字段值不为空。)

bookrecord 表(库存信息表)

 字段名称 数据类型 说明

k bookid 数字 图书编号

 bookname 文本 图书名

 author 文本 作者

 publisher 文本 出版社

 pubdate 日期/时间 出版日期

 price 货币 价格

 booktype 文本 图书类型

 number1 数字 库存数量

 addation 文本 备注

图4.13  库存信息表

库存信息表主要用于记录仓库中现存放的所有图书的详细信息,包括图书编号、书名、作者、出版社、图书类型等有关图书的各类信息,它即是该数据库的主表,也是系统主界面的主要内容。

在该表中图书编号是主键,它按图书入库的先后次序来编写,每当有图书入库,系统自动给出图书编号,这样我们按图书编号来查找图书是比较方便的。考虑到编号比较难于记忆,所以使用了出版社和图书类型两个字段,在系统中我提供了出版社和图书类型的分类查找,而且全部采用自动生成,每当系统中有新的出版社类型和图书类型,弹出菜单会自动添中新类型,这样就可以比较方便地实现按出版社和按图书类型查找。此外,库存数量也是一个比较关键的字段,该字段是在系统初始化时就给定的,每当有图书入库或出库操作,系统就会自动修改图书的库存数量,以保持数据的一致性。做为备注有一点说明,我的数据库中备注的数据类型是文本,而不是备注类型,主要考虑到该字段的长度并不大,而且在delphi中文本数据类型的处理也比较方便一点。

employee 表(员工信息表)

 字段名称 数据类型 说明

k employeeid 数字 员工编号

 employeename 文本 员工姓名

 sex 文本 性别

 borndate 日期/时间 出生日期

 grade 文本 职称

 workdate 日期/时间 工作日期

 telephone 文本 联系电话

 address 文本 联系地址

   图4.14  员工信息表

员工信息表主要用于记录有关员工的各类信息,包括姓名、职称、出生日期、联系电话、联系地址等。它主要用来为系统提供员工的有关信息,因为在系统中,入库和出库操作均与员工有着一定的联系,在查询入库信息和出库信息时,有时需要查找有关此项记录有关的员工信息,在系统中我是通过入库记录与员工记录(出库记录和员工记录)之间的联接查询来完成的。另外,作为一个仓库也有必要了解其所属员工的一些基本情况,以便查询。

shopkeeper 表(供应商信息表)

 字段名称 数据类型 说明

k shopkeeperid 数字 供应商编号

 shopkeepername 文本 供应商姓名

 address 文本 地址

 postno 数字 邮编

 officephone 文本 办公电话

 homephone 文本 住宅电话

 email 文本 e-mail

 paytype 文本 付款方式

   图4.15  供应商信息表

供应商信息表主要用于记录有关供应商的各类信息,包括姓名、地址、电话、付款方式等。它主要用来为系统提供供应商的有关信息,在系统中入库记录是与供应商记录相联系的,通过入库记录可以查找相关的供应商信息。在供应商信息中,考虑当实际情况,我特别加入了email和付款方式这两个字段,因为在当今信息世界中,多种多样的通讯方式和多种多样的付款方式是必然的,是数据库中必须与以记录。

inrecord 表(入库信息表)

 字段名称 数据类型 说明

k inid 数字 入库编号

# bookid 数字 图书编号

# employeeid 数字 员工编号

# shopkeeperid 数字 供应商编号

 number 数字 入库数量

 buydate 日期/时间 入库日期

  图4.16  入库信息表

outrecord 表(出库信息表)

 字段名称 数据类型 说明

k outid 数字 出库编号

# bookid 数字 图书编号

# employeeid 数字 员工编号

 number2 数字 出库数量

 outdate 日期/时间 出库日期

   图4.17  出库信息表

入库信息表主要用于记录有关入库的详细信息,包括入库数量、入库日期以及图书、员工、供应商三方的编号,以便查询。出库信息表主要用于记录有关出库的详细信息,包括出库数量、出库日期以及图书、员工的编号。出库信息表和入库信息表一样,其实它们都属于联系类型,系统通过这两个表可以联接上其它的表为用户提供多种条件的联接查询。值得提出的一点是入库记录和出库记录的添加不仅仅是单表操作,由于它们都与库存记录相联系,所以,无论您是添中入库记录还是添加出库记录,都必须同时修改库存记录,以保持数据的一致性,否则将引发系统出错而这些我都让其在系统中自动完成。无论您是添加入库记录,还是添加出库记录,系统都将自动修改库存中图书的数量,而且,在您出库的数量大于库存数量时,系统还会自动提示错误,这样就可以防止一定错误的发生。

在入库信息表和出库信息表中我还定义了几个外键,它提供了一种表示几个关系联系的方法。比如,系统中通过在入库信息表中定义的外键 bookid、employeeid和shopkeeperid可以将库存信息表、员工信息表和供应商信息表联系在一起,从而方便地实现联接查询,而且,引入外键的定义是实体完整性约束的一个主要方面。

key 表(密码信息表)

 字段名称 数据类型 说明

k keyname 文本 用户姓名

 keyno 文本 用户密码

图4.18  密码信息表

密码信息表主要用于记录所有的用户名和用户密码。它是在用户登陆时用来确定用户和密码的正确性,以防止非法用户登陆。

通过以上设计已经完成了系统的概要设计,当我们有了系统的功能模块图和数据库之后,就需要着手去实现每一个模块,为每一个功能设计程序流程图,这也就是系统的详细设计。

§4.3   系统详细设计

在前面的概要设计中,已将系统划分为多个模块,并将它们按照一定的原则组装起来,同时确定了每个功能及模块之间的外部接口。现在所要做的就是确定每个模块具体执行过程,也可以说是“过程设计”。

在处理过程设计时我采用的是结构化程序设计(简称sp)方法。需要指出的是系统的详细设计并不是指具体的编程序,而是将概要设计阶段产生的系统功能模块图细化成很容易产生程序的图纸。因此详细设计的结果基本决定了最终程序的质量。为软件的质量,延长软件的生存期,软件的可测试性、可维护性提供重要的保障。详细设计的目标不仅是逻辑上正确地实现每个模块的功能,还应使设计出的处理过程清晰易读。

由前一阶段产生的系统功能模块图,我为系统的主要部分设计了如下程序流程图:通过以上步骤,基本上完成了对整个系统的总体设计,接下来所要做的就是软件的编码工作。系统总体设计的好坏直接影响着下一步工作,只有在这一阶段设计出好的模块图和程序流程图,才能更有利于编码,产生好的软件系统。

第五章   系统应用程序设计

§5.1  系统窗体模块组成

§5.2  数据模块窗体的设置

在编写数据库应用程序时,经常要遇到这样的情况,即好多组件、窗体同时访问相同的数据源,如果为每一个组件或者窗体都设置一个数据源将是十分耗时的工件,而且要保证这些数据源的确是相同的也需花一番功夫。那么,能不能将这些数据源集中管理,最好是做成一个统一的模块,需要时就将该模块引入而不必直接操作数据源本身呢?数据模块(datamodule)是解决这个问题最好的答案。简单说来,数据模块是用来集中管理数据源的一个窗体,该窗体可被需要的地方随时引入。

图5.2给出了本程序的数据模块(datamoduleform)窗体图,除报表窗体外所有的数据存取组件和数据源组件都在此数据模块中进行了定义。值得一提的是,设置了数据库database组件,该组件引入了系统所需的唯一的数据库tsxs,database组件的databasename属性设置为tsckgl。tsxs数据库已在odbc配置程序中进行了设置。其他的数据存取组件都是基于此数据库组件创建的,这样做的好处是,当数据库的别名或者其他信息改变之后,只需修改tdatabase组件的aliasname属性即可。

另外,在本系统的数据模块窗体图中,我大多采用的aodquery组件而没有采用bde组,这主要是基于对ado组件的了解。在delphi的学习中我对ado组件了解的更加清楚,使用也较bde更为熟练,而且,ado组件的功能也较bde更为强大,所以在这里大多采用ado组件来进行数据库联接。同时我也使用了bde组件中的table,因为在某些时候bde有着其自身特有的优越性。  主窗体功能模块的实现                          

file://主窗体程序代码

public      file://在程序的起始部分,定义快捷按钮点击事件

procedure popup1handler(sender:tobject);

procedure popup2handler(sender:tobject);

**********************************************************************

procedure tmainform.popup1handler(sender: tobject);

begin       file://快捷按钮1(点“按出版社分类”按钮产生)的点击事件

with datamoduleform.mainquery do    

begin     file://打开数据模块窗体的mainquery,对bookrecord表进行操作

close;     file://关闭mainquery

sql.clear;      file://清除sql属性中的sql命令语句

sql.add(‘select * from bookrecord where publisher=:pub‘); file://添加新的sql语句

parameters.parambyname(‘pub‘).value:=(sender as tmenuitem).caption;

open;      file://重新打开mainquery

end;

end;

**********************************************************************

procedure tmainform.speedbutton1click(sender: tobject);

var s1,s2,s3,s4,s5 :string;     file://设立5个变量以方便实现模糊查询

begin      file://主窗口库存查询按钮事件

with datamoduleform.mainquery do

begin

close;

sql.clear;

sql.add(‘select * from bookrecord‘);

sql.add(‘where bookid like :bookid and bookname like :name and author like :author and publisher like :pub and booktype like :booktype‘);

           file://使用like语句来实现模糊查询

if edit1.text<>‘‘  then  s1:=‘%‘+edit1.text+‘%‘   else  s1:=‘%‘;

parameters.parambyname(‘bookid‘).value:=s1;         file://给变量s1赋值

if edit2.text<>‘‘  then  s2:=‘%‘+edit2.text+‘%‘   else  s2:=‘%‘;

parameters.parambyname(‘name‘).value:=s2;           file://给变量s2赋值

if edit3.text<>‘‘  then  s3:=‘%‘+edit3.text+‘%‘   else  s3:=‘%‘;

parameters.parambyname(‘author‘).value:=s3;          file://给变量s2赋值

if edit4.text<>‘‘  then  s4:=‘%‘+edit4.text+‘%‘   else  s4:=‘%‘;

parameters.parambyname(‘pub‘).value:=s4;             file://给变量s2赋值

if edit5.text <>‘‘  then  s5:=‘%‘+edit5.text+‘%‘   else  s5:=‘%‘;

parameters.parambyname(‘booktype‘).value:=s5;        file://给变量s2赋值

open;

if fieldvalues[‘bookid‘]=null         file://判断是否找到记录

then  begin

messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit4.text:=‘‘;edit5.text:=‘‘;

close;

sql.clear;

sql.add(‘select * from bookrecord‘);     file://这里相当于一个刷新功能

open;

end;end;

end;

**********************************************************************

procedure tmainform.speedbutton3click(sender: tobject);

begin         file://库存表刷新按钮事件

with datamoduleform.mainquery do

begin

close;

sql.clear;

sql.add(‘select * from bookrecord‘);

open;

end;  

end;

**********************************************************************

procedure tmainform.speedbutton11click(sender: tobject);

var popupitem:tmenuitem;

begin         file://自动生成快捷按钮1的内容

with datamoduleform.bookquery do

begin         file://从数据库中选择出版社类型

close;

sql.clear;

sql.add(‘select distinct publisher from bookrecord‘);

open;

popupmenu1:=tpopupmenu.create(self);  file://自动生成快捷菜单

popupmenu1.autohotkeys:=mamanual;    file://自定义热键

while not eof do

begin           file://根据出版社内容生成菜单子项

popupitem:=tmenuitem.create(self);

popupitem.caption:=fieldbyname(‘publisher‘).asstring;

popupmenu1.items.add(popupitem);

popupitem.onclick:=popup1handler;     file://确定菜单子项的点击事件

next;

end;  end;

popupmenu1.popup(384,67);      file://在指定位置显示快捷菜单1

end;

**********************************************************************

procedure tmainform.formactivate(sender: tobject);

begin      file://系统初始化,在进入mainform时自动添加数据源

mainform.dbgrid1.datasource:=datamoduleform.mainsource;

mainform.dbnavigator1.datasource:=datamoduleform.mainsource;

mainform.dbgrid2.datasource:=datamoduleform.empsource;

mainform.dbnavigator2.datasource:=datamoduleform.empsource;

mainform.dbgrid3.datasource:=datamoduleform.shopsource;

mainform.dbnavigator3.datasource:=datamoduleform.shopsource;

mainform.dbgrid4.datasource:=datamoduleform.insource;

mainform.dbnavigator4.datasource:=datamoduleform.insource;

mainform.dbgrid5.datasource:=datamoduleform.outsource;

mainform.dbnavigator5.datasource:=datamoduleform.outsource;

end;

**********************************************************************

procedure tmainform.formcreate(sender: tobject);

begin     file://系统初始化,定义界面大小,以适应不同分辩率

width:=800;height:=600;

end;

**********************************************************************

procedure tmainform.timer1timer(sender: tobject);

begin         file://在状态栏显示时间

statusbar1.panels[2].text:=datetostr(date);

statusbar1.panels[4].text:=timetostr(time);

end;

§5.4  入库、出库窗体模块的实现

 

                      图5.4  系统入库管理窗体

 

                          图5.5  系统出库管理窗体

procedure tinoutform.speedbutton4click(sender: tobject);

begin           file://入库管理查找按钮事件

  with datamoduleform.bookquery do    file://入库查询处理

  begin

    close;

    sql.clear;

    sql.add(‘select * from bookrecord where bookid=:bookid‘);

    parameters.parambyname(‘bookid‘).value:=edit13.text;

    open;

    if fieldvalues[‘bookid‘]<>null

then

begin

      edit1.text:=‘‘;

      edit1.readonly:=true;edit1.color:=clmenu;

      edit6.text:=fieldvalues[‘bookname‘];  file://显示图书名

edit6.readonly:=true;edit6.color:=clmenu;   file://设置显示框不可更改属性

      edit7.text:=fieldvalues[‘author‘];

      edit7.readonly:=true;edit7.color:=clmenu;

      edit8.text:=fieldvalues[‘publisher‘];

      edit8.readonly:=true;edit8.color:=clmenu;

      edit9.text:=fieldvalues[‘pubdate‘];

      edit9.readonly:=true;edit9.color:=clmenu;

      edit10.text:=fieldvalues[‘price‘];

      edit10.readonly:=true;edit10.color:=clmenu;

      edit11.text:=fieldvalues[‘booktype‘];

      edit11.readonly:=true;edit11.color:=clmenu;

      edit12.text:=fieldvalues[‘number1‘];

      edit12.readonly:=true;edit12.color:=clmenu;

      if  fieldvalues[‘addation‘]<>null

then edit25.text:=fieldvalues[‘addation‘]

      else edit25.text:=‘‘;

      edit25.readonly:=true;edit25.color:=clmenu;

      end

      else

      begin    file://在没有查找到的情况下,清空所有显示框

      edit1.readonly:=false;edit1.text:=‘‘;edit1.color:=clmenu;

      edit6.readonly:=false;edit6.text:=‘‘;edit6.color:=clmenu;

      edit7.readonly:=false;edit7.text:=‘‘;edit7.color:=clmenu;

      edit8.readonly:=false;edit8.text:=‘‘;edit8.color:=clmenu;

      edit9.readonly:=false;edit9.text:=‘‘;edit9.color:=clmenu;

      edit10.readonly:=false;edit10.text:=‘‘;edit10.color:=clmenu;

      edit11.readonly:=false;edit11.text:=‘‘;edit11.color:=clmenu;

      edit12.readonly:=false;edit12.text:=‘‘;edit12.color:=clmenu;

      edit25.readonly:=false;edit25.text:=‘‘;edit25.color:=clmenu;

      messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

      edit13.text:=‘‘;edit13.setfocus;

      end;

  end;

with datamoduleform.inquery do   file://自动入库编号的获取

  begin

    close;

    sql.clear;

    sql.add(‘select * from inrecord where inid>=all(select inid from inrecord)‘);

    open;            file://找到入库编号中最大的一个

    edit26.readonly:=false;

    edit26.text:=fieldvalues[‘inid‘]+1;  file://最大的入库编号加1形成新的入库编号

    edit26.readonly:=true;edit26.color:=clmenu;  file://设置编号的不可更改性

  end;

end;

**********************************************************************

procedure tinoutform.speedbutton1click(sender: tobject);

var s:integer;

begin            file://入库管理添加按钮事件

  if edit1.text<>null

  then messagedlg(‘请输入完整的入库信息和图书信息,然后单击确定按钮。‘,

mtinformation,[mbok],0)

  else  begin

    if (edit2.text=‘‘) or (edit3.text=‘‘) or (edit4.text=‘‘) or (edit5.text=‘‘)

    then  begin

      messagedlg(‘请输入完整的入库信息!‘,mtinformation,[mbok],0);

      edit2.setfocus;

    end

    else  begin

      with datamoduleform.inquery do    file://将找到的图书信息显示

      begin

      close;

      sql.clear;

sql.add(‘insert into inrecord values(:inid,:bookid,:empid,:shopid,

:number,:indate)‘);   file://向入库信息表中插入记录

      parameters.parambyname(‘inid‘).value:=edit26.text;  file://向edit框取值

      parameters.parambyname(‘bookid‘).value:=edit13.text;

      parameters.parambyname(‘empid‘).value:=edit2.text;

      parameters.parambyname(‘shopid‘).value:=edit3.text;

      parameters.parambyname(‘number‘).value:=edit4.text;

      parameters.parambyname(‘indate‘).value:=edit5.text;

      execsql;

      end;

      edit12.readonly:=false;

      s:=strtoint(edit12.text)+strtoint(edit4.text);  file://计算入库后库存图书数量

      edit12.text:=inttostr(s);    file://将修改后的库存图书数量显示

      edit12.readonly:=true;

      with datamoduleform.bookquery do     file://修改库存记录中图书数量

      begin

      close;

      sql.clear;

      sql.add(‘update bookrecord set number1=:number where

bookid=:bookid‘);

      parameters.parambyname(‘number‘).value:=s;

      parameters.parambyname(‘bookid‘).value:=edit13.text;

      execsql;         file://提交sql语句

      messagedlg(‘记录已成功添加!‘,mtinformation,[mbok],0);

      edit13.setfocus;

      end;

    end;

  end;

end;

**********************************************************************

procedure tinoutform.speedbutton2click(sender: tobject);

begin          file://入库管理确定按钮事件

  if (edit2.text=‘‘) or (edit3.text=‘‘) or (edit4.text=‘‘) or (edit5.text=‘‘)

     or (edit6.text=‘‘) or (edit7.text=‘‘) or (edit8.text=‘‘) or (edit9.text=‘‘)

     or (edit10.text=‘‘) or (edit11.text=‘‘) or (edit25.text=‘‘)

  then  begin          file://判断输入信息的完整性

  messagedlg(‘请输入所需的全部入库信息!‘,mtinformation,[mbok],0);

edit2.setfocus;

end

  else

  begin

    with datamoduleform.inquery do    file://入库信息添加

    begin

    close;

    sql.clear;

sql.add(‘insert into inrecord values(:inid,:bookid,:empid,:shopid,

:number,:indate)‘);      file://向入库信息表中插入记录

    parameters.parambyname(‘inid‘).value:=edit26.text;

    parameters.parambyname(‘bookid‘).value:=edit1.text;

    parameters.parambyname(‘empid‘).value:=edit2.text;

    parameters.parambyname(‘shopid‘).value:=edit3.text;

    parameters.parambyname(‘number‘).value:=edit4.text;

    parameters.parambyname(‘indate‘).value:=edit5.text;

    execsql;

    end;

    with datamoduleform.bookquery do

    begin

     close;

     sql.clear;        file://在完成入库信息的添加后,修改库存记录

sql.add(‘insert into bookrecord values(:bookid,:bookname,:author,

:publisher,:pubdate,:price,:booktype,:number,:addration)‘);

     parameters.parambyname(‘bookid‘).value:=edit1.text;

     parameters.parambyname(‘bookname‘).value:=edit6.text;

     parameters.parambyname(‘author‘).value:=edit7.text;

     parameters.parambyname(‘publisher‘).value:=edit8.text;

     parameters.parambyname(‘pubdate‘).value:=edit9.text;

     parameters.parambyname(‘price‘).value:=edit10.text;

     parameters.parambyname(‘booktype‘).value:=edit11.text;

     parameters.parambyname(‘number‘).value:=edit4.text;

     parameters.parambyname(‘addration‘).value:=edit25.text;

     execsql;

    end;

    messagedlg(‘记录添加成功!‘,mtinformation,[mbok],0);

  end;

end;

**********************************************************************

procedure tinoutform.speedbutton11click(sender: tobject);

begin           file://新书入库按钮事件

  edit13.text:=‘‘;edit13.color:=clmenu;

  with datamoduleform.inquery do   file://自动入库编号的获取

  begin

  close;

  sql.clear;

  sql.add(‘select * from inrecord where inid>=all(select inid from inrecord)‘);

  open;

  edit26.text:=fieldvalues[‘inid‘]+1;

  edit26.readonly:=true;edit26.color:=clmenu;

  end;

  with datamoduleform.bookquery do    file://自动图书编号的获取

  begin

  close;

    sql.clear;

    sql.add(‘select * from bookrecord where bookid>=all(select bookid from bookrecord)‘);     file://找到库存图书编号中最大的一个

    open;

    edit1.readonly:=false;

    edit1.text:=fieldvalues[‘bookid‘]+1;   file://显示自动生成的图书编号

    edit1.readonly:=true;edit1.color:=clmenu;

  end;

  edit2.text:=‘‘;edit3.text:=‘‘;edit4.text:=‘‘;edit5.text:=‘‘;

  edit6.readonly:=false;edit6.text:=‘‘;edit6.color:=clwindow;

  edit7.readonly:=false;edit7.text:=‘‘;edit7.color:=clwindow;

  edit8.readonly:=false;edit8.text:=‘‘;edit8.color:=clwindow;

  edit9.readonly:=false;edit9.text:=‘‘;edit9.color:=clwindow;

  edit10.readonly:=false;edit10.text:=‘‘;edit10.color:=clwindow;

  edit11.readonly:=false;edit11.text:=‘‘;edit11.color:=clwindow;

  edit12.readonly:=false;edit12.text:=‘‘;edit12.color:=clmenu;

  edit25.readonly:=false;edit25.text:=‘‘;edit25.color:=clwindow;

end;

procedure tinoutform.speedbutton22click(sender: tobject);

var s:integer;

begin            file://出库管理确定按钮事件

if (edit24.text=‘‘) or (edit27.text=‘‘) or (edit28.text=‘‘)

then begin

messagedlg(‘请输入完整的出库信息!‘,mtinformation,[mbok],0);

edit24.setfocus;

   end

else begin

if edit27.text>edit21.text    file://检查出库数量是否小于库存数量

then begin

messagedlg(‘库存中的图书数量不够!‘,mtinformation,[mbok],0);

edit27.text:=‘‘;edit27.setfocus;

     end

else begin

  with datamoduleform.outquery do

  begin

  close;

  sql.clear;

sql.add(‘insert into outrecord values(:outid,:bookid,:empid,

:number,:outtime)‘);    file://添加出库记录

parameters.parambyname(‘outid‘).value:=edit23.text;

parameters.parambyname(‘bookid‘).value:=edit14.text;

parameters.parambyname(‘empid‘).value:=edit24.text;

parameters.parambyname(‘number‘).value:=edit27.text;

parameters.parambyname(‘outtime‘).value:=edit28.text;

execsql;

end;

edit21.readonly:=false;

s:=strtoint(edit21.text)-strtoint(edit27.text);  file://计算出库后库存图书数量

edit21.text:=inttostr(s);    file://显示出库后库存图书数量

edit21.readonly:=true;

with datamoduleform.bookquery do

begin      file://修改库存图书数量

close;

sql.clear;

sql.add(‘update bookrecord set number1=:number where bookid=:bookid‘);

parameters.parambyname(‘number‘).value:=s;

parameters.parambyname(‘bookid‘).value:=edit14.text;

execsql;

end;

messagedlg(‘出库记录添加成功!‘,mtinformation,[mbok],0);

edit14.text:=‘‘;edit14.setfocus;

end;

end;

end;       

§5.5  查询功能的实现

    查询功能包括员工信息查询,供应商信息查询,入库信息查询和出库信息查询。由于每一个功能的实现都差不太多,而且其窗体也差不太多,所以在这里只给出员工信息查询窗体及其源代码。

           

                      图5.6  员工信息查询窗体

procedure tfindempform.speedbutton1click(sender: tobject);

var s1,s2,s3 :string;

begin          file://员工记录查询窗体查找按钮事件

with datamoduleform.empquery do

begin

close;

sql.clear;

sql.add(‘select * from employee‘);

sql.add(‘where employeeid like :empid and employeename like :name and grade like :grade‘);         file://实现模糊查询功能

if edit1.text<>‘‘  then  s1:=‘%‘+edit1.text+‘%‘  else  s1:=‘%‘;

parameters.parambyname(‘empid‘).value:=s1;

if edit2.text<>‘‘ then  s2:=‘%‘+edit2.text+‘%‘   else  s2:=‘%‘;

parameters.parambyname(‘name‘).value:=s2;

if edit3.text<>‘‘  then  s3:=‘%‘+edit3.text+‘%‘  else  s3:=‘%‘;

parameters.parambyname(‘grade‘).value:=s3;

open;

if fieldvalues[‘employeeid‘]<>null

then  findempform.close      file://在找到记录的情况下关闭查找窗口

else

begin

messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

close;  sql.clear;

sql.add(‘select * from employee‘);    file://刷新员工信息窗口

open;

end; end;

end;

§5.6  系统登陆窗体模块的实现

由于系统登陆窗体中有一幅彩图,在这里不便给出,而只给出了系统的实现。

var  keyname: string;   file://定义了一个全局变量,在key2中有调用

procedure tkeyform.speedbutton1click(sender: tobject);

var s:string;              file://登陆窗口登陆按钮事件

begin

if  (edit1.text=‘‘)  then  begin

messagedlg(‘清输入登陆姓名和密码!‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

datamoduleform.keytable.active:=true;

if not datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

            file://判断登陆名是否存在

then begin

messagedlg(‘登陆名错误,请重新输入!‘,mtinformation,[mbok],0);

edit1.text:=‘‘; edit1.setfocus;

end

else begin

with datamoduleform.keyquery do

begin

close;  sql.clear;

sql.add(‘select * from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

open;

s:=fieldvalues[‘keyno‘];

end;

if s<>edit2.text   file://判断登陆密码是否正确

then begin

messagedlg(‘登陆密码错误,请重新输入!‘,mtinformation,[mbok],0);

edit2.text:=‘‘; edit2.setfocus;

end

else begin

keyname:=edit1.text;

keyform.hide;

mainform.show;mainform.windowstate:=wsmaximized;

end; end; end;

end;

§5.7  用户管理功能的实现

5.7.1   用户管理主窗体

           

                       图5.7  用户管理主窗体

5.7.2   密码修改窗体模块的实现

           

                        图5.8  密码修改窗体

procedure tkey2form.speedbutton1click(sender: tobject);

begin          file://密码修改窗口修改按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)or(edit3.text=‘‘)

then begin

messagedlg(‘请输入完整的信息。‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

if not datamoduleform.keytable.locate(‘keyno‘,edit1.text,[])

then begin

messagedlg(‘原密码输入错误,不能修改新密码!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end

else begin

if edit2.text<>edit3.text

then begin

messagedlg(‘两次密码输入不同,请重新输入新密码!‘,mtinformation,[mbok],0);

edit2.text:=‘‘;edit3.text:=‘‘;edit2.setfocus;

end

else begin         file://在数据库中修改密码

with datamoduleform.keyquery do

begin

close;   sql.clear;

sql.add(‘update key set keyno=:keyno where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=keyname;

parameters.parambyname(‘keyno‘).value:=edit2.text;

execsql;

messagedlg(‘密码修改成功!‘,mtinformation,[mbok],0);

key2form.close;

end; end; end; end;

end;

5.7.3   用户注册窗体模块的实现

           

                         图5.9  用户注册窗体

procedure tkey3form.speedbutton1click(sender: tobject);

begin        file://用户注删窗口注删按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)or(edit3.text=‘‘)

then begin

messagedlg(‘请输入完整的信息!‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

if datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

       file://判断用户名是否存在,系统不允许用户名重复

then begin

messagedlg(‘用户名已存在,请输入新的用户名和密码!‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end

else begin

if edit2.text<>edit3.text

then begin

messagedlg(‘您输入的两个密码不相同,请重新输入!‘,mtinformation,[mbok],0);

edit2.text:=‘‘;edit3.text:=‘‘;edit2.setfocus;

end

else begin

with datamoduleform.keyquery do     file://在数据库中添加该用户

begin

close;

sql.clear;

sql.add(‘insert into key values(:keyname,:keyno)‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

parameters.parambyname(‘keyno‘).value:=edit2.text;

execsql;

end;

messagedlg(‘新用户添加成功,您可以继续添加用户,或按“取消”退出。‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end; end; end;

end;

5.7.4   用户注销窗体模块的实现

           

                         图5.10  用户注销窗体

procedure tkey4form.speedbutton1click(sender: tobject);

var s:string;

begin        file://用户注销窗口注销按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)

then messagedlg(‘请输入完整的信息!‘,mtinformation,[mbok],0)

else begin

if not datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

      file://判断用户名是否存在,用户名必须存在,才可以删除

then begin

messagedlg(‘您所输入的用户名不存在,请重新输入或按“取消”退出。‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit1.setfocus;

end

else begin

with datamoduleform.keyquery do

begin

close;

sql.clear;

sql.add(‘select * from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

open;

s:=fieldvalues[‘keyno‘];

end;

if s<>edit2.text  file://判断该用户名下的密码是否正确

then begin

messagedlg(‘您所输入的密码不正确,请重新输入或按“取消”退出。‘,

mtinformation,[mbok],0);

edit2.text:=‘‘;edit2.setfocus;

end

else begin        file://从数据库中删除该用户

with datamoduleform.keyquery do

begin

close;

sql.clear;

sql.add(‘delete from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

execsql;

end;

messagedlg(‘用户已成功删除,您可以继续删除用户,或按“取消”退出。‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit1.setfocus;

end; end; end;

end;

 

                        结束语

本系统是一个面向小型图书企业,具有一定实用性的数据库信息管理系统。它主要完成对图书仓库的一系列管理,包括入库、出库、库存以及员工和供应商信息管理。本系统采用当前流行的面向对象的开发工具—delphi来完成整个系统的设计,在数据库的设计上利用了access的便利性和实用性。

本系统具有相当的实用功能。在查询方面,系统实现了多条件任意字段的模糊查询,同时在分类查询上实现了动态生成,系统可以自动识别用户不同的输入。在图书入库、出库和库存三者之间建立了良好的链接关系,某一部分地修改均会自动引发系统对与其相关的部分进行连锁修改。在用户管理方面,系统较好地实现了用户注册,用户注销和密码修改等各项功能。

系统在设计过程中不可避免地遇到了各种各样的问题,由于整个系统完全都是由个人设计的,有关delphi许多细节问题都要靠自己去摸索,加之本人水平有限,并没有完全地理解delphi的强大功能,而且还存在着许多不足之处。如:

 受开发条件和开发时间的限制,本系统只利用了本地数据库access,它同应用程序处于同一系统中,能存储的数据量也有一定限制,并没有发挥出delphi其数据库方面的优势;

 报表打印功能尚不够全面完善,不能实现动态报表;

 在一些数据输入时没有及时的进行数据格式校验,不能保证数据输入的绝对正确性。

 由于时间关系,系统功能实现不够完善,使用不是很方便,比如,没有实现多条记录的连锁删除和添加以及数据的导入功能。

这些都是需要完善的地方,该系统离实际使用也还有相当的距离,需要我进行不断地补充和完善。

通过本次毕业设计我学到了不少新的东西,也发现了大量的问题,有些在设计过程中已经解决,有些还有待今后慢慢学习。只要学习就会有更多的问题,有更多的难点,但也会有更多的收获。

 考 文 献

[1] 郑荣贵、黄平、谷会东,delphi 6.0数据库开发与应用,中科多媒体电子出版社,2002

[2] 伍俊良,delphi 6控件应用实例教程,北京希望电子出版社,2002

[3] 卢国俊,delphi 6数据库开发,电子工业出版社,2002

第12篇

本系统主要完成对图书仓库的库存管理,包括图书入库、出库、库存,员工信息,供应商信息以及密码管理等六个方面。系统可以完成对各类信息的浏览、查询、添加、删除、修改、报表等功能。

系统的核心是入库、库存和出库三者之间的联系,每一个表的修改都将联动的影响其它的表,当完成入库或出库操作时系统会自动地完成库存的修改。查询功能也是系统的核心之一,在系统中即有单条件查询和多条件查询,也有精确查询和模糊查询,系统不仅有静态的条件查询,也有动态生成的条件查询,其目的都是为了方便用户使用。系统有完整的用户添加、删除和密码修改功能,并具备报表打印功能。

系统采用microsoft office中的access 2000来设计数据库,并使用当前优秀的开发工具—delphi 6.0 ,它有着最为灵活的数据库结构,对数据库应用有着良好的支持。

论文主要介绍了本课题的开发背景,所要完成的功能和开发的过程。重点的说明了系统设计的重点、设计思想、难点技术和解决方案。

关键字:数据库,sql语言,delph 6,数据库组件,仓库管理

目 录

第一章 引言 ……………………………………………………………………………1

1.1 课题来源 ……………………………………………………………………1

1.2 开发工具的选择 ……………………………………………………………2

1.3 所做的主要工作 ……………………………………………………………3

第二章 数据库概论 ……………………………………………………………………4

2.1 数据库的发展 ………………………………………………………………4

2.1.1 数据库的发展 …………………………………………………………4

2.1.2 数据库阶段的特点 ……………………………………………………5

2.1.3 数据库技术 ……………………………………………………………6

2.2 数据库理论基础 ……………………………………………………………7

2.2.1 数据库模型 ……………………………………………………………7

2.2.2 数据库体系结构 ……………………………………………………10

2.2.3 数据的独立性 ………………………………………………………11

2.2.4 范式 …………………………………………………………………11

2.3 sql语言基础 ……………………………………………………………13

2.3.1 sql简介 ……………………………………………………………13

2.3.2 sql查询 ……………………………………………………………13

2.3.3 sql数据更新 ………………………………………………………14

第三章数据库开发工具 ……………………………………………………………16

3.1 delphi 6.0 简介 ……………………………………………………………16

3.2 delphi 6.0 控件 ……………………………………………………………17

3.2.1 ado数据访问组件 …………………………………………………17

3.2.2 数据控制类datacontrol ……………………………………………18

3.2.3 数据访问类dataaccess ……………………………………………18

3.2.4 sql语言在delphi中的应用 ………………………………………19

3.3 access 简介 ………………………………………………………………21

第四章 系统总体设计 ………………………………………………………………23

4.1 系统需求分析 ……………………………………………………………23

4.2 系统概要设计 ……………………………………………………………25

4.2.1 系统结构设计 ………………………………………………………25

4.2.2 数据库设计 …………………………………………………………27

4.2.2.1 er图设计 ……………………………………………………27

4.2.2.2 数据库表格设计………………………………………………29

4.3系统详细设计………………………………………………………………34

第五章 系统应用程序设计 …………………………………………………………37

5.1 系统窗体模块组成…………………………………………………………37

5.2 数据模块窗体设置…………………………………………………………38

5.3 主窗体功能模块的实现……………………………………………………39

5.4 入库、出库窗体模块的实现………………………………………………43

5.5 查询功能的实现……………………………………………………………51

5.6 系统登陆窗体模块的实现…………………………………………………52

5.7 用户管理功能的实现………………………………………………………54

5.7.1 用户管理主窗体 ……………………………………………………54

5.7.2 密码修改窗体模块的实现 …………………………………………54

5.7.3 用户注册窗体模块的实现 …………………………………………55

5.7.4 用户注销窗体模块的实现 …………………………………………57

结束语 …………………………………………………………………………………59

致谢 ……………………………………………………………………………………60

参考文献 ………………………………………………………………………………61

第一章 引 言

§1.1 课题来源

随着社会经济的迅速发展和科学技术的全面进步,计算机事业的飞速发展,以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期。随着经济文化水平的显著提高,人们对生活质量及工作环境的要求也越来越高。书籍做为人类的精神食粮,在现代社会中越来越受到重视,大量的书籍出现在市场上,人们有了各种各样不同的选择。与此同时,为了管理大量的图书,图书仓库也大量的出现,仓库的管理问题也就提上了日程。随着图书的大量增加,其管理难度也越来越大,如何优化仓库的日常管理也就成为了一个大众化的课题。

在计算机飞速发展的今天,将计算机这一信息处理利器应用于仓库的日常管理已是势必所然,而且这也将为仓库管理带来前所未有的改变,它可以带来意想不到的效益,同时也会为企业的飞速发展提供无限潜力。采用计算机管理信息系统已成为仓库管理科学化和现代化的重要标志,它给企业管理来了明显的经济效益和社会效益。主要体现在:

极大提高了仓库工作人员的工作效率,大大减少了以往入出存流程繁琐,杂乱,周期长的弊端。

基于仓库管理的全面自动化,可以减少入库管理、出库管理及库存管理中的漏洞,可以节约不少管理开支,增加企业收入。

仓库的管理的操作自动化和信息的电子化,全面提高了仓库的管理水平。

随着我国改革开放的不断深入,经济飞速的发展,企业要想生存、发展,要想在激烈的市场竞争中立于不败之地,没有现代化的管理是万万不行的,仓库管理的全面自动化、信息化则是其中极其重要的部分。为了加快仓库管理自动化的步伐,提高仓库的管理业务处理效率,建立仓库管理系统已变得十分心要。

入库、库存、出库还是现在企业图书仓库管理的常规基本模式,虽然,最近又出现了很多新的管理模式,如:基于零库存思想的沃尔玛特管理方式,但这些新的思想在

第二章 数据库概论

§2.1 数据库的发展

数据库处理在信息系统的研究中一直是非常重要的主题,然而,近年来,随着world wide web(/yingyongwengao/" target="_blank" title="">应用超越具有早期应用特点的简单的。同时,internet技术提供了一种向用户数据库内容的标准化的访问方法。这些技术没有脱离经典数据库技术的要求。它们只是加重了数据库技术的重要性。

数据库的设计和开发及包括艺术有包括工程。理解用户的需求,然后,把它们转变为有效的数据库设计是一个艺术过程。把设计转变为实际的数据库,并且这些数据库带有功能完备、高效能的应用,是一个工程过程。

数据库的目的是帮助人们跟踪事务。经典的数据库应用涉及诸如订单、顾客、工作、员工、学生、电话之类的项,或其它数据量较大、需要密起关注的事务。最近,由于数据库的普及,数据库技术已经被应用到了新的领域,诸如用于internet的数据库或用于公司内联网的数据库。数据库也被越来越多地应用于生成和维护多媒体应用程序上。

计算机的数据处理应用,首先要把大量的信息以数据形式存放在存储器中。存储器的容量、存储速率直接影响到数据管理技术的发展。从1956年生产出第一台计算机到现在,存储器的发展,为数据库技术提供了良好的物质基础。

使用计算机以后,数据处理的速度和规模,无论是相对于手工方式,还是机械方式,都有无可比拟的优势。通常在数据处理中,计算是比较简单的而数据的管理却比较复杂。数据管理是指数据的收集、整理、组织、存储、维护、检索、传送等操作,这部分操作是数据处理业务的基本环节,而且是任何数据处理业务中必不可少的共有部分。数据管理技术的优劣,将直接影响数据处理的效率。

2.1.1 数据库的发展

数据管理技术的发展,与硬件(主要是外存)、软件、计算机应用的范围有密切的联系。数据管理技术的发展经过三个阶段:人工管理阶段、文件系统阶段和数据库阶段。

人工管理阶段和文件系统阶段都有着相当多的缺陷,诸如数据冗余性 ,数据不一致性以及数据联系弱等等。也正是由于这些原因,促使人们研究新的数据管理技术,从而产生了数据库技术。

20世纪60年代末发生的三件大事,层次模型ims系统的推出、关于网状模型dbtg报告的发表以及关于关系模型论文的连续发表标志着数据管理技术进入数据库阶段。进入70年代以后,数据库技术得到迅速发展,开发了许多有效的产品并投入运行。数据库系统克服了文件系统的缺陷,提供了对数据更高级更有效的管理。

当进入数据库阶段后,随着数据管理规模一再扩大,数据量急剧增加,为了提高效率,开始时,人们只是对文件系统加以扩充,在应用文件中建立了许多辅助索引,形成倒排文件系统。但这并不能最终解决问题。在20世纪60年代末,磁盘技术取得重要进展,具有数百兆容量和快速存取的磁盘陆续进入市场,成本也不高,为数据库技术的产生提供了良好的物质条件。

2.1.2 数据库阶段的特点

(1)减少数据的重复(redundancy can be reduced)

当在一个非数据库系统当中,每一个应用程序都有属于他们自己的文件,由于无法有系统建立的数据,因此常常会造成存储数据的重复与浪费。例如:在一家公司当中,人事管理程序与工资管理程序或许都会使用到职员与部门的信息或文件,而我们可以运用数据库的方法,把这两个文件整理起来,以减少多余的数据,过度地占用存储空间。

(2)避免数据的不一致(inconsistency can avoid)

本项的特色,可以说是延伸前项的一个特点,要说明这样的一个现象,我们可以从下面这个实例来看:若是在同一家公司当中,职员甲在策划部门工作,且职员甲的记录同时被存放在数据库的两个地方,而数据库管理系统却没有对这样重要的情况加以控制,当其中一条数据库被修改时,便会造成数据的不一致,但是,对于一个健全的数据库管理系统而言,将会对这样的情况加以控制,但有时并不需要刻意消除这种情形,应当视该数据库的需求与效率来决定。

(3)数据共享(data shared)

对于数据共享的意义,并不是只有针对数据库设计的应用程序,可以使用数据库中的数据,对于其他撰写好的应用程序,同样可以对相同数据库当中的数据进行处理,进而达到数据共享的目的。

(4)强化数据的标准化(standard can be enforced)

由数据库管理系统,对数据做出统筹性的管理,对于数据的格式与一些存储上的标准进行控制,如此一来,对于不同的环境的数据交换(data interchange)上将有很大的帮助,也能提高数据处理的效率。

(5)实践安全性的管理(security restriction can be applied)

通过对数据库完整的权限控制,数据库管理者可以确认所有可供用户存取数据的合法途径渠道,并且可以事先对一些较重要或关键性的数据进行安全检查,以确保数据存取时,能够将任何不当损毁的情形降至最低。

(6)完整性的维护(integrity can be maintained)

所谓完整性的问题,就是要确认某条数据在数据库当中,是正确无误的。正如(2)所述,若是无法控制数据的不一致性,便会产生完整性不足的问题,所以,我们会发现,当数据重复性高的时候,数据不完整的情形也会增加,当然,若是数据库的功能完整,将会大大地提高数据完整性,也会增加数据库的维护能力与维护简便性。

(7)需求冲突会获得平衡(conflicting requirements can be balance)

在一个较大型的企业当中,用户不同的需求,往往会造成系统或数据库在设计上的困扰,但是一个合适的数据库系统,可以通过数据库管理员的管理,将会有效地整理各方面的信息,对于一些较重要的应用程序,可以适时地提供较快速的数据存取方法与格式,以平衡多个用户在需求上的冲突。

上述七个方面构成了数据库系统的主要特征。这个阶段的程序和数据间的联系可用下图表示: 2.1.3 数据库技术

从文件系统发展到数据库系统是信息处理领域的一个重大变化。在文件系统阶段,人们关注的中心问题是系统功能的设计,因而程序设计处于主导地位,数据只起着服从程序需要的作用。在数据库方式下,信息处理观念已为新体系所取代,数据占据了中心位置。数据结构的设计成为信息系统首先关心的问题,而利用这些数据的应用程序设计则退居到以既定的数据结构为基础的地位。

目前世界上已有数百万个数据库系统在运行,其应用已经深入到人类社会生活的各个领域,从企业管理、银行业务、资源分配、经济预测一直到信息检索、档案管理、普查统计等。并在通信网络基础上,建立了许多国际性的联机检索系统。我国20世纪90年代初在全国范围内装备了12个以数据库技术为基础的大型计算机系统,这些系分布在邮电、计委、银行、电力、铁路、气象、民航、情报、公安、军事、航天和财税等行业。

数据库技术还在不断的发展,并且不断地与其它计算机技术相互渗透。数据库技术与网络通信技术相结合,产生了分布式数据库系统。数据库技术与面向对象技术相结合,产生了面向对象数据库系统。

在数据库技术中有四个名词,其概念应该分清。

(1)数据库(database,db):db是统一管理的相关数据的集合。db能为各种用户共享,具有最小冗余度,数据间联系密切,而又有较高的数据独立性。

(2)数据库管理系统(database management system,dbms):dbms是位于用户与操作系统之间的一层数据管理软件,为用户或应用程序提供访问db的方法,包括db的建立、查询、更新及各种数据控制。dbms总是基于某种数据模型,可以分为层次型、网状型、关系型和面向对象型dbms。

(3)数据库系统(database system,dbs):dbs是实现有组织地、动态地存储大量关联数据,方便多用户访问的计算机软件、硬件和数据资源组成的系统,即采用了数据库技术的计算机系统。

(4)数据库技术:这是一门研究数据库的结构、存储、管理和使用的软件学科。数据库技术是操作系统的文件系统基础上发展起来的。而dbms本身要在操作系统的支持下才能工作。数据库不仅用到数据结构的知识,而且丰富了数据结构的内容。在关系数据库中要用到集合论、数理逻辑的理论。因此,数据库技术是一门综合性较强的学科。

§2.2数据库理论基础

2.2.1 数据库模型

从20世纪50年代中期开始,计算机的应用由科学研究部门逐步扩展到企业、行政部门。至60年代,数据处理成为计算机的主要应用。数据库技术作为数据管理技术,是计算机软件领域的一个重要分支,产生于60年代末。现已形成相当规模的理论体系和实用技术。

模型是对现实世界的抽象。在数据库技术中,我们用模型的概念描述数据库的结构与语义,对现实世界进行抽象,表示实体类型及实体间联系的模型称为“数据模型” 。

目前广泛作用的数据模型可分为两种类型。

一种是独立于计算机系统的模型,完全不涉及信息在系统中的表示,只是用来描述某个特定组织所关心的信息结构,这类模型称为“概念数据模型” 。要领模型用于建立信息世界的数据模型,强调其语义表达功能,应该概念简单、清晰,易于用户理解,它是现实世界的第一层抽象,是用户和数据库设计人员之间进行交流的工具。这一其中著名的模型是“实体联系模型” 。

另一种数据模型是直接面向数据库的逻辑结构,它是现实世界的第二层抽象。 这类模型涉及到计算机系统和数据库管理系统,又称为“结构数据模型” 。例如,层次、网状、关系、面向对象等模型。这类模型有严格的形式化定义,以便于在计算机系统中实现。

(1)层次模型。用树型结构表示实体类型及实体间联系的数据模型。树的结点是记录类型,每个非根结点有且只有一个父结点。上一层记录类型和下一层记录类型间联系是1∶n联系。

层次模型的特点是记录之间的联系通过指针实现,查询效率较高。但层次模型有两个缺点:一是只能表示1∶n联系,虽然有多种辅助手段实现了m∶n联系,但都较复杂,用户不易掌握,二是由于树型结构层次顺序的严格和复杂,引起数据的查询和更新操作也很复杂,因此,编写应用程序也很复杂。

(2)网状模型。用有向图结构表示实体类型及实体间联系的数据模型。。1969年dbtg报告提出的数据模型是网状模型的主要代表。有向图中的结点是记录类型,有向边表示从箭尾一端的记录类型到箭头一端的记录类型间联系是1∶n联系。

网状模型的特点:记录之间联系通过指针实现,m∶n联系也容易实现(每个m∶n联系可拆成两个1∶n联系),查询效率较高。网状模型的缺点是编写应用程序比较复杂,程序员必须熟悉数据库的逻辑结构。由于层次系统和网状系统的应用程序编制比较复杂,因此,从20世纪80年代中期起,其市场已被关系系统所取代。但是使用这两种模型建立起的许多数据库仍然在正常运转,只是在外层加了个关系数据库语言的接口。网状模型有许多成功的产品,20世纪70年代的产品大部分网状系统,例如,honeywell公司的ids/ⅱ、hp公司的image/3000、burroughs公司的dmsⅱ、umivac公司的dms1100、cullinet公司的idms、cimcom公司的total等

(3)关系模型。关系模型的主要是用二维表格结构表达实体集,用外键表示实体间联系。关系模型是由若干个关系模式组成的集合。关系模式相当于前面提到的记录类型,它的实例称为关系,每个关系实际上是一张二维表格。

关系模型和层次、网状模型的最大判别是用关键码而不是用指针导航数据,表格简单用户易懂,编程时并不涉及存储结构,访问技术等细节。关系模型是数学化模型。sql语言是关系数据库的标准化语言,已得到了广泛的应用。20世纪70年代对关系数据库的研究主要集中在理论和实验系统的开发方面。80年代初才形成产品,但很快得到广泛的应用和普及,并最终取代了层次、网状数据库产品。现在市场上典型的关系dbms产品有db2、oracle、sybase、informix和微机型产品foxpro、access等。

关系模型和网状、层次模型的最大区别是:关系模型用表格数据而不是通过指针链来表示和实现实体间联系。关系模型的数据结构简单、易懂。只需用简单的查询语句就可对数据库进行操作。

关系模型是数学化的模型,可把表格看成一个集合,因此集合论、数理逻辑等知识可引入到关系模型中来。关系模型已是一个成熟的有前途的模型,已得到广泛应用。

(4)面向对象模型。目前,关系数据库的使用已相当普遍,但是,现实世界中仍然存在着许多含有复杂数据结构的应用领域,例如,cad数据、图形数据等,而关系模型在这方面的处理能力就显得力不从心。因此,人们需要更高级的数据库技术来表达这类信息。面向对象的概念最早出现在程序设计语言中,随后迅速渗透到计算机领域的每一个分支。面向对象数据库是面向对象概念与数据库技术相结合的产物。

面向对象模型能完整地描述现实世界的数据结构,具有丰富的表达能力,但模型相对较复杂,涉及的知识面也广,因此面向对象数据库尚未达到关系数据库那样的普及程度。

2.2.2 数据库体系结构

数据库的体系结构分三级:内部级(internal),概念级(conceptual)和外部级(external)。这个三级结构有时也称为“三级模式结构”,或“数据抽象的三个级别”,最早是在1971年通过的dbtg报告中提出,后来收入在1975年的美国ansi/sparc报告中。虽然现在dbms的产品多种多样,在不同的操作系统支持下工作,但是大多数系统在总的体系结构上都具有三级模式的结构特征。从某个角度看到的数据特性称为“数据视图”(data view)。

外部级最接近用户,是单个用户所能看到的数据特性。单个用户使用的数据视图的描述称为“外模式”。

概念级涉及到所有用户的数据定义,是全局的数据视图。全局数据视图的描述称为“概念模式”。

内部级最接近于物理存储设备,涉及到实际数据存储的结构。物理存储数据视图的描述称为“内模式”。

数据库的三级模式结构是数据的三个抽象级别。它把数据的具体组织留给dbms去做,用户只要抽象地处理数据,而不必关心数据在计算机中的表示和存储,这样就减轻了用户使用系统的负担。

三级结构之间往往差别很大,为了实现这三个抽象级别的联系和转换,dbms在三级结构之间提供两个层次的映象(mappings):外模式/模式映象,模式/内模式映象。此处模式是概念模式的简称。

2.2.3 数据的独立性

由于数据库系统采用三级模式结构,因此系统具有数据独立性的特点。在数据库技术中,数据独立性是指应用程序和数据之间相互独立,不受影响。数据独立性分成物理数据独立性和逻辑数据独立性两级。

(1)物理数据独立性

如果数据库的内模式要进行修改,即数据库的存储设备和存储方法有所变化,那么模式/内模式映象也要进行相当的修改,使概念模式尽可能保持不变。也就是对内模式的修改尽量不影响概念模式,当然,对于外模式和应用程序的影响更小,这样,我们称数据库达到了物理数据独立性。

(2)逻辑数据独立性

如果数据库的概念模式要进行修改,譬如增加记录类型或增加数据项,那么外模式/模式映象也要进行相应的修改,使外模式尽可能保持不变。也就是对概念模式的修改尽量不影响外模式和应用程序,这样,我们称数据库达到了逻辑数据独立性。

现有关系系统产品均提供了较高的物理独立性,而对逻辑独立性的支持尚有欠缺,例如,对外模式的数据更新受到限制等。

2.2.4 范式

建立起一个良好的数据指标体系,是建立数据结构和数据库的最重要的一环。一个良好的数据指标体系是建立db的必要条件,但不是充分条件。我们完全可以认为所建指标体系中的一个指标类就是关系数据库中的一个基本表,而这个指标类下面的一个个具体指标就是这个基本表中的一个字段。但如果直接按照这种方式建库显然还不能算最佳。对于指标体系中数据的结构在建库前还必须进行规范化的重新组织。

在数据的规范化表达中,一般将一组相互关联的数据称为一个关系(relation),而在这个关系下的每个数据指标项则被称为数据元素(data element),这种关系落实到具体数据库上就是基本表,而数据元素就是基本表中的一个字段(field)。规范化表达还规定在每一个基本表中必须定义一个数据元素为关键字(key),它可以唯一地标识出该表中其它相关的数据元素。在规范化理论中表是二维的,它有如下四个性质:

在表中的任意一列上,数据项应属于同一个属性(如图中每一列都存放着不同合同记录的同一属性数据)。

表中所有行都是不相同的,不允许有重复组项出现(如图中每一行都是一个不同的合同记录)。

在表中,行的顺序无关紧要(如图中每行存的都是合同记录,至于先放哪一个合同都没关系)。

在表中,列的顺序无关紧要,但不能重复(如图中合同号和合同名谁先谁后都没关系,但二者不可重复或同名)。

在对表的形式进行了规范化定义后,数据结构还有五种规范化定义,定名为规范化模式,称为范式。在这五种范式中,一般只用前三种,对于常用系统就足够了。而且这五种范式是“向上兼容”的,即满足第五范式的数据结构自动满足一、二、三、四范式,满足第四范式的数据结构自动满足第一、二、三范式,……,依此类推。

第一范式(first normal form,简称1st nf)就是指在同一表中没有重复项出现,如果有则应将重复项去掉。这个去掉重复项的过程就称之为规范化处理。在本文所讨论的开发方法里,1st nf实际上是没有什么意义的。因为我们按规范化建立的指标体系和表的过程都自动保证了所有表都满足1st nf。

第二范式(second normal form,简称 2nd nf)是指每个表必须有一个(而且仅一个)数据元素为主关键字(primary key),其它数据元素与主关键字一一对应。例如,在图l9.7中如果我们将合同号定义为主关键字(其它数据元素中的记录数据都有可能重名,故不能作为主关键字),故只要知道了一个合同记录的合同号,就可以唯一地在同一行中找到该合同的任何一项具体信息。通常我们称这种关系为函数依赖(functional dependence)关系。即表中其它数据元素都依赖于主关键字,或称该数据元素唯一地被主关键字所标识。

第三范式(third normal form,简称 3rd nf)就是指表中的所有数据元素不但要能够唯一地被主关键字所标识,而且它们之间还必须相互独立,不存在其它的函数关系。也就是说对于一个满足了 2nd nf的数据结构来说,表中有可能存在某些数据元素依赖于其它非关键宇数据元素的现象,必须加以消除。

为防止数据库出现更新异常、插入异常、删除异常、数据冗余太大等现象,关系型数据库要尽量按关系规范化要求进行数据库设计。

§2.3 sql语言基础

2.3.1 sql简介

用户对数据库的使用,是通过数据库管理系统提供的语言来实现的。不同的数据库管理系统提供不同的数据库语言。关系数据库管理系统几乎都提供关系数据库标准语言——sql。

sql 的全称是structured query language,即结构化查询语言。sql语句可以从关系数据库中获得数据,也可以建立数据库、增加数据、修改数据。1986年ansi采用sql语言作为关系数据库系统的标准语言,后被国际化标准组织(iso)采纳为国际标准。sql语言使用方便、功能丰富、简洁易学,是操作数据库的工业标准语言,得到广泛地应用。例如关系数据库产品db2、oracle等都实现了sql语言。同时,其它数据库产品厂家也纷纷推出各自的支持sql的软件或者与sql的接口软件。这样sql语言很快被整个计算机界认可。

sql语言是一种非过程化语言,它一次处理一个记录集合,对数据提供自动导航。sql语言允许用户在高层的数据结构上工作,而不对单个记录进行操作。sql语言不要求用户指定数据的存取方法,而是使用查询优化器,由系统决定对指定数据存取的最快速手段。当设计者在关系表上定义了索引时,系统会自动利用索引进行快速检索,用户不需知道表上是否有索引或者有什么类型的索引等细节。

sql语言可以完成许多功能,例如:

查询数据

在数据库表格中插入、修改和删除记录

建立、修改和删除数据对象

控制对数据和数据对象的存取

确保数据库的一致性和完整性等

2.3.2 sql查询

数据查询是关系运算理论在sql语言中的主要体现,select 语句是sql查询的基本语句,当我们在对一个数据库进各种各样的操作时,使用的最多的就是数据查询,在以sql为基础的关系数据库中,使用的最多的就是select查询语句。

select语句的完整句法如下:

select 目标表的列名或列表达式序列

from 基本表和(或)视图序列

[where 行条件表达式]

[group by 列名序列]

[having 组条件表达式]

[order by列名 [asc│deac]…]

我在select语句中还使用了大量的保留字和通配符以进行各种各样的条件查询。在系统中有大量的查询按钮,其使用了大量的查询语句,而且这些查询语句大部分使用的是模糊查询,所以大量的使用了模式匹配符like(判断值是否与指定的字符通配格式相符)。在包含like的查询语句中可以使用两个通配符:%(百分号):与零个或多个字符组成的字符串匹配;_(下划线):与单个字符匹配。系统中的条件判断往往包含多个条件,这时就需要使用逻辑运算符not、and、or(用于多条件的逻辑连接),谓词all以及保留字distinct等等。做为select语句还有很多的使用方法,这里就不再叙述。

2.3.3 sql数据更新

使用数据库的目的是为了有效地管理数据,而数据的插入、删除和修改则是必不可少的一个功能。在本系统中就大量地使用了数据插入、删除和修改这三种操作,现做一个简单地介绍。

数据插入

往数据库的基本表中插入数据使用的是insert语句,其方式有两种:一种是元组值的插入,另一种是查询结果的插入。在本系统中使用的是前一种方式,其句法如下:

insert into 基本表名(列表名)values(元组值)

数据删除

往数据库的基本表中删除数据使用的是delete语句,其句法如下:

delete from 基本表名 [where 条件表达式]

在些作一点说明,删除语句实际上是“select * from 基本表名 [where 条件表达式]”和delete操作的结合,每找到一个元组,就把它删除。此外,delete语句只能从一个基本表中删除元组,where子句中条件可以嵌套,也可以是来自几个基本表的复合条件。

数据修改

当需要修改基本表中元组的某些列值时,可以用update语句实现,其句法如下:

update基本表名

set列名=值表达式[,列名=值表达式…]

[where条件表达式]

在delphi中使用sql语句是很方便的,一般来说,都是通过tquery组件来使用sql语言的。有一点要进行说明,虽然通过tquery组件来使用sql语言很方便,但考虑到自己对不同组件的理解程度、个人习惯以及其它各个方面,在本系统中我采用的是ado组件来对数据库进行操作。最简单的方法比如在tadoquery组件的sql属性中就可以键入sql语句,至于详细的使用方法在后面进行介绍。

第三章 数据库开发工具

§3.1 delphi 6.0 简介

delphi类可以粗略地分成两部分:一部分是组件类,这些组件类通常以某种方式出现在组件面板上,当用户从组件面板上点取一个类的图标后,在程序中就自动生成了该类的对象(非可视组件除外);另一部分是功能类,这此功能类的对象通常出现在程序代码中,起着不可代替的作用,但是这些功能类在组件面板上是找不到的。在delphi中,每一个类的祖先都是tobject类,整个类的层次结构就像一棵倒挂的树,在最顶层的树根即为tobject类。这样,按照面向对象编程的基本思想,就使得用户可用tobject类这个类型代替任何其它类的数据类型。实际上在delphi的类库中,tobject类派生出了为数相当众多的子类,它们形成了一个庞大的体系,通常情况下,如果不自行开发组件,就不必了解整个类的体系结构,只用到类层次树的叶结点就足够了。

凡是做过程序开发的人都知道从来没有单纯的数据应用程序,也就是说,数据库应用程序必须和用户界面(可以是图形界面,也可以是命令接口)元素相结合,只讲界面或只讲数据库本身都构不成数据库应用程序,因而用delphi 6.0开发数据库应用程序就隐含着界面开发。delphi6中的vcl组件可用图3-1来说明。组件在delphi程序的开发中是最显眼的角色。大家知道,在编写程序时一般都开始于在组件面板上选择组件并定义组件间的相互作用。但也有一些组件不在组件面板上,例如tform和tapplication(典型的非可视组件)。组件是tcomponents派生出来的子类,可以流的形式存放在dfm文件中,具有事件和publish属性。

窗口组件类是窗口化的可视化组件类,在delphi的类库中占有最大的份额。在实际编程中,窗口组件类的对象都有句柄,可以接受输入焦点和包含其它组件。

图形组件与窗口组件并列,是另一大类组件。图形组件不是基于窗口的,因而不能有窗口句柄,不能接受输入焦点和包含其它组件。从图8-43中可以看出,图形组件的基类是tgraphiccontrol,在实际编程中,它们必须寄生于它们的宿主——窗口组件类的对象,由它们的拥有者负责其显示,而且它们还能触发一些和鼠标活动相关的事件。图形控件最典型的例子是tlabel和tspeedbutton。由此可以看出图形组件的功能很弱,有读者会问图形组件的用处何在呢?其实使用图形组件的最大好处在于节省资源,正是因为它们的功能较弱,所以使用的系统资源就要少。在一个应用程序中,如果能在不影响其功能的前提下合理大量地使用图形组件,将会大减少程序对系统资源的消耗。

非可视组件是与可视组件相并列的另一类组件,非可视组件在程序运行中是不可见的(除各种对话框组件之外,事实上有人认为对话框组件不能归入非可视组件,应该是另一种介于可视与非可视之间的组件)。

§3.2 delphi 6.0 控件

用delphi6开发数据库应用,重点是和各种数据库组件打交道,当然也要使用其它的一些组件,现在就我在系统设计中所使用的重要组件给与简单介绍。

3.2.1 ado数据访问组件

ado数据对象(active data objects)实际是一种提供访问各种数据类型的链接机制。ado设计为一种极简单的格式,通过odbc的方法同数据库接口中,可以使用任何一种odbc数据源,即不止适合于sql server、oracle、access等数据库应用程序,也适合于excel表格、文本文件、图形文件和无格式的数据文件。ado是基于ole-db之上的技术,因此ado通过其内部的属性和方法提供统一的数据访问接口方法。ado使您的客户端应用程序能够通过ole db提供访问和操作在数据库服务器中的数据。ado支持用于建立c/s和web的应用程序的主要功能。其主要优点是易于使用、高速度、低内存支出和占用磁盘空间较少。ado同时具有远程数据服务(rds)功能,通过rds可以在一次往返过程中实现将数据从服务器移动到客户端应用程序和web页、在客户端对数据进行处然后将更新结果返回服务器的操作。

delphi 6.0继续对microsoft的ado访问能力的支持。这种能力是通过一组新组件实现的,这些组件是在企业版的ado组件页中,在组件面版的ado页上可以找到这些组件。利用在前面章节提到的tdataset抽象类,ado组件可以不通过bde而直接实现ado连接。这意味着只需要很少的代码就可以实现该连接并且性能得到提高。

利用ado数据访问组件,可以只使用ado结构与数据库取得联系并对其中的数据进行操作,而在这些过程中完全不需要使用bde。大多数的ado连接和数据集组件都是与基于bde的连接和数据集组件相类似的。tadoconnection组件与基于bde的应用程序中的tdatabase组件类似。tadotable与ttable,tadoquery与tquery,以及tadostoreproc和tstoredproc之间都具有这种类似的对应关系。使用这些ado组件的方式与我们常使用的数据访问组件(基于bde)都有许多相同之处。ttadodataset没有直接的bde对应组件,但它提供了许多与ttable和tquery相同的功能。同样,tadocommand也没有相对应的bde组件,它是在delphi/ado环境中完成特定功能的组件。delphi 6.0通过ado数据集访问组件,可以不借助bde数据引擎而是通过微软的oledb来访问更为广泛的数据库中的数据。ado数据集访问组件与常用的数据访问组件是并列的关系。

在系统中我主要使用的是adotablet和adoquery两个组件。

3.2.2 数据控制类datacontrol

数据控制类负责数据库数据的显示,并把用户对数据的修改传回。这里的绝大多数组件,如dbtext, dbedit, dbmemo, dbimage, dblistbox, dbcombobox, dbcheckbox, dbradiogroup, dblookuplistbox, dblookupcombox, dbctrgrid的功能和对应的非数据感知组件相同,如tedit框,tradiogroups单选按钮组等,只不过在显示数据库数据时要用而已。

在系统中主要使用数据网格控件dbgrid和数据库导航器控件dbnavigator。

3.2.3 数据访问类dataaccess

数据库应用系统中数据访问是一个首要问题,包括单用户和 c/s系统,都必须联系一些数据库和数据表文件。delphi 6 提供了专门用于数据访问的基类控件。主要包括数据源控件datasource、客户数据集控件clientdataset、数据集提供器控件datasetprovider等等。

tdatabase:当一个基于bde的数据库应用程序需要一个永久数据库连接时,需要定制向一个数据库服务器的连接时,需要事务控制和特殊的数据库别名时就得用到tdatabase对象。特别是当连接到一个远程的sql数据库服务器时,如果要利用bde进行数据库事务处理,那么,tdatabase对象的威力就体现出来了。在一个应用程序中为每一个数据库连接显示的声明tdatabase对象要根据需要而定,不是必需的。对一个数据库连接,如果没有显示的声明并实例化tdatabase对象,系统就会产生一个带有默认属性的tdatabase对象。

tdatasource对象用于在dataset对象(包括tquery,tstoredproc,ttable等)和数据感知组件之间提供一个连接的纽带,以便在窗体上显示数据库中的数据,在数据库中导航定位与编辑数据集中的数据。如果一个dataset对象中的数据想在数据感知组件中显示和修改,它就必须和tdatasource对象相联系。同样,一个数据感知组件如果想和数据源相联系以便显示和操纵数据,就必须以tdatasource对象为中介。

用delphi6作数据库应用开发概括来说如下:先利用数据存取组件和实际的数据库建立连接,并用tsession对象和tdatabase对象管理这些连接。然后以tdatasource对象为中介,用数据感知组件向用户显示数据库的内容并接受用户的查询和修改等操作。

3.2.4 sql语言在delphi中的应用

在delphi中使用sql语言非常方便,一般来说,都是通过tquery组件来使用sql语言的。可以在tquery组件的sql属性中设置sql语句。设计程序时,在该组件的属性对话框中选择sql属性,单击带省略号的按钮,就可以打开string list editor对话框,然后我们就可以在对话框中添加sql语句。还可以使用delphi的sql builder来自动生成sql语句,这样可以避免手工编写sql而可能造成的语法错误。

静态sql语句在程序设计时便已固定下来,它不包含任何参数和变量。

动态sql语句,也被称作参数化的语句,在其中间包含着表示字段名或表名的参数,例如下面的语句是一条动态sql语句:

select * from students where studentcode =: studentcode;

其中的变量studentcode便是一个参数变量,它由一个冒号引导,在程序运行过程中,必须要为该参数赋值,该条sql语句才能正确执行,每次运行应用程序时可以为该参数变量赋予不同的值。为参数赋值有三种方法:

①根据参数在sql语句中出现的顺序,设置tquery部件的params属性值为参数赋值。

②直接根据sql语句中各参数的名字,调用parambyname方法来为各参数赋值。

③将tquery部件的datasource属性设置为另一个数据源,这样将另一个数据源中与当前tquery部件的sql语句中的参数名相匹配的字段值赋给其对应的参数。利用这种方法也能实现所谓的连接查询,创建主要—明细型数据库应用。

在程序运行过程中,要想设置tquery部件的sql属性,必须首先调用close方法,关闭tquery部件,然后再调用clear方法清除sql属性中现存的sql命令语句, 最后再调用add方法为sql属性设置新的sql命令语句。例如:

query1.close {关闭query1)

query1.sql.clear {清除sql属性中的sql命令语句}

query1.sql.add(‘select * from students‘);

query1.sql.add(‘ where name ="lucy" ‘);

在为tquery部件设置sql属性时调用close方法总是很安全的,如果tquery部件已经被关闭了,调用close方法时不会产生任何影响。在应用程序中为sql属性设置新的sql 命令语句时,必须要调用clear方法以清除sql属性中现存的sql命令语句,如果不调用clear方法,便调用add方法向sql属性中设置sql命令语句,那么新设置的sql命令语句会追加在现存sql命令语句后面, 在程序运行时常常会出现出乎意料的查询结果甚至程序无法运行下去。

在这里要特别注意的,一般情况下tquery部件的sql属性只能包含一条完整的sql语句,它不允许被设置成多条sql语句。当然有些数据库服务器也支持在tquery部件的sql属性中设置多条sql语句,只要数据库服务器允许这样,我们在编程时可以为 sql 属性设置多条sql语句。

在为tquery部件设置完sql属性的属性值之后,也即编写好适当的sql程序之后,可以有多种方式来执行sql程序。

在设计过程中,设置完tquery部件的sql属性之后将其active属性的值置为true, 这样便可以执行sql属性中的sql程序,如果应用中有与tquery部件相连的数据浏览部件( 如tddgrid tdbedit等)那么在这些数据浏览部件中会显示sql程序的执行结果。

在应用程序运行过程中,通过程序调用tquery部件的open方法或execsql 方法可以执行其sql属性中的sql程序。open方法和execsql方法是不一样的。open方法只能用来执行sql语言的查询语句(select命令), 并返回一个查询结果集,而execsql方法还可以用来执行其它常用的sql语句(如insert, update, delete等命令),例如:

query1.open (这样会返回一个查询结果集)

如果调用open方法,而没有查询结果时,会出错。此时应该调用execsql 方法来代替open方法。如:

query1.execsql (没有返回结果)

当然在设计应用程序时,程序设计人员是无法确定tquery部件中的sql 语句是否会返回一个查询结果的。对于这种情况应当用try…except模块来设计程序。在 try 部分调用open方法,而在except部分调用excesql方法,这样才能保证程序的正确运行。

delphi中用adoquery来使用sql语句同样十分方便。在adoquery组件中首先通过connectionstring属性值来联接数据源,然后就通过双击sql…属性值来写入sql语句。在delphi中调用数据库,就可以调用adoquery组件,通过修改其中的sql…属性中的sql语句来实现对数据库的各项操作。

值得注意的是,adoquery组件只有在激活的情况下才可以被正确地使用,这样就提出了一个问题,也就是说,在每次修改adoquery组件的sql…属性时都必须先行进行关闭,待清除掉sql…中所有的sql语句后才可以添加新的sql语句。而且,在每一次修改完成以后,还应该记得重新将adoquery激活。其它的使用方法与ttquery有许多的相似之处。

§3.3 access 简介

建立一个数据库我们有多种选择,现在市场上有各种各样的数据库,而且每一种数据库都有其自身的特点,不能说哪一种更好,只能在其中寻找一种能更好地适应系统需求、更好地满足用户的要求以及适应开发人员的习惯。在本系统中,做为图书仓库管理系统是一个比较小的应用系统,它所产生和处理的数据量也比较小。因此,没有必要使用像sql server和oracle这样的大型数据库。我首先想到的数据库是borland公司的paradox数据库。另外,microsoft office中的access数据库在计算机上的应用比较普及,是开发小型数据库系统的比较理想的选择,所以,在本系统中我选择了access数据库。

access做为一个数据库管理系统,它被集成在microsoft office中。access数据库处理的基本结构,采取关系型数据库模式。与其他的数据库系统相比,access更加简单易学,一个普通的计算机用户可以很快地掌握它。access 2000的功能十分强大,利用它可以方便地实现对信息保存、维护、查询、统计、打印、交流、,而且它可以十分方便地与office其他组件交流数据,这些功能对一个一般用户而言已经足够了。

第四章 系统总体设计

软件系统的总体设计大约要经历可行性分析和项目开发计划,需求分析,概要设计,详细设计,编码,测试以及维护等七个阶段。可行性分析和项目开发计划在前面已经叙述,下面所要做的是进行软件需求分析,概要设计和详细设计。编码过程将在下一节论述,而测试和维护过程不在本文叙及。

§4.1 系统需求分析

在经过前一阶段的分析之后,我确定了我的开发课题为图书仓库管理。现在所要做的是要准确定义系统必须做什么以及系统必须具备的功能。

软件需求分析中我采用结构化分析方法(structured analysis,简称sa),sa是面向数据流进行需求分析的方法,像所有的软件分析方法(如面向对象分析方法、idef方法等等)一样,sa也是一种建模活动,它使用简单易读的符号,根据软件内部数据传递、变换的关系,自顶向下逐层分解,描绘满足功能要求的软件模型。

在系统中我采用数据流图(dfd)这种半形式化的描述方式表达需求。它是一种功能模型,以图形的方式描绘数据在系统中流动和处理的过程,只反映系统必须完成的逻辑功能。它有四种基本图形符号:

:箭头,表示数据流;

?:圆或椭圆,表示加工;

?:双杠,表示数据存储;

:方框,表示数据的源点或终点。

为了表达较为复杂问题的数据处理过程,用一张数据流图是不够的,要按照问题的层次结构进行逐步分解,并以一套分层的数据流图反映这种结构关系。在这里我一共使用了三层数据流图,即顶层图,0层图和1层图(也是底层图)。

在多层数据流图中,顶层流图仅包含一个加工,它代表被开发系统,它的输入流是该系统的输入数据了,输出流是该系统的输出数据;底层流图是指其加工不需要再做分解的数据流图,中间层流图表示对其上层父图的细化,它的每一步加工可能继续细化成子图。

经过对系统的分析首先得到系统的顶层dfd,如下: 一步细化得到系统的0层dfd,如下:

再进一步细化每一个数据加工功能,得到系统的1层dfd图。

在这里只给出有关入库管理和出库管理的1层数据流图,它们是系统的关?部分,也是主要的部分。通过以上对数据流图的分析之后,我们已大体地了解了系统的功能和目标,接下来所要做的就是系统功能模块的划分和数据库的设计,也就是系统的概要设计。

§4.2 系统概要设计

在软件需求分析阶段,搞清楚了软件“做什么”的问题,形成了目标系统的逻辑模型。现在我们所要做的就是要把软件“做什么”的逻辑模型变换为“怎么做”的物理模型,即着手实现软件的需求。首先,我们需要描述的是系统的总的体系结构。

4.2.1 系统结构设计

系统的概要设计中最重要的就是系统的模块化。模块化是指解决一个复杂问题时自项向下逐层把软件系统划分成若干个模块的过程。每个模块完成一个特定的功能,所有的模块按某种方法组织起来,成为一个整体,完成整个系统所要求的功能。

将系统划分为多个模块是为了降低软件系统的复杂性,提高可读性、可维护性,但模块的划分不能是任意的,应尽量保持其独立性。也就是说,每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单,即尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。

在系统的概要设计中我采用结构化设计(structure design,简称sd),sd以需求分析阶段产生的数据流图dfd为基础,按一定的步骤映射成软件结构。我首先将整个系统化分为几个小问题,小模块,在系统中,我设计了用户管理、库存管理、入库管理、出库管理、员工管理和供应商管理6个小模块。然后,进一步细分模块,添加细节。比如,用户管理我又将其分为用户注册、用户注销、密码修改;库存管理分为库存记录查询、库存记录修改、库存记录打印等等。

以下就是系统的结构图:(在这里为了表达方便我将结构图分开来表达。)

在得到系统的第一层功能模块图后,经过进一步地细化,得一系统的子功能模块图:

4.2.2 数据库设计

在信息世界中,信息从客观事物出发流经数据库,通过决策机构最后又回到客观世界,信息的这一循环经历了三个领域:信息世界,数据世界,现实世界。现实世界的事物反映到人的头脑中,人的大脑对它有个认识过程,经过分析(选择、命名、分类等)进入信息世界。这些信息再进一步加工、编码,然后进数据世界,而软件系统的开发工作需要考虑这两个方面的问题,也就是要考虑系统开发所需要的数据,以及如何对这些数据进行操作。这两个问题贯穿了整个软件系统的开发过程,这也就是数据库的设计问题,软件设计的一个核心。

4.2.2.1 er图设计

在系统设计的开始,我首先考虑的是如何用数据模型来数据库的结构与语义,以对现实世界进行抽象。目前广泛使用的数据模型可分为两种类型,一种是独立于计算机系统的“概念数据模型”,如“实体联系模型”;另一种是直接面向数据库逻辑结构的“结构数据模型”。在本系统中我采用“实体联系模型”(er模型)来描述数据库的结构与语义,以对现实世界进行第一次抽象。er模型直接从现实世界抽象出实体类型及实体间联系,然后用er图来表示数据模型。它有两个明显的优点:接近于人的思维,容易理解;与计算机无关,用户容易接受。但er模型只能说明实体间语义的联系,不能进一步说明详细的数据结构,它只是数据库设计的第一步。

er图是直观表示概念模型的工具,它有四个基本成分:

矩形框,表示实体类型(考虑问题的对象)。

菱形框,表示联系类型(实体间的联系)。

椭圆形框,表示实体类型和联系类型的属性。对于关键码的属性,在属性名下划一横线。

直线,联系类型与其涉及的实体类型之间以直线连接。

本系统为图书仓库管理,主要管理图书的入库、出库以及库存等事项。仓库根据需要可以查询图书供应商的信息,同时还需要了解在入库和出库中员工的参与情况。依据仓库管理的实际情况,考虑了多方面的因素以后,确定系统的er图如下:

(为了表达的方便,在这里我没有在一张图上表达出所有的关系,而是用一张总体er图,和几张实体属性关系图来表达数据库的结构。)

在该数据库中,我设计了三个实体,分别是库存、员工和供应商以及两个联系类型入库和出库。在本系统中库存是核心,也是基本,没有了库存其它的也就没有什么意义了。员工记录的添加是考虑到责任问题,也就是说,在仓库管理的实际运用中,出现了责任不清的现象,特别是由于仓库的进出图书数量都比较大时产生了一系列问题,所以在设计数据库时,我特别考虑到这一点,加入了员工记录这一实体。供应商信息的添加主要出于对图书来源问题的思考。通过添加供应商信息可以比较清楚地了解图书的进货渠道,从图书的质量到供应商的信誉都可以进行了解,同时可以为以后的图书进购提供一定有用的信息。

入库联系类型将库存信息、供应商信息和员工信息联系在一起,可以方便地实现三个实体之间的联接,而出库联系类型则将库存信息和员工信息较好地联接起,同时这两个联系类型又都具有各自特有的属性。

下面就是各实体及联系类型的属性图:(带#号的属性为关键字段)4.2.2.2 数据库表格设计

在完成系统的er图之后,需要将er模型转化为关系模型,也就是说,要设计出数据库所需要的表格。在这里,我选用的是关系数据库。因为关系数据库中的二维表格可以很清楚地描述数据之间的联系。

在这里不得不提到一个概念——范式。其实在上一节的er图设计中,已经运用了范式的思想,不仅如此,在数据库的表格设计中更离不开范式的思想,它是数据库设计的基础,如果不注意这个问题将会导致一系列问题的出现。

我在系统中定义的表格都严格地按照范式的思想和要求去完成,数据库中的所有表格都达到了三范式的要求。根据系统er图,针对本系统的特点,在对所搜集的数据进行规范化之后,定义了如下六张表格,分别是库存信息表,入库信息表,出库信息表,员工信息表,供应商信息表和密码信息表。通过对这六张表格的操作可以较好地完成系统设计的各项功能,六张表格之间有着不同程度的联系。(说明:在以下数据表中,k代表主键,#代表外键,字段值不为空。)

bookrecord 表(库存信息表)

字段名称 数据类型 说明

k bookid 数字 图书编号

bookname 文本 图书名

author 文本 作者

publisher 文本 出版社

pubdate 日期/时间 出版日期

price 货币 价格

booktype 文本 图书类型

number1 数字 库存数量

addation 文本 备注

图4.13 库存信息表

库存信息表主要用于记录仓库中现存放的所有图书的详细信息,包括图书编号、书名、作者、出版社、图书类型等有关图书的各类信息,它即是该数据库的主表,也是系统主界面的主要内容。

在该表中图书编号是主键,它按图书入库的先后次序来编写,每当有图书入库,系统自动给出图书编号,这样我们按图书编号来查找图书是比较方便的。考虑到编号比较难于记忆,所以使用了出版社和图书类型两个字段,在系统中我提供了出版社和图书类型的分类查找,而且全部采用自动生成,每当系统中有新的出版社类型和图书类型,弹出菜单会自动添中新类型,这样就可以比较方便地实现按出版社和按图书类型查找。此外,库存数量也是一个比较关键的字段,该字段是在系统初始化时就给定的,每当有图书入库或出库操作,系统就会自动修改图书的库存数量,以保持数据的一致性。做为备注有一点说明,我的数据库中备注的数据类型是文本,而不是备注类型,主要考虑到该字段的长度并不大,而且在delphi中文本数据类型的处理也比较方便一点。

employee 表(员工信息表)

字段名称 数据类型 说明

k employeeid 数字 员工编号

employeename 文本 员工姓名

sex 文本 性别

borndate 日期/时间 出生日期

grade 文本 职称

workdate 日期/时间 工作日期

telephone 文本 联系电话

address 文本 联系地址

图4.14 员工信息表

员工信息表主要用于记录有关员工的各类信息,包括姓名、职称、出生日期、联系电话、联系地址等。它主要用来为系统提供员工的有关信息,因为在系统中,入库和出库操作均与员工有着一定的联系,在查询入库信息和出库信息时,有时需要查找有关此项记录有关的员工信息,在系统中我是通过入库记录与员工记录(出库记录和员工记录)之间的联接查询来完成的。另外,作为一个仓库也有必要了解其所属员工的一些基本情况,以便查询。

shopkeeper 表(供应商信息表)

字段名称 数据类型 说明

k shopkeeperid 数字 供应商编号

shopkeepername 文本 供应商姓名

address 文本 地址

postno 数字 邮编

officephone 文本 办公电话

homephone 文本 住宅电话

email 文本 e-mail

paytype 文本 付款方式

图4.15 供应商信息表

供应商信息表主要用于记录有关供应商的各类信息,包括姓名、地址、电话、付款方式等。它主要用来为系统提供供应商的有关信息,在系统中入库记录是与供应商记录相联系的,通过入库记录可以查找相关的供应商信息。在供应商信息中,考虑当实际情况,我特别加入了email和付款方式这两个字段,因为在当今信息世界中,多种多样的通讯方式和多种多样的付款方式是必然的,是数据库中必须与以记录。

inrecord 表(入库信息表)

字段名称 数据类型 说明

k inid 数字 入库编号

# bookid 数字 图书编号

# employeeid 数字 员工编号

# shopkeeperid 数字 供应商编号

number 数字 入库数量

buydate 日期/时间 入库日期

图4.16 入库信息表

outrecord 表(出库信息表)

字段名称 数据类型 说明

k outid 数字 出库编号

# bookid 数字 图书编号

# employeeid 数字 员工编号

number2 数字 出库数量

outdate 日期/时间 出库日期

图4.17 出库信息表

入库信息表主要用于记录有关入库的详细信息,包括入库数量、入库日期以及图书、员工、供应商三方的编号,以便查询。出库信息表主要用于记录有关出库的详细信息,包括出库数量、出库日期以及图书、员工的编号。出库信息表和入库信息表一样,其实它们都属于联系类型,系统通过这两个表可以联接上其它的表为用户提供多种条件的联接查询。值得提出的一点是入库记录和出库记录的添加不仅仅是单表操作,由于它们都与库存记录相联系,所以,无论您是添中入库记录还是添加出库记录,都必须同时修改库存记录,以保持数据的一致性,否则将引发系统出错而这些我都让其在系统中自动完成。无论您是添加入库记录,还是添加出库记录,系统都将自动修改库存中图书的数量,而且,在您出库的数量大于库存数量时,系统还会自动提示错误,这样就可以防止一定错误的发生。

在入库信息表和出库信息表中我还定义了几个外键,它提供了一种表示几个关系联系的方法。比如,系统中通过在入库信息表中定义的外键 bookid、employeeid和shopkeeperid可以将库存信息表、员工信息表和供应商信息表联系在一起,从而方便地实现联接查询,而且,引入外键的定义是实体完整性约束的一个主要方面。

key 表(密码信息表)

字段名称 数据类型 说明

k keyname 文本 用户姓名

keyno 文本 用户密码

图4.18 密码信息表

密码信息表主要用于记录所有的用户名和用户密码。它是在用户登陆时用来确定用户和密码的正确性,以防止非法用户登陆。

通过以上设计已经完成了系统的概要设计,当我们有了系统的功能模块图和数据库之后,就需要着手去实现每一个模块,为每一个功能设计程序流程图,这也就是系统的详细设计。

§4.3 系统详细设计

在前面的概要设计中,已将系统划分为多个模块,并将它们按照一定的原则组装起来,同时确定了每个功能及模块之间的外部接口。现在所要做的就是确定每个模块具体执行过程,也可以说是“过程设计”。

在处理过程设计时我采用的是结构化程序设计(简称sp)方法。需要指出的是系统的详细设计并不是指具体的编程序,而是将概要设计阶段产生的系统功能模块图细化成很容易产生程序的图纸。因此详细设计的结果基本决定了最终程序的质量。为软件的质量,延长软件的生存期,软件的可测试性、可维护性提供重要的保障。详细设计的目标不仅是逻辑上正确地实现每个模块的功能,还应使设计出的处理过程清晰易读。

由前一阶段产生的系统功能模块图,我为系统的主要部分设计了如下程序流程图:通过以上步骤,基本上完成了对整个系统的总体设计,接下来所要做的就是软件的编码工作。系统总体设计的好坏直接影响着下一步工作,只有在这一阶段设计出好的模块图和程序流程图,才能更有利于编码,产生好的软件系统。

第五章 系统应用程序设计

§5.1 系统窗体模块组成

§5.2 数据模块窗体的设置

在编写数据库应用程序时,经常要遇到这样的情况,即好多组件、窗体同时访问相同的数据源,如果为每一个组件或者窗体都设置一个数据源将是十分耗时的工件,而且要保证这些数据源的确是相同的也需花一番功夫。那么,能不能将这些数据源集中管理,最好是做成一个统一的模块,需要时就将该模块引入而不必直接操作数据源本身呢?数据模块(datamodule)是解决这个问题最好的答案。简单说来,数据模块是用来集中管理数据源的一个窗体,该窗体可被需要的地方随时引入。

图5.2给出了本程序的数据模块(datamoduleform)窗体图,除报表窗体外所有的数据存取组件和数据源组件都在此数据模块中进行了定义。值得一提的是,设置了数据库database组件,该组件引入了系统所需的唯一的数据库tsxs,database组件的databasename属性设置为tsckgl。tsxs数据库已在odbc配置程序中进行了设置。其他的数据存取组件都是基于此数据库组件创建的,这样做的好处是,当数据库的别名或者其他信息改变之后,只需修改tdatabase组件的aliasname属性即可。

另外,在本系统的数据模块窗体图中,我大多采用的aodquery组件而没有采用bde组,这主要是基于对ado组件的了解。在delphi的学习中我对ado组件了解的更加清楚,使用也较bde更为熟练,而且,ado组件的功能也较bde更为强大,所以在这里大多采用ado组件来进行数据库联接。同时我也使用了bde组件中的table,因为在某些时候bde有着其自身特有的优越性。 主窗体功能模块的实现

file://主窗体程序代码

public file://在程序的起始部分,定义快捷按钮点击事件

procedure popup1handler(sender:tobject);

procedure popup2handler(sender:tobject);

**********************************************************************

procedure tmainform.popup1handler(sender: tobject);

begin file://快捷按钮1(点“按出版社分类”按钮产生)的点击事件

with datamoduleform.mainquery do

begin file://打开数据模块窗体的mainquery,对bookrecord表进行操作

close; file://关闭mainquery

sql.clear; file://清除sql属性中的sql命令语句

sql.add(‘select * from bookrecord where publisher=:pub‘); file://添加新的sql语句

parameters.parambyname(‘pub‘).value:=(sender as tmenuitem).caption;

open; file://重新打开mainquery

end;

end;

**********************************************************************

procedure tmainform.speedbutton1click(sender: tobject);

var s1,s2,s3,s4,s5 :string; file://设立5个变量以方便实现模糊查询

begin file://主窗口库存查询按钮事件

with datamoduleform.mainquery do

begin

close;

sql.clear;

sql.add(‘select * from bookrecord‘);

sql.add(‘where bookid like :bookid and bookname like :name and author like :author and publisher like :pub and booktype like :booktype‘);

file://使用like语句来实现模糊查询

if edit1.text<>‘‘ then s1:=‘%‘+edit1.text+‘%‘ else s1:=‘%‘;

parameters.parambyname(‘bookid‘).value:=s1; file://给变量s1赋值

if edit2.text<>‘‘ then s2:=‘%‘+edit2.text+‘%‘ else s2:=‘%‘;

parameters.parambyname(‘name‘).value:=s2; file://给变量s2赋值

if edit3.text<>‘‘ then s3:=‘%‘+edit3.text+‘%‘ else s3:=‘%‘;

parameters.parambyname(‘author‘).value:=s3; file://给变量s2赋值

if edit4.text<>‘‘ then s4:=‘%‘+edit4.text+‘%‘ else s4:=‘%‘;

parameters.parambyname(‘pub‘).value:=s4; file://给变量s2赋值

if edit5.text <>‘‘ then s5:=‘%‘+edit5.text+‘%‘ else s5:=‘%‘;

parameters.parambyname(‘booktype‘).value:=s5; file://给变量s2赋值

open;

if fieldvalues[‘bookid‘]=null file://判断是否找到记录

then begin

messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit4.text:=‘‘;edit5.text:=‘‘;

close;

sql.clear;

sql.add(‘select * from bookrecord‘); file://这里相当于一个刷新功能

open;

end;end;

end;

**********************************************************************

procedure tmainform.speedbutton3click(sender: tobject);

begin file://库存表刷新按钮事件

with datamoduleform.mainquery do

begin

close;

sql.clear;

sql.add(‘select * from bookrecord‘);

open;

end;

end;

**********************************************************************

procedure tmainform.speedbutton11click(sender: tobject);

var popupitem:tmenuitem;

begin file://自动生成快捷按钮1的内容

with datamoduleform.bookquery do

begin file://从数据库中选择出版社类型

close;

sql.clear;

sql.add(‘select distinct publisher from bookrecord‘);

open;

popupmenu1:=tpopupmenu.create(self); file://自动生成快捷菜单

popupmenu1.autohotkeys:=mamanual; file://自定义热键

while not eof do

begin file://根据出版社内容生成菜单子项

popupitem:=tmenuitem.create(self);

popupitem.caption:=fieldbyname(‘publisher‘).asstring;

popupmenu1.items.add(popupitem);

popupitem.onclick:=popup1handler; file://确定菜单子项的点击事件

next;

end; end;

popupmenu1.popup(384,67); file://在指定位置显示快捷菜单1

end;

**********************************************************************

procedure tmainform.formactivate(sender: tobject);

begin file://系统初始化,在进入mainform时自动添加数据源

mainform.dbgrid1.datasource:=datamoduleform.mainsource;

mainform.dbnavigator1.datasource:=datamoduleform.mainsource;

mainform.dbgrid2.datasource:=datamoduleform.empsource;

mainform.dbnavigator2.datasource:=datamoduleform.empsource;

mainform.dbgrid3.datasource:=datamoduleform.shopsource;

mainform.dbnavigator3.datasource:=datamoduleform.shopsource;

mainform.dbgrid4.datasource:=datamoduleform.insource;

mainform.dbnavigator4.datasource:=datamoduleform.insource;

mainform.dbgrid5.datasource:=datamoduleform.outsource;

mainform.dbnavigator5.datasource:=datamoduleform.outsource;

end;

**********************************************************************

procedure tmainform.formcreate(sender: tobject);

begin file://系统初始化,定义界面大小,以适应不同分辩率

width:=800;height:=600;

end;

**********************************************************************

procedure tmainform.timer1timer(sender: tobject);

begin file://在状态栏显示时间

statusbar1.panels[2].text:=datetostr(date);

statusbar1.panels[4].text:=timetostr(time);

end;

§5.4 入库、出库窗体模块的实现

图5.4 系统入库管理窗体

图5.5 系统出库管理窗体

procedure tinoutform.speedbutton4click(sender: tobject);

begin file://入库管理查找按钮事件

with datamoduleform.bookquery do file://入库查询处理

begin

close;

sql.clear;

sql.add(‘select * from bookrecord where bookid=:bookid‘);

parameters.parambyname(‘bookid‘).value:=edit13.text;

open;

if fieldvalues[‘bookid‘]<>null

then

begin

edit1.text:=‘‘;

edit1.readonly:=true;edit1.color:=clmenu;

edit6.text:=fieldvalues[‘bookname‘]; file://显示图书名

edit6.readonly:=true;edit6.color:=clmenu; file://设置显示框不可更改属性

edit7.text:=fieldvalues[‘author‘];

edit7.readonly:=true;edit7.color:=clmenu;

edit8.text:=fieldvalues[‘publisher‘];

edit8.readonly:=true;edit8.color:=clmenu;

edit9.text:=fieldvalues[‘pubdate‘];

edit9.readonly:=true;edit9.color:=clmenu;

edit10.text:=fieldvalues[‘price‘];

edit10.readonly:=true;edit10.color:=clmenu;

edit11.text:=fieldvalues[‘booktype‘];

edit11.readonly:=true;edit11.color:=clmenu;

edit12.text:=fieldvalues[‘number1‘];

edit12.readonly:=true;edit12.color:=clmenu;

if fieldvalues[‘addation‘]<>null

then edit25.text:=fieldvalues[‘addation‘]

else edit25.text:=‘‘;

edit25.readonly:=true;edit25.color:=clmenu;

end

else

begin file://在没有查找到的情况下,清空所有显示框

edit1.readonly:=false;edit1.text:=‘‘;edit1.color:=clmenu;

edit6.readonly:=false;edit6.text:=‘‘;edit6.color:=clmenu;

edit7.readonly:=false;edit7.text:=‘‘;edit7.color:=clmenu;

edit8.readonly:=false;edit8.text:=‘‘;edit8.color:=clmenu;

edit9.readonly:=false;edit9.text:=‘‘;edit9.color:=clmenu;

edit10.readonly:=false;edit10.text:=‘‘;edit10.color:=clmenu;

edit11.readonly:=false;edit11.text:=‘‘;edit11.color:=clmenu;

edit12.readonly:=false;edit12.text:=‘‘;edit12.color:=clmenu;

edit25.readonly:=false;edit25.text:=‘‘;edit25.color:=clmenu;

messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

edit13.text:=‘‘;edit13.setfocus;

end;

end;

with datamoduleform.inquery do file://自动入库编号的获取

begin

close;

sql.clear;

sql.add(‘select * from inrecord where inid>=all(select inid from inrecord)‘);

open; file://找到入库编号中最大的一个

edit26.readonly:=false;

edit26.text:=fieldvalues[‘inid‘]+1; file://最大的入库编号加1形成新的入库编号

edit26.readonly:=true;edit26.color:=clmenu; file://设置编号的不可更改性

end;

end;

**********************************************************************

procedure tinoutform.speedbutton1click(sender: tobject);

var s:integer;

begin file://入库管理添加按钮事件

if edit1.text<>null

then messagedlg(‘请输入完整的入库信息和图书信息,然后单击确定按钮。‘,

mtinformation,[mbok],0)

else begin

if (edit2.text=‘‘) or (edit3.text=‘‘) or (edit4.text=‘‘) or (edit5.text=‘‘)

then begin

messagedlg(‘请输入完整的入库信息!‘,mtinformation,[mbok],0);

edit2.setfocus;

end

else begin

with datamoduleform.inquery do file://将找到的图书信息显示

begin

close;

sql.clear;

sql.add(‘insert into inrecord values(:inid,:bookid,:empid,:shopid,

:number,:indate)‘); file://向入库信息表中插入记录

parameters.parambyname(‘inid‘).value:=edit26.text; file://向edit框取值

parameters.parambyname(‘bookid‘).value:=edit13.text;

parameters.parambyname(‘empid‘).value:=edit2.text;

parameters.parambyname(‘shopid‘).value:=edit3.text;

parameters.parambyname(‘number‘).value:=edit4.text;

parameters.parambyname(‘indate‘).value:=edit5.text;

execsql;

end;

edit12.readonly:=false;

s:=strtoint(edit12.text)+strtoint(edit4.text); file://计算入库后库存图书数量

edit12.text:=inttostr(s); file://将修改后的库存图书数量显示

edit12.readonly:=true;

with datamoduleform.bookquery do file://修改库存记录中图书数量

begin

close;

sql.clear;

sql.add(‘update bookrecord set number1=:number where

bookid=:bookid‘);

parameters.parambyname(‘number‘).value:=s;

parameters.parambyname(‘bookid‘).value:=edit13.text;

execsql; file://提交sql语句

messagedlg(‘记录已成功添加!‘,mtinformation,[mbok],0);

edit13.setfocus;

end;

end;

end;

end;

**********************************************************************

procedure tinoutform.speedbutton2click(sender: tobject);

begin file://入库管理确定按钮事件

if (edit2.text=‘‘) or (edit3.text=‘‘) or (edit4.text=‘‘) or (edit5.text=‘‘)

or (edit6.text=‘‘) or (edit7.text=‘‘) or (edit8.text=‘‘) or (edit9.text=‘‘)

or (edit10.text=‘‘) or (edit11.text=‘‘) or (edit25.text=‘‘)

then begin file://判断输入信息的完整性

messagedlg(‘请输入所需的全部入库信息!‘,mtinformation,[mbok],0);

edit2.setfocus;

end

else

begin

with datamoduleform.inquery do file://入库信息添加

begin

close;

sql.clear;

sql.add(‘insert into inrecord values(:inid,:bookid,:empid,:shopid,

:number,:indate)‘); file://向入库信息表中插入记录

parameters.parambyname(‘inid‘).value:=edit26.text;

parameters.parambyname(‘bookid‘).value:=edit1.text;

parameters.parambyname(‘empid‘).value:=edit2.text;

parameters.parambyname(‘shopid‘).value:=edit3.text;

parameters.parambyname(‘number‘).value:=edit4.text;

parameters.parambyname(‘indate‘).value:=edit5.text;

execsql;

end;

with datamoduleform.bookquery do

begin

close;

sql.clear; file://在完成入库信息的添加后,修改库存记录

sql.add(‘insert into bookrecord values(:bookid,:bookname,:author,

:publisher,:pubdate,:price,:booktype,:number,:addration)‘);

parameters.parambyname(‘bookid‘).value:=edit1.text;

parameters.parambyname(‘bookname‘).value:=edit6.text;

parameters.parambyname(‘author‘).value:=edit7.text;

parameters.parambyname(‘publisher‘).value:=edit8.text;

parameters.parambyname(‘pubdate‘).value:=edit9.text;

parameters.parambyname(‘price‘).value:=edit10.text;

parameters.parambyname(‘booktype‘).value:=edit11.text;

parameters.parambyname(‘number‘).value:=edit4.text;

parameters.parambyname(‘addration‘).value:=edit25.text;

execsql;

end;

messagedlg(‘记录添加成功!‘,mtinformation,[mbok],0);

end;

end;

**********************************************************************

procedure tinoutform.speedbutton11click(sender: tobject);

begin file://新书入库按钮事件

edit13.text:=‘‘;edit13.color:=clmenu;

with datamoduleform.inquery do file://自动入库编号的获取

begin

close;

sql.clear;

sql.add(‘select * from inrecord where inid>=all(select inid from inrecord)‘);

open;

edit26.text:=fieldvalues[‘inid‘]+1;

edit26.readonly:=true;edit26.color:=clmenu;

end;

with datamoduleform.bookquery do file://自动图书编号的获取

begin

close;

sql.clear;

sql.add(‘select * from bookrecord where bookid>=all(select bookid from bookrecord)‘); file://找到库存图书编号中最大的一个

open;

edit1.readonly:=false;

edit1.text:=fieldvalues[‘bookid‘]+1; file://显示自动生成的图书编号

edit1.readonly:=true;edit1.color:=clmenu;

end;

edit2.text:=‘‘;edit3.text:=‘‘;edit4.text:=‘‘;edit5.text:=‘‘;

edit6.readonly:=false;edit6.text:=‘‘;edit6.color:=clwindow;

edit7.readonly:=false;edit7.text:=‘‘;edit7.color:=clwindow;

edit8.readonly:=false;edit8.text:=‘‘;edit8.color:=clwindow;

edit9.readonly:=false;edit9.text:=‘‘;edit9.color:=clwindow;

edit10.readonly:=false;edit10.text:=‘‘;edit10.color:=clwindow;

edit11.readonly:=false;edit11.text:=‘‘;edit11.color:=clwindow;

edit12.readonly:=false;edit12.text:=‘‘;edit12.color:=clmenu;

edit25.readonly:=false;edit25.text:=‘‘;edit25.color:=clwindow;

end;

procedure tinoutform.speedbutton22click(sender: tobject);

var s:integer;

begin file://出库管理确定按钮事件

if (edit24.text=‘‘) or (edit27.text=‘‘) or (edit28.text=‘‘)

then begin

messagedlg(‘请输入完整的出库信息!‘,mtinformation,[mbok],0);

edit24.setfocus;

end

else begin

if edit27.text>edit21.text file://检查出库数量是否小于库存数量

then begin

messagedlg(‘库存中的图书数量不够!‘,mtinformation,[mbok],0);

edit27.text:=‘‘;edit27.setfocus;

end

else begin

with datamoduleform.outquery do

begin

close;

sql.clear;

sql.add(‘insert into outrecord values(:outid,:bookid,:empid,

:number,:outtime)‘); file://添加出库记录

parameters.parambyname(‘outid‘).value:=edit23.text;

parameters.parambyname(‘bookid‘).value:=edit14.text;

parameters.parambyname(‘empid‘).value:=edit24.text;

parameters.parambyname(‘number‘).value:=edit27.text;

parameters.parambyname(‘outtime‘).value:=edit28.text;

execsql;

end;

edit21.readonly:=false;

s:=strtoint(edit21.text)-strtoint(edit27.text); file://计算出库后库存图书数量

edit21.text:=inttostr(s); file://显示出库后库存图书数量

edit21.readonly:=true;

with datamoduleform.bookquery do

begin file://修改库存图书数量

close;

sql.clear;

sql.add(‘update bookrecord set number1=:number where bookid=:bookid‘);

parameters.parambyname(‘number‘).value:=s;

parameters.parambyname(‘bookid‘).value:=edit14.text;

execsql;

end;

messagedlg(‘出库记录添加成功!‘,mtinformation,[mbok],0);

edit14.text:=‘‘;edit14.setfocus;

end;

end;

end;

§5.5 查询功能的实现

查询功能包括员工信息查询,供应商信息查询,入库信息查询和出库信息查询。由于每一个功能的实现都差不太多,而且其窗体也差不太多,所以在这里只给出员工信息查询窗体及其源代码。

图5.6 员工信息查询窗体

procedure tfindempform.speedbutton1click(sender: tobject);

var s1,s2,s3 :string;

begin file://员工记录查询窗体查找按钮事件

with datamoduleform.empquery do

begin

close;

sql.clear;

sql.add(‘select * from employee‘);

sql.add(‘where employeeid like :empid and employeename like :name and grade like :grade‘); file://实现模糊查询功能

if edit1.text<>‘‘ then s1:=‘%‘+edit1.text+‘%‘ else s1:=‘%‘;

parameters.parambyname(‘empid‘).value:=s1;

if edit2.text<>‘‘ then s2:=‘%‘+edit2.text+‘%‘ else s2:=‘%‘;

parameters.parambyname(‘name‘).value:=s2;

if edit3.text<>‘‘ then s3:=‘%‘+edit3.text+‘%‘ else s3:=‘%‘;

parameters.parambyname(‘grade‘).value:=s3;

open;

if fieldvalues[‘employeeid‘]<>null

then findempform.close file://在找到记录的情况下关闭查找窗口

else

begin

messagedlg(‘没有找到你所需要的记录!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

close; sql.clear;

sql.add(‘select * from employee‘); file://刷新员工信息窗口

open;

end; end;

end;

§5.6 系统登陆窗体模块的实现

由于系统登陆窗体中有一幅彩图,在这里不便给出,而只给出了系统的实现。

var keyname: string; file://定义了一个全局变量,在key2中有调用

procedure tkeyform.speedbutton1click(sender: tobject);

var s:string; file://登陆窗口登陆按钮事件

begin

if (edit1.text=‘‘) then begin

messagedlg(‘清输入登陆姓名和密码!‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

datamoduleform.keytable.active:=true;

if not datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

file://判断登陆名是否存在

then begin

messagedlg(‘登陆名错误,请重新输入!‘,mtinformation,[mbok],0);

edit1.text:=‘‘; edit1.setfocus;

end

else begin

with datamoduleform.keyquery do

begin

close; sql.clear;

sql.add(‘select * from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

open;

s:=fieldvalues[‘keyno‘];

end;

if s<>edit2.text file://判断登陆密码是否正确

then begin

messagedlg(‘登陆密码错误,请重新输入!‘,mtinformation,[mbok],0);

edit2.text:=‘‘; edit2.setfocus;

end

else begin

keyname:=edit1.text;

keyform.hide;

mainform.show;mainform.windowstate:=wsmaximized;

end; end; end;

end;

§5.7 用户管理功能的实现

5.7.1 用户管理主窗体

图5.7 用户管理主窗体

5.7.2 密码修改窗体模块的实现

图5.8 密码修改窗体

procedure tkey2form.speedbutton1click(sender: tobject);

begin file://密码修改窗口修改按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)or(edit3.text=‘‘)

then begin

messagedlg(‘请输入完整的信息。‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

if not datamoduleform.keytable.locate(‘keyno‘,edit1.text,[])

then begin

messagedlg(‘原密码输入错误,不能修改新密码!‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end

else begin

if edit2.text<>edit3.text

then begin

messagedlg(‘两次密码输入不同,请重新输入新密码!‘,mtinformation,[mbok],0);

edit2.text:=‘‘;edit3.text:=‘‘;edit2.setfocus;

end

else begin file://在数据库中修改密码

with datamoduleform.keyquery do

begin

close; sql.clear;

sql.add(‘update key set keyno=:keyno where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=keyname;

parameters.parambyname(‘keyno‘).value:=edit2.text;

execsql;

messagedlg(‘密码修改成功!‘,mtinformation,[mbok],0);

key2form.close;

end; end; end; end;

end;

5.7.3 用户注册窗体模块的实现

图5.9 用户注册窗体

procedure tkey3form.speedbutton1click(sender: tobject);

begin file://用户注删窗口注删按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)or(edit3.text=‘‘)

then begin

messagedlg(‘请输入完整的信息!‘,mtinformation,[mbok],0);

edit1.setfocus;

end

else begin

if datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

file://判断用户名是否存在,系统不允许用户名重复

then begin

messagedlg(‘用户名已存在,请输入新的用户名和密码!‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end

else begin

if edit2.text<>edit3.text

then begin

messagedlg(‘您输入的两个密码不相同,请重新输入!‘,mtinformation,[mbok],0);

edit2.text:=‘‘;edit3.text:=‘‘;edit2.setfocus;

end

else begin

with datamoduleform.keyquery do file://在数据库中添加该用户

begin

close;

sql.clear;

sql.add(‘insert into key values(:keyname,:keyno)‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

parameters.parambyname(‘keyno‘).value:=edit2.text;

execsql;

end;

messagedlg(‘新用户添加成功,您可以继续添加用户,或按“取消”退出。‘,mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit3.text:=‘‘;edit1.setfocus;

end; end; end;

end;

5.7.4 用户注销窗体模块的实现

图5.10 用户注销窗体

procedure tkey4form.speedbutton1click(sender: tobject);

var s:string;

begin file://用户注销窗口注销按钮事件

if (edit1.text=‘‘)or(edit2.text=‘‘)

then messagedlg(‘请输入完整的信息!‘,mtinformation,[mbok],0)

else begin

if not datamoduleform.keytable.locate(‘keyname‘,edit1.text,[])

file://判断用户名是否存在,用户名必须存在,才可以删除

then begin

messagedlg(‘您所输入的用户名不存在,请重新输入或按“取消”退出。‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit1.setfocus;

end

else begin

with datamoduleform.keyquery do

begin

close;

sql.clear;

sql.add(‘select * from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

open;

s:=fieldvalues[‘keyno‘];

end;

if s<>edit2.text file://判断该用户名下的密码是否正确

then begin

messagedlg(‘您所输入的密码不正确,请重新输入或按“取消”退出。‘,

mtinformation,[mbok],0);

edit2.text:=‘‘;edit2.setfocus;

end

else begin file://从数据库中删除该用户

with datamoduleform.keyquery do

begin

close;

sql.clear;

sql.add(‘delete from key where keyname=:keyname‘);

parameters.parambyname(‘keyname‘).value:=edit1.text;

execsql;

end;

messagedlg(‘用户已成功删除,您可以继续删除用户,或按“取消”退出。‘,

mtinformation,[mbok],0);

edit1.text:=‘‘;edit2.text:=‘‘;edit1.setfocus;

end; end; end;

end;

结束语

本系统是一个面向小型图书企业,具有一定实用性的数据库信息管理系统。它主要完成对图书仓库的一系列管理,包括入库、出库、库存以及员工和供应商信息管理。本系统采用当前流行的面向对象的开发工具—delphi来完成整个系统的设计,在数据库的设计上利用了access的便利性和实用性。

本系统具有相当的实用功能。在查询方面,系统实现了多条件任意字段的模糊查询,同时在分类查询上实现了动态生成,系统可以自动识别用户不同的输入。在图书入库、出库和库存三者之间建立了良好的链接关系,某一部分地修改均会自动引发系统对与其相关的部分进行连锁修改。在用户管理方面,系统较好地实现了用户注册,用户注销和密码修改等各项功能。

系统在设计过程中不可避免地遇到了各种各样的问题,由于整个系统完全都是由个人设计的,有关delphi许多细节问题都要靠自己去摸索,加之本人水平有限,并没有完全地理解delphi的强大功能,而且还存在着许多不足之处。如:

受开发条件和开发时间的限制,本系统只利用了本地数据库access,它同应用程序处于同一系统中,能存储的数据量也有一定限制,并没有发挥出delphi其数据库方面的优势;

报表打印功能尚不够全面完善,不能实现动态报表;

在一些数据输入时没有及时的进行数据格式校验,不能保证数据输入的绝对正确性。

由于时间关系,系统功能实现不够完善,使用不是很方便,比如,没有实现多条记录的连锁删除和添加以及数据的导入功能。

这些都是需要完善的地方,该系统离实际使用也还有相当的距离,需要我进行不断地补充和完善。

通过本次毕业设计我学到了不少新的东西,也发现了大量的问题,有些在设计过程中已经解决,有些还有待今后慢慢学习。只要学习就会有更多的问题,有更多的难点,但也会有更多的收获。

考 文 献

[1] 郑荣贵、黄平、谷会东,delphi 6.0数据库开发与应用,中科多媒体电子出版社,2002

[2] 伍俊良,delphi 6控件应用实例教程,北京希望电子出版社,2002

[3] 卢国俊,delphi 6数据库开发,电子工业出版社,2002