浅谈一下关于与MES系统的对接原创
金蝶云社区-new_昵称
new_昵称
7人赞赏了该文章 961次浏览 未经作者许可,禁止转载编辑于2024年08月22日 11:12:06
summary-icon摘要由AI智能服务提供

本文介绍了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(),的转换。

图标赞 7
7人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!