天津丰源汽车连锁服务有限公司成立于 1988 年,由最初从事汽车及汽车配
件进出口贸易,发展成为现在拥有 5 家 3000~5000 m2 汽车用品直营连锁超市、
一家 3500 m2 一类大修资质的汽车修理厂、3 家三类快修店、一家二手车交易公
司、一个汽车锁业公司、一个爱车俱乐部、一个汽车电子技术培训学校的大型联
合企业。2001 年引进国外汽车用品连锁超市的经营模式,借鉴正规美式仓储超
市的经营理念及国内大型民用超市的管理经验,开办了大型汽车用品连锁超市。
2001 年~2004 年,连续开办了 5 家直营连锁店。公司计划在 2010 年前再发展
20~40 家连锁店,除了占领天津市场外,还要进军外埠市场。
用户发展战略
1. 横向发展战略
利用自身的优势,涉足与汽车相关的所有领域,包括汽车销售、汽车进出口
贸易、二手车销售、爱车俱乐部、汽车装饰用品加工生产及开办汽车电子学校等。
2. 纵向发展战略
∶ 依托领先的专业品质和 16 年的行业经验,构筑天津乃至华北地区汽车用品连锁超市网
络。
∶ 沿袭欧美风尚,创造丰源车居文化,引导有车族的消费观向着更高品味发展。
∶ 拓展丰源汽车用品经营范围,向“高、精、尖、全”发展;不断开发汽车服务领域,以
高质量的服务,力争作汽车行业的“龙头”。
3. 公司发展目标
∶ 5 年之内再开设 20~40 家连锁超市,占领天津市场。
∶ 以天津为基地,进军外埠市场,力争 10 年内在华北地区赢得一定的市场占有率。
项目整体目标
对企业的各个层面进行全面、细致、规范的管理。为实现管理手段的科学化、
现代化和规范化建立一套先进的信息管理系统。通过本系统的使用,能够达到以
下目标:
∶ 精确、实时地反映和准确处理公司各项业务活动,实现企业商品“进、销、调、耗、存、
结”以及汽车维修、美容、加工的一体化管理。
∶ 对汽车维修、美容、加工等环节进行精细化管理。
∶ 对商品进行条码管理,从商品入库、出库到盘点,统一通过条码进行管理,从而杜绝
人为错误的操作和由此导致的盘点数据不正确的问题。
∶ 有效控制商品的采购,避免商品短缺或重复进货,提高资金利用率。
∶ 优化商品结构,减少资金占用。
∶ 合理控制库存,提高库存周转率。
∶ 彻底解决信息孤岛问题,将各分店、各部门的信息完全共享,为公司将来的快速扩张
提供强有力的支持。
∶ 利用视窗卡对会员进行智能化、人性化的管理,提高公司的形象。
∶ 及时、准确地将企业各类信息加工处理后反馈给公司的最高管理层,提供可靠、完整、
科学的决策依据。
∶ 加强对员工管理考核的科学性,提高劳动效率,充分调动员工的积极性和创造性。
∶ 对于公司组织机构的调整、人员职务的变化、业务流程的重新设计及业务操作细节的
调整,系统能够有足够的应变机制和可扩展性,从而快速地适应公司的编号。
财务管理作为企业管理的组成部分,与经济价值或财富的保值增值有关,是
关于创造财富的决策,企业生存、发展、获利的总目标离不开财务的筹资、投资
以及对资金的运用管理。另一方面,财务管理目标是制定生产目标、销售目标等
一系列目标的基础和前提,这使得财务管理在企业管理中处于一个核心地位,财
务管理目标将从根本上反映企业的总目标。所以确立一个合理的财务管理目标对
企业的长远发展有着极为重要的意义。
财务管理的任务
近来,美国接二连三发生的著名企业财务作假事件,不仅沉重地打击了美国
经济和投资者的信心,同时也在全球经济一体化的今天,警示着中国企业的决策
者们,要让更多的职业经理人具有一双能够识别伪装的慧眼,使企业能够防患于
未然,将风险降至最小。当前中国许多企业面临着许许多多的问题,然而比较具
有普遍性的是企业的经营决策仅凭经验感性判断,缺乏必要的理论指导和定量分
析,财务会计信息资源未能得到充分利用。
财务管理是为实现企业的目标服务的,并受财务管理的内容制约。基本任务
是依法合理筹资并有效地利用企业各项资产,最终提高效益。具体来说,企业的
财务管理任务包括以下几方面内容:
(1) 依法合理筹集资金,满足企业资金需要量。企业进行生产经营活动需要
必备的资金额,企业财务管理的首要任务是合理地从各种渠道,采用种种方式合
理地筹集到生产经营活动所需要的资金。这项任务有两个面向,一是要正确确定
企业的资金需求量,二是要选择好获得资金的渠道和方式。因为企业筹资有多种
渠道和方式可供选择,在进行比较选择时主要考虑资金成本,偿还期限,担保条
件可能性和资金供应者的其他具体要求,并考虑其对企业投资收益和风险影响,
据此选择确定企业筹资的最佳组合方式。
(2) 有效地分配和使用企业资金,提高资金利用效果。财务管理部门应规划
性地,合理地安排各类资产,使其形成合理的资产结构。要使货币资产保持在最
佳的水平上,要避免存货资产占用过多,要及时解决资金使用过程中出现的问题,
加速资金周转,提高资金的利用效果。
(3) 分配企业的收益,协调各方面的经济关系。税后利润按照规定的顺序进
行分配,在分配中处理好各方面的经济关系,以调动企业、员工、投资者各方面
的积极性。
(4) 实行财务监督,维护财经法规。财务监督是利用货币形式对企业的经济
活动进行监督,它是通过对财务收支的审核控制和对财务指标的检查分析,及时
发现生产经营活动存在的问题,及时进行处理。实行财务监督,能够促使企业
在严格地规范化的范围内生产经营,维护法律制度上的企业完整性。
会计学的理论基础
会计学是一门专门的学科,涉及众多内容,这里不可能一一深入介绍,下面
仅介绍一些原理性的知识,通过这些介绍读者基本可以了解会计学的基本理论,
从而对财务管理有一个基本的认识。
(1) 会计的对象
会计的一个显著特点是以货币形式对经济活动进行反映,而会计的对象就是
会计核算和监督的内容,因此概括地说,会计对象是扩大再生产过程中的资金运
动,企业的会计对象是企业经营活动中的资金运动。企业的资金运动在经营活动
中表现为各种经济业务,因此企业会计对象又具体表现为反映资金运动的企业经
营活动中的经济业务。会计对象具体表象的经济业务,按其性质的分类,就形成
会计对象的要素。会计对象要素主要包括资产、负债、所有者权益、收入、费用、
利润等。
(2) 会计的职能
会计职能是会计应发挥的作用或应有的功能。会计的基本职能有两项,即会
计核算职能和会计监督职能。会计核算是以货币为主要计量单位,对企业、事业
等单位一定时期的经济活动进行真实、准确、完整和及时的记录、计算和报告。
会计核算的内容是会计对象要素,具体表现为经济活动中的各种经济业务,包括:
∶ 款项和有价证券的收付
∶ 财物的收发、增减和使用
∶ 债权债务的发生和结算
∶ 资本、基金的增减和经费的收支
∶ 收入、费用、成本的计算
∶ 财务成果的计算和处理
∶ 其他需要办理会计手续、进行会计核算的事项
会计核算要求做到真实、准确、完整和及时。会计核算是一个过程,在企业
中,经济业务发生后,要填写原始凭证,编制记帐凭证,根据记帐凭证登记会计
帐簿,根据会计帐簿和有关资料编制会计报表。
会计监督是指依据监督标准,对企业、事业等单位的资金运动进行的指导、
控制和检查。会计监督的对象是资金运动,而资金运动在企业中主要负责筹集资
金、使用资金和收回资金。会计对资金运动的监督主要表现在:
∶ 监督经济业务的真实性
∶ 监督财务收支的合法性
∶ 监督公共财产的完整性
(3) 会计核算方法
在会计核算方法体系中,主要的方法有:
∶ 设置会计科目和帐户
会计科目就是对会计对象的具体内容进行分类核算的项目,而设置会计科目
就是在设计会计制度时事先规定这些项目,然后根据它在帐目中开立帐户,分类、
连续地记录各项经济业务,反映由于各经济业务的发生而引起的各会计要素的增
减变动情况和结果,为经营管理提供各种类型的会计指标。
∶ 复式记帐
复式记帐是与单式记帐相对应的一种记帐方法,这种记帐方法的特点是对每
一项经济业务都要以相等的金额同时记入两个或两个以上的有关帐户,例如我们
用银行存款购买材料。按照复式记帐法就应该一方面记材料的增加,另一方面记
银行存款的减少。它的优点就是通过帐户的对应关系,可以了解有关经济业务内
容的来龙去脉,通过帐户的平衡关系,可以检查有关业务的记录是否正确。
∶ 填制和审核会计凭证
会计凭证是记录经济业务,明确经济责任的书面证明,也是登记帐簿的依据。
业务发生以后,首先要取得凭证,凭证必须经过会计部门或有关部门审核,只有
经过审核并认为正确无误的会计凭证才能作为记帐的依据,而作为会计核算的方
法,填制和审核凭证不仅为经济管理提供真实可靠的数据资料,也是实行会计监
督的一个重要方面。
∶ 登记会计帐簿
帐簿是用来全面、连续、系统地记录各项业务的簿籍,是保存会计数据资料
的重要工具。而登记帐簿就是将会计凭证记录的经济业务,序时分类的记入有关
簿籍中设置的各个帐户。登记帐簿必须以凭证为根据并定期进行结帐、对帐以便
为编制会计报表提供完整而系统的会计数据。
∶ 成本计算
成本计算就是指在生产经营过程中按照一定的对象归集和分配发生的各种
费用支出,以确定该对象的总成本和单位成本的一种专门方法。通过成本计算可
以确定材料的采购成本、产品的生产成本和销售成本,也就是说,在这个生产经
营过程当中,既要计算材料的采购成本,也要计算产品的生产成本和销售成本。
通过成本计算,可以反映和监督生产经营过程当中发生的各项费用是否节约或超
支,并据此确定企业的经营盈亏。
∶ 财产清查
财产清查是指通过盘点实物、核对帐目,保持帐实相符的一种方法。在清查
当中如果发现财产物资和货币资金的实有数与帐面结存数额不一致,应该及时查
明原因,通过一定的审批手续进行处理,并调整帐簿记录,使帐面数额与结存数
额保持一致从而保证会计核算资料的正确性和真实性。
∶ 编制会计报表
会计报表是根据帐簿记录定期编制的。它是一种总括并反映了企业或行政事
业单位在特定时点(月末、季末、年末)和一定时期(月、季、年)的财务状况、经
营成果以及成本费用等的书面文件。会计报表提供的资料不仅是分析考核财务成
本计划和预算执行情况,以及编制下期财务成本计划和预算的重要依据,也是进
行经营决策和国民经济综合平衡工作必要的参考资料。
这些方法反映了会计核算过程。在会计核算过程中,填制和审核会计凭证是
开始环节。登记会计帐簿是中间环节,编制会计报表是终结环节。在一个会计期
间所发生的所有经济业务都要经这三个环节进行处理,将大量的经济业务转换为
系统的会计信息,这个转换过程也就是从填制和审核凭证到登记帐簿,直到编制
出会计报表,周而复始的变化过程就是一般所讲的会计循环。经济业务发生后,
经办人员要添置或取得原始凭证,经会计人员审核整理后,按照设置的会计科目,
运用复式记帐法编制记帐凭证并据以登记帐簿,要依据凭证和帐簿记录对生产经
营过程中发生的各项费用进行成本计算,并依据财产清查对帐簿记录加以核实,
在保证帐实相符的基础上定期编制会计报表。
(4) 会计科目
我国企业会计准则将企业会计要素划分为资产、负债、所有者权益、收入、
费用和利润六个要素,这些要素对应不同的会计科目。会计科目是对会计对象具
体内容及会计要素进一步分类核算的项目。为了全面系统地反映和监督各项会计
要素的增减变动情况,分门别类地为经济管理提供会计核算资料,就需要设置会
计科目。设置会计科目就是通过会计制度预先规定这些项目的名称,并限定其核
算的内容范围,它是设置帐户、处理帐务所必须遵守的规则和依据,是正确组织
会计核算的一个重要条件。例如,为反映和监督各项资产的增减变动,设置了现
金、材料、长期投资、固定资产等科目;为反映和监督负债和所有者权益的增减
变动,设置了短期借款、应付帐款、长期借款和资本公积、盈余公积等科目。为
反映和监督收入费用和利润的增减变动设置了产品销售收入、生产成本,本年利
润和利润分配等科目。
(5) 帐户
设置会计科目只是规定了对会计对象具体内容进行分类核算的项目,而为了
及时、连续、系统地记录由于经营业务的发生而引起的会计要素的增减变动,提
供各种会计信息,还必须根据规定的会计科目在帐簿中开设帐户。帐户是对会计
要素进行分类核算的工具,它应该以会计科目作为它的名称并具有一定的格式。
帐户的设置也与帐户的级次有关,也就是根据总分类科目开设总分类帐户,根据
明细科目开设明细帐户。由于总分类帐户提供的是总括核算指标,因而一般的只
用货币计量。而明细帐户提供的是明细分类核算指标,因而除了用货币量度外,
有的还用实物量度,进行辅助计量。
既然帐户是用来分类记录经营业务的,就必须具有一定的结构。由于经济业
务发生所引起的各项会计要素的变动,从数量上来看,不外乎是增加和减少两种
情况。因此帐户结构也相应地分为两个基本部分,划分为左右两方,以一方登记
增加额,另一方登记减少额。如图 所示,图 是银行存款和应付帐款的帐
户实例。帐户要依附于帐簿开设,每一个帐户只表现为帐簿中的某章或某些帐页,
它们一般应该包括帐户的名称、日期和摘要、增加和减少的金额及余额、凭证号
数等。
图 帐户结构 图 帐户实例
(6) 会计科目与帐户的关系
会计帐户和会计科目是两个既有区别又相互联系的概念,它们的联系是:帐
户是根据会计科目设置的。会计科目就是帐户的名称,设置会计科目和开设帐户
的目的都是为了分类提供会计信息,两者所反映的经济内容是一致的。它们的区
别是:会计科目仅是分类核算的项目,而帐户既有名称又有具体结构;会计科目
是进行分类核算的依据,而帐户则是记录经济业务的载体。在实际工作中,会计
科目和帐户往往作为同义词来理解,互相通用,不加区别。
(7) 复式记帐原理
记帐方法是在帐户中登记经济业务的方法。经济业务的发生会引起各有关会
计要素的增减变动。为将这些经济业务记录在有关的帐户中,曾采用过单式记帐
和复式记帐两种方法。单式记帐是指对发生的经济业务只在一个帐户中进行记录
的记帐方法,例如用银行存款购买材料的业务,发生后,采用单式记帐法只在帐
户中记录银行存款的付出业务,而对材料的收入业务却不在帐户中记录。与单式
记帐不同,复式记帐是指对发生的每一项经济业务都以相等的金额,在相互关联
的两个或两个以上帐户中进行记录的记帐方法。例如上述用银行存款购买材料的
业务,按照复式记帐则应以相等的金额,一方面在银行的存款帐户中记录银行存
款的付出业务;另一方面在材料帐户中记录材料的收入业务。
(8) 借贷记帐法
借贷记帐法是以借贷作为记帐符号,反映各项会计要素增减变动情况的一种
记帐方法,是各种复式记帐方法中应用得最广泛的一种方法。从上面的定义可以
看出,借贷记帐法是一种复式记帐法,它的特点是以借贷作为记帐符号,反映各
项会计要素增减变动情况。借贷记帐法的记帐规则是“有借必有贷,借贷必相
等”。也就是说,由于资金运动的数量变化不外乎增加或减少,一个要素项目的
金额增加引起的是同类性质的另一个(或几个)项目的金额减少,或另一类性质的
某一个(或几个)项目的金额增加或减少,而不同性质要素项目(帐户)的金额增减
恰恰是用不同的记帐符号“借”或“贷”来表示的。因此借贷记帐法下对于每一笔经
济业务的帐务处理都必然是既要用“借”方反映增加项目的金额,又要用“贷”方反
映减少项目的金额,这就叫做“有借必有贷,借贷必相等”,如图 所示。
(9) 会计分录
会计分录就是标明某项经济业务的应借应贷帐户及其金额的记录,所有的财
务管理软件都要有“会计分录”的功能,就是以借贷记帐法输入所有的企业经济业
务。注意会计分录的书写格式一般是借方在上贷方在下,而且贷方应该向右错开
一格。若有多个借方或多个贷方,则借贷方各自应该对齐。会计分录的实例如
图 所示。
图 借贷记帐法(会计分录)
(10) 试算表与试算平衡
把整个期间(一个月或一年)的会计分录,从会计凭证全部过入分类帐后,各
分类帐就已经记录和反映了当期的经济业务。为了验证各分类帐登记和过帐的会
计处理的正确性,根据“有借必有贷,借贷必相等”的平衡原理,编制“试算表”进
行试算平衡,同时也为编制财务报表作好了准备,如图 所示。
图 试算表
(11) 结帐与会计报表
为了总结一定会计期间财务状况和经营成果的大小,企业一般在会计期末进
行结帐。结帐是一项将帐簿记录定期结算清楚的帐务工作。结帐后会形成该会计
期间的会计报表,常用的会计报表有损溢表和资产负债表,分别如图 和
所示。
图 损溢表 图 资产负债表
根据以上对财务管理内容的分析和会计基础知识的介绍,一个标准的财务管
理系统应该包括如图 所示的几大功能。除此之外系统还应包括信息系统必须
具备的通用功能,例如系统管理、权限设置、数据备份与恢复等,这些功能的实
现可以参考第 1 章。
其中每个功能都由若干相关联的子功能模块组成。
图 财务管理系统应包括的基本功能
财务管理系统的基本流程如图 所示。
图 财务管理系统基本流程
基础资料维护
“基础资料维护”用于对会计科目、核算项目以及凭证、帐簿、固定资产等项
目进行初始化设置,这些设置一般不轻易改动,包含的功能模块如图 所示。
图 “基础资料维护”功能模块
其中“会计科目”是基础资料的重点,财务软件的使用离不开科目的正确设置,
其内容包括科目代码、科目名称、助记码、科目类别、是否存货科目、余额方向、
数量单位等。
凭证管理
“凭证管理”用于完成凭证制定、审核、记帐、查询等功能,自动生成各种会
计帐,包含的功能模块如图 所示。
图 “凭证管理”功能模块
其中“凭证输入”是凭证管理的重点,在凭证输入模块中将实际业务的分录输
入到计算机,内容包括凭证状态、会计期间、凭证字号、凭证编号、顺序号、日
期、附单据、审核、过帐、制单、借方合计、贷方合计、过帐状态、顺序号码等。
一张凭证对应多个分录,分录内容包括分录编号、会计期间、凭证字号、凭证编
号、摘要、科目代码、借方、贷方、数量、单价、结算方式、结算号、结算日期
等。
帐簿管理
“帐簿管理”用于提供各种帐务处理查询筛选的功能,包含的功能模块如图
1 所示。总帐可按科目级别、币别、科目范围等查询;明细帐可按期间范围、币
别、科目范围查询;还提供多栏帐、数量金额明细帐、核算项目分类总帐等帐簿
报表。
图 “帐簿管理”功能模块
报表管理
“报表管理”用于报表的定义、编制和输出。企业会计核算的结果最后需要用
报表的形式反映出来,一般包括帐务报表处理、汇总报表处理、合并报表处理等。
一般财务系统会预设资产负债表、损益表、利润分配表等各类报表模板,如图 4
.12 所示,简化报表操作过程。
图 “报表管理”功能模块
期末处理
“期末处理”是系统总结某一会计期间的经营活动情况,转至下一期的必做事
项。同时该模块在结帐前,按企业财务管理和成本计算的要求,必须进行制造费
用、产成品成本的结转、期末调汇及损益结转等工作,包含的功能模块如图
所示。
图 “期末处理”功能模块
往来管理
“往来管理” 用于对企业的往来帐款进行全面核算、管理、分析、预测、决
策。一般包括往来单位管理、经济业务的管理、往来帐龄分析等模块、往来帐
款的核销、坏帐处理等功能,如图 所示。
图 “往来管理”功能模块
出纳管理
出纳是会计中十分重要的一个岗位,它担负着现金、银行存款的收付职能。
“出纳管理”既可同总帐系统联合起来使用,也可单独提供给出纳人员使用。一般
包括现金帐管理、银行存款帐管理、票据管理等,如图 所示。
图 “出纳管理”功能模块
出纳系统与帐务系统功能分离但数据却可紧密连结共享,合理的数据共享模
式可使得会计与出纳人员更能高效的独立工作。
工资管理
“工资管理”用于进行企业工资的发放和核算,工资动态变动管理,工资费用
计提与分配、银行代发等;一般包括基础设置、工资结构设置、工资变动管理、
工资数据处理、工资报表管理等功能,如图 所示。
图 “工资管理”功能模块
固定资产管理
“固定资产管理”用于管理、核算固定资产增减变化、变动、以及折旧的计提、
转帐等,一般包括如图 所示的功能模块。允许不同固定资产采用不同的折
旧方法,提供标准的折旧方法,提供固定资产卡片自定义设置功能和灵活的报表
查询系统。
图 “固定资产管理”功能模块
财务分析
“财务分析” 是财务管理的重要组成部分,在核算的基础上以财务报表和其
他资料为依据和起点,采用专门方法,系统分析和评价企业的过去和现在的经营
成果、财务状况及其变动,对帐务数据作进一步的加工、整理、分析和研究,将
大量的报表数据转换成对决策有用的信息,是管理层进行日常及重大决策的好帮
手,包含的功能模块如图 所示。
图 “财务分析”功能模块
“财务状况分析”对截止报告期的资产、负债及所有者权益的结构、比例及变
化趋势等情况进行分析,可分为结构分析、比较分析、趋势分析三种分析方法。
结构分析对资产、负债及所有者权益中每一具体项目占该类项目以及与总体项目
的结构、比重进行分析,从而揭示该类财务指标的结构是否合理;比较分析能对
同口径(指标名称相同、计算方法相同)指标在任意两个会计期间(或一个会计期间
与它的预算值之间)进行比较,借以反映其增减变动情况;趋势分析反映某一财
务指标,如资产总计、流动资产合计、银行存款等在年度内月份之间、季度之间
和年度之间变化的趋势。
“损溢分析”对本期、本年累计及任一会计期间的盈利状况和盈利能力进行分
析。对损益分析也可分为结构分析、比较分析、趋势分析三种分析方法。
根据以上需求分析,一个基本的财务管理系统数据库中大致包括 100 多张数
据表,分别存放相应子功能的数据信息,其中“科目表”是关键的表,用于存放科
目的信息。其他涉及科目信息的数据表,都只记录科目的代码,根据作为外键的
“科目代码”字段相对应。因此“科目表”和其他数据表间的关系是 1∶N 的关系。
财务管理系统 E-R 图
图 所示为财务管理系统 E-R 图。
图 财务管理系统 E-R 图
财务管理系统数据表清单
配书光盘中“\Chap4\建库脚本\财务管理系统.sql”文件提供了创建数据库所有
表的脚本,下面我们仅列出一些重要表的名称及其用途供读者参考(表 )。其
中每张表所包含的字段读者可以自己查看建库脚本和前面的需求分析。
表 财务管理系统数据表清单
数据表名称 数据表用途
科目表 保存企业财务的科目设置信息
科目余额表 保存财务(帐户)科目的余额信息
分录表 用于凭证管理中的分录输入
凭证表 用于凭证输入管理
分录历史表 分录输入确认后数据放入历史
凭证历史表 凭证输入确认后数据放入历史
明细帐簿 用于企业财务明细帐簿的输入
分类帐簿 用于企业财务分类帐簿的输入
本年明细帐簿 年度明细帐簿的汇总
本年分类帐簿 年度明分类簿的汇总
历史明细帐簿 保存明细帐簿历史
历史分类帐簿 保存分类帐簿历史
财务状况变动表 保存企业财务的财务状况变动表信息
年终损益表 保存企业财务的年终损溢表信息
年终资产负债表 保存企业财务的年终资产负债表信息
固定资产清单 保存企业的固定资产基础资料信息
变动资料表 保存企业的固定资产的变动信息
变动资料历史表 保存企业的固定资产变动历史
折旧分配表 保存固定资产折旧分配的方法
固定资产变动情况表 保存(计算)固定资产变动情况
固定资产折旧表 存储用来生成转帐凭证的本期折旧数据,在计提折旧时生成数据
固定资产折旧登记表 存储固折旧方式、使用期间、预计工作总量、月折旧率等
折旧工作量登记表 按工作量折旧的固定资产的工作量输入
折旧工作量历史表 保存固定资产工作量历史
固定资产折旧汇总表 统计用表
固定资产处理情况表 统计用表
固定资产构成分析表 统计用表
员工清单 保存企业员工信息
工资清单 保存员工工资的明细项目
工资表 保存当月员工工资信息,由员工清单和工资清单计算生成
工资费用分配表 按各部门职务为类别对员工工资费用分配
银行代发工资文件 过帐时生成,保存银行代发工资的历史信息
工资汇总表 统计用表
工资发放表 保存转帐后工资发放历史
工资统计表 统计用表
基于以上需求分析和数据库分析,读者对一个标准的财务管理系统应该有了
一个全面的认识。下面我们将实例说明如何利用 Delphi 完成系统的开发。
实例功能
由于篇幅有限,本实例详细介绍如图 所示的功能的开发过程,并简化其
中各功能
图 详细介绍的功能模块
所包含的属性,其他功能读者完全可以参照这些功能的开发方法完成开发。
需要强调的是,由于用户登录和权限管理的功能各个系统实现的方法是一致
的,这里就不在详细介绍,具体实现方法参看第 1 章。
系统流程图
系统流程图如图 所示。
图 系统流程图
根据实例介绍,“科目表”是系统的关键表,其他各表均与“科目表”通过“科目
代码”字段进行多对一的关联。系统共需要 11 张表,用途分别如表 所示。
表 系统数据表及其用途
数据表名称 数据表用途
科目表 保存企业财务的科目设置信息
帐簿初始化表 正式使用系统前初始化科目的期初余额
凭证表 输入会计凭证,分录表的主表
分录表 输入会计分录,分录表的从表
科目余额表 保存各个会计期间的科目借、贷、余额情况
凭证表历史 保存过帐后的凭证历史
分录表历史 保存过帐后的分录历史
本期明细帐簿 保存当前会计期间的明细帐簿数据
本期汇总帐簿 保存当前会计期间的明细帐簿数据,期末结帐后期末变成新会计期间的期初
资产负债表 统计用表,用于计算资产负债表
系统参数表 系统运行所需的参数信息
创建数据库
打开 SQL Server 企业管理器,新建一个数据库,名称为 caiwubook。利用配
书光盘中的脚本代码“\Chap4\建库脚本\ 财务管理系统实例程序.sql”文件创建数
据库对象,完成数据库的设计。也可以利用“\Chap4\建库脚本\”文
件直接恢复数据库,这样数据库中存在初始的科目信息和系统参数数据数据。
后面几小节我们将列出几个重点的数据表的建库脚本,其他数据表的脚本请
参考脚本文件。
创建“科目表”数据表
创建“科目表”数据表的 SQL 脚本如下:
CREATE TABLE [dbo].[科目表] (
[科目代码] [char] (20) NOT NULL ,
[科目名称] [char] (20) NULL ,
[助记码] [char] (20) NULL ,
[科目类别] [char] (20) NULL ,
[是否存货科目] [char] (10) NULL ,
[余额方向] [char] (4) NULL ,
[数量单位] [char] (10) NULL
) ON [PRIMARY]
GO
创建“凭证表”和“分录表”数据表
创建“凭证表”数据表的 SQL 脚本如下:
CREATE TABLE [dbo].[凭证表] (
[凭证编号] [char] (10) NOT NULL ,
[会计期间] [int] NULL ,
[凭证字号] [char] (2) NULL ,
[日期] [datetime] NULL ,
[附单据] [int] NULL ,
[制单] [char] (20) NULL ,
[借方合计] [money] NULL ,
[贷方合计] [money] NULL ,
[过帐状态] [char] (4) NULL ,
[凭证状态] [char] (10) NULL
) ON [PRIMARY]
GO
创建“分录表”数据表的 SQL 脚本如下:
CREATE TABLE [dbo].[分录表] (
[编号] [int] IDENTITY (1, 1) NOT NULL ,
[凭证编号] [char] (10) NOT NULL ,
[摘要] [char] (40) NULL ,
[科目代码] [char] (20) NULL ,
[借方] [money] NULL ,
[贷方] [money] NULL ,
[数量] [int] NULL ,
[单价] [money] NULL ,
[结算方式] [char] (10) NULL ,
[结算号] [int] NULL ,
[结算日期] [datetime] NULL
) ON [PRIMARY]
GO
创建其他关键数据表
以下是其他关键数据表的创建脚本,其他数据表可以参看配书光盘中的相关
内容。
CREATE TABLE [dbo].[科目余额表] (
[科目代码] [char] (20) NULL ,
[期初借方余额] [money] NULL ,
[期初贷方余额] [money] NULL ,
[本期借方发生额] [money] NULL ,
[本期贷方发生额] [money] NULL ,
[本年借方累计发生额] [money] NULL ,
[本年贷方累计发生额] [money] NULL ,
[本期借方余额] [money] NULL ,
[本期贷方余额] [money] NULL ,
[最后结算分录] [int] NULL ,
[会计期间] [int] NULL ,
[余额方向] [char] (4) NULL ,
[内部编号] [int] IDENTITY (1, 1) NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[资产负债表] (
[会计期间] [int] NOT NULL ,
[现金及现金等价物] [money] NULL ,
[应收帐款] [money] NULL ,
[坏帐准备] [money] NULL ,
[应收帐款净值] [money] NULL ,
[流动资产总计] [money] NULL ,
[固定资产原值] [money] NULL ,
[累计折旧] [money] NULL ,
[固定资产总计] [money] NULL ,
[其他资产] [money] NULL ,
[资产总计] [money] NULL ,
[应付帐款] [money] NULL ,
[预收帐款] [money] NULL ,
[应付工资] [money] NULL ,
[其他负债] [money] NULL ,
[负债总计] [money] NULL ,
[实收资本] [money] NULL ,
[资本公积] [money] NULL ,
[赢余公积] [money] NULL ,
[未分配利润] [money] NULL ,
[所有者权益总计] [money] NULL ,
[负债及所有者权益总计] [money] NULL
) ON [PRIMARY]
GO
创建主键及外键等表约束
在查询分析器中通过如下代码创建数据表的主键及外键等表约束。
-- 主键、外键关联字段
ALTER TABLE [dbo].[科目表] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED
(
[科目代码]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[凭证表] WITH NOCHECK ADD
CONSTRAINT [PK_凭证表] PRIMARY KEY CLUSTERED
(
[凭证编号]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[分录表] WITH NOCHECK ADD
CONSTRAINT [PK_分录表] PRIMARY KEY CLUSTERED
(
[编号]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[帐簿初始化表] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED
(
[科目代码]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[本期汇总帐簿] WITH NOCHECK ADD
CONSTRAINT [PK_本期汇总帐簿] PRIMARY KEY CLUSTERED
(
[科目代码]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[分录表] ADD
CONSTRAINT [FK_分录表_凭证表] FOREIGN KEY
(
[凭证编号]
) REFERENCES [dbo].[凭证表] (
[凭证编号]
),
CONSTRAINT [分录表_科目代码_fk] FOREIGN KEY
(
[科目代码]
) REFERENCES [dbo].[科目表] (
[科目代码]
)
GO
-------------------------------------------
其他外键、主键等约束参看配书光盘脚本
创建存储过程
系统使用了“sf_初始化帐户”、“sf_启用帐户”、“sf_凭证过帐”、“sf_期末结帐”
和“sf_计算资产负债表”5 个存储过程,实现的功能分别为新建帐套、启用帐套、
凭证过帐确认、期末结帐和运算指定会计期间的资产负债表等功能。具体计算方
法在下面的脚本中有详细的注释,读者可以参考这些注释。
create proc sf_初始化帐户
as
begin tran
-- 清除原来数据,从新建立帐户
delete from 帐簿初始化表
-- 设置帐户初始基本数据
insert into 帐簿初始化表
(科目代码,科目名称,累计借方,累计贷方,期初余额,余额方向)
select 科目代码,科目名称,0,0,0,余额方向 from 科目表
-- 设置初始信息
update 系统参数表 set 取值 = datepart(mm,getdate())
where 参数名称 = '会计期间开始月份'
update 系统参数表 set 取值 = datepart(mm,getdate())
where 参数名称 = '当前会计期间'
commit
GO
create proc sf_启用帐户
as
begin tran
-- 清除原来数据,从新建立帐户
delete from 科目余额表
delete from 本期汇总帐簿
delete from 本期明细帐簿
delete from 分录表
delete from 分录表历史
delete from 凭证表
delete from 凭证表历史
-- 设置本期汇总帐簿及科目余额表
insert into 本期汇总帐簿 select 科目代码,0,期初余额,
0,0,0,0,期初余额,余额方向 from 帐簿初始化表
update 本期汇总帐簿 set 会计期间=b.取值 from
系统参数表 as b where 参数名称='当前会计期间'
insert into 科目余额表(科目代码, 期初借方余额, 期初贷方余额,
本期借方发生额, 本期贷方发生额, 本年借方累计发生额,
本年贷方累计发生额, 本期借方余额, 本期贷方余额,
余额方向)
select 科目代码,累计借方,累计贷方,0,0,0,0,
case when 余额方向='借方' then 期初余额 else 0 end,
case when 余额方向='贷方' then 期初余额 else 0 end,
余额方向 from 帐簿初始化表
update 科目余额表 set 会计期间=b.取值 from
系统参数表 as b where 参数名称='当前会计期间'
commit
GO
create proc sf_凭证过帐
as
begin tran
-- 设置本期汇总帐簿信息
update 本期汇总帐簿 set 本期借方合计 = 本期借方合计 + b.借方,
本期贷方合计 = 本期贷方合计 + b.贷方,
本年借方累计 = 本年借方累计 + b.借方,
本年贷方累计 = 本年贷方累计 + b.贷方,
余额 = 余额 + case when 余额方向='借方' then (借方 - 贷方)
else (贷方 - 借方) end
from 本期汇总帐簿 as a,
(select 科目代码, sum(借方) as 借方, sum(贷方) as 贷方
from 分录表 as f, 凭证表 as p where f.凭证编号 = p.凭证编号
group by f.科目代码) as b
where a.科目代码 = b.科目代码
-- 设置本期明细帐簿信息
insert into 本期明细帐簿(分录编号,会计期间,凭证字号, 凭证编号, 摘要,
科目代码, 借方, 贷方, 数量, 单价, 结算方式, 结算号, 结算日期)
select 编号,会计期间,凭证字号, p.凭证编号, 摘要, 科目代码, 借方, 贷方, 数量, 单价,
结算方式, 结算号, 结算日期 from 凭证表 as p, 分录表 as f where f.凭证编号 = p
.
凭证编号
--计算余额
update 本期明细帐簿
set 余额方向=a.余额方向 from 科目表 as a
where 本期明细帐簿.科目代码=a.科目代码
-- 通过游标循环计算余额
declare @bh int, @dm char(20), @jf money, @df money
declare @fx char(4), @bj char(4), @ye money, @kjqj int
declare mycursor cursor for select 内部编号,科目代码,
借方,贷方,余额方向,余额标记,会计期间 from 本期明细帐簿
where 余额标记 is null order by 内部编号
open mycursor
fetch next from mycursor into @bh,@dm,@jf,@df,@fx,@bj,@kjqj
while (@@fetch_status=0)
begin
select @ye = 余额 from 本期明细帐簿 where 内部编号 in (select max(内部编号) from
本期明细帐簿 where 内部编号 < @bh and 科目代码=@dm and 余额标记 = '是')
-- 没有,本期第一条明细,从科目余额表取余额
if(@ye is null)
select @ye = case when 余额方向='借方' then
本期借方余额 - 本期贷方余额 else
本期贷方余额 - 本期借方余额 end
from 科目余额表 where 会计期间 = @kjqj
and 科目代码 = @dm
select @ye = isnull(@ye,0)
update 本期明细帐簿
set 余额=case when @fx='借方' then
@ye + @jf - @df else
@ye + @df - @jf end,
余额标记='是'
where 内部编号=@bh
fetch next from mycursor into @bh,@dm,@jf,@df,@fx,@bj,@kjqj
end
close mycursor
deallocate mycursor
-- 更改状态
update 凭证表 set 过帐状态 = '已过'
-- 放入历史
insert into 凭证表历史 select * from 凭证表
insert into 分录表历史 select * from 分录表
-- 清除已过帐数据,注意,应放到程序中清除,因为要统计凭证张数/分录张数和金额
-- 统计后删除
-- delete from 分录表
-- delete from 凭证表
commit
GO
create proc sf_期末结帐
as
begin tran
-- 先将没有过帐的凭证过帐
exec sf_凭证过帐
declare @kjqj int -- 当前会计期间
select @kjqj = 会计期间 from 本期汇总帐簿
-- 计算科目余额表,可以统计资产负债表/损溢表等
update 科目余额表 set 本期借方发生额 = b.本期借方合计,本期贷方发生额 = b.本期贷
方合计,
会计期间 = b.会计期间, 余额方向 = b.余额方向
from 科目余额表 as a, 本期汇总帐簿 as b
where a.科目代码 = b.科目代码 and a.会计期间=b.会计期间
update 科目余额表 set
本年借方累计发生额 = 本年借方累计发生额 + 本期借方发生额,
本年贷方累计发生额 = 本年贷方累计发生额 + 本期贷方发生额,
本期借方余额 = 期初借方余额 + 本期借方发生额,
本期贷方余额 = 期初贷方余额 + 本期贷方发生额
where 会计期间 = @kjqj
-- 更新会计期间
update 系统参数表 set 取值 = 取值 + 1 where 参数名称='当前会计期间'
-- 将本期汇总帐簿和明细帐簿倒入历史,实例程序不演示
----------------------------------------------
-- 清除汇总帐簿和明细帐簿,进入新的会计期间
update 本期汇总帐簿 set 会计期间 = 会计期间 + 1, 期初余额=余额,
本期借方合计 = 0, 本期贷方合计 = 0, 余额 = 0
delete from 本期明细帐簿
-- 新会计期间的科目余额表
insert into 科目余额表(科目代码, 期初借方余额, 期初贷方余额, 本期借方发生额,
本期贷方发生额, 本年借方累计发生额, 本年贷方累计发生额, 本期借方余额,
本期贷方余额, 余额方向,会计期间)
select 科目代码, 本期借方余额, 本期贷方余额,0,0,0,0,
本期借方余额, 本期贷方余额, 余额方向,会计期间+1
from 科目余额表 where 会计期间 = @kjqj
commit
GO
create proc sf_计算资产负债表 @kjqj int
as
begin tran
-- 计算资产负债表,这里提供计算的方法仅供演示
-- 没有列出的明细项目都归到其他资产和其他负债里
-- 注意,这里按照科目代码统计,主要说明资产负债表的含意和计算方法
-- 如果科目代码不是这样,则该存储过程需要作相应的修改
delete from 资产负债表 where 会计期间 = @kjqj
insert into 资产负债表(会计期间) values(@kjqj)
update 资产负债表 set 现金及现金等价物 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期借方余额,0)-isnull(本期贷方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 >= 101 and 科目代码 <= 111)
as b where a.会计期间 = @kjqj
update 资产负债表 set 应收帐款 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期借方余额,0)-isnull(本期贷方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 >= 121 and 科目代码 <= 129 and 科目代码<>125)
as b where a.会计期间 = @kjqj
-- 注意坏帐准备为贷方
update 资产负债表 set 坏帐准备 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 = 125)
as b where a.会计期间 = @kjqj
update 资产负债表 set 应收帐款净值 = 应收帐款 - 坏帐准备
update 资产负债表 set 流动资产总计 = 现金及现金等价物 + 应收帐款净值
update 资产负债表 set 固定资产原值 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期借方余额,0)-isnull(本期贷方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 =171)
as b where a.会计期间 = @kjqj
-- 注意累计折旧为贷方
update 资产负债表 set 累计折旧 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 = 175)
as b where a.会计期间 = @kjqj
update 资产负债表 set 固定资产总计 = 固定资产原值 - 累计折旧
update 资产负债表 set 其他资产 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期借方余额,0)-isnull(本期贷方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 >= 131 and 科目代码 <= 195 and 科目代码<>171
and 科目代码 <> 175)
as b where a.会计期间 = @kjqj
update 资产负债表 set 资产总计 = 流动资产总计 + 固定资产总计 + 其他资产
-- 计算负债及所有者权益
-- 负债类级别都是贷方金额
update 资产负债表 set 应付帐款 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 >= 201 and 科目代码 <= 204 )
as b where a.会计期间 = @kjqj
update 资产负债表 set 预收帐款 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 = 206)
as b where a.会计期间 = @kjqj
update 资产负债表 set 应付工资 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 = 215)
as b where a.会计期间 = @kjqj
update 资产负债表 set 其他负债 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 >= 209 and 科目代码 <= 281 and 科目代码 <> 215)
as b where a.会计期间 = @kjqj
update 资产负债表 set 负债总计 = 应付帐款 + 预收帐款 + 应付工资 + 其他负债
-- 计算所有者权益
update 资产负债表 set 实收资本 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 = 301)
as b where a.会计期间 = @kjqj
update 资产负债表 set 资本公积 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 = 311)
as b where a.会计期间 = @kjqj
update 资产负债表 set 赢余公积 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and 科目代码 = 313)
as b where a.会计期间 = @kjqj
update 资产负债表 set 未分配利润 = b.金额 from 资产负债表 as a,
(select sum(isnull(本期贷方余额,0)-isnull(本期借方余额,0)) as 金额
from 科目余额表 where 会计期间 = @kjqj and
科目代码 = 321 or 科目代码 = 322 )
as b where a.会计期间 = @kjqj
update 资产负债表 set 所有者权益总计 = 实收资本 + 资本公积 +
赢余公积 + 未分配利润
update 资产负债表 set 负债及所有者权益总计 = 负债总计 + 所有者权益总计
commit
GO
实例的程序结构仍然为 MDI 模式,这种开发模式结构清晰简单,易于理解,
每一个功能对应一个子窗体。
程序运行结果
本实例运行后的效果如图 所示。选择菜单中的各菜单项就可以进入各相
应功能窗口。
图 实例运行效果
(1) 选择【基础数据管理】|【科目设置】菜单命令,进入【会计科目设置】
功能窗体,如图 所示。在这个窗体中,可以对会计科目的各项基础信息进
行管理。其中【科目类别】选项组表示该科目所属的类别,有资产、负债、权益、
损溢和成本 5 个选项,一般资产类科目余额方向为借方,负债和权益科目余额方
向为贷方,但这也不绝对,其中也有例外的情况,如“坏帐准备”的科目余额方向
则为贷方。
图 会计科目设置功能
该窗体中还设有搜索功能,在窗体中的文本框内输入科目代码,科目名称或
类别中的任何一项或几项,再单击【搜索】按钮,即可在窗体左边的表格中得到
与设定的搜索条件相符合的结果。同时窗体中还显示当前表格中的数据总数。
在浏览情况下,除搜索一栏的文本框外,窗体中的表格,数据文本框和选项
组中的数据都是不可编辑状态的,只有当【新增】或者【修改】按钮被按下后才
可以使用,当单击【保存】或【取消】按钮提交后,它们又恢复只读状态。
需要对数据表中的数据进行修改或者新增数据时,单击相应的按钮,输入新
信息后单击【保存】按钮即可。需要删除一条信息,单击【删除】按钮。
(2) 科目设置完成后,选择【基础数据管理】|【帐户设置】菜单命令,进入
【帐户设置(期初数据录入)】功能窗体,如图 所示。
图 帐户设置功能
该功能模块有【建立新帐簿】、【启用帐簿】和【试算平衡】3 个按钮。【建
立新帐簿】按钮用于建立一个新的初始帐簿,单击该按钮,系统在后台调用“sf_
初始化帐户”存储过程,删除“帐簿初始化表”原有的信息,根据“科目表”重新创
建“帐簿初始化表”并在窗体中显示。在表格中输入各科目的初始信息和系统参数
信息,完成后通过【启用帐簿】按钮启用新的帐簿。【启用帐簿】按钮先检查当
前帐簿试算是否平衡,如果平衡在后台调用“sf_启用帐户”存储过程,启用新定
义的帐簿,如果不平衡,会提示用户查阅试算平衡表,检查输入的初始化信息并
修改,直到试算平衡才能启用新定义的帐簿。需要注意的是,启用新定义的帐簿
会删除系统中历史的所有数据。【试算平衡】按钮可以随时查看当前的帐簿信息
是否平衡,当试算不平衡时,窗体下方的表格将变为红色,向用户发出试算不平
衡的警告。如图 和 所示。从窗体下方的合计金额可以看出不平衡的原
因。
图 试算结果不平衡
图 试算结果平衡
(3) 启用帐簿后可以进行凭证录入的工作。选择【凭证管理】|【凭证输入】
菜单命令,进入【会计凭证输入】功能窗体,如图 所示,在其中输入凭证
和会计分录信息。若单击【新增】按钮,系统自动新建一个凭证,凭证号和会计
期间等信息自动生成,其中的会计期间是“系统参数表”中的“当前会计期间”,日
期是系统的当前日期,窗体后台程序对凭证编号自动进行计算保证新输入的凭证
号不和以前已有的凭证编号冲突。在下方的 StringGrid 中,双击“科目名称”列,
将弹出一个包括科目设置的基本信息的窗体,在该窗体表格中的任意一栏双击,
将选中的科目名称和科目代码自动输入到【会计凭证输入】窗体中的 StringGrid
中并关闭该选择窗体,如需添加多条分录信息,则可以再次双击“科目名称”列,
重复前面的操作逐项输入分录的信息,完成后单击【保存】按钮,系统先检查借
贷双方是否平衡,如果平衡给予保存。需要修改某个凭证的信息,选择相应的凭
证,单击【修改】按钮,修改完成后单击【保存】按钮即可,如图 和图
所示。
图 会计凭证输入功能
图 科目名称选择窗体
在保存会计凭证设置时,程序也会进行计算,核查分录表中的数据是否平衡,
如果各项分录数据的借贷双方合计不等,程序将提示用户进行修改,直到平衡。
这样,就完成了会计凭证的输入工作,需要对凭证进行过帐。凭证过帐就是确认
输入的会计凭证,过帐后的凭证不能在进行修改。
(4) 选择【凭证管理】|【凭证过帐】菜单命令,系统提示是否过帐,如图
9 所示。单击【是】按钮,系统在后台调用“sf_凭证过帐”存储过程,对凭证进行
过帐,计算本期汇总帐簿和明细帐簿。过帐完成后系统提示过帐成功,并显示过
帐的凭证数及借贷方金额等反馈信息,如图 所示。
图 凭证过帐功能
图 凭证过帐后的反馈信息
(5) 可以分别选择【帐簿查询】|【总分类帐】和【帐簿查询】|【明细帐】命
令,进入本期【总分类帐查询】和【明细帐查询】功能。在【总分类帐查询】窗
体中,可以通过选中【无发生金额布显示】单选框来确定是否要对表格中的数据
进行过滤,只显示那些发生了金额的项目,如图 所示。
图 总分类帐查询
(6) 【明细帐查询】窗体的表中显示的是所有的明细帐单,用户可以将左边
的列表框中现有所有明细帐单的科目名称逐个添加到右边的列表框中,从而控制
在表格中显示哪些明细帐单,如图 和图 所示。
图 明细帐查询
图 明细帐单项过滤
当前会计期间内的所有凭证过帐完成后,可以进行月末结帐操作,转入下一
会计期间,结帐前首先要进行试算平衡的检查。
(7) 选择【结帐及报表】|【试算平衡表】菜单命令,可以看到当前帐目的平
衡信息,如图 所示。这里的试算平衡表与前面初始化帐簿中的试算平衡表
是有所差别的。初始化帐簿的试算平衡,需要根据初始化的信息反算期初信息,
而结帐阶段的试算平衡表主要反映在凭证过帐之后结帐时的统计信息。对比图 4
.34 和图 就可以发现其区别。
试算结果平衡后选择【结帐及报表】|【期末结帐】菜单命令,系统在后台调
用“sf_期末结帐”存储过程,进行结帐操作。
图 试算平衡功能
(8) 结帐后可以查询当月的资产负债表,选择【结帐及报表】|【资产负债表】
菜单命令,系统先提示输入统计的会计期间,默认是当前会计期间,确定后调用
“sf_计算资产负债表”存储过程计算资产负债表,然后在报表窗体中显示报表,
如图 所示。
图 资产负债表
启动 Delphi,采用默认设置新建一个工程,并将工程保存为“”。选择 Project
| Options…菜单命令,在 Application 选项卡中修改工程的 Title 属性为“财务管理系统”,并
为项目选择一个.exe 程序的图标,本例我们在配书光盘的 \Chap4\icon 目录下选择
文件。(1) 利用系统默认生成的窗体作为主窗体,并为其添加主菜单控件和其他
控件,布局如图 所示。将该窗体设置为 MDI 的主窗体,正如我们在第 3 章
中所做的那样。
图 系统主窗体
窗体及其控件的属性设置如表 所示。
表 主窗体属性设置
控件类型 对象(控件)名 属 性 取值(说明)
TForm Main Name main
Caption 财务管理系统
FormStyle fsMDIForm
Position poDesktopCenter
TADOCommand ADOCommand ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
TADOQuery ADOQuery1 ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
SQL select count(distinct 凭证编号) 凭证数, sum(借方) 借方
金额,sum(贷方) 贷方金额 from 分录表
TADOQuery ADOQuery3 ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
SQL select * from 系统参数表
(2) 窗体的主菜单属性设置如图 所示。
(3) 为各菜单的添加如下功能代码。
type
Ttable=array[0..2] of string;
//…此处为系统窗体构件声明,省略…
public
{ Public declarations }
//para 用于保存系统参数,FindForm 用于寻找 MDI 子窗体,//setpara 用于更新 para 的值
para:Ttable;
function FindForm(caption:string):bool;
procedure setpara();
end;
var
main: Tmain;
para:Ttable;
implementation
{$R *.dfm}
uses SecSettingForm,AccountSettingForm,DocuInputForm,TotalAccountForm,DetailAccountFor
m,SumAccountForm,FinalReportForm;
//-----------通过用户定义的函数,判断窗体是否存在--------------------
function (caption: string): bool;
var
i:integer;
begin
for i:=0 to do
begin
// 通过对窗体标题判断窗体是否存在
if [i].Caption=caption then
begin
//如果窗体已存在,则恢复窗体,并返回 true
SendMessage(mdichildren[i].Handle, WM_SYSCOMMAND, SC_restore, 0);
mdichildren[i].Enabled:=true;
mdichildren[i].Show;
mdichildren[i].SetFocus;
result:=true;
break;
end
else
//如窗体不存在,则返回 false,程序将创建窗体
result:=false;
end
end;
//----该函数的作用是保存系统参数表中的参数,并在调用前更新---
procedure ;
var
i:integer;
begin
:=false;
:=true;
i:=0;
while not do
begin
//保存系统参数
para[i]:=('取值').AsString;
i:=i+1;
;
end;
end;
//----------------显示会计科目设置窗体-------------------
procedure (Sender: TObject);
var
newform:TSecSetting;
begin
if findForm('会计科目设置')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='会计科目设置';
end;
end;
//----------------显示帐户设置窗体-------------------
procedure (Sender: TObject);
var
newform:TaccountSetting;
begin
if findForm('帐户设置(期初数据录入)')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='帐户设置(期初数据录入)';
end;
end;
//----------------显示凭证设置窗体-------------------
procedure (Sender: TObject);
var
newform:TDocuInput;
begin
if findForm('会计凭证输入')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='会计凭证输入';
end;
end;
//----------------显示总分类帐查询窗体-------------------
procedure (Sender: TObject);
var
newform:Ttotalaccount;
begin
if findForm('总分类帐查询')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='总分类帐查询';
end;
end;
//----------------显示明细帐查询窗体-------------------
procedure (Sender: TObject);
var
newform:Tdetailaccount;
begin
if findForm('明细帐查询')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='明细帐查询';
end;
end;
//----------------显示试算平衡表窗体-------------------
procedure (Sender: TObject);
var
newform:Tsumaccount;
begin
if findForm('试算平衡表(正式使用)')=false then
begin
//若窗体不存在,则创建窗体
newform:=(application);
:='试算平衡表(正式使用)';
//在正式平衡表中使用
;
end;
end;
//----------------执行凭证过帐储存过程---------------------
procedure (Sender: TObject);
var
pnum,inputsum,outputsum:string;
begin
if ('凭证过帐后即不可修改,是否确认过帐?','确认',MB_OKCANCEL)=IDOK
then
begin
//获得分录表中的统计数据
:=false;
:=true;
pnum:=('凭证数').AsString;
inputsum:=('借方金额').AsString;
outputsum:=('贷方金额').AsString;
//执行储存过程,实现凭证过帐
try
:='exec sf_凭证过帐';
;
except
showmessage('过帐失败');
exit;
end;
//显示成功信息,并显示统计数据
showmessage('过帐成功'+#13+#13+'过帐凭证数目为:'+pnum+#13+'借方金额合计:
'+inputsum+#13+'贷方金额合计'+outputsum);
//删除分录表和凭证表
:='delete from 分录表';
;
:='delete from 凭证表';
;
end;
end;
//-----执行期末结帐的储存过程--------
procedure (Sender: TObject);
begin
if ('结帐将进入下一个会计期间,是否结帐?','确认',
MB_OKCANCEL)=IDOK then
begin
try
:='exec sf_期末结帐';
;
except
showmessage('结帐失败');
exit;
end;
showmessage('结帐成功');
end;
end;
//--------资产负债报表的生成和打印----------
procedure (Sender: TObject);
var
index:integer;
inputstring:string;
newform:TFinalReport;
begin
//取得当前会计期间的值
setpara();
index:=strtoint(para[2]);
//提示用户输入要显示的会计期间
inputstring:= InputBox('请选择所要统计的会计期间', '会计期间', inttostr(index-1));
index:=strtoint(inputstring);
//计算资产负债表
:='exec sf_计算资产负债表 '''+inputstring+'''';
;
//显示报表窗体,这里不需要再查找是否已有报表窗体
//这是因为每次调用的报表窗体都可能显示不同的会计期间
newform:=(application);
(index);
;
end;
//------关闭窗体--------------------
procedure (Sender: TObject);
begin
close;
end;
以上是主窗体的所有代码,与第 3 章中主窗体代码有区别的是我们自己编写
了一个 FindForm 函数来查找一个 MDI 子窗体是否存在,使用专门的函数可以大
大地压缩代码规模,使程序显得简练。同时,我们在主窗体执行储存过程中还是
使用了 try…except 语句,这样做可以在储存过程出现错误时提示用户。读者可
以在自己的程序中选择使用。
在前面的章节中,无论我们的程序是多文档还是多窗口结构,使用到的窗
体都是预先定义好,并在编写程序时就加载到了工程文件之中的。在这里我们
将要用到 DLL,DLL 是 Dynamic-Link Libraries(动态链接库)的缩写,它包含代
码、数据和资源,可以被其他程序共享,使用 DLL 应用程序能够在程序运行期
间动态地调入代码,而不是在编译期间静态地链接代码。可以认为 DLL 和 EXE
基本上是一回事,只是 DLL 不能直接执行,而必须由应用程序或者其他 DLL
调用。DLL 为应用程序间的资源共享提供了方便,同时也是多语言混合编程的
重要手段。由此可见学习使用 DLL 是 Windows 程序员必须掌握的一项重要技
术。
使用 DLL 从效果上看很像使用单元(Unit),因为程序员可以在一个程序模
块中调用别的 Unit 中声明且定义的过程、函数,甚至变量。如果一个程序模块
中用 uses 语句应用别的 Unit,那么编译程序在编译该模块时便会连同被调用的
Unit 一同编译,并且把编译后得到的课执行文件连接到本模块的可执行文件上。
即编译后的一个工程 Project 只有一个可执行文件,但是可以包含多个单元的执
行代码。当 Unit 被多个 Project 所引用,则它的执行代码将会出现在多个 Project
的可执行代码中。如果多个 Project 同时运行,那么 Unit 的代码会随着 Project
多次被调入内存,内存资源被多个重复的代码段所占用,既浪费空间,又影响
程序的允许速度。用 DLL 就可以解决这个问题。DLL 被某个可 project 编译后
仍然是独立的,当多个 project 调用某个 dll 文件时,只有第一个调用 dll 的 proje
ct 才把 DLL 的执行代码调入内存,其他的 Project 并不把 Dll 调入而是增加其
引用次数,并与第一个 Project 一起共享某个 DLL 的执行代码。
例如,在本章中我们将设计一个 DLL,它本身有一个窗体,在外部程序调
用它时,依靠外部变量输入的变量来判断调用数据库中的哪个表,并有一个函
数负责返回双击某数据栏后该数据栏的内容。使用这个 DLL,我们可以在程序
中通过调用它来浏览财务管理数据库中的任何一个表,并可以通过双击来选择
某一栏的内容。读者可以在读完本节后回顾前面三章中我们如何处理类似的任
务,例如在第 1 章中进货单和销售单对于双击选择商品名称,编号的处理,再
和本节中的处理方法加以比较,就可以看到 DLL 的巨大作用。
至于 DLL 更深层次的问题,不属于本书的讨论范围,这里不再叙述。
在本章中,我们用到的 DLL 非常简单,我们使用它的目的在于向读者介绍
这样一种方法,其功能完全可以单独建立一个 MDI 子窗体来替代,在以后的
章节中我们将越来越多地用到这些高级技术。
(1) 首先重新打开 Delphi,选择 File | New | Other...,在弹出的窗口中的 New
选项卡中选择 DLL Wizard 并单击 OK,如图 所示,将建立一个新的工程。
(2) 将这个新的工程保存为 ,再新建一个窗体(Form),将其 Name 属
性改为 dllSec,并保存该窗体文件为 。查看工程的代码,可以看到如
下程序。
library sec;
uses
SysUtils,
Classes,
//此处是加入工程的 unit,dllSec 是该 Unit 的 Name,而 dllForm 是该 Unit 保存的文件名
dllForm in '' {dllSec};
{$R *.res}
exports
//这是将要输出供外部调用的函数
showdllform index 1;
begin
end.
图 建立 DLL 工程文件
(3) 在新建的 Form 放置如图 所示的控件。
图 将在 dll 调用的窗体
该窗体的控件设置如表 所示。
表 主窗体属性设置
控件类型 对象(控件)名 属 性 取值(说明)
TForm DllSec Name dllSec
Caption 选择
续表
控件类型 对象(控件)名 属 性 取值(说明)
TADOTable ADOTable ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
TDataSource DataSource1 DataSet ADOTable1
TDBGrid DBGrid1 DataSource DataSource1
该窗体所要完成的任务是调用该 dll 的程序向窗体输入要链接的数据表的表
名,当数据表链接成功后可以通过双击 DBGrid 的某栏向调用该窗体的程序返回
表中的某一项值,并关闭窗体。
(4) 为该窗体的设置处理代码如下。
unit dllForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, ADODB;
type
TdllSec = class(TForm)
ADOTable1: TADOTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure DBGrid1DblClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//此函数负责取得当前应用程序的句柄并显示窗体,它是供外部调用的函数
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
//用此变量向调用 dll 的程序返回值
resultstr:string;
implementation
{$R *.dfm}
function showdllform(Ahandle:Thandle;Acaption:string;tablename:string):string;stdcall;
var
newform:Tdllsec;
begin
//取得句柄
:=Ahandle;
//建立窗体
newform:=(application);
:=Acaption+'(双击选择)';
//建立数据库链接
:=tablename;
:=true;
//显示窗体
try
;
//返回双击所选择的结果
result:=resultstr;
//释放该窗体
finally ;
end;
end;
//-------双击选择数据栏返回数值---------
procedure (Sender: TObject);
begin
resultstr:=[0].Text;
close;
end;
//--------设置表宽度----------
procedure (Sender: TObject);
var
i:integer;
begin
for i:=0 to -1 do
[i].Width:=64;
end;
end.
此时按 F9 键运行该工程的话,就会得到如图 所示的信息。
图 直接运行 dll 得到的信息
这是因为调试.dll 时需要一个宿主程序,如果编译后直接运行,就会得到这
个提示,解决这一问题需要写一个调用这个.dll 的.exe 程序,编译后将它的路径
填到 Run | Parameters 菜单的 Host app... 输入条中。
但是实际上,如果直接按 F9 或编译允许 DLL 工程后,即便是弹出了上面的
对话框,若读者浏览该工程所储存目录,就可以发现已经生成了一个 动态
链接库,这就是我们在下面的程序中要用到的 DLL,就可以直接调用了。
新建一个窗体,将窗体的 Name 属性设置为“SecSetting”,Caption 属性设
置为“会计科目设置”。
(1) 单击 Project | Options...菜单命令,将 SecSetting 窗体从自动创建的窗体
列表中删除,将窗体保存为“”。为窗体添加如图 所示的控
件。其中除搜索栏的编辑框属于 Edit 控件外,其他编辑框都使用 DBEdit 控件,
所有数据库控件的 DataSet 都设置为 DataSource1 各控件属性如表 所示。
图 会计科目设置窗体
表 会计科目设置窗体控件清单
控件类型 对象(控件)名 属 性 取值(说明)
TForm SetSetting Name SecSetting
Caption 会计科目设置
FormStyle fsMDIChild
Position poDesktopCenter
DataSource DataSource1 DataSource ADOQuery1
TADOQuery ADOQuery1 ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
SQL select * from 科目表
Active True
TADOQuery ADOQuery3 ConnectionString 连接方法如 节所述,数据库设置为 caiwubook
TDBRadioGroup DBRadioGroup1 Items 资产
负债
权益
损溢
成本
TDBRadioGroup DBRadioGroup2 Items 借方
贷方
(2) 这里需要说明的是窗体中 ImageList 和 ToolBar 中 ToolButton 的设置方
法。
首先双击这个控件,弹出如图 所示的对话框,单击 Add.. 按钮,将配书
光盘中\Chap4\ocons 目录下的图标一一添加,从对话框中的 Images 框中可以看
到添加的图标。然后将 ToolBar 的 Images 属性设为 ImageList1 后,在 ToolBar 上
再右击,在弹出的菜单中选择 New Button 或 New Separator 可以在工具栏上添
加按钮或分割符,按钮的图标就是刚才在 ImageList 中加入的图标了。
图 设置 ImageList
(3) 需要注意的一点是在设置 DBRadioGroup1 的 Items 属性时,由于数据库
中的项目都是 10 个字符长度,因此可能出现无法正常显示的情况,这时只要将
Items 中每项后面补上足够的空格即可。
public
{ Public declarations }
procedure SetToolBar(isEnable:bool);
end;
var
SecSetting: TSecSetting;
implementation
{$R *.dfm}
//---------------设置关闭窗体的模式-----------------
procedure (Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
end;
//--------------设置表格宽度----------------
procedure (Sender: TObject;
Field: TField);
begin
//显示数据数量
:=inttostr();
//设置数据表宽度
[0].Width:=60;
[1].Width:=90;
end;
//-----------专门写一个函数来实现工具栏按钮的设置,让代码更加简练----------------
procedure (isEnable: bool);
begin
if isEnable=true then
begin
//将首记录等记录移动按钮设置为不可用
:=false;
:=false;
:=false;
:=false;
//将新增、修改等按钮设置为不可用
:=false;
:=false;
:=false;
//将保存和取消按钮设置为可用
:=true;
:=true;
//将窗体内的数据显示控件设为可读
:=false;
:=false;
:=false;
:=false;
:=false;
end;
if isEnable=false then
begin
//将首记录等记录移动按钮设置为可用
:=true;
:=true;
:=true;
:=true;
//将新增修改等按钮设置为可用
:=true;
:=true;
:=true;
//将保存和取消按钮设置为不可用
:=false;
:=false;
//将窗体内的数据显示控件设为只读
:=true;
:=true;
:=true;
:=true;
:=true;
end;
end;
//---------------新增记录----------------
procedure (Sender: TObject);
begin
SetToolBar(true);
;
end;
//---------------修改记录----------------
procedure (Sender: TObject);
begin
SetToolBar(true);
;
end;
//---------------删除记录----------------
procedure (Sender: TObject);
begin
if ('删除该条记录?','财务管理系统',MB_OKCANCEL)=IDOK then
;
end;
//---------------首记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------上记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------下记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------尾记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------关闭窗体----------------
procedure (Sender: TObject);
begin
close;
end;
//---------------保存记录----------------
procedure (Sender: TObject);
begin
//检查科目代码是否已输入
if ='' then
begin
showmessage('科目代码不允许为空值');
exit;
end;
;
SetToolBar(false);
end;
//---------------取消操作----------------
procedure (Sender: TObject);
begin
;
SetToolBar(false);
end;
//----------查询数据并显示-------------
procedure (Sender: TObject);
begin
;
;
('select * from 科目表 where (科目代码 like ''%'++'%'')and');
('(科目名称 like ''%'++'%'')and(科目类别 like ''%'++'%'')
');
;
end;
完成帐户设置功能
(1) 新建一个窗体,将窗体的 Name 属性设置为“AccountSetting”,选择 Project
| Options...菜单命令,将 SecSetting 窗体从自动创建的窗体列表中删除,将窗体
保存为“”。该窗体的控件布局和设置如图 所示。其
中所有 ADO 控件的 ConnectionString 在前面几章中已多次提及,因此在此后的
内容中将不再一一列出它们的此项属性。
图 帐户设置窗体
(2) 窗体的控件设置如表 所示。
表 帐户设置窗体控件属性
控件类型 对 象 名 属 性 取值(说明)
TADOTable ADOTable1 TableName 帐簿初始化表
Active true
TADOTable ADOTable1 TableName 系统参数表
Active true
DataSouce DataSource1 DataSet ADOTable1
DataSouce DataSource2 DataSet ADOTable2
TBitBtn BitBtn1 Caption 建立新帐簿
TBitBtn BitBtn2 Caption 启用帐簿
TBitBtn BitBtn3 Caption 试算平衡
TDBGrid DBGrid1 DataSource DataSource1
TDBGrid DBGrid2 DataSource DataSource2
(3) 分别双击 DBGrid1 和 DBGrid2,为其指定显示的字段,如图 所示。
图 DBGrid1 和 DBGrid2 的字段
(4) 将“科目代码”、“科目名称”、“余额方向”和“编号”、“参数名称”字段的 ReadO
nly 属性设置为“true”,因为这些字段是不允许用户修改的;将这些字段的 Color
属性设置为“clMoneyGreen”,从而和可编辑的字段区分开来。
单击【试算平衡】按钮将创建一个新的窗体来显示初始化帐本后试算平衡的
结果,这个新窗体还同时担负显示过帐后试算平衡的结果,因此需要专门设计。
(5) 新建一个窗体,名为“SumAccount”,将它从自动创建的窗体列表中删除,
并为其添加如图 所示的控件,控件属性如表 所示。
图 试算平衡窗体
表 试算平衡窗体控件属性设置
控件类型 对 象 名 属 性 取值(说明)
Tform SumAccount Name SumAccount
TForm SumAccount Caption 试算平衡表
续表
控件类型 对 象 名 属 性 取值(说明)
TADOQuery ADOQuery1 SQL select 科目代码, 科目名称, (case when 余额方向='借方' then 期初
余额 else 0 end - 累计借方) as 期初借方, (case when 余额方向='贷
方' then 期初余额 else 0 end - 累计贷方) as 期初贷方, 累计借方 as
本期发生借方,累计贷方 as 本期发生贷方, case when 余额方向='借
方' then 期初余额 else 0 end as 期末借方, case when 余额方向='贷
方' then 期初余额 else 0 end as 期末贷方 from 帐簿初始化表 where
累计借方<>0 or 累计贷方<>0 or 期初余额<>0
Active True
DataSource DataSource1 DataSet ADOQuery1
DBGrid DBGrid1 DataSource DataSource1
StringGrid StringGrid1 ColCount 8
RowCount 2
(6) 试算平衡表和帐户设置窗体的的事件处理代码如下。
//---------------------以下为试算平衡表的事件处理代码--------------------
private
{ Private declarations }
//统计计算是否平衡
procedure sumtable();
public
{ Public declarations }
//当使用后结帐时所调用的函数
procedure foruse();
//初始化帐本时使用
procedure forinitial();
end;
var
SumAccount: TSumAccount;
implementation
uses MainForm;
{$R *.dfm}
procedure (Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
end;
//------设置窗体宽度和过滤条件---------
procedure (Sender: TObject;
Field: TField);
begin
//设置过滤条件
:='本期发生借方<>0 OR 本期发生贷方<>0 OR 期初借方<>0
OR 期初贷方<>0 OR 期末借方<>0 OR 期末贷方<>0';
:=true;
//设置表的列宽
[0].Width:=48;
[1].Width:=100;
[2].Width:=64;
[3].Width:=64;
[4].Width:=64;
[5].Width:=64;
[6].Width:=64;
[7].Width:=64;
end;
//----------------初始化表的设置------------
procedure (Sender: TObject);
begin
//设置表格表头显示与宽度
[1,0]:='是否平衡';
[2,0]:='期初借方';
[3,0]:='期初贷方';
[4,0]:='本期发生借方';
[5,0]:='本期发生贷方';
[6,0]:='期末借方';
[7,0]:='期末贷方';
[0,1]:='合计';
[0]:=48;
[1]:=64;
[2]:=64;
[3]:=64;
[4]:=128;
[5]:=128;
[6]:=64;
[7]:=64;
[0]:=20;
[1]:=20;
end;
//------------在初始化时统计工作的完成-----------
procedure ;
begin
//根据不同的状态设置 SQL 代码,以计算不同的平衡情况
;
;
('select 科目代码, 科目名称,');
('(case when 余额方向=''借方'' then 期初余额 else 0 end - 累计借方)');
('as 期初借方,');
('(case when 余额方向=''贷方'' then 期初余额 else 0 end - 累计贷方)');
(' as 期初贷方,');
('累计借方 as 本期发生借方,累计贷方 as 本期发生贷方,');
(' case when 余额方向=''借方'' then 期初余额 else 0 end as 期末借方,');
(' case when 余额方向=''贷方'' then 期初余额 else 0 end as 期末贷方');
(' from 帐簿初始化表 where 累计借方<>0 or 累计贷方<>0 or 期初余
额<>0');
;
//统计数据
sumtable;
end;
//------------在正式使用时统计工作的完成-----------
procedure ;
begin
//根据不同的状态设置 SQL 代码,以计算不同的平衡情况
;
;
('select a.科目代码, b.科目名称,');
('(case when a.余额方向=''借方'' then 期初余额 else 0 end )');
(' as 期初借方,');
('(case when a.余额方向=''贷方'' then 期初余额 else 0 end)');
('as 期初贷方,');
('本期借方合计 as 本期发生借方, 本期贷方合计 as 本期发生贷方,');
('case when a.余额方向=''借方'' then 余额 else 0 end as 期末借方,');
('case when a.余额方向=''贷方'' then 余额 else 0 end as 期末贷方');
(' from 本期汇总帐簿 as a, 科目表 as b ');
(' where a.科目代码 = b.科目代码 and (本期借方合计<> 0');
(' or 本期贷方合计<>0 or 期初余额<>0 or 余额<>0)');
;
//统计数据
sumtable;
end;
//-----------------对数据进行统计---------------
procedure ;
var
count,i:integer;
val1,val2,val3,val4,val5,val6:double;
begin
//计算平衡表中的记录数
count:=;
//统计信息,判断是否试算平衡
val1:=0;
val2:=0;
val3:=0;
val4:=0;
val5:=0;
val6:=0;
while not do
begin
val1:=strtofloat([2].Text)+val1;
val2:=strtofloat([3].Text)+val2;
val3:=strtofloat([4].Text)+val3;
val4:=strtofloat([5].Text)+val4;
val5:=strtofloat([6].Text)+val5;
val6:=strtofloat([7].Text)+val6;
;
end;
//显示统计结果
[1,1]:='是否平衡';
[2,1]:=floattostr(val1);
[3,1]:=floattostr(val2);
[4,1]:=floattostr(val3);
[5,1]:=floattostr(val4);
[6,1]:=floattostr(val5);
[7,1]:=floattostr(val6);
if (val1<>val2)or(val3<>val4)or(val5<>val6) then
begin
[1,1]:='不平衡';
:=clred;
end
else
[1,1]:='平衡';
end;
//-------------------------------------------------------------------
//-----------------以下是帐户设置窗体的代码------------------------------
implementation
{$R *.dfm}
uses sumaccountform;
procedure (Sender: TObject;
var Action: TCloseAction);
begin
action:=cafree;
end;
//-------------设置表格-----------------
procedure (Sender: TObject;
Field: TField);
begin
//设置帐簿初始化表列宽
[0].Width:=64;
[1].Width:=100;
[2].Width:=64;
[3].Width:=64;
[4].Width:=64;
[5].Width:=64;
end;
procedure (Sender: TObject、Field: TField);
begin
//设置系统参数表列宽
[0].Width:=32;
[1].Width:=112;
[2].Width:=32;
end;
//-----------------初始化帐户-----------------------
procedure (Sender: TObject);
begin
//执行储存过程,初始化帐户
:='EXEC sf_初始化帐户';
if ('是否清除原帐簿信息,并初始化新帐簿?','确认',
MB_OKCANCEL)=IDOK then
;
//刷新数据表
:=false;
:=true;
:=false;
:=true;
end;
//--------------------启用新帐户-----------------
procedure (Sender: TObject);
begin
//判断是否试算平衡
;
;
('select sum(累计借方) 借方,sum(累计贷方) 贷方 from 帐簿初始化表');
;
if ('借方').AsString<>('贷方').AsString then
begin
showmessage('新帐簿初始化不平衡,请检查试算平衡表后重新输入');
exit;
end;
//如果试算平衡,则可以新建帐簿
if ('试算结果平衡,启用新帐簿将删除所有历史记录'+#13+'是否继续?
',
'确认',MB_OKCANCEL)=IDOK then
begin
//执行储存过程,启用帐户
:='EXEC sf_启用帐户';
;
//刷新数据表
:=false;
:=true;
:=false;
:=true;
//显示帐户启用成功消息
showmessage('新帐户启用成功');
end;
end;
//显示初始化时的试算平衡表
procedure (Sender: TObject);
var
newform:Tsumaccount;
begin
//创建试算平衡窗体
newform:=(application);
:='试算平衡表(初始化)';
//在初始化时使用
;
end;
(1) 新建一个窗体,将窗体的 Name 属性设置为“DocuInput”,选择 Project | Options..
.菜单命令,将 DocuInp 窗体从自动创建的窗体列表中删除,将窗体保存为“DocuInput
”。该窗体的控件布局和设置如图 所示。
图 凭证输入窗体
该窗体是本实例中比较重要也比较复杂的一个窗体。由于每个凭证项均可对
应多个分录数据,因此,用 StringGrid 来输入和编辑各个凭证项下属的分录数据
比较合适,这种关系在一定程度上类似于我们在第 1 章中进销存实例中处理的进
货单和进货单明细的关系。另外,当工具栏中的【修改】、【保存】等按钮被按
下时,实际上是对两个表进行操作,由于凭证表和分录表之间存在的约束关系,
因此代码中对两个表的操作顺序要特别注意。各控件的属性设置如表 所示,
窗体中除搜索栏中的编辑框为 Edit 控件之外,其他所有编辑框都是 DBEdit 控件,
其 DataSource 属性都设置为 DataSource1,DataField 设置为与其相邻的文本中的
内容,一个 DBCombobox 的 DataSource 和 DataSource 属性和 DBEdit 相同,其 Ite
ms 字段中添加收、付、转这 3 项。
表 凭证输入窗体控件属性设置
控件类型 对 象 名 属 性 取值(说明)
TForm DocuInput Name DocuInput
Caption 会计凭证输入
TADOQuery ADOQuery1 SQL select * from 凭证表
order by 凭证编号
Active True
TADOQuery ADOQuery2 SQL select distinct * from 分录表
Active True
TDataSource DataSource1 DataSet ADOQuery1
TDataSource DataSource2 DataSet ADOQuery2
TADOQuery ADOQuery3 SQL select distinct a.* from 分录表 a,凭证表 b where a.凭证编号
='000001'
Active True
TDBGrid DBGrid1 DataSource DataSource1
ReadOnly True
(2) 设置凭证输入窗体的代码如下。
public
{ Public declarations }
procedure SetToolBar(isEnable:bool);
procedure SumAccount();
//执行新增和编辑操作后,保存时会执行不同的代码
procedure OpType(opname:string);
end;
//对将要从 dll 中的调用的函数的声明
type
Tshowdllform=function(Ahandle:Thandle; Acaption:string; tablename:string):string; stdcall;
Ttable=array[1..20] of string;
var
DocuInput: TDocuInput;
maxnum,recordnum,curRow,curCol:integer;
mytable:Ttable;
op:string;
implementation
{$R *.dfm}
procedure (Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
end;
//----------------初始化表----------------------
procedure (Sender: TObject;
Field: TField);
var
i,j:integer;
begin
//设置数据表宽度
[0].Width:=48;
[1].Width:=64;
[2].Width:=64;
//显示与凭证编号对应的分录表
;
;
('select distinct a.*,c.科目名称 from 分录表 a,凭证表 b,科目表 c
where (a.凭证编号='''++''')and(a.科目代码=c.科目代码) order by 编号');
;
//初始化表,将表格清空
for i:=1 to 20 do
for j:=0 to 4 do
if op<>'insert' then
[j,i]:='';
//将分录表数据读入表格,并保存编号数据以供后面的数据库操作使用
i:=1;
recordnum:=0;
while not do
begin
[0,i]:=('科目代码').AsString;
[1,i]:=('科目名称').AsString;
[2,i]:=('借方').AsString;
[3,i]:=('贷方').AsString;
[4,i]:=('摘要').AsString;
mytable[i]:=('编号').AsString;
i:=i+1;
recordnum:=recordnum+1;
;
end;
//设置分录表的列宽度
[0]:=48;
[1]:=116;
[2]:=64;
[3]:=64;
[4]:=150;
//显示凭证数
:=inttostr();
end;
//-----------------设置工具栏按钮--------------------
procedure (isEnable: bool);
begin
if isEnable=true then
begin
//将首记录等记录移动按钮设置为不可用
:=false;
:=false;
:=false;
:=false;
//将新增、修改等按钮设置为不可用
:=false;
:=false;
:=false;
//将保存和取消按钮设置为可用
:=true;
:=true;
//将窗体内的数据显示控件设为可修改
:=true;
:=true;
:=true;
:=true;
:=false;
end;
if isEnable=false then
begin
//将首记录等记录移动按钮设置为可用
:=true;
:=true;
:=true;
:=true;
//将新增、修改等按钮设置为可用
:=true;
:=true;
:=true;
//将保存和取消按钮设置为不可用
:=false;
:=false;
//将窗体内的数据显示控件设为不可修改
:=false;
:=false;
:=false;
:=true;
:=false;
end;
end;
//---------------新增记录----------------
procedure (Sender: TObject);
var
totalnum:string;
begin
//刷新数据,得到凭证数据中最大编码并加一,防止编码重复
;
;
('select max(凭证编号) 最大编号 from 凭证表');
;
totalnum:=('最大编号').Asstring;
totalnum:=copy(totalnum,1,6);
if totalnum='' then totalnum:='0';
totalnum:=inttostr(strtoint(totalnum)+1);
//开始新增
SetToolBar(true);
;
//组成六位的凭证编码
if length(totalnum)=1 then
:='00000'+totalnum;
if length(totalnum)=2 then
:='0000'+totalnum;
if length(totalnum)=3 then
:='000'+totalnum;
//默认凭证字号
:='收';
//加入当前日期
:=datetostr(date);
//默认会计期间
;
:=[2];
//默认过帐状态
:='未过';
//设置操作类型
op:='insert';
end;
//---------------修改记录----------------
procedure (Sender: TObject);
begin
SetToolBar(true);
;
//设置操作类型
op:='edit';
end;
//---------------删除记录----------------
procedure (Sender: TObject);
begin
if ('删除该条记录?','财务管理系统',MB_OKCANCEL)=IDOK then
begin
//先删除分录表记录,再删除凭证记录
:='delete from 分录表 where 凭证编号='''++'''';
;
;
end;
end;
//---------------首记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------上记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------下记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------尾记录----------------
procedure (Sender: TObject);
begin
;
end;
procedure (Sender: TObject);
begin
close;
end;
//---------------保存记录----------------
procedure (Sender: TObject);
begin
if <> then
showmessage('借贷双方不平衡,请检查')
else
begin
if op='insert' then
begin
;
opType(op);
end;
if op='edit' then
begin
opType(op);
;
end;
SetToolBar(false);
//清除操作标识符
op:='';
end;
end;
//---------------取消操作----------------
procedure (Sender: TObject);
begin
;
SetToolBar(false);
//清除操作标识符
op:='';
end;
//----------查询数据并显示-------------
procedure (Sender: TObject);
begin
;
;
('select * from 凭证表 where (凭证编号 like ''%'++'%'')and');
('(会计期间 like ''%'++'%'')and(日期 like ''%'++'%'')');
;
end;
//----------------为凭证录入分录表-----------------
procedure (Sender: TObject);
begin
;
end;
//----------统计分录表中的各项信息以储存到数据库----------
procedure ;
var
sumoutput,suminput:double;
i:integer;
begin
suminput:=0;
sumoutput:=0;
//统计借贷双方的数额
for i:=1 to 20 do
if ([2,i]<>'')and([3,i]<>'') then
begin
suminput:=suminput+strtofloat([2,i]);
sumoutput:=sumoutput+strtofloat([3,i]);
end;
:=floattostr(suminput);
:=floattostr(sumoutput);
end;
procedure (Sender: TObject);
begin
SumAccount;
end;
//------------设置分录表表头-------
procedure (Sender: TObject);
begin
[0,0]:='科目编码';
[1,0]:='科目名称(双击选择)';
[2,0]:='借方';
[3,0]:='贷方';
[4,0]:='摘要';
end;
//----当在分录表中输入时,不允许在上面有空行的情况下输入一行新的数据----
procedure (Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
//防止在输入数据时上面有空行
if [0,Arow-1]='' then
begin
showmessage('请先完成上行中空的项目');
exit;
end;
//保存选取的单元行列值
curRow:=ARow;
curCol:=ACol;
if (curCol<=4)and(curCol>=2) then
:=+[goEditing];
//防止选中标题栏
if ARow=0 then curRow:=ARow+1;
//统计借贷双方信息
sumAccount();
end;
//---在输入分录表时调用 DLL 中的表格,选择科目名称和号码 -----
procedure (Sender: TObject);
var
showForm:TShowDllForm;
module:Thandle;
begin
//只有双击指定列才有效
if curCol<>1 then exit;
//读入 DLL
module:=loadlibrary('');
//如果读入错误,则 module 会是一个小于 32 的错误代码
//由此可以判断是否读入成功
if module<32 then exit;
@showForm:=getprocaddress(module,pchar(1));
if @showForm=nil then exit;
//通过 DLL 传递参数
[0,curRow]:=showForm(,'选择科目名称','科目表');
//为科目代码添加科目名称
;
;
('select 科目名称 from 科目表 where 科目代码
='''+[0,curRow]+'''');
;
[1,curRow]:=('科目名称').AsString;
end;
//------------对分录表进行插入和修改时所执行的操作--------------------------
procedure (opname: string);
var
i:integer;
inputval,outputval,oldnum:string;
begin
//如果是新增凭证,则直接将分录表中的数据逐条插入
if opname='insert' then
begin
for i:=1 to 20 do
begin
//如果表格中为空,则跳出循环
if [0,i]='' then continue;
inputval:=[2,i];
outputval:=[3,i];
//插入数据,由于借方和贷方数据在 sql server 中为 money,故需要进行转换
:='insert into 分录表([凭证编号],[科目代码],
[借方],[贷方],[摘要]) values('''++''','''
+[0,i]+''',cast('''+inputval+''' as money),
cast('''+outputval+''' as money),'''+[4,i]+''')';
;
end;
end;
if opname='edit' then
begin
for i:=1 to 20 do
begin
if [0,i]='' then continue;
inputval:=[2,i];
outputval:=[3,i];
//对凭证所属的分录表原有数据进行更新
if i<=recordnum then
:='update 分录表 set [科目代码]
='''+[0,i]+''',[借方]=cast('''+inputval+''' as money),
[贷方]=cast('''+outputval+''' as money),[摘要]='''+[4,i]
+''' where 编号='''+mytable[i]+''''
else
//插入凭证所属的分录表中的新数据
:='insert into 分录表([凭证编号],[科目代码],
[借方],[贷方],[摘要]) values('''++''','''
+[0,i]+''',cast('''+inputval+''' as money),
cast('''+outputval+''' as money),'''+[4,i]+''')';
;
end;
end;
end;
凭证过帐功能是依靠在程序中调用“sf_凭证过帐”存储过程完成的,由 SQL Ser
ver 在后台执行,因此不需要再制作窗体界面。在程序主窗体中【凭证过帐】菜
单的响应函数中添加相应的处理代码,完成凭证过帐的功能。具体代码参看
节代码中 N8Click 部分的函数代码(其功能为“显示总分类帐查询窗体”)。
(1) 新建一个窗体,将窗体的 Name 属性设置为“TotalAccount”,选择 Project
| Options...菜单命令,将 TotalAccount 窗体从自动创建的窗体列表中删除,将窗
体保存为“TotalAccount ”。该窗体的控件布局和设置如图 所示。
图 总分类帐查询窗体
(2) 窗体控件属性设置如表 所示。
表 总分类帐查询窗体控件属性设置
控件类型 对 象 名 属 性 取值(说明)
TForm TotalAccount Name TotalAccount
Caption 总分类帐查询
TADOQuery ADOQuery1 SQL select a.*,b.科目名称 from 本期汇总帐簿 a,科目表 b
where a.科目代码=b.科目代码
续表
控件类型 对 象 名 属 性 取值(说明)
Active True
TDataSource DataSource1 DataSet ADOQuery1
TDBGrid DBGrid1 DataSource DataSource1
ReadOnly True
TADOQuery ADOQuery3 SQL select distinct a.* from 分录表 a,凭证表 b where a.凭证编
号='000001'
Active True
StringGrid StringGrid1 ColCount 5
RowCount 20
总分类查询主要实现的是查询总分类帐,不需要编辑,所以【编辑】、【新
增】等按钮在这里用不到,设置为 false,同时,由于凭证过帐时将大量没有发
生金额的数据也放入了数据表中,为了用户查阅时方便,这里设置了一个过滤数
据的功能,当窗体中的【无发生金额不显示】单选框被选中时,只有余额不为 0
的数据项被显示在表格中。该窗体的处理代码如下所示。
implementation
{$R *.dfm}
procedure (Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
end;
//--------------------设置表的宽度-------------------
procedure (Sender: TObject;
Field: TField);
begin
//显示数据数量
:=inttostr();
//设置数据表宽度
[0].Width:=50;
[1].Width:=80;
[2].Width:=80;
[3].Width:=80;
[4].Width:=80;
[5].Width:=80;
[6].Width:=80;
[7].Width:=80;
[8].Width:=50;
end;
//---------------首记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------上记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------下记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------尾记录----------------
procedure (Sender: TObject);
begin
;
end;
procedure (Sender: TObject);
begin
close;
end;
//----------查询数据并显示-------------
procedure (Sender: TObject);
begin
;
;
('select a.*,b.科目名称 from 本期汇总帐簿 a,科目表 b
where (a.科目代码 like ''%'++'%'')and');
('(a.科目代码=b.科目代码)');
;
end;
//---------根据用户的操作对表中的数据进行过滤-----------
procedure (Sender: TObject);
begin
if then
begin
:='余额<>0';
:=true;
end
else
:=false;
end;
总分类帐查询和明细帐查询的区别在于,前者是查询科目的汇总信息,后者
是查询科目在当前会计期间发生的每一笔业务及其余额。
(1) 新建一个窗体,将窗体的 Name 属性设置为“DetailAccount”,选择 Project
| Options...菜单命令,将 DetailAccount 窗体从自动创建的窗体列表中删除,将窗
体保存为“”。该窗体的控件布局和设置如图 所示。
图 明细帐查询窗体
(2) 该窗体的控件属性设置如表 所示。
表 明细帐查询窗体控件属性设置
控件类型 对 象 名 属 性 取值(说明)
TForm DetailAccount Name DetailAccount
Caption 明细帐查询
TADOQuery ADOQuery1 SQL select a.*,b.科目名称 from 本期明细帐簿 a,科目表 bwhere
a.科目代码=b.科目代码
Active True
TDataSource DataSource1 DataSet ADOQuery1
TADOQuery ADOQuery3 SQL select distinct a.* from 分录表 a,凭证表 b where a.凭证编号
='000001'
Active True
TDBGrid DBGrid1 DataSource DataSource1
ReadOnly True
(3) 该窗体的代码如下所示。
//添加列表框中项目的函数
procedure setlist();
end;
var
DetailAccount: TDetailAccount;
implementation
{$R *.dfm}
procedure (Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
end;
//------------设置表宽度------------------
procedure (Sender: TObject;
Field: TField);
begin
//显示数据数量
:=inttostr();
//设置数据表宽度
[0].Width:=80;
[1].Width:=64;
[2].Width:=64;
[3].Width:=64;
[4].Width:=64;
[5].Width:=64;
[6].Width:=64;
[7].Width:=64;
[8].Width:=64;
end;
//---------------首记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------上记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------下记录----------------
procedure (Sender: TObject);
begin
;
end;
//---------------尾记录----------------
procedure (Sender: TObject);
begin
;
end;
procedure (Sender: TObject);
begin
close;
end;
//----------查询数据并显示-------------
procedure (Sender: TObject);
begin
;
;
('select a.*,b.科目名称 from 本期明细帐簿 a,科目表 b
where (a.科目代码 like ''%'++'%'')and');
('(a.科目代码=b.科目代码)');
;
//清除设置的数据过滤器并重新设置列表
:=false;
setlist();
end;
//----------窗体显示时,向左边列表框中添加科目名称--------------
procedure (Sender: TObject);
begin
setlist();
end;
//-------------将数据集中已有的科目名称添加到列表中-------------
procedure ;
var
name:string;
begin
;
;
while not do
begin
name:=('科目名称').AsString;
//如果列表中没有该名称则添加,若已有则不做任何动作
if (name)=-1 then
(,name);
;
end;
end;
//选中一个科目名称并允许将其添加到右边的列表中
procedure (Sender: TObject);
begin
if <>0 then
:=true;
end;
//选中一个科目名称,并允许从右边的列表中删除它
procedure (Sender: TObject);
begin
if <>0 then
:=true;
end;
//-----在右边的列表中添加某一项----------
procedure (Sender: TObject);
var
name:string;
begin
name:=[];
//若右边的列表框不存在该项,再向其中添加
if (name)=-1 then
(,name);
//允许在表中根据选择的项进行显示
:=true;
end;
//-----在右边的列表中删除某一项----------
procedure (Sender: TObject);
begin
//若不为空,则可以将名称项从列表中删除
if <>0 then
();
//若右边列表已空,则将按钮变灰(不可用)
if =0 then
begin
:=false;
:=false;
end;
end;
//----------根据选择的项显示数据-----------
procedure (Sender: TObject);
var
filstr:string;
i:integer;
begin
filstr:='';
//根据列表中内容设置数据集的过滤项并过滤
for i:=0 to -1 do
begin
filstr:=filstr+'科目名称='''+[i]+'''';
if i<>-1 then
filstr:=filstr+' OR ';
end;
:=filstr;
:=true;
end;
前面我们已经建立了【试算平衡表】功能窗体,该窗体中带有两个过程分别对应初始化
帐本时的试算平衡和帐本使用后的最终试算平衡计算,因此在不同的时刻调用不同的过程即
可。在程序主窗体的【试算平衡表】菜单的响应函数中添加相应的处理代码,完成凭证过帐
的功能。具体代码参看 节的代码中 N11Click 的函数代码(其功能为“显示试算平衡表窗
体”)。期末结帐功能和前面的凭证过帐一样,是依靠在程序中调用“sf_期末结帐”
存储过程完成的,由 SQL Server 在后台执行,因此不需要再制作窗体界面。在
程序主窗体的【期末结帐】菜单的响应函数中添加相应的处理代码,完成期末结
帐的功能。具体代码参看 节代码中 N12Click 的函数代码(其功能为“执行期
末结帐的储存过程”)。
关于利用 QuickRep 控件制作报表的方法,我们在第一章进销存系统中已经
由详细的说明,这里就不再赘述。
新建一个窗体,将其 Name 属性改为“FinalReport”,Caption 属性改为“资产
负债表”,并为其添加一个 QuickRep 和一个 ADOTable 控件。在 QuickRep1 控件
的各个 Band 上分别放置相应的 QRSysData 控件、QRLabel 控件和 QRDBText 控
件,如图 所示,其中 QRDBText 控件 DataField 属性设置为相应 QRLabel 的
标题。两个控件属性设置如表 所示。
图 资产负债表报表窗体
当需要显示【资产负债表】报表时,首先需要提示用户输入统计的会计期间,
默认是当前会计期间,确定后调用“sf_计算资产负债表”存储过程计算资产负债
表,最后在报表窗体中显示报表。菜单的响应函数处理具体代码参看 节代
码中 N13Click 的函数代码(其功能为“资产负债报表的生成和打印”)。
表 资产负债表窗体控件属性设置
控件类型 对 象 名 属 性 取值(说明)
TADOTable ADOTable1 TableName 资产负债表
Active true
QuickRep QuickRep1 DateSet ADOTable
Bands HasDetail、HasTitle
ReportTitle 打印
至此我们完成了整个系统的制作,选择 Run | Run 菜单命令或按 F9 键,编
译并运行程序,可以看到前面 节中介绍的程序。
系统设计完成后需要打包发布,将应用系统制作成安装程序。制作安装程序
的工具很多,一般 Delphi 开发的应用系统可以使用 Install Shield 来完成系统的
安装查询。
系统发布的注意事项参考第 1 章。
财务管理系统可以作为一个独立的系统运行,也可以和其他的应用系统结合
起来,实现数据共享。例如可以和前面的进销存管理系统相结合,可以将进销存
系统中的进货、销售、应收及应付款等会计分录自动生成凭证,如图 所示。
图 财务管理系统与其他系统的结合
一般常见的财务管理系统都提供会计分录数据倒入的功能,即由业务系统将
进货、销售、应付、应收等业务记录按照一定的格式倒出成文本文件,再利用数
据导入功能将这些文件导入数据库中成为会计分录数据,从而减少财务系统的输
入工作量,提高工作效率。
通过该实例我们可以掌握以下知识和技巧。
∶ 财务管理系统的需求。
∶ 利用 Delphi 进行数据库编程的多种方法。
∶ ADO 数据集控件中 Filter 的使用方法。
∶ DLL 动态链接库的设计和调用方法。
∶ DataSource 中数据记录数量的统计方法。
∶ 利用 Delphi 编写财务管理系统。
∶ 财务管理系统的扩展。
读者可以根据这些方法自行完成财务管理系统的其他功能。