已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
生产计划的生产排程的算法制造业的ERP系统应该以计划为核心,特别是生产计划如何合理的进行排产显得尤为重要。但如何实现生产计划为核心?我想,生产排程系统的实施,是对此问题的最好答复。 所谓生产排程通俗讲,是指生产计划和作业计划的统称。通常企业制定生产计划的过程一般分成两部分,首先是生成主生产计划,其次是根据主生产计划生成生产作业计划。主生产计划一般来源于订单,部分企业来源于市场预测,安排一个生产计划,基本是管理者在进行决策,人的因素起绝对作用。这个过程中会有一些行业或者企业的特别计算方法,需经过一些四则运算式的统计分析。但是,光有主生产计划是远远不够的。一个简单的主生产计划的生产要求,要把它自动分解为复杂、具体的生产作业过程,这就是详细生产排程,是生产排程系统真正核心功能价值的体现。一般说,生产作业计划越详细,它给出的信息越丰富、越有价值,相应计算起来也就越困难。生产作业计划越粗略,越接近主生产计划,信息越少、价值就越低。企业总是希望自动得到尽可能详细的作业计划,减少作业下达的层次。但是ERP在这方面遇到了真正的技术瓶颈。就我目前所见,几乎全部的ERP生产管理都是从四则运算的主生产计划入手,重点利用BOM解决MRP物料需求计划,之后再解决生产过程的记录和统计。如果考虑生产计划全方位信息,减少人为因素影响问题,生产排程系统可以满足你的要求。生产排程系统是基于ERP系统结构设计而成,生产排程系统可独立于ERP系统,作为ERP系统高级功能的一个模块,帮助企业解决:一、订单管理跟踪问题通过需求整理平台实现营销需求订单与生产需求的衔接。通过排程平台实现计划订单排程、生产作业下达和管理、任务完工到中转出库的全面订单跟踪管理。二、生产排程问题,实现总装任务排产到生产线的管理按任意需求时间范围、排程时间范围执行预排处理。按提前天数、生产需求时间、订单优先级、排程分类、生产线优先级、线能力执行生产线分配。依据需求时间的固定自动创建固定的计划订单。按生产线优先级、产能、折返时间等平衡生产线的负荷。计划订单生产线的换线处理、排程分类变更引发的预排自动换线处理。三、实现总装部装的按需联动处理总装部装跟单同步排程。总装部装跟单任务同步下达。总装部装计划同步变更调整。总装部装跟单件按规则同步分配到相关生产车间。其次,排程平台的实施,推进生产管理模式的变革计划层次减少,计划集中处理加强。排程的联动处理,加速了计划与生产的响应效率。减少传统计划排产的出错机率:如总装部装同步排程、同步下达,时间差异、数据差异减少。重新界定主计划员、生产部计划员、车间计划员的职责。强调车间层面的执行与现场跟进,提高了发现问题解决问题的精准性、时效性。最后,生产排程系统主要由:基础数据设置、需求平台、预排程和排程、排程工作台核心四部分内容组成。基础数据主要是把企业生产人员的想法,通过系统进行固化,通过系统强大的计算功能对计划进行优化和排程。需求平台:主要通过需求平台和其他系统或者预测进行连接,获取订单信息和预测信息,同时对加载的这部分需求信息进行整理和维护。预排程:按所有生产订单的优先级,按照一定的次序时间安排到具体生产线上;在排程时考虑折返天数;考虑能力约束;考虑排程需求成组;考虑换线时间;考虑已经确认的计划订单和车间任务;考虑排程时间栏,以确定排程计划在该时间范围内计算;考虑不同的订单类型。排程:把生产线上计划定单,按照顺排的规则,重新安排计划定单;在排程时仅考虑生产线能力;生成总装计划定单;跟单部件计划定单生成;未确认物料定单的报告;实际排程和需求差异报告;成组需求排程例外报告;能力例外报告。排程工作台:排程计划生产订单的下达;对排程中订单优先级的调整;对排程产品生产线的调整;排程订单的重排;车间任务的重排;车间某个计划订单树的重排;车间某个需求订单树的重排;查询每条线上生产任务清单;查询需求订单和实际排产订单的时间安排;查询能力负荷情况提示;查询及跟踪按照某个需求的订单树状态。算法一个根据主生产计划进行生产排程的算法,供各位研究产品技术栏目总是空谈的多,现在来点刺激的。公布一个根据主生产计划进行生产排程的算法,供各位研。 算法体现两个基本原则:1、需求拉动原则 2、物料供需综合平衡原则/-type NodeRecord1=record nodetype: integer; 类型: 0-流程节点 1-配方节点 2-半成品物料节点 3-原始物料节点 MaterialId: string; 物料编号 MaterialName: string; 物料名称 MUnit: string; 计量单位 stepid: string; 工序编号 stepname: string; 工序名称 ProRate: real; 全程投料比例 Number: real; 实际作业需求量 proneed0: real; 理论投料需求量 proneed: real; 实际投料需求量 FlowId: string; 节点流程号 IngredientId: string; 节点配方号 Resolved: boolean; 是否已分解处理end;/ 排程的结果所存放的数组(结构见上面的定义) nodecount1: integer; nodes1: array of noderecord1;/ 子函数:根据半成品物料编码和理论需求量,计算其最佳作业需求量的函数.Function TTaskForm.BestNumber(materialId: string; ProNumber: real): real;var i: integer; oldneed,oknumber,leftnumber,x,oldneed1,addnumber: real;begin try / 得到该物料的原有需求总量. mandtext:=SELECT MINNUMBER+PRONEED+PLANNUMBER FROM MATERIAL WHERE MATERIALID=+MaterialId+; oldneed:=form2.syscommand.execute.Fields0.Value; mandtext:=SELECT MINNUMBER+PLANNUMBER FROM MATERIAL WHERE MATERIALID=+MaterialId+; oldneed1:=form2.syscommand.execute.Fields0.Value; / / 得到本次分解其他结构部分对该物料的需求量. x:=0; for i:=1 to nodecount1 do if nodes1i-1.MaterialId=materialid then x:=x+nodes1i-1.ProNeed; / / 得到原有供应总量. mandtext:=SELECT SAVEDNUMBER+WORKSHOPNUMBER+BUYPLANNUMBER+PROPLANNUMBER FROM MATERIAL WHERE MATERIALID=+MaterialId+; oknumber:=form2.syscommand.execute.Fields0.Value; / / 得到该物料的当前剩余量. leftnumber:=oknumber-oldneed-x; if leftnumber0 then begin if oknumber=pronumber then result:=0 / / 否则,理论需求量-原有剩余量=新增作业需求量 else result:=pronumber-leftnumber; / result:=result+addnumber; except result:=pronumber; end;end;/ -/ 主过程:根据一个上层部件(或顶层产品)的生产需求量,计算下层各生产工序的最佳作业需求量和各物料的投料需求量的过程,结果保存在nodes1数组中./ 入口参数:/ FlowId:上层部件(或顶层产品)的所属流程号/ StepId:上层部件(或顶层产品)所在工序号/ ProNumber:上层部件(或顶层产品)的生产数量(主生产计划)/ 出口参数:/ NodeCount1:总记录数/ Nodes1:记录数组,结构见开始处/ 其中关键数据:/ ProRate: real; 全程投料比例,乘上ProNumber=理论作业需求量/ Number: real; 实际作业需求量/ proneed0: real; 理论投料需求量/proneed: real; 实际投料需求量/ 说明:理论作业需求量:根据BOM直接计算出的工序作业需求量/ 实际作业需求量:在理论作业需求量基础上,再综合所在该工序对应物料的供需平衡/ 关系所确定的最佳作业需求量/理论投料需求量:根据BOM直接计算出的某个物料即将用于生产的需求量/ 实际投料需求量:根据父件的实际作业需求量计算出的某个物料即将用于生产的需求量/ 生产排程的结果是:实际作业需求量/ 物料需求表的数据来源是:实际投料需求量/ -/procedure TTaskForm.ResolveMaterial1(FlowId: string; StepId: string; ProNumber: real);var i,j,k: integer; firststepid: string; tempprorate,tempnumber,proneed,prorate,x: real;begin/ 初始化节点表. nodecount1:=1; setlength(nodes1,1); nodes10.nodetype:=0; 流程节点 mandtext:=SELECT TOP 1 * FROM WORKSTEP WHERE FLOWID=+flowid+ ORDER BY STEPID DESC; form2.sysdataset.active:=true; nodes10.MaterialId:=trim(form2.sysdataset.fieldbyname(MaterialId).asstring); nodes10.MaterialName:=trim(form2.sysdataset.fieldbyname(MaterialName).asstring); nodes10.Munit:=trim(form2.sysdataset.fieldbyname(Unit).asstring); nodes10.stepid:=; nodes10.stepname:=; nodes10.ProRate:=1.00; nodes10.Number:=pronumber; nodes10.FlowId:=flowid; nodes10.IngredientId:=; nodes10.Resolved:=true; 已分解 form2.sysdataset.active:=false;/ 对顶层流程中剩余的工序进行特殊处理. tempprorate:=1.0; 全程投料因子 prorate:=1.0; 继承用投料因子: 即上道工序作业量 tempnumber:=pronumber; 继承用作业量: 即上道工序作业量 / / 得到该流程的末端工序编号. mandtext:=SELECT TOP 1 STEPID FROM WORKSTEP WHERE FLOWID=+flowid+ ORDER BY STEPID; firststepid:=trim(form2.syscommand.execute.fields0.value); / / 过滤出本流程所有剩余工序,从后向前逐个处理. mandtext:=SELECT * FROM WORKSTEP WHERE FLOWID=+FlowId+ AND STEPID=+stepid+ ORDER BY STEPID DESC; form2.sysdataset.Active:=true; while not form2.sysdataset.eof do begin / / 实际投料需求量=上道工序的作业需求量*本道工序投料比例. if trim(form2.sysdataset.fieldbyname(MaterialId).asstring)=nodes10.MaterialId then proneed:=0 else proneed:=tempnumber*prorate; / 计算最佳作业需求量(对于顶层物料,实际作业需求量=理论作业需求量) if trim(form2.sysdataset.fieldbyname(MaterialId).asstring)nodes10.MaterialId then tempnumber:=BestNumber(trim(form2.sysdataset.fieldbyname(MaterialId).asstring),tempnumber*prorate); / / 继承本道工序的投料因子到下道工序的处理过程. prorate:=form2.sysdataset.fieldbyname(ProRate).asfloat; / k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=2; 半成品节点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(MaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(MaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(Unit).asstring); nodes1k.stepid:=trim(form2.sysdataset.fieldbyname(StepId).asstring); nodes1k.stepname:=trim(form2.sysdataset.fieldbyname(StepName).asstring); nodes1k.ProRate:=tempprorate; 全程投料因子 nodes1k.FlowId:=FlowId; nodes1k.IngredientId:=; nodes1k.Resolved:=true; / / 保存实际作业需求量与实际投料需求量. nodes1k.Number:=tempnumber; 实际作业需求量 need:=proneed; 实际投料需求量 / / 计算理论投料需求量. if trim(form2.sysdataset.fieldbyname(MaterialId).asstring)nodes10.MaterialId then need0:=0 else need0:=nodes1k.ProRate*pronumber; 理论投料需求量 / / 假如是末端工序,处理配方连接或流程串接. if trim(form2.sysdataset.fieldbyname(StepId).asstring)=firststepid then begin / / 假如工序号是00,则生成一个配方节点. if nodes1k.stepid=00 then begin k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=1; 配方接点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(OldMaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(OldUnit).asstring); nodes1k.stepid:=; nodes1k.stepname:=; / / 从流程继承到配方(由于组装工序产出物料=流程末端原料,因此,直接从上一个节点记录复制数据). nodes1k.ProRate:=tempprorate; 与流程末端情况一致 nodes1k.number:=tempnumber; need:=proneed; need0:=nodes1k.ProRate*pronumber; / / 取配方号. nodes1k.FlowId:=; nodes1k.IngredientId:=trim(form2.sysdataset.fieldbyname(IngredientId).asstring); nodes1k.Resolved:=false; 未处理 end / / 假如工序号不是00,则处理流程串接. else begin / / 将当前工序的原材料作为产成品的流程,是要对接的流程. mandtext:=SELECT * FROM FLOWS WHERE TMATERIALID=+trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring)+; form2.tempdataset.active:=true; / / 假如不存在对接流程,产生一个原配件接点. if form2.tempdataset.Eof then begin form2.tempdataset.active:=false; / k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=3; 原配件节点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(OldMaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(OldUnit).asstring); nodes1k.stepid:=; nodes1k.stepname:=; / / 修正全程投料因子. nodes1k.ProRate:=tempprorate*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 原材料的作业需求量为0. nodes1k.number:=0; / / 实际投料需求量=上道工序作业量*本道工序的投料比例. need:=tempnumber*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 理论投料需求量计算. need0:=nodes1k.ProRate*pronumber; / nodes1k.FlowId:=; nodes1k.IngredientId:=; nodes1k.Resolved:=true; 已处理 end / / 假如存在对接流程,产生一个流程节点. else begin / / 计算实际投料需求量. x:=bestnumber(trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring),tempnumber*form2.sysdataset.fieldbyname(ProRate).asfloat); / k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=0; 流程节点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(OldMaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(OldUnit).asstring); nodes1k.stepid:=; nodes1k.stepname:=; / / 全程投料因子修正. nodes1k.ProRate:=tempprorate*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 得到最佳作业需求量.(继承到下个流程) nodes1k.number:=x; / / 实际投料需求量=上道工序作业量*本道工序的投料比例. need:=tempnumber*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 理论投料需求量计算. need0:=nodes1k.ProRate*pronumber; / nodes1k.FlowId:=trim(form2.tempdataset.fieldbyname(FlowId).asstring); nodes1k.IngredientId:=; nodes1k.Resolved:=false; 未处理 end; / form2.tempdataset.Active:=false; end; end; / / 修正全程投料因子. tempprorate:=tempprorate*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 指向顶层流程的下个剩余工序. form2.sysdataset.next; end; form2.sysdataset.active:=false;/ 循环分解处理. j:=0; while jnodecount1 do begin / / 假如是已处理节点,则跳过. if nodes1j.Resolved then begin inc(j); continue; end; / / 分不同情况分别处理. case nodes1j.nodetype of / / 处理流程节点. 0: begin / / 得到该流程的末端工序编号. mandtext:=SELECT TOP 1 STEPID FROM WORKSTEP WHERE FLOWID=+nodes1j.flowid+ ORDER BY STEPID; firststepid:=trim(form2.syscommand.execute.fields0.value); / / 过滤出所有工序,逐个处理. tempprorate:=rate; 继承全程投料因子 prorate:=1.0; 单道工序投料因子 tempnumber:=nodes1j.Number; 流程作业需求量 mandtext:=SELECT * FROM WORKSTEP WHERE FLOWID=+nodes1j.FlowId+ ORDER BY STEPID DESC; form2.sysdataset.Active:=true; while not form2.sysdataset.eof do begin / / 实际投料需求量:假如是流程顶端工序,直接从流程继承. if trim(form2.sysdataset.fieldbyname(MaterialId).asstring)=nodes1j.MaterialId then proneed:=need / / 否则,=上道工序作业量*本道工序投料因子. else proneed:=tempnumber*prorate; / / 计算最佳作业需求量,对于顶层工序,作业需求量从流程继承. if trim(form2.sysdataset.fieldbyname(MaterialId).asstring)nodes1j.MaterialId then tempnumber:=BestNumber(trim(form2.sysdataset.fieldbyname(MaterialId).asstring),tempnumber*prorate); / / 继承本道工序的投料因子到下道. prorate:=form2.sysdataset.fieldbyname(ProRate).asfloat; / / 生成半成品节点. k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=2; 半成品节点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(MaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(MaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(Unit).asstring); nodes1k.stepid:=trim(form2.sysdataset.fieldbyname(StepId).asstring); nodes1k.stepname:=trim(form2.sysdataset.fieldbyname(StepName).asstring); nodes1k.ProRate:=tempprorate; nodes1k.FlowId:=nodes1j.FlowId; nodes1k.IngredientId:=; nodes1k.Resolved:=true; nodes1k.Number:=tempnumber; 作业需求量 need:=proneed; 实际投料需求量 need0:=nodes1k.ProRate*pronumber; 理论投料需求量 / / 假如是末端工序,处理配方连接或流程串接. if trim(form2.sysdataset.fieldbyname(StepId).asstring)=firststepid then begin / / 假如工序号是00,则生成一个配方节点. if nodes1k.stepid=00 then begin k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=1; 配方接点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(OldMaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(OldUnit).asstring); nodes1k.stepid:=; nodes1k.stepname:=; / / 从流程继承到配方. nodes1k.ProRate:=tempprorate; nodes1k.number:=tempnumber; need:=proneed; need0:=nodes1k.ProRate*pronumber; / / 取配方号. nodes1k.FlowId:=; nodes1k.IngredientId:=trim(form2.sysdataset.fieldbyname(IngredientId).asstring); nodes1k.Resolved:=false; 未处理 end / / 假如工序号不是00,则处理流程串接. else begin / / 将当前工序的原材料作为产成品的流程,是要对接的流程. mandtext:=SELECT * FROM FLOWS WHERE TMATERIALID=+trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring)+; form2.tempdataset.active:=true; / / 假如不存在对接流程,产生一个原配件接点. if form2.tempdataset.Eof then begin form2.tempdataset.active:=false; / k:=nodecount1; inc(nodecount1); setlength(nodes1,nodecount1); nodes1k.nodetype:=3; 原配件节点 nodes1k.MaterialId:=trim(form2.sysdataset.fieldbyname(OldMaterialId).asstring); nodes1k.MaterialName:=trim(form2.sysdataset.fieldbyname(OldMaterialName).asstring); nodes1k.MUnit:=trim(form2.sysdataset.fieldbyname(OldUnit).asstring); nodes1k.stepid:=; nodes1k.stepname:=; / / 乘上本道工序的投料因子,作为原材料投料因子. nodes1k.ProRate:=tempprorate*form2.sysdataset.fieldbyname(ProRate).asfloat; / / 原材料的作业需求量为0. nodes1k.number:=0; / / 实际投料需求量=上道工序作业量*本道工序的投料比例. ne
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年初一语文现代文阅读训练(附答案)
- 辽宁省公务员2025年考试申论材料分析专项训练试卷(含答案)
- 第五单元餐饮试卷及答案
- 罕见垂体柄阻断综合征诊疗方案
- 如何自我介绍自己
- 结直肠癌肝转移术后营养支持治疗规范化方案
- 扣款抵消借款协议书
- 2025年中职教育学(教育学基础知识)试题及答案
- 2025年中职建筑工程施工(建筑测量)试题及答案
- 2025年中职计算机应用技术(计算机操作)试题及答案
- 读后续写个人成长课件-高三英语一轮复习
- 外科学模块十一重症监测治疗及复苏练习题及答案
- 2025年道路养护合同协议书(含补贴条款)
- 医院急诊抢救流程标准操作手册
- 汽车视觉原理讲解
- 2025年河南事业单位公共基础知识真题以及答案
- 全国大学生职业规划大赛《智慧农业》专业生涯发展展示【曾获省级一等奖】
- 雨课堂在线学堂《审美的历程》作业单元考核答案
- 2025年副主任医师(副高)骨外科学(副高)考试题库(含答案)
- 《中华人民共和国水法》解读培训
- 油烟一体机安装施工方案
评论
0/150
提交评论