摘要:本文针对ERP中MRP核心模块的算法进行了分析,描述的角度有多方面,首先从基础定义上做了一些简单的解释说明,其次在每一个小算法里面做了流程图分析,最后用伪代码将所有的函数进行了梳理,本文或许会需要一个较长的更新周期,但相信大家在顺着本文的思路可以开发一个小小的MRP计算程序,也可以完全做一个比较实用的生产调度系统。
下面就逐步介绍该算法
一、ERP计算总体流程
或许大家大都对这个流程图比较熟悉,但是这里还是把他列了出来,因为这是本文的一个开始,也是一个基奠,如下图:
分 三个部分,首先是MRP的输入部门,其次是MRP计算部分,最后是MRP的计算结果。从本图例上看,其过程应该是我们根据主生产计划、物料主文件、物料清单、库存信息以及工作日历通过MRP计算器得到采购计划及自制计划。下面将做分步详细的说明。
(一)、主生产计划(MPS)
1、主生产计划(MPS)存储结构
代号 | 产品编码 | 产品图号 | 产品名称 | 需求数量 | 订货日期 | 需求日期 |
MPS001 | A | A | A | 5 | 2011/1/25 | 2011/2/25 |
MPS001 | A | A | A | 10 | 2011/1/25 | 2011/2/30 |
MPS001 | A | A | A | 10 | 2011/1/25 | 2011/3/2 |
2、主生产计划(MPS)数据库设计
名称 | 代码 | 数据类型 | 非空 | 是否主键 |
MPS代号 | ID | nvarchar(20) | TRUE | TRUE |
产品代码 | ItemCode | nvarchar(20) | TRUE | FALSE |
产品图号 | DrawID | nvarchar(20) | TRUE | FALSE |
产品名称 | DrawName | nvarchar(20) | TRUE | FALSE |
需求数量 | DemandNum | int | TRUE | FALSE |
订单日期 | OrderTime | datetime | TRUE | FALSE |
需求日期 | DEMandTime | datetime | TRUE | FALSE |
(二)、物料主文件(Materiel)
1、物料主文件(Materiel)存储结构
物料编码 | 物料名称 | 图号 | 计量单位 | 物料类型 | 物料来源 | 批量 | 最小订货量 | 订货倍量 | 固定提前期 | 可变提前期 | 安全库存 | 是否独立需求 | 是否虚拟件 |
A | A | A | EA | M | M | 5 | 5 | 1 | 5 | 0 | 0 | ||
B | B | B | EA | M | M | 10 | 5 | 2 | 100 | 0 | 0 | ||
C | C | C | EA | M | M | 10 | 5 | 2 | 100 | 0 | 0 | ||
D | D | D | EA | M | P | 30 | 30 | 30 | 5 | 2 | 100 | 1 | 0 |
E | E | E | EA | M | P | 40 | 40 | 40 | 5 | 2 | 100 | 0 | 0 |
F | F | F | EA | M | P | 40 | 40 | 40 | 5 | 2 | 100 | 0 | 0 |
G | G | G | EA | M | M | 20 | 5 | 2 | 100 | 0 | 1 | ||
H | H | H | EA | M | P | 50 | 50 | 50 | 5 | 2 | 100 | 1 | 0 |
I | I | I | EA | M | P | 50 | 50 | 50 | 5 | 2 | 100 | 1 | 0 |
2、物料主文件(Materiel)数据库设计
名称 | 代码 | 数据类型 | 非空 | 是否主键 | 说明 |
物料编码 | ItemCode | nvarchar(20) | TRUE | TRUE | |
物料名称 | ItemName | nvarchar(20) | TRUE | FALSE | |
图号 | DrawID | nvarchar(20) | TRUE | FALSE | |
单位 | UM | char(4) | TRUE | FALSE | |
物料类型 | MatType | char(4) | TRUE | FALSE | |
物料来源 | Sourse | char(4) | TRUE | FALSE | M或P |
批量 | LotSize | numeric | TRUE | FALSE | |
最小订货量 | OrderMin | numeric | TRUE | FALSE | |
订货倍量 | OrderMul | numeric | TRUE | FALSE | |
固定提前期 | LeadTime | int | TRUE | FALSE | |
可变提前期 | VleadTime | int | TRUE | FALSE | |
安全库存 | SafeStock | numeric | TRUE | FALSE | |
是否独立需求 | Mpsflag | char(4) | TRUE | FALSE | 0或1 |
虚拟标识 | Phflag | char(4) | TRUE | FALSE | 0或1 |
…… |
(三)、产品物料清单(BOM)
1、产品物料清单(BOM)图示
产品A的结构
2、产品物料清单(BOM)库存储结构
物料编码 | 父物料编码 | 数量关系 | 层级 | …… |
A | 1 | 0 | ||
B | A | 3 | 1 | |
C | A | 2 | 1 | |
D | A | 4 | 1 | |
E | B | 2 | 2 | |
F | B | 1 | 2 | |
G | C | 2 | 2 | |
F | C | 3 | 2 | |
H | G | 4 | 3 | |
I | G | 1 | 3 |
3、产品物料清单的数据库设计
名称 | 代码 | 数据类型 | 非空 | 是否主键 |
物料编码 | ItemCode | nvarchar(20) | TRUE | FALSE |
父物料编码 | FaItemCode | nvarchar(20) | TRUE | FALSE |
数量关系 | Num | int | TRUE | FALSE |
层级 | Step | int | TRUE | FALSE |
(四)、库存文件(INVENTORY)
1、库存文件(INVENTORY)的存储结构
物料编码 | 物料名称 | 当前实存 | 计划入库 | 已分配量 | 预计可入库量 |
A | A | 5 | 5 | ||
B | B | 100 | 100 | 50 | 50 |
C | C | 100 | 100 | 50 | 50 |
D | D | 100 | 100 | 50 | 50 |
E | E | 100 | 100 | 50 | 50 |
F | F | 100 | 100 | 50 | 50 |
G | G | 100 | 100 | 50 | 50 |
H | H | 100 | 100 | 50 | 50 |
I | I | 100 | 100 | 50 | 50 |
2、库存文件(INVENTORY)的数据库设计
名称 | 代码 | 数据类型 | 非空 | 是否主键 | 说明 |
物料编码 | ItemCode | nvarchar(20) | TRUE | TRUE | |
物料编码 | ItemCode | nvarchar(20) | TRUE | FALSE | |
物料名称 | ItemName | nvarchar(20) | TRUE | FALSE | |
当前实存 | StoNow | numeric | TRUE | FALSE | |
计划入库 | StoPlan | numeric | TRUE | FALSE | |
已分配量 | StoDown | numeric | TRUE | FALSE | |
预计可入库量 | StoHave | numeric | TRUE | FALSE |
(五)、工作日历(WORKDAY)
1、工作日历(WORKDAY)数据库设计
名称 | 代码 | 数据类型 | 非空 | 主键 | 说明 |
日期编号 | wd001 | varchar(20) | TRUE | TRUE | |
日期 | wd002 | varchar(20) | TRUE | FALSE | |
是否为工作日 | wd003 | varchar(1) | TRUE | FALSE | O或1 |
工作日数量 | wd004 | numeric | TRUE | FALSE | |
对应工作日日期 | wd005 | datetime | TRUE | FALSE |
2、对工作日历数据库设计的说明
工作日数量:如果是工作日,则自动加1
对应工作日日期:如果是工作日则对应日期,如果不是工作日则是最近的工作日日期
(——今天先到这里吧……)
二、物料需求计划(MRP)计算逻辑
(一)、基本逻辑,MRP的基本逻辑可做如下解释
A、要生产什么,包括采购的和制造的,生产多少?
B、生产这些东西要用的什么物料?这些数据可以通过BOM表获得
C、已经有了什么?这些数据可以根据库存文件获得
D、还缺什么?需要多少?这些由通过MRP计算结果得到
E、何时开始制造(采购),什么时间完成?这些信息由MRP计算结构得到
(二)、物料需求计划(MRP)的相关计算
1、计算毛需求Demandrough(T)
是指在T计划周期内对物料的总需求量,分两种情况,第一种情况是如果是独立需求件,毛需求量根据主生产计划得到;第一种如果是相关需求件,则通过如下计算公式:Demandrough(T)=
其中Di (T)是指该物料的第i个父项在第T时段计划下达数量,Qi为单位第i个父项所需子项的数量,即BOM表中的数量关系。
注意:在实际的计算过程中或许会碰到同一物料在不同层级上的现象,这时候就引用了底层码的概念,低层码是指如果同一物料在不同层级上出现则其低层码取层级较低的那个,从数字上看就是数字较大的那个;在实际的MRP计算中是按照低层码顺序对产品结构树进行层序遍历的。
2、有效库存(V(t))与净需求量(G(t))
有效库存 V(t)=S(t)-A(t)+R(t)-safestock,净需求量 G(t)=Demandrough(T)-V(t)
S(t) 为当前是存量,A(t)为已分配量,R(t) 为预计到货量;如果G(t)>0,在T时段能够满足需求,需要下达任务;如果G(t)<0,则说明当前库存能够满足T时段的需求,不需要下达任务。
3、计划产出量P(t)
为了满足净需求,我们需要计算计划产出量,从上面的分析或大家认为,计划产出量为Demandrough(T) 不就可以了吗?!实际上这里面有个策略的问题,大家或许都比较明白经济订货批量或经济生产批量的定义或最小订货量的定义,我们把这个参数定义为EOQ,为此这里我们需考虑这些因素,所以这里需要做个判断:
如果G(t)>EOQ,则订货量为G(t)
如果G(t)<EOQ,则订货量为EOQ
注:当然这里或许还有一个订货倍量或者物品的包装规格的计算问题,在这里就搞这么复杂了。
4、计划投入量R(t)
之所以提出这个概念是因为里面考虑一个参数,这个参数就是废品率P,在实际的生产或采购过程中必然会遇到废品率或不合格率的问题,所以我们的投入一般都要根据这个参数将计划产出量(P(t))进行放大,其计算方法如下:
R(t)=P(t)*(1-p)
5、期末库存量(H(t))
指的是在某物料在T计算周期期末的库存量,这里有两种情况,第一,当毛需求量Demandrough(T) 大于上一期的期末H(t-1)再减去安全库存safestock时,则期末库存H(t)为计划产出量与净需求之差,第二,反之,则为上一期的期末库存与毛需求之差,用公式表示如下:
若Demandrough(T) <H(t-1)-safestock,则H(t)=P(t)-G(t);
若Demandrough(T) <=H(t-1)-safestock,则H(t)=H(t-1)-Demandrough(T)
(三)、物料需求计划(MRP)的计算流程
1、MRP计算流程,如下图:
2、MRP计算逻辑
1)初始化,导入主生产计划(MPS)、物料清单(BOM)、库存信息、工作日历等文件数据
2)分解计算,对每个物料按期在BOM中的层次自上而下,自左而右进行循环分解,从层级为0的物料开始,依次执行步骤3)——9)
3)计算毛需求Demandrough(t),计算出当前层次上物料的毛需求量
4)若该物料的底层码等于当前层次号,则执行步骤5)——7)否则该物料的毛需求结果进行暂时保存,并跳转步骤8)
5)计算净需求G(t)
6)计算计划产出量P(t)
7)计算计划投入量R(t)
8)若该物料有子节点,转步骤9),否则计算该层下一个物料的相关需求量,并跳转步骤3)
9)若N不是最后的层次,则N=N+1,转步骤3),否则表明该物料的所有层次遍历完毕,分解结束
3、MRP计算结果报表格式
物料编码 | 物料名称 | 毛需求量 | 净需求量 | 计划产出量 | 计划投入量 | 预计期末库存量 | 开工时间 | 完工时间 |
三、物料需求计划(MRP)的软件实现
一)MRP系统总体功能结构图
二)数据库设计见上述表格
三)物料需求计划(MRP)代码设计
今天(2011-1-27)暂时到这里吧……