关于改造维护工单BAPI_ALM_ORDER_MAINTAIN用于生产订单组件批量修改

news2024/9/22 4:56:04

1、研究背景

1.1、业务背景

 由于销售、研发、工艺等需要频繁变更,导致工单中组件需要频繁的进行变更,修改组件的物料,数量,库存地点,工序等内容。

1.2、技术痛点

为了满足要求,使用了函数:CO_XT_COMPONENT_ADD和CO_XT_COMPONENT_CHANGE用于组件的新增和修改,使用CO_XT_COMPONENTS_DELETE用于组件的批量删除。

痛点1:新增和修改函数,每次只能更改一行组件,而且无法按照订单维度,批量修改组件,只能按照组件维度,多次调用函数,每一次都需要提交保存一遍工单,效率很慢。

痛点2:项目中在工单修改保存时,调用了同步接口推送工单到MES,且MES必须返回成功结果,工单修改才允许保存。受接口+网络影响,工单保存效率很慢。

痛点3:受制于同步接口等原因,导致工单保存时耗时较长,且一直保持着对工单的锁定状态。而批导程序紧接着处理第二行同一工单的组件数据,就会导致出现工单锁表报错。

2、改造BAPI

2.1、BAPI现状

维护订单的BAPI:BAPI_ALM_ORDER_MAINTAIN,拥有丰富的工单修改字段,然而对于生产订单限制修改,只允许修改维护订单。

另外,经过测试,还有反冲强制取物料主数据内容导致不能指定;组件分配报错问题;组件分配BOM行号重新被指定问题等,需要逐一进行修改。

2.1.1、反冲被默认

在原逻辑中,有赋默认值的函数,里面根据物料主数据对传入的反冲标识做了更改

 调用子例程

 在以下代码处修改了传入的反冲标识

2.1.2、组件分配

在工单中,工序可以通过主数据带入工艺路线,也可以直接在工单前台手工创建。

问题在于,当在CO02手工创建时,与CA01创建的工序不一样,缺少了部分字段值,最主要的序列字段为空

导致组件分配给30工序后,前台查看组件出现报错,或组件全部丢失,最终判定都是因为序列PLNFL字段为空导致

2.1.3、BOM行项目

标准程序中,会根据要分配的工序,查找已经存在分配给该工序的组件,获取这些组件的最大BOM号,+10获得最新BOM号。

如果当前分配的工序,没有存在已经分配给该工序的组件,则直接+10得到最新BOM号0010。

例如:将0030行分配给20工序,而现有的两个工序都是10,没有20工序的组件,则BOM号0030行分配完之后,BOM号将变为0010

2.1.4、工单类型限制

 该BAPI只能修改维护订单,不能修改其他类型工单

2.2、增强改造(未采用)

第一次改造,使用了代码修改器,修改原有逻辑,如下所示:

跳过反冲默认

跳过订单类型限制

但是最终感觉太多的地方要修改,并且从未来持续优化功能的角度出发,写大量的代码片段不是一件好事情,且四代增强也要花很多时间调试,因此打算放弃改源码,而直接做代码拷贝。参考2.3自定义BAPI

2.3、自定义BAPI

 根据多次的源码调试,找到程序运行相关的函数、包含文件等,依次进行代码的复制,过程不做过多说明,结果如下:

1、复制标准BAPI:BAPI_ALM_ORDER_MAINTAIN 为:ZBAPI_ALM_ORDER_MAINTAIN

2、复制标准函数:IBAPI_C_DEFAULT_VALUES_01 为:ZBAPI_C_DEFAULT_VALUES_01 修改反冲标识

3、复制标准程序:LIBAPI_ALM_ORDER_PROCESSINGF10 为: LZBAPI_ALM_ORDER_PROCESSINGF10

在AFVC表中,序列PLNFL为空,但是序列APLFL有值,可以使用

在程序中为PLNFL赋值,解决组件分配报错

4、复制标准程序:LIBAPI_CF03 为: LZBAPI_CF03

注释掉BOM号递增逻辑

5、复制标准函数:IBAPI_H_ORDER_READ 为: ZBAPI_H_ORDER_READ

去掉对生产订单的限制

另外在标准逻辑调用过程中上下文需要做修改的程序也需要一起复制。

3、修改路径图

4、参考源码

调用BAPI代码示例:

"--------------------@斌将军--------------------
LOOP AT lt_alv INTO DATA(ls_alv) GROUP BY ls_alv-aufnr.
    REFRESH:lt_methods[],lt_component[],lt_componentup[],lt_return[].
    CLEAR:lv_rspos.

    CLEAR:ls_methods.
    ls_methods-refnumber  = 1.
    ls_methods-method = 'SAVE'.
    ls_methods-objectkey = ls_alv-aufnr.
    APPEND ls_methods TO lt_methods.

    LOOP AT GROUP ls_alv ASSIGNING FIELD-SYMBOL(<fs_alv>).

      READ TABLE gt_resb INTO gs_resb WITH KEY aufnr = <fs_alv>-aufnr
                                                rspos = <fs_alv>-rspos BINARY SEARCH.
      IF sy-subrc EQ 0."修改逻辑
        IF gs_resb-xloek = 'X'.
          <fs_alv>-icon = icon_led_red.
          <fs_alv>-log = <fs_alv>-log && '项目已删除,不允许修改'.
          MODIFY gt_alv FROM <fs_alv>.
          CONTINUE.
        ENDIF.

        IF gs_resb-enmng > abs( gs_alv-bdmng ).
          <fs_alv>-icon = icon_led_red.
          <fs_alv>-log = <fs_alv>-log && '修改的数量小于已提货数,不允许修改'.
          MODIFY gt_alv FROM <fs_alv>.
          CONTINUE.
        ELSE.
          lv_rspos = lv_rspos + 1.
          CLEAR:ls_component.
*          ls_component-item_number = gs_alv-posnr.    "BOM
          ls_component-reserv_no = gs_resb-rsnum.    "预留号
          ls_component-res_item = gs_resb-rspos.    "预留项目
          ls_component-material = <fs_alv>-idnrk.    "物料编码
          ls_component-requirement_quantity = <fs_alv>-bdmng."数量
*          ls_component-plant = gs_alv-werks.
          IF <fs_alv>-lgort IS NOT INITIAL.
            ls_component-stge_loc = <fs_alv>-lgort."存储地点
          ENDIF.

          ls_component-batch = <fs_alv>-charg."批次号
          ls_component-req_date = <fs_alv>-bdter."组件的需求日期
          IF <fs_alv>-rgekz IS NOT INITIAL.
            ls_component-backflush = 'X'."反冲标识
          ELSE.
            ls_component-backflush = ''."反冲标识
          ENDIF.
          ls_component-special_stock = <fs_alv>-sobkz."特殊库存
          ls_component-activity = gs_resb-vornr."操作/活动编号
          APPEND ls_component TO lt_component.

          CLEAR:ls_componentup.
*          ls_componentup-item_number = 'X'.                  "BOM
          ls_componentup-material = 'X'.                  "物料编码
          ls_componentup-requirement_quantity = 'X'."数量
*          ls_componentup-plant = 'X'.
          IF <fs_alv>-lgort IS NOT INITIAL.
            ls_componentup-stge_loc = 'X'."存储地点
          ENDIF.
          ls_componentup-batch = 'X'."批次号
          ls_componentup-req_date = 'X'."组件的需求日期
          ls_componentup-backflush = 'X'."反冲标识
          ls_componentup-special_stock = 'X'."特殊库存
          APPEND ls_componentup TO lt_componentup.

          CLEAR:ls_methods.
          ls_methods-refnumber = lv_rspos.                "参照组件编号
          ls_methods-objecttype = 'COMPONENT'.    "组件
          ls_methods-method = 'CHANGE'.                "修改
          ls_methods-objectkey = <fs_alv>-aufnr.          "订单号
          ls_methods-objectkey+12(4) = gs_resb-rspos.          "预留行
          APPEND ls_methods TO lt_methods.

          "组件分配
          IF <fs_alv>-vornr IS NOT INITIAL.
            lv_rspos = lv_rspos + 1.
            CLEAR:ls_component.
            ls_component-reserv_no = gs_resb-rsnum.    "预留号
            ls_component-res_item = gs_resb-rspos.    "预留项目
            ls_component-activity = <fs_alv>-vornr."新分配的工序
            APPEND ls_component TO lt_component.

            CLEAR:ls_componentup.
            ls_componentup-activity = 'X'.
            APPEND ls_componentup TO lt_componentup.

            CLEAR:ls_methods.
            ls_methods-refnumber = lv_rspos.                "参照组件编号
            ls_methods-objecttype = 'COMPONENT'. "组件
            ls_methods-method = 'REASSIGN'. "重新分配
            ls_methods-objectkey = <fs_alv>-aufnr.          "订单号
            ls_methods-objectkey+12(4) = gs_resb-rspos.          "预留行
            APPEND ls_methods TO lt_methods.
          ENDIF.
        ENDIF.
      ELSE."新增逻辑
        lv_rspos = lv_rspos + 1.

        CLEAR:ls_component.
        ls_component-item_number = <fs_alv>-posnr.    "BOM
        ls_component-material = <fs_alv>-idnrk.    "物料编码
        ls_component-requirement_quantity = <fs_alv>-bdmng."数量
        ls_component-plant = <fs_alv>-werks."工厂
        ls_component-stge_loc = <fs_alv>-lgort."存储地点
        ls_component-batch = <fs_alv>-charg."批次
        ls_component-req_date = <fs_alv>-bdter."组件的需求日期
        IF <fs_alv>-rgekz IS NOT INITIAL.
          ls_component-backflush = 'X'."反冲标识
        ELSE.
          ls_component-backflush = ''."反冲标识
        ENDIF.
        ls_component-special_stock = <fs_alv>-sobkz."特殊库存
        ls_component-activity = <fs_alv>-vornr."工序
        ls_component-item_cat = 'L'."项目类别
        APPEND ls_component TO lt_component.

        CLEAR:ls_componentup.
        ls_componentup-item_number = 'X'.                  "BOM
        ls_componentup-material = 'X'.                  "物料编码
        ls_componentup-requirement_quantity = 'X'."数量
        ls_componentup-plant = 'X'."工厂
        ls_componentup-stge_loc = 'X'."存储地点
        ls_componentup-batch = 'X'."批次
        ls_componentup-req_date = 'X'."组件的需求日期
        ls_componentup-backflush = 'X'."反冲标识
        ls_componentup-special_stock = 'X'."特殊库存
        ls_componentup-activity = 'X'."工序
        ls_componentup-item_cat = 'X'."项目类别
        APPEND ls_componentup TO lt_componentup.

        CLEAR:ls_methods.
        ls_methods-refnumber = lv_rspos.                "参照组件编号
        ls_methods-objecttype = 'COMPONENT'.      "组件
        ls_methods-method = 'CREATE'.       "创建
        ls_methods-objectkey = <fs_alv>-aufnr.          "订单号
        APPEND ls_methods TO lt_methods.
      ENDIF.
    ENDLOOP.

    READ TABLE gt_afko INTO DATA(ls_afko) WITH KEY aufnr = ls_alv-aufnr BINARY SEARCH.
    IF sy-subrc EQ 0.
      CALL FUNCTION 'T350_READ'
        EXPORTING
          auart         = ls_afko-auart
        EXCEPTIONS
          no_t350_entry = 1
          OTHERS        = 2.

* override buffered table T350
      ASSIGN ('(SAPLINST)T350') TO <t350>.
      IF sy-subrc = 0.
        <t350>-auart = ls_afko-auart.
      ENDIF.
    ENDIF.

    "调用ZBAPI
    CALL FUNCTION 'ZBAPI_ALM_ORDER_MAINTAIN'
      TABLES
        it_methods      = lt_methods
        it_component    = lt_component[]
        it_component_up = lt_componentup[]
        return          = lt_return.

    CLEAR:lv_check,lv_message.
    LOOP AT lt_return INTO ls_return WHERE type CA 'AEX'.
      lv_check = 'E'.
      lv_message = lv_message && ls_return-message.
      CLEAR:ls_return.
    ENDLOOP.

    IF lv_check = 'E'.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

      ls_alv-icon = icon_led_red.
      ls_alv-log = lv_message.

    ELSE.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.
      ls_alv-icon = icon_led_green.
      ls_alv-log = '添加成功'.
    ENDIF.
    MODIFY gt_alv FROM ls_alv TRANSPORTING icon log WHERE aufnr = ls_alv-aufnr
                                                        AND xloek = ''
                                                        AND item = 'X'
                                                        AND icon <> icon_led_red.

    CLEAR:ls_alv.
  ENDLOOP.
"--------------------@斌将军--------------------   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/440537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FVM链的Themis Pro(0x,f4) 5日IDO超百万美元,或让Filecoin逆风翻盘

交易一直是DeFi乃至web3领域最经久不衰的话题&#xff0c;也因此催生了众多优秀的去中心化协议&#xff0c;如Uniswap和Curve。这些协议逐渐成为了整个系统的基石。 在永续合约方面&#xff0c;DYDX的出现将WEB2时代的订单簿带回了web3。其链下交易的设计&#xff0c;仿佛回到了…

为你的软件测试全职业生涯规划保驾护航

目录 前言 1. 软件测试行业现状和未来趋势 2. 从初级测试工程师到高级测试架构师的职业路径 3. 如何提升自身技能和素质 4. 如何管理好自己的职业生涯 总结 前言 作为一名软件测试人员&#xff0c;职业生涯规划是非常重要的。在这篇文章中&#xff0c;我将从以下几个方面…

Mac电脑安装apktool工具包

开发中少不了想看看别人怎么实现某个功能&#xff0c;于是会用到apktool反编译apk&#xff0c;apktool工具包是一个压缩包&#xff0c;下载后无需安装&#xff0c;简单配置下执行命令就能反编译apk了&#xff0c;下面我们看一下如何在Mac OS系统下如何安装apktool工具包&#x…

《Netty》从零开始学netty源码(四十)之SizeClasses

目录 SizeClasses SizeClasses 在netty中&#xff0c;内存会被切割成不同size的块&#xff0c;在分配的时候会根据所需的大小分配相应的内存大小&#xff0c;然而并不是所有的大小都会有相应大小的内存块&#xff0c;比如想要11kb的内存&#xff0c;它并不会确切的给你11kb&am…

Mybatis高级映射及延迟加载

准备数据库表&#xff1a;一个班级对应多个学生。班级表&#xff1a;t_clazz&#xff1b;学生表&#xff1a;t_student 创建pojo&#xff1a;Student、Clazz // Student public class Student {private Integer sid;private String sname;//...... }// Clazz public class Cla…

我开发了一个温柔的智能客服聊天机器人ChatBot,并回答为什么不是ChatGPT(附思路和代码)

前言 若问2023年科技领域什么最火&#xff0c;那当然是ChatGPT了&#xff0c;这么智能的对话机器人&#xff0c;给人带来无限的想象&#xff0c;围绕着ChatpGPT的各种热点和创意层出不穷。作为一个多年从事编程开发的程序员&#xff0c;我对于这么大的一个热点也很兴奋&#x…

视频虚拟主播怎们搞?体验报告全记录;一图掌握SD应用精髓;Chat效率工具大汇总;品牌营销进入AI时代 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『Stable Diffusion界面解读』一张图掌握SD使用精髓 ShowMeAI资源编号&#xff1a;No.R052 图片可能被平台压缩&#xff0c;加入知识星…

安装配置 JupyterLab ubuntu20.04

目录 ​编辑 &#xff08;1&#xff09;安装 &#xff08;2&#xff09;配置 &#xff08;1&#xff09;生成配置文件 &#xff08;2&#xff09;生成jupyterlab的登录密码 &#xff08;3&#xff09;修改 jupyter 的配置文件 &#xff08;4&#xff09;安装 jupyterlab…

Mybatis(三)

1、mybatis中的连接池以及事务控制 原理部分了解&#xff0c;应用部分会用 mybatis中连接池使用及分析 mybatis事务控制的分析2、mybatis基于XML配置的动态SQL语句使用 会用即可 mappers配置文件中的几个标签&#xff1a; <if> …

Linux网络编程 第八天

目录 学习目标 内容回顾 完善网页服务器 中文乱码问题 服务器中断处理 读取目录文件 BS模式示意图 Web服务器开发流程图 日志服务器 Libevent下的网页服务器 学习目标 第八天主要是在第七天的基础上&#xff0c;完善网页服务器的设计&#xff0c;学习日志服务器以及li…

MySQL中distinct和group by性能比较

distinc的使用 用法 select distinct columns from table_name where where_conditions;示例&#xff1a; DISTINCT 用于返回唯一不同的值&#xff08;即去重后的值&#xff09; &#xff0c;使用时需要放在查询语句中第一个查询字段前使用。如果列有NULL值&#xff0c;会将所…

C语言/C++随机数生成,程序运行时间计时器(含高精度计时器),包括Windows环境与Linux环境

&#x1f38a;【数据结构与算法】专题正在持续更新中&#xff0c;各种数据结构的创建原理与运用✨&#xff0c;经典算法的解析✨都在这儿&#xff0c;欢迎大家前往订阅本专题&#xff0c;获取更多详细信息哦&#x1f38f;&#x1f38f;&#x1f38f; &#x1fa94;本系列专栏 -…

工厂模式概述

通常有三种形态: 简单工厂模式&#xff0c;不属于23种设计模式之一 工厂方法模式&#xff0c;是23种设计模式之一 抽象工厂模式&#xff0c;是23种设计模式之一 1.简单工厂模式是工厂模式的一种特殊实现&#xff0c;又被称为静态工厂方法模式 2.简单工厂模式解决的问题:客户端不…

【Verilog HDL】FPGA-Verilog文件的基本结构

&#x1f389;欢迎来到FPGA专栏~Verilog文件的基本结构 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大…

SSM框架MyBatis 三种分页查询 PageHlper的使用以及五个参数的简单解释

SSM框架MyBatis 三种简单的分页查询 1. 基础分页查询&#xff08;环境在第一天的配置中有&#xff09; mapper也就是dao //查询总数Select("select count(*) from book;")int selectCount();//分页查询Select("select * from book limit #{currpage},#{size}&q…

windows快捷键汇总

Windows 系统中有很多常用的快捷键&#xff0c;这些快捷键可以帮助我们快速完成一些操作&#xff0c;提高我们的工作效率。下面是一些使用 Windows 快捷键的好处和长期利弊&#xff1a; 好处&#xff1a; 可以快速完成一些操作&#xff0c;提高工作效率。可以让我们的工作更加…

2023年RHCE第二次作业

1.配置ntp时间服务器&#xff0c;确保客户端主机能和服务主机同步时间 2.配置ssh免密登陆&#xff0c;能够通过客户端主机通过redhat用户和服务端主机基于公钥验证方式进行远程连接 1配置Chrony服务器 先下载chrony--------dnf install -y chrony 查看和配置chrony.conf文件 …

Centos7 安装mysql 8.0.32版本(解压glibc版本)

Centos 7 安装 MySQL 8.0.32 glibc 版本总结 Centos7中安装MySQL服务时&#xff0c;首先需要卸载掉mariadb&#xff0c;mariadb可能会与MySQL产生冲突。 1、卸载mariadb 查找mariadb是否已经安装&#xff08;默认已经安装&#xff09; rpm -qa | grep mariadb接下来将查找到…

QWidget改变背景图的方法和坑

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、添加背景图资源文件二、使用 QPalette三、重写paintEvent() 函数四、使用QT的设计师界面总结 前言 本篇文章将讲解QWidget改变背景图的方法和会遇到的问题…

Flutter插件开发-(基础篇)

在开发flutter项目的时分通常会运用一些三方的的packages或许plugin&#xff0c;二者的区别&#xff1a;packages主要是包括的Dart代码块&#xff0c;而plugin则包括iOS和android的代码。 因此来说创立plugin和packages的流程是相似的&#xff0c;下面就以创立plugin为例进行展…