本文介绍了MES(制造执行系统)的基本概念、功能以及与ERP系统的集成,详细阐述了与MES交互时的基础数据、工单、生产用料清单、开工、领料、退料、生产汇报、检验、入库等业务流程的处理方式,包括数据传递、接口调用、错误处理及状态机插件的使用。同时,还讨论了BOS中新增字段的必要性及C#调用外部系统接口的标准方法,并解释了为何需要这些方法以及如何在代码中实现。
此文章内容较多,预计一周内更新完成,各位见谅
更新日志:
2024-06-25 大致逻辑梳理
2024-07-01 BOS配置与字段新增(最近有点忙,水一期)
2024-08-22 接口参数构建与发起请求
先跟一下潮流,根据AI的回复介绍一下MES
MES系统
MES系统(Manufacturing Execution System,制造执行系统)是用于监控和管理制造生产过程的系统。它通常与企业资源计划(ERP)和生产设备集成,用于实现生产计划、生产调度、设备状态监控、质量追踪、工艺控制等功能,从而提高制造业的生产效率和生产质量。
MES系统通常包括以下功能: 1.生产调度与执行:根据生产计划调度生产任务,监控生产执行情况。 2.产品追踪与溯源:追踪产品生产过程,实现对产品的溯源和质量追踪。 3.工艺控制:监测生产过程中的参数,控制生产设备和工艺流程。 4.资源管理:管理生产作业所需的人力、物料和设备资源。 5.数据采集与分析:采集生产数据,并进行分析以优化生产过程。
MES系统的实施可以带来一系列的益处,包括生产调度的精细化、生产效率的提升、生产质量的保障、生产过程的数字化监控以及产品追溯能力的提升等。
好了,正文开始
基础数据
与mes交互的基础数据,一般为物料(产成品与原材料)、仓库(一般为车间仓)。这里使用的方案是在星空中做服务插件审核基础资料的时候,调用接口将数据传递到mes中,并在调用接口失败的时候强行触发事务回退数据( throw new KDException("???", "传递到MES失败:" + MES系统的错误提示);),这样做的目的是保证双方系统数据一致性。
工单(生产订单)
生产订单的业务状态有很多(计划、计划确认、下达、开工、完工、结案、结算),从逻辑上,在生产订单为下达的时候,将数据传递至mes系统(当然,这里看各个公司的实际情况),唯一要注意的是,这里传递给MES系统时,单据与生产用料清单都是不可修改的时候(保证双方系统数据一致性)。并在反执行到计划确认时进行逆向的操作(删除mes系统工单)。生产订单的状态改变,不要写服务插件挂在操作列表的“执行至XXX”,“反执行XXX”。这里使用状态机插件(如何二开“生产订单”状态机执行插件,不要质疑,这里真的是用sql部署插件的!!!)。因为生产订单上的业务状态操作按钮,是一个空操作,主要的作用是触发状态机,如果在操作按钮上挂在插件,同样会执行数据传递到mes的功能,但是在接口报错触发事务的时候,不会回退业务状态,业务状态此时运行在另一个线程上,所以要使用状态机插件,才能正确回退业务状态。
生产用料清单
这里要特别注意,因为系统标准功能生产用料清单是随时好改的,但是做了与mes的对接,在生产用料清单反审核的时候,一定要校验该生产订单有没有传递到MES,如果传递到MES,报错提示:无法修改!!!因为传生产订单的时候,将生产用料清单一起传递给mes,这个时候如果更改了生产用料清单,在领料的环节就会出现领料与用料清单不一致的异常。
开工
如果是从下达转给mes的,可以设置领料自动开工,或者由mes调用生产订单开工接口。
生产领料单
生产领料由mes发起,调用生产领料单的保存接口(注意这里要构建link数据,建立与生产用料清单的关联关系),还要根据物料的参数(批号、保质期、序列号)等来构建不同的字符串
生产退料单
生产退料与生产领料配合使用,在mes出现关于领料的逆向操作的时候生成退料单(不建议删除领料单,可能会出现未知的风险),调用生产退料单的保存接口(注意这里要构建link数据,建立与生产用料清单的关联关系),还要根据物料的参数(批号、保质期、序列号)等来构建不同的字符串
生产汇报单
生产汇报单在星空上作为入库的前一个步骤,与检验业务相关,在mes生产至后续工步或者需要检验的时候,通过生产汇报单的保存接口(注意这里要构建link数据,建立与生产订单的关联关系),如果有工时的数据,也可以传递到生产汇报单上。在生产汇报单上有个大坑,FIsNew(是否新增行)这个字段一定要传fales,否则会有很多奇奇怪怪的错误。
检验单
在需要等待检验结果的时候使用该单据,与MRP评审、不良品处理单配合使用(在整个汇报单检验结果都出来的时候,将检验结果回传给mes,这里目前没有找到好的方法,目前是通过SQL查询是否检验结果都有了)
生产入库单
检验结果收到后,由mes发起入库操作,调用生产入库的保存接口,建立与汇报单的关联关系。其他单据mes在传过来时都可以调用提交、审核的操作,但是生产入库单不建议由mes提交审核。
结案
通过状态机来执行,将结案的生产订单状态传递mes(看客户是否需要)
结算
结算这个状态就比较特殊了,它是由成本模块发起的,因此,状态机捕获不到结算状态,只能在存货核算结账、反结账后通过插件来捕获(存货核算期末结账,反结账增加二开内容的处理方案)。
2024-07-01
单据新增字段
关于要在bos中新增的字段,在每个单据上,建议增加一个复选框(是否mes传递【锁定】),用于记录哪些单据是由mes传递过来的,并且后期如果有个性化的配置,也可以根据这个复选框来做不一样的数据处理。
物料新增字段
如果不是所有的生产订单都下发到mes,那我们就需要有一定的标识,在程序中做判断,什么样的生产订单、什么样的物料下发到mes,建议在物料中新增字段来解决这个问题(便于维护,减少出错)。在物料中标识了以后,在生产订单下达的时候,通过物料来判断该生产订单是否要传递到mes中。 并且在构建物料清单数据的时候,也可以通过该字段来判断,哪些原材料下发给mes(有些行业主材是按单领料,辅料是倒冲,具体的情况要根据客户的实际情况来判断)。
2024-08-22
C#调用外部系统接口的一些标准方法
这里分享一个我这个项目使用的调用方法(根据mes的接口协议不同,不同的项目要根据需求 更改),有些系统需要签名的数据
public static string PostWebRequest(string postUrl, string paramData) { string ret = string.Empty; try { //if (!postUrl.StartsWith("https://")) // return ""; byte[] byteArray = Encoding.GetEncoding("UTF-8").GetBytes(paramData); //转化 / HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl)); webReq.Method = "POST"; webReq.ContentType = "application/json"; webReq.ContentLength = byteArray.Length; Stream newStream = webReq.GetRequestStream(); newStream.Write(byteArray, 0, byteArray.Length);//写入参数 newStream.Close(); HttpWebResponse response = (HttpWebResponse)webReq.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8); ret = sr.ReadToEnd(); sr.Close(); response.Close(); newStream.Close(); } catch (Exception ex) { return ex.Message; } return ret; } //调用时 //GetHttpPost.PostWebRequest:我的方法时放在GetHttpPost这个类下的 //MESApi.Url:请求地址 //json:请求参数 string Result = GetHttpPost.PostWebRequest(MESApi.Url + "/addManufactureOrder", json);//请求接口
获取表单全部数据
为什么会有这个需求?
在我们写插件的时候,如果需要加载字段,需要在OnPreparePropertys方法中 e.FieldKeys.Add("字段属性"); 来加载字段,当字段很多的时候,很麻烦。
总部有LoadSingle方法可以加载单据所有的字段(会一定程度上影响性能)
示例:
using Kingdee.BOS.ServiceHelper; var meta = FormMetaDataCache.GetCachedFormMetaData(this.Context, "单据标识"); //获取数据包 var dataObj = BusinessDataServiceHelper.LoadSingle(this.Context, 对应单据标识的主键(FID), meta.BusinessInfo.GetDynamicObjectType()); //转换为json格式 var data = CommonFunctions.DynamicObjectToJson(dataObj);
构建请求参数
也就是构建上文的json字段
我们用到JSONObject与JSONArray的相互配合来构建json字符串,具体需要根据MES的接口文档来构建,最终在PostWebRequest方法的时候,别忘记第二个参数,也就是请求参数,进行ToString(),的转换。
推荐阅读