BOM带库存算法
向你请教一种算法
现在我有一张表bom mid表示物品编码 ,Cid表示所组成的物品编码,num表示 所需要 Cid物品个数
(举例现有一支笔A,笔由笔帽,笔心,外壳组成,笔心由,油墨,笔心壳组成)这种组合会随不同物品而变化,产生不同的层级)
Mid Cid num
A A1 2
A A2 3
A A3 3
A2 A3 3
A2 A4 3
A2 A5 3
A4 A5 3
A4 A6 3
.........
表 store 仓库,mid即物品编码 SL表示数量
Mid SL
A 2
A1 5
A2 3
A4 1
A5 2
A6 3
现在要求领10个A,程序大致要这样执行,先去store看A的个数,成品有2个,接下来8个要用子原料来生产,A2=3*8 A3=3*8,然后再看A2 A3各自库存数……这样,可以通过哪种算法去实现?
[解决办法]
以下这些代码是从书上抄的,希望对大家有用
--------mrp计算存储过程CREATE PROCEDURE sf_mrp计算 ( @考虑库存等 bit=1, @考虑提前期 bit=1, @考虑损耗 bit=1)ASbegin tran --清除 delete from mrp物料需求计算 -- 更新物料清单底层码,计算时使用 update 物料清单 set 低层码 = 0 where 父项编号 = 0 -- 循环10次,根据情况,这里默认bom物料的层级不超过10级 declare @i int select @i = 1 while (@i<=10) begin update 物料清单 set 低层码 = b.低层码+1 from 物料清单 as a, (select * from 物料清单) as b where a.父项编号 = b.物料编号 select @i = @i + 1 end --重新生成物料需求计算表,并计算毛需求 -- 低层码代表物料的层级,使用他来循环 insert into mrp物料需求计算(物料编号,年份,计划期,毛需求) select 物料编号,年份,计划期,sum(MPS数量) FROM 主生产计划 group by 物料编号,年份,计划期 select @i = 1 while (@i<=10) begin -- 没有的先查入记录,因为一个物料可以对应多个父项 insert into mrp物料需求计算(物料编号,年份,计划期,毛需求) select distinct b.物料编号,年份,计划期,0 FROM mrp物料需求计算 as a, 物料清单 as b where rtrim(b.物料编号)+convert(char(4),年份)+ convert(char(2),计划期) not in(select rtrim(物料编号)+ convert(char(4),年份)+convert(char(2),计划期) from mrp物料需求计算) and b.父项编号=a.物料编号 and b.低层码=@i -- 计算毛需求 -- 注意考虑损耗的情况 update mrp物料需求计算 set 毛需求 = c.毛需求 + d.需求 from mrp物料需求计算 as c, (select b.物料编号,年份,计划期, sum((a.毛需求*b.需要数量)/(1-(case when @考虑损耗=1 then isnull(损耗率,0) else 0 end))) as 需求 FROM mrp物料需求计算 as a, 物料清单 as b where b.父项编号=a.物料编号 and b.低层码=@i group by b.物料编号,a.年份,a.计划期 ) as d where c.物料编号=d.物料编号 and c.年份=d.年份 and c.计划期=d.计划期 select @i = @i + 1 end --------------- 不考虑提前期的毛需求计算完成 -- 考虑提前期,计算提前期 --if (@考虑提前期=1) --begin -- 这里不在计算,具体计算方法为将当前计划期的数量移到提前期 -- 注意跨年度计划期的 --end if (@考虑库存等=1) begin -- 第一次计算,设置期初库存 -- 这里统一设置起初库存为100 -- 实际系统应该和库存库及上期情况结合 update mrp物料需求计算 set 期初库存=100 update mrp物料需求计算 set 预计入库 = isnull(预计入库,0) + 数量 from mrp物料需求计算 as a, (select sum(剩余数量) as 数量, 物料编号,年份,计划期 from 采购订单 group by 物料编号,年份,计划期) as b, 物料主文件 as c where a.物料编号=b.物料编号 and a.年份=b.年份 and a.计划期=b.计划期 and a.物料编号 = c.物料编号 and c.计划类别='wg' -- 外购产品 update mrp物料需求计算 set 预计入库 = isnull(预计入库,0) + 数量 from mrp物料需求计算 as a, (select sum(剩余数量) as 数量, 物料编号,年份,计划期 from 生产订单 group by 物料编号,年份,计划期) as b, 物料主文件 as c where a.物料编号=b.物料编号 and a.年份=b.年份 and a.计划期=b.计划期 and a.物料编号 = c.物料编号 and c.计划类别='bcp' -- 半成品 -- 这里计算预计出库的情况 update mrp物料需求计算 set 预计出库 = isnull(预计出库,0) end -- 按照计划期循环计算各个计划期的物料需求 declare @年份 int, @计划期 int declare mycur cursor for select 年份,计划期 from mrp物料需求计算 order by 年份,计划期 open mycur fetch next from mycur into @年份, @计划期 WHILE (@@FETCH_STATUS = 0 ) BEGIN -- 如果不是最小的计划期, 计算期初库存 -- 注意跨年度的计算,这里先不考虑 update mrp物料需求计算 set 期初库存=b.预计库存 from mrp物料需求计算 as a, (select * from mrp物料需求计算) as b where a.年份=@年份 and a.计划期=@计划期 and a.年份=b.年份 and a.计划期=b.计划期+1 -- 计算净需求 update mrp物料需求计算 set 预计库存 = isnull(期初库存,0) - isnull(毛需求,0) + isnull(预计入库,0) - isnull(预计出库,0) where 年份=@年份 and 计划期=@计划期 update mrp物料需求计算 set 净需求=0 where 年份=@年份 and 计划期=@计划期 -- 预期(期末库存)小于0的存在净需求 update mrp物料需求计算 set 净需求=-预计库存, 预计库存=0 where 年份=@年份 and 计划期=@计划期 and 预计库存<0 fetch next from mycur into @年份, @计划期 END close mycur deallocate mycurcommitGO
[解决办法]
从书上抄的,希望对大家有用
--------mrp计算存储过程CREATE PROCEDURE sf_mrp计算 ( @考虑库存等 bit=1, @考虑提前期 bit=1, @考虑损耗 bit=1)ASbegin tran --清除 delete from mrp物料需求计算 -- 更新物料清单底层码,计算时使用 update 物料清单 set 低层码 = 0 where 父项编号 = 0 -- 循环10次,根据情况,这里默认bom物料的层级不超过10级 declare @i int select @i = 1 while (@i<=10) begin update 物料清单 set 低层码 = b.低层码+1 from 物料清单 as a, (select * from 物料清单) as b where a.父项编号 = b.物料编号 select @i = @i + 1 end --重新生成物料需求计算表,并计算毛需求 -- 低层码代表物料的层级,使用他来循环 insert into mrp物料需求计算(物料编号,年份,计划期,毛需求) select 物料编号,年份,计划期,sum(MPS数量) FROM 主生产计划 group by 物料编号,年份,计划期 select @i = 1 while (@i<=10) begin -- 没有的先查入记录,因为一个物料可以对应多个父项 insert into mrp物料需求计算(物料编号,年份,计划期,毛需求) select distinct b.物料编号,年份,计划期,0 FROM mrp物料需求计算 as a, 物料清单 as b where rtrim(b.物料编号)+convert(char(4),年份)+ convert(char(2),计划期) not in(select rtrim(物料编号)+ convert(char(4),年份)+convert(char(2),计划期) from mrp物料需求计算) and b.父项编号=a.物料编号 and b.低层码=@i -- 计算毛需求 -- 注意考虑损耗的情况 update mrp物料需求计算 set 毛需求 = c.毛需求 + d.需求 from mrp物料需求计算 as c, (select b.物料编号,年份,计划期, sum((a.毛需求*b.需要数量)/(1-(case when @考虑损耗=1 then isnull(损耗率,0) else 0 end))) as 需求 FROM mrp物料需求计算 as a, 物料清单 as b where b.父项编号=a.物料编号 and b.低层码=@i group by b.物料编号,a.年份,a.计划期 ) as d where c.物料编号=d.物料编号 and c.年份=d.年份 and c.计划期=d.计划期 select @i = @i + 1 end --------------- 不考虑提前期的毛需求计算完成 -- 考虑提前期,计算提前期 --if (@考虑提前期=1) --begin -- 这里不在计算,具体计算方法为将当前计划期的数量移到提前期 -- 注意跨年度计划期的 --end if (@考虑库存等=1) begin -- 第一次计算,设置期初库存 -- 这里统一设置起初库存为100 -- 实际系统应该和库存库及上期情况结合 update mrp物料需求计算 set 期初库存=100 update mrp物料需求计算 set 预计入库 = isnull(预计入库,0) + 数量 from mrp物料需求计算 as a, (select sum(剩余数量) as 数量, 物料编号,年份,计划期 from 采购订单 group by 物料编号,年份,计划期) as b, 物料主文件 as c where a.物料编号=b.物料编号 and a.年份=b.年份 and a.计划期=b.计划期 and a.物料编号 = c.物料编号 and c.计划类别='wg' -- 外购产品 update mrp物料需求计算 set 预计入库 = isnull(预计入库,0) + 数量 from mrp物料需求计算 as a, (select sum(剩余数量) as 数量, 物料编号,年份,计划期 from 生产订单 group by 物料编号,年份,计划期) as b, 物料主文件 as c where a.物料编号=b.物料编号 and a.年份=b.年份 and a.计划期=b.计划期 and a.物料编号 = c.物料编号 and c.计划类别='bcp' -- 半成品 -- 这里计算预计出库的情况 update mrp物料需求计算 set 预计出库 = isnull(预计出库,0) end -- 按照计划期循环计算各个计划期的物料需求 declare @年份 int, @计划期 int declare mycur cursor for select 年份,计划期 from mrp物料需求计算 order by 年份,计划期 open mycur fetch next from mycur into @年份, @计划期 WHILE (@@FETCH_STATUS = 0 ) BEGIN -- 如果不是最小的计划期, 计算期初库存 -- 注意跨年度的计算,这里先不考虑 update mrp物料需求计算 set 期初库存=b.预计库存 from mrp物料需求计算 as a, (select * from mrp物料需求计算) as b where a.年份=@年份 and a.计划期=@计划期 and a.年份=b.年份 and a.计划期=b.计划期+1 -- 计算净需求 update mrp物料需求计算 set 预计库存 = isnull(期初库存,0) - isnull(毛需求,0) + isnull(预计入库,0) - isnull(预计出库,0) where 年份=@年份 and 计划期=@计划期 update mrp物料需求计算 set 净需求=0 where 年份=@年份 and 计划期=@计划期 -- 预期(期末库存)小于0的存在净需求 update mrp物料需求计算 set 净需求=-预计库存, 预计库存=0 where 年份=@年份 and 计划期=@计划期 and 预计库存<0 fetch next from mycur into @年份, @计划期 END close mycur deallocate mycurcommitGO