摘要:目前企业管理软件的数据结构大多采用关系型数据库,随着系统处理的业务的增多,数据结构、内容和彼此相关的逻辑关系越来越复杂,整个系统在企业应用中不仅学习成本高,实施困难,而且对于企业的个性化需求二次开发难度都非常大。本文提出一种全新的数据结构和算法:“二元”分析法,用简单的数据结构即可满足企业管理中数据处理的需要,并且可以非常方便地修改、调整,逻辑清晰明了,思维方式契合管理理念,核心运算只需三个Table就可以完成。通过一个简单的示例,介绍说明该数据结构和算法,以及在管理应用中的使用变化。该算法不同于传统管理软件的结构和思维方式,以极简的办法解决了复杂的问题,并且在此思路上还有更大的创新、扩展空间。
企业信息化是计算机应用中的一个重要领域,信息技术在企业管理中的应用对企业管理效率的提高,规范化管理等发挥着重要作用。但在企业管理软件在企业的应用,特别是在中小企业中的应用却不尽人意,经过多年的努力业界提供了各种概念和解决方案,成功的案例不多。大多数中小企业还停留在使用Office系统产品,做简单的文档和数据处理,仅实现了无纸化办公的初级要求,目前国内企业面临转型压力,迫切需要管理工具帮助企业提高管理水平,提高工作效率。在中小企业的信息化中,困难主要在于两点:一是系统太复杂,学习和实施比较困难,费用也比较高;二是系统僵硬,管理内容和模式固定,个性化适应性差,二次开发难度高,实际根源在于系统结构太复杂、庞大,缺乏弹性。为此经过多年在甲乙两方的工作经验的总结,创新出一种全新模式的数据结构和算法,极大的简化了数据结构,这样就很易于系统的配置和修改。在使用这一算法的基础上设计的企业信息化工具,可以让企业以极低的投入建立适合自己企业的信息系统,并且可以伴随企业的发展,管理的进步不断调整、修改,作为真正的“企业管理信息化工具”帮助中小企业完成信息化建设。
声明:题目中“三个Table”是指记录、统计和计算的核心只要用三个表,如果做成完整的软件还需其他数据的补充协助;“ERP”是泛指企业管理中对业务数据的管理应用,如ERP、进销存等,不是严格意义的ERP,仅为了便于描述。
1 传统信息化软件越来越复杂的原因
传统管理软件,不论是进销存、ERP,还是为行业量身打造的各种管理系统,通常都不外乎遵循:根据“业务数据”产生“表单”,然后经过“数据逻辑处理”保存到对应的“数据库”中;查看、统计时,根据表的内容设计“查询统计逻辑”,将结果输出,如下图:
图1 传统软件数据处理模式
这样的结构, “业务数据”、“逻辑处理”和“数据库”这三层的关系是一一对应的,或者相互交叉、组合的,那么随着业务内容的增加,各个环节都会相应增加,业务越复杂,逻辑和数据库也就越复杂。作为管理软件的供应商,为使自己的软件可以有更广泛的适应性,尽量把可能会用到的管理内容加到系统中,把系统做得越来越庞大,越来越复杂,甚至以此为傲。但这样的系统对中小企业来说实施的困难就加大了,特别是当有行业个性化需求的时候,需要修改和添加功能,就几乎是不可能完成的任务。虽然各厂商纷纷推出各自的PaaS系统,包装了许多API、UI元素,“低代码开发”甚至“0代码开发”以提高开发的效率,但根基就是那么复杂,中小企业自己很难驾驭,委托二次开发成本也太高,往往是个“坑”。这应该是多年来在中小企业推广信息化非常艰难的原因之一。
如果我们目标在“简化管理系统”,必须要考虑从根本上改变这个逻辑结构。
2 “二元”分析法的核心思想
上面所说的结构是从数据库技术的角度去做企业管理,实际上我们应该抛开数据库的理论结构,从管理应用的角度去思考系统的架构。也就是说当企业产生了一个业务数据,传统思维只盯住数据,处理的方法就是把数据存储到对应的数据库表中,新的思维模式是首先分解这个业务操作的“管理意义”,所谓“管理意义”就是业务操作对整个管理系统的各个方面的影响和作用。例如:做了一个“入库”的工作,那么产生的“管理意义”就可能是:①产生了若干数量某物料的“库存”,②产生对某供应商的“应付款”(假设是货到付款)。设定那些“管理意义”和具体操作无关,企业根据管理流程和管理关注点的不同,设定的“管理影响”项目也可以不同。假如企业又有一项工作是“客供物料入库”,那么这个业务的“管理意义”只有①产生了若干数量某物料的“库存”,和上面的入库一样,但没有②产生“应付款”。一项工作可以对整个管理系统有多项影响,产生多个“管理意义”;而对于某项“管理意义”可能来源于不同的工作。这样,通过对每个业务操作解析出“管理意义”,使具体的操作数据和管理逻辑分开,“松耦合”,这样设置和修改就相对清晰、容易。
一个完整的企业管理系统是由一个个业务工作有顺序、有逻辑、有制约组成的,都是链条上的一环,那么如何将们链接在一起呢?这里引入了我们古老智慧中的哲学“世间万物,阴阳互变,有阴即有阳”,事物都有其“两面性”,也就是说对于每个业务工作产生的每项“管理意义”都要找到它的“另一面”,例如上面的例子中,入库操作产生了一个“库存”的“管理意义”,如果把这个设为“+”,那么假设这个入库是根据某个采购单来的,可以设定另一个“管理意义”,即“已下单未交货数量”,这个设为“-”,而对于“下采购单”的这个业务操作,它产生的“管理意义”对于“已下单未交货数量”就是“+”,形成下面的关系:
图2 “二元”关系描述
这样,两项工作就通过一对对“+”“-”,就像链条的每个环节都有两端那样,首尾相连,建立起企业管理的完整链条。并且相互关系清晰明了,当需要关注某些管理要素的时候查询统计会非常简单,例如:想查看一下供应商还有多少没交货,合计“已下单未交数量”这个“管理意义”就得出结果了。假设我们考虑每项工作可能会对“物料”和“财务”两方面产生影响,例如上面“入库”的操作,在数量上产生库存,同时在财务方面要产生相应的“应付款”,这样我们就可以建立如下的模型:
图3 “二元”算法数据处理模型
对“物料”和“财务”这两方面的逻辑可以分别设置,在各项工作中可以单独分解对这两个方面的影响。这些就是新数据架构的主要核心思想,下面举个简单的例子说明一下。
3 简单的数据模拟演示
基于上面的理论,我们模拟一个简单的外贸业务系统,业务内容是:和外商签订合同,在国内找供应商生产采购,然后出口,赚取差价。将用“三个Table”,即可完成对全部业务的存储,数据的统计管理,并且可以方便的扩展和修改调整。
3.1 先做几项准备工作对管理系统的结构和逻辑进行设计
在进行数据配置之前,先对业务数据进行整理,作为配置的基础。整理的内容为“一图二表”,一图是整理“业务流程图”,“二表”为“关键字段表”和“逻辑关系表”。
3.1.1 理顺工作流程,画出业务流程图如下:
图4 模拟企业管理流程图
此图可以看出管理系统所涉及的各项工作及顺序、逻辑关系等。
3.1.2 分解各项工作的“管理意义”形成“逻辑关系表”
首先明确几个概念,上面论述的“管理意义”,简称为“科目”,实例中分解每项工作对“物料”和“财务”两个方面的管理意义,如下图所示,并且相应进行编号。
图5 各项工作的管理意义和逻辑关系
3.1.3 列出每项工作的具体数据内容,确定“关键数据表”
所谓“关键数据”是指在工作数据中,不仅要记录在本工作的单据中,其内容还要在后续的工作中不断引用,或者作为条件去查询的,例如:合同签订工作中,具体数据:
表1 “合同签订”数据内容
|
||||||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||||||
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
1000 |
12600 |
||||||||||||||
CP002 |
电感 |
ML7823 |
个 |
8.4 |
2000 |
16840 |
其中的“合同号”、“产品编号”、“规格型号” 、“单位”和“单价”等数据,在后续的采购、出入库的工作中都有可能会需要,也就是说“关键数据”是在整个管理系统中共同普遍关注的数据。
下面把各项工作的“关键数据”罗列在一起,因为有很多工作是在前一个工作的基础上进行的,例如:入库工作是根据采购的数据进行入库,就对上面的数据基础上只产生“入库单据号”就可以,很多数据是在各项工作间共用的,所以总的并不多,标识中“*”是在该项工作中产生输入的数据,“#”为沿用上面工作的数据。
图6 各项工作所涉及的关键数据列表
到此为止,对于整个管理系统的逻辑规划设计就已完成,整个管理系统的逻辑关系和数据内容都体现出来了。根据管理的要求建立了管理逻辑,把每项工作对“物”和“财”两方面对管理的影响都分解出来,这样工作的具体数据和逻辑设置是分离的,可以综合考虑,分别设计,一个工作有多项影响,而逻辑中的某项“管理影响”可以由不同的工作产生数据。
下面就在三个表中按照上面的逻辑设计运行。
3.2 模拟数据运行
这里使用MySQL数据库来演示,首先建立三个表,mat,mon,index,表结构如下:
表2 mat表结构
字段 |
类型 |
作用 |
No |
int |
序号 |
MatIndex |
int |
Index表主键 |
MatId |
String |
逻辑组编号 |
MatSubId |
String |
科目号 |
MatValue |
Float |
数量值 |
表3 mon表结构
字段 |
类型 |
作用 |
No |
int |
序号 |
MonIndex |
int |
Index表主键 |
MonId |
String |
逻辑组编号 |
MonSubId |
String |
科目号 |
MonValue |
Float |
数量值 |
表4 index表结构
字段 |
类型 |
作用 |
WID |
int |
索引号 |
workId |
String |
*工作编号 |
HTId |
String |
*合同号 |
KHName |
String |
客户名称 |
CPId |
String |
产品编号 |
CPName |
String |
产品名称 |
Size |
String |
规格型号 |
Unit |
String |
产品单位 |
CPPrice |
Float |
产品单价 |
GYSName |
String |
供应商名称 |
CGPrice |
Float |
采购单价 |
CKNo |
String |
仓库单据号 |
CWNo |
String |
财务单据号 |
三个表的关系是:mat表的MatIndex字段和mon表的MonIndex字段都和index表的WID字段关联。
在实际应用中mat和mon表不用动,仅根据管理系统的各项工作内容不同添加index表中的字段即可。下面我们模拟业务运行这6项工作。
3.2.1 合同签订
单据内容:
表5 “合同签订”模拟数据内容
|
||||||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||||||
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
1000 |
12600 |
||||||||||||||
CP002 |
电感 |
ML7823 |
个 |
8.4 |
2000 |
16840 |
在三个表添加的内容:
表6 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
4 |
W001 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
|
|
|
|
|
5 |
W001 |
HT0183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
|
|
|
|
|
表7 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
9 |
4 |
M001 |
1001 |
-1000 |
10 |
4 |
M001 |
1002 |
1000 |
11 |
5 |
M001 |
1001 |
-2000 |
12 |
5 |
M001 |
1002 |
2000 |
表8 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
9 |
4 |
C001 |
1001 |
-12600 |
10 |
4 |
C001 |
1002 |
12600 |
11 |
5 |
C001 |
1001 |
-16800 |
12 |
5 |
C001 |
1002 |
16800 |
解释:为了简化数据结构,数据不分“主从”,按明细的记录数量记录,所以首先在index表中产生两条记录,并自动生成“WID”号,而对于每条记录的正负是根据逻辑设计的:
图7 “合同签订”工作物料科目、财务科目逻辑设置
在“物料”和“财务”都各有一对科目记录,所以在mat表和mon表中各添加“两对”四条记录,并且其中的MatIndex字段和MonIndex字段的值和index表中的WID相关联对应
可以看到这样处理一项工作的涉及逻辑的数据被分离出去了,关键数据被集中管理了。
这时,如果想查看“有哪些产品需要采购?”可以运行如下SQL语句:
SELECT DISTINCT `index`.HTId AS `合同号`, `index`.KHName AS `客户名称`, `index`.CPId AS `产品编号`, `index`.CPName AS `产品名称`, `index`.Size AS `规格型号`, `index`.Unit AS `单位`, Sum(mat.MatValue) AS `需求数量` FROM `index` , mat WHERE `index`.WID = mat.MatIndex AND mat.MatSubId = '1002' AND `index`.HTId = 'HT0183' GROUP BY `index`.CPId |
其中:查询条件,合同号HT0183,科目“1002”就是在逻辑设计表中的“采购需求”。运行结果:
表9 “产品需求”查询结果
合同号 |
客户名称 |
产品编号 |
产品名称 |
规格型号 |
单位 |
需求数量 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
1000 |
HT0183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
3.2.2 采购合同签订
根据签订的外销合同,在国内进行采购,可以从多家工厂分别采购。
单据内容:
表10 采购合同模拟数据内容
|
||||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||||
CP001 |
变压器 |
KM9824 |
个 |
8.34 |
800 |
6672 |
在三个表中添加内容:
表11 在index表中添加的数据(黄色为新增数据)
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
4 |
W001 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
|
|
|
|
|
5 |
W001 |
HT0183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
|
|
|
|
|
6 |
W002 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
CG001867 |
电子厂1 |
8.34 |
|
|
表12 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
…… |
||||
13 |
6 |
M002 |
1002 |
-800 |
14 |
6 |
M002 |
1003 |
800 |
表13 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
13 |
6 |
C002 |
1003 |
-6672 |
14 |
6 |
C002 |
1004 |
6672 |
这时再运行SQL语句BI001,查询结果:
表14 “产品需求”再查询结果
合同号 |
客户名称 |
产品编号 |
产品名称 |
规格型号 |
单位 |
需求数量 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
200 |
HT0183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
再做一个采购合同:
单据内容:
表15 第二个采购合同模拟数据内容
|
||||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||||
CP001 |
变压器 |
KM9824 |
个 |
8.56 |
200 |
1712 |
||||||||||||
CP002 |
电感 |
ML7823 |
个 |
6.82 |
2000 |
13640 |
在三个表中添加数据:
表16 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
…… |
|||||||||||||
7 |
W002 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
CG001868 |
电子厂2 |
8.56 |
|
|
8 |
W002 |
HT0183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
CG001868 |
电子厂2 |
6.82 |
|
|
表17 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
…… |
||||
15 |
7 |
M002 |
1002 |
-200 |
16 |
7 |
M002 |
1003 |
200 |
17 |
8 |
M002 |
1002 |
-2000 |
18 |
8 |
M002 |
1003 |
2000 |
表18 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
15 |
7 |
C002 |
1003 |
-6672 |
16 |
7 |
C002 |
1004 |
6672 |
17 |
8 |
C002 |
1003 |
-13640 |
18 |
8 |
C002 |
1004 |
13640 |
这个操作就相当于把剩下的“产品需要”都采购了,可以看到在mat表中记录了科目数量的变化,mon表中财务金额的变化。
3.2.3 产品入库
根据采购合同做一笔入库,订货800个,实际到货810个,要按照实际收货数量付款。
单据内容:
表19 产品入库模拟数据内容
|
||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||
CP001 |
变压器 |
KM9824 |
个 |
8.34 |
810 |
6755.4 |
在三个表中添加内容:
表20 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
|
…… |
||||||||||||||
9 |
W003 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
CG001867 |
电子厂1 |
8.34 |
RK012 |
|
|
表21 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
…… |
||||
19 |
9 |
M003 |
1003 |
-810 |
20 |
9 |
M003 |
1004 |
810 |
表22 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
19 |
9 |
C003 |
1004 |
-6755.4 |
20 |
9 |
C003 |
1005 |
6755.4 |
查看统计结果:
操作到这个环节,为了方便查看数据的变化,建立一套“企业综合报表”,有如下结果:
表23 合同明细
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
1000 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
表24 采购情况
生产厂名称 |
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
电子厂2 |
CP001 |
变压器 |
KM9824 |
个 |
200 |
电子厂2 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
电子厂1 |
CP001 |
变压器 |
KM9824 |
个 |
800 |
表25 产品库存
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
810 |
表26 应付款
生产厂名称 |
采购单号 |
应付款 |
电子厂1 |
CG001867 |
6755.4 |
表27 应收款
客户名称 |
发货单号 |
应收款 |
|
|
|
数据显示的结果符合实际工作的进展情况,并且可以达到管理要求。
上面的报表,参考SQL语句:
合同产品明细 |
采购情况 |
产品库存 |
SELECT DISTINCT `index`.CPId AS `产品编号`, `index`.CPName AS `产品名称`, `index`.Size AS `规格型号`, `index`.Unit AS `单位`, Sum(mat.MatValue) AS `数量` FROM `index` , mat WHERE `index`.WID = mat.MatIndex AND `index`.WorkId = 'W001' AND mat.MatSubId = '1002' AND `index`.HTId = 'HT0183' GROUP BY `index`.CPId |
SELECT DISTINCT `index`.GYSName AS `生产厂名称`, `index`.CPId AS `产品编号`, `index`.CPName AS `产品名称`, `index`.Size AS `规格型号`, `index`.Unit AS `单位`, Sum(mat.MatValue) AS `数量` FROM `index` , mat WHERE `index`.WID = mat.MatIndex AND `index`.WorkId = 'W002' AND mat.MatSubId = '1003' AND `index`.HTId = 'HT0183' GROUP BY `index`.GYSName, `index`.CPId ORDER BY `生产厂名称` ASC, `产品编号` ASC
|
SELECT DISTINCT `index`.CPId AS `产品编号`, `index`.CPName AS `产品名称`, `index`.Size AS `规格型号`, `index`.Unit AS `单位`, Sum(mat.MatValue) AS `数量` FROM `index` , mat WHERE `index`.WID = mat.MatIndex AND mat.MatSubId = '1004' AND `index`.HTId = 'HT0183' GROUP BY `index`.CPId |
应付款 |
应收款 |
|
SELECT `index`.GYSName AS `生产厂名称`, `index`.CGHTId AS `采购单号`, Sum(mon.MonValue) AS `应付款` FROM `index` , mon WHERE `index`.WID = mon.MonIndex AND mon.MonSubId = '1005' GROUP BY `index`.GYSName ORDER BY `生产厂名称` ASC |
SELECT `index`.KHName AS `客户名称`, `index`.CKNo AS `发货单号`, Sum(mon.MonValue) AS `应收款` FROM `index` , mon WHERE `index`.WID = mon.MonIndex AND mon.MonSubId = '1006' GROUP BY `index`.CKNo |
|
统计查询也就是围绕这三个表,变换一下“科目”的相关查询条件就可以,也很简单,逻辑清晰。
下面同样的道理,把第二笔采购合同全部入库。
表28 第二笔产品入库模拟数据内容
|
||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||
CP001 |
变压器 |
KM9824 |
个 |
8.56 |
200 |
1712 |
||||||||||
CP002 |
电感 |
ML7823 |
个 |
6.82 |
2000 |
13640 |
三个表添加数据:
表29 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
|
…… |
||||||||||||||
10 |
W003 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
CG001868 |
电子厂2 |
8.56 |
RK013 |
|
|
11 |
W003 |
HT00183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
CG001868 |
电子厂2 |
6.82 |
RK013 |
|
|
表30 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
…… |
||||
21 |
10 |
M003 |
1003 |
-200 |
22 |
10 |
M003 |
1004 |
200 |
23 |
11 |
M003 |
1003 |
-2000 |
24 |
11 |
M003 |
1004 |
2000 |
表31 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
21 |
10 |
C003 |
1004 |
-1712 |
22 |
10 |
C003 |
1005 |
1712 |
23 |
11 |
C003 |
1004 |
-13640 |
24 |
11 |
C003 |
1005 |
13640 |
3.2.4 产品出库
单据内容:
表32“产品出库”模拟数据内容
|
||||||||||||||||
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
||||||||||
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
700 |
8820 |
||||||||||
CP002 |
电感 |
ML7823 |
个 |
8.4 |
1200 |
10080 |
三个表添加的数据:
表33 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
|
…… |
||||||||||||||
12 |
W004 |
HT0183 |
客户 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
|
|
|
|
CK003 |
|
13 |
W004 |
HT00183 |
客户 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
|
|
|
|
CK003 |
|
表34 在mat表中添加的数据
No |
MatIndex |
MatId |
MatSubId |
MatValue |
…… |
||||
25 |
12 |
M004 |
1004 |
-700 |
26 |
12 |
M004 |
1005 |
700 |
27 |
13 |
M004 |
1004 |
-1200 |
28 |
13 |
M004 |
1005 |
1200 |
表35 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
25 |
12 |
C004 |
1002 |
-8820 |
26 |
12 |
C004 |
1006 |
8820 |
27 |
13 |
C004 |
1002 |
-10080 |
28 |
13 |
C004 |
1006 |
10080 |
这时我们再运行一下建立的综合报表:
表36 合同明细
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
1000 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
表37 采购情况
生产厂名称 |
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
电子厂2 |
CP001 |
变压器 |
KM9824 |
个 |
200 |
电子厂2 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
电子厂1 |
CP001 |
变压器 |
KM9824 |
个 |
800 |
表38 产品库存
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
310 |
CP002 |
电感 |
ML7823 |
个 |
800 |
表39 应付款
生产厂名称 |
采购单号 |
应付款 |
电子厂1 |
CG001867 |
6755.4 |
电子厂2 |
CG001868 |
15352 |
表40 应收款
客户名称 |
发货单号 |
应收款 |
客户 |
CK003 |
18900 |
数据的变化完全符合逻辑。
3.2.5 付款
做一笔付款操作,为“电子厂2”付款。
单据内容:
表41“付款”模拟数据内容
|
||||||
付款金额 |
||||||
12000 |
三个表添加数据:
表42 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
|
…… |
||||||||||||||
14 |
W005 |
|
|
|
|
|
|
|
|
电子厂2 |
|
|
CK006 |
|
表43 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
29 |
14 |
C005 |
1005 |
-12000 |
30 |
14 |
C005 |
1007 |
12000 |
Mat表没有添加数据。
3.2.6 收款
单据内容:
表44“收款”模拟数据内容
|
||||||
收款金额 |
||||||
18000 |
三个表添加数据:
表45 在index表中添加的数据
WID |
WorkId |
HTId |
KHName |
CPId |
CPName |
Size |
Unit |
CPPrice |
CGHTId |
GYSName |
CGPrice |
CKNo |
CWNo |
|
…… |
||||||||||||||
15 |
W006 |
HT0183 |
客户 |
|
|
|
|
|
|
|
|
CK003 |
CK007 |
|
表46 在mon表中添加的数据
No |
MonIndex |
MonId |
MonSubId |
MonValue |
…… |
||||
31 |
15 |
C006 |
1006 |
-18000 |
32 |
15 |
C006 |
1008 |
18000 |
Mat表没有数据添加。
这时我们再运行一下建立的综合报表:
表47 合同明细
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
1000 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
表48 采购情况
生产厂名称 |
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
电子厂2 |
CP001 |
变压器 |
KM9824 |
个 |
200 |
电子厂2 |
CP002 |
电感 |
ML7823 |
个 |
2000 |
电子厂1 |
CP001 |
变压器 |
KM9824 |
个 |
800 |
表49 产品库存
产品编号 |
产品名称 |
规格型号 |
单位 |
数量 |
CP001 |
变压器 |
KM9824 |
个 |
310 |
CP002 |
电感 |
ML7823 |
个 |
800 |
表50 应付款
生产厂名称 |
采购单号 |
应付款 |
电子厂1 |
CG001867 |
6755.4 |
电子厂2 |
CG001868 |
3352 |
表51 应收款
客户名称 |
发货单号 |
应收款 |
客户 |
CK003 |
900 |
结果和我们预期的一样。
由此可见,如果用常规数据库结构进行设计恐怕三个表很难完成,采用新的算法,可以增加更多的业务操作内容,还是使用这三个表,并且调整修改非常简单,对已有的内容影响也不大。
3.2.7 在已有的基础上添加新功能和调整逻辑
上面的例子只是一个简单的应用,管理还比较粗放,只是记个账而已,如果对企业管理要求提高,要求整个系统以“合同”为中心开展各项工作,考核最终合同执行完成后实际的利润情况,并增加一项工作“其他费用录入”,把在合同执行过程中的运费、辅料费等都计入成本,我们对已有的结构做如下调整。
对逻辑设计表进行修改:
图8 逻辑设计表调整
在逻辑设计添加一项新工作“W007-费用录入”,在“财务”科目里添加两项“1009-成本预算”、“1010-成本”,在“付款”和“费用录入”两项工作时,发生成本,也就是说对某个合同产生实际付款和费用的时候产生成本,统计1010科目即可查看实际成本发生情况。
对“关键数据”表做如下修改:
图9 关键字段表调整
也添加了“费用录入”工作,关键数据增加一个“费用名称”,注意:对于“付款”增加了对“合同号”数据的继承,也就是说,原来在付款的时候不会考虑“合同号”,只针对供应商就行,总计欠多少,付多少,现在付款要不仅要针对供应商,还有具体到哪个合同,区分款项是给哪个合同付的,这样才能记录合同的成本。
以上是理清思路和逻辑规划的工作,实际上对于“三个表”的改变仅需要在index表中加个字段Cost(费用名称)即可。
表52 index表添加字段后结构
字段 |
类型 |
作用 |
WID |
int |
索引号 |
workId |
String |
*工作编号 |
HTId |
String |
*合同号 |
KHName |
String |
客户名称 |
CPId |
String |
产品编号 |
CPName |
String |
产品名称 |
Size |
String |
规格型号 |
Unit |
String |
产品单位 |
CPPrice |
Float |
产品单价 |
GYSName |
String |
供应商名称 |
CGPrice |
Float |
采购单价 |
CKNo |
String |
仓库单据号 |
CWNo |
String |
财务单据号 |
Cost |
String |
费用名称 |
这样在实际运行中,比如原来付款在mon表中记录的数据将有如下变化:
表53 在mon表中原来的数据
|
表54 在mon表中变化后的数据
|
操作“费用录入”和上面道理一样不做赘述。这样处理数据,当合同执行结束,各项款项都处理了,按“合同号”统计1010科目的数据即可得到整个合同的成本了。增加一个工作简单吧!
分析:在逻辑设计中,添加“成本”时,为了能找到可以“抵扣”的对象,同时加了个“成本预算”科目,如果系统功能要求已经达到了,那么这个科目就没有统计意义了,但是,再深入考虑一下,在最初“合同签订”的时候,和客户谈判确定产品的价格的时候是不是会考虑“根据经验在国内采购这些产品大概价格是说多少?加上合理的利润,确定报价”?对逻辑设计做如下修改:
图10 逻辑设计调整
添加个“虚”的“总成本”作为抵扣
在“合同签订”的工作操作时,输入如下数据:
表55 “合同签订”修改后模拟数据
产品编号 |
产品名称 |
规格型号 |
单位 |
单价 |
数量 |
金额 |
预算单价 |
预算金额 |
CP001 |
变压器 |
KM9824 |
个 |
12.6 |
1000 |
12600 |
8.6 |
8600 |
CP002 |
电感 |
ML7823 |
个 |
8.4 |
2000 |
16800 |
6.85 |
13700 |
把“预算金额”加入到“成本预算1009”中,这样将来合同执行结束后,根据“合同号”统计成本预算,通过合计的正负可知实际经营的结果和预想的差异,如果为正,则说明实际执行的情况比预算好,多赚钱了,如果为负,则说明实际执行情况超出预算了。这样在管理上如果业务和采购是两个部门,相应的考核标准也就出来了。并且这样的改动调整对企业业务没有什么影响。
这样看来,这种算法是不是非常符合企业管理的自然思维,很多管理功能和管理想法很轻松的就实现了,并且逻辑关系严密、清晰。的
4 创新算法的意义
企业信息化的应用历史从DOS时代的dBase,到Windows时代的FoxPro、MRP、ERP等等一路走来,都是沿着数据记录、逻辑处理这个路子不断罗列、扩展而来,新的算法完全颠覆目前所有管理软件的模式,把管理逻辑作为思维的核心,大大简化了数据结构,处理企业管理的数据更加“简单、清晰、合理”,系统设计的思维方式也和管理契合,以此理论为基础设计开发的管理软件将更加适合企业应用,很容易二次开发和修改调整。在设计和应用中不仅可以完成企业已有的实际管理工作,还可以很自然地发现管理逻辑中的漏洞和问题,在应用过程中调动管理者的聪明才智,激发灵感,反过来推动企业管理的完善和提高,这才是管理软件的目标和真正意义所在。
5 应用实践
我们根据上述的算法原理,开发了“脉达M3”软件系统,其核心数据架构依照上面介绍的原理,只不过进一步完善辅助的各项配置数据和功能,并形成配置工具,可以方便地配置出“二元”分析所得到的结果。