神奇,Foxtable瞬间完成30万行的MRP计算


作者:天问

遇到Foxtable,或许真的是我意外的收获。

我在一家企业从事生产管理工作多年,数据管理和统计分析的任务非常繁重,这些年我试用了国内很多企业管理软件,但是现成的管理软件局限太多,难以满足我们一些个性化的需求,让开发商专门为我们修改,这几乎是不可能的;于是我开始尝试自己开发,因为我不是学计算机的,对于专业开发工具,我是没有精力和能力去学习掌握的,所以我将目光投向了一些快速开发工具,可以说国内稍微有点名气的开发工具,我都有研究过,有的还购买过,很多工具价格昂贵不说,功能却徒有虚名,诸多限制,几乎没有可能真正开发出一套真正合格的管理软件来。

直到1年前,我偶然间发现了易表,正如其名,易表易学易用,很快我就做出了一个小项目,在开始应用的时候,问题来了,因为易表对于网络环境下多用户协同工作的情况,是不太合适的, 而且数据量较大的时候(我公司一天的数据量有5万行左右),易表处理起来也捉襟见肘,万般无奈正想放弃的时候,易表公司突然推出了另一个开发工具:Foxtable。Foxtable不仅功能和性能有质的飞跃,而且支持局域网和互联网,海量数据的处理也能应付自如了。

2011年的5月1号,利用五一休假的时间,我正式开始试用Foxtable,一开始我根本不知道怎么弄,于是边学边练,不懂就问,好在Foxtable官方的技术支持非常专业和及时,尽管我只是一个试用版用户, 但我在官方论坛上提的每一个问题, 都能得到耐心的解答,慢慢的我就有了一些心得。

一周之后,我毅然决定选择Foxtable作为公司未来管理软件的开发平台,原因很简单,他快速架构系统的能力 ,快捷的录入、查询、统计方式,以及高效专业的报表输出功能,绝对优于国内其他任何快速开发平台,而且界面设计和实现复杂功能的能力,也高出其他平台一个等级,许多以前没有办法解决的难题,现在都能轻松松搞定。玩到兴奋的时候,我甚至觉得Foxtable简直就是我们这种编程门外汉的舞台,慢慢地我在这个舞台上玩出了一些另样的精彩。

我最得意的一次“表演”,是我开发的一套系统,只用了6秒钟,就完成30万行数据量的MRP计算,不少Foxtable论坛的用户因为这个功能私下人找过我,请教方法,我今天也“无私”一回,在此给大家分享一下这段代码的运算方式。

我任职企业早期的MRP的计算,和市面上传统的MRP软件没什么太大的区别,可怜运算一次MRP居然要耗时近3小时,如果碰上数据修改的话,一天算上两回就该下班了,显然这样的运算速度,是无法满足企业正常的生产运转的,老板看了直摇头。 并非我们的MRP软件有问题,因为据说金蝶K3进行一次30万行数据的MRP运算,也要耗时数十个小时的。之前每次进行MRP计算,我都格外的纠结,直到有一次在翻阅Foxtable的 帮助文档时,在《代码优化》这一章发现一个很神奇的例子,一万行的数据运算居然只要0.1秒, 这简直不可思议。在学习消化这个例子后,我也写出了“神奇”的代码:30万行数据量的MRP计算只需耗时6秒。

其实这段MRP计算代码的原理很简单,先是将各个需要参与计算的数据表组合成一张混合的超级查询表(我的系统是14表的组合,在这里我就不解释了),然后根据 《代码优化》的原理,先将物料以时间为序计算出相同物料的累积需求,然后再利用表达式列以累积需求为基准计算出物料的分配状态,以及需求数量等等一系列的数据。为了能够让大家更好的理解,我以采购MRP需求运算为例,介绍一下设计的要点。

首先我整理出需要参与计算的各个表,在正常的情况下,参与计算的表单有:《生产物料需求表(一般指物料BOM表)》、《库存表》、《待入库物料表》、《采购在途物料表》、《采购请购状况物料表》。

我们将以上各表以物料代码为基准条件组合成一张查询表,不过这里有个前提,就是《待入库物料表》、《采购在途物料表》、《采购请购状况物料表》这3张表必须先处理成唯一物料的统计表,不然在生成查询表的时候会出错。 生成的查询表包括以下字段:

 

 

在生成查询表后,我再用代码添加用来进行横向计算的表达式列(注意在设置表达式列的时候先不要设置表达式列的计算公式,否者会影响计算速度),我的做法是加上以下表达式列 ,但不设置计算公式:

 

 

然后我们就可以将物料以时间为序计算出相同物料的累积需求了,如下图所示:

 

 

计算代码很简单:

Dim drs As List(of DataRow) = DataTables("MRP物料需求").Select("", "物料代码, 计划开始")
drs(0)("需求累计") = drs(0)("需求数量")
For i As Integer = 1 To drs.Count - 1
    If drs(i)("物料代码") = drs(i - 1)("物料代码") Then
        drs(i)("需求累计") = drs(i-1)("需求累计") + drs(i)("需求数量")
    Else
        drs(i)("需求累计") = drs(i)("需求数量")
    End If
Next

计算出累积需求之后,我们就可以用代码设置各表达式列的计算公式,各列的计算公式如下:
 

【去库存需求】 :

IIF(IsNull([库存数量],0) -IsNull([需求累计],0) >= 0, Null ,IIF([需求数量] +IsNull([库存数量],0) -IsNull([需求累计],0) > 0,[需求数量] + isNull([库存数量],0)-IsNull([需求累计],0),[需求数量]))

【缺件数量】:

IIF(IsNull([库存数量],0) + IsNull([待入库数量],0) + IsNull([在途数量],0) + IsNull([请购数量],0) - IsNull([需求累计],0) >= 0,0,IIF([需求数量] + (IsNull([库存数量],0) + IsNull([待入库数量],0) + IsNull([在途数量],0) + IsNull([请购数量],0) - IsNull([需求累计],0)) > 0,[需求数量] + IsNull([库存数量],0) + IsNull([待入库数量],0) + IsNull([在途数量],0) + IsNull([请购数量],0) - IsNull([需求累计],0),[需求数量]))

【分配状态】

IIF([去库存需求] is Null,Null,
IIF(IsNull([库存数量],0) + IsNull([待入库数量],0) - [需求累计] > 0,'待入库',
IIF(IsNull([库存数量],0) + IsNull([待入库数量],0) + IsNull([在途数量],0) - [需求累计] > 0,'在途',
IIF(IsNull([库存数量],0) + IsNull([待入库数量],0) + IsNull([在途数量],0) + IsNull([请购数量],0) - [需求累计] > 0,'请购', Null ))))

30万行数据的运算代码就是如此的简单,整个过程瞬息之间就完成了,当我演示给金蝶的客服看时,他不仅惊叹:原来MRP还可以这样计算!
 

自此之后我对Foxtable的兴趣也越来越足了,后来利用数据表与目录树的相结合,又成功开发出了主界面为目录树的工作流业务管理系统,比我单位之前花费数万购买的以工作流作为买点的Excel服务器要强大灵活很多:

 

 

 

 

 

再后来,我又用Foxtable实现了QQ通讯(内部通讯) 、万年日历、菜单流程权限等一系列的功能,同样的是这些功能的原型全部来自于foxtable的自带案例和他那强大的帮助文件(2000多页的帮助,我在此试问一下国内有几个软件的开发商能写出如此 详尽的文档?并且每段代码都能带上不同的操作案例,以便用户进行有效的学习及思路的延伸),或许这就是FoxTable能快速架构系统的原因之一吧。只要认真的看帮助,看Foxtable的自带案例,不懂就到官方论坛提问,很快就能找到开发的感觉。在2011年5月1号之前,我是一个完全不知道编程是什么的门外汉,到2011年12月31号,仅仅是半年的的时间,我就在Foxtable这个平民的舞台上绽放出了另样的精彩。

在这半年的时间内,我不仅掌握了Foxtable,还为4家企业或个人开发过项目,下面是我部分作品的截图,窗口是我自己写的皮肤: