当前位置:   article > 正文

SAP生产订单创建、工序删除/增加、组件删除/增加、生产订单下达、采购订单创建_sap so 禁止新增/删除item

sap so 禁止新增/删除item

2021年的时候在深圳光明区某企业做了一个项目:委外生产订单创建。因为委外的生产订单和当前企业的工序以及组件并不相同,所以需要对创建的生产订单的工序进行删除和增加,对组件进行删除和增加。

当时的业务程序的步骤如下:创建生产订单——>删除默认组件——>添加配置表的组件——>删除默认工序——>添加配置表的工序——>生产订单下达——>创建采购订单

程序代码如下:

 TYPES:BEGIN OF ty_order,
          snro TYPE zsnro, "流水码
        END OF ty_order.
  DATA:lt_order TYPE TABLE OF ty_order,
       ls_order TYPE ty_order.
  "定义创建MO所需变量
  DATA:lt_create TYPE TABLE OF ty_create,
       ls_create TYPE ty_create.

  "定义创建生产订单所需参数
  DATA:ls_orderdata    TYPE bapi_pp_order_create, "抬头
       ls_return       TYPE bapiret2, "返回参数
       lv_order_number TYPE bapi_order_key-order_number.

  "删除组件所需变量
  DATA:lt_resbkeys   TYPE coxt_t_resbdel,
       lv_error      TYPE c,
       lt_bapireturn TYPE coxt_t_bapireturn.

  "增加组件所需变量
  DATA:ls_requ              TYPE coxt_s_quantity, "数量,单位
       lv_operation         TYPE afvc-aplzl, "
       lv_sequence          TYPE afvc-plnfl,
       ls_storage_location  TYPE coxt_s_storage_location,
       ls_storage_locationx TYPE coxt_s_storage_locationx,
       lv_posno             TYPE cif_r3res-positionno.

  "删除工序所需变量
  DATA:lt_afvgkeys TYPE  coxt_t_afvg_del,
       ls_afvgkeys LIKE LINE OF lt_afvgkeys.

  "标记是否产生错误,如果值为X,则有错误,反之,则正确
  DATA:lv_flag_err TYPE c,
       lv_msg_err  TYPE char100. "错误信息

  CLEAR:lv_flag_err.


  "创建采购订单所需变量
  DATA:ls_header  TYPE bapimepoheader,
       ls_headerx TYPE bapimepoheaderx.
  DATA:lt_poitem  TYPE TABLE OF bapimepoitem,
       ls_poitem  TYPE bapimepoitem,
       lt_poitemx TYPE TABLE OF bapimepoitemx,
       ls_poitemx TYPE bapimepoitemx.
  DATA:lt_poaccount  TYPE TABLE OF bapimepoaccount,
       ls_poaccount  TYPE bapimepoaccount,
       lt_poaccountx TYPE TABLE OF bapimepoaccountx,
       ls_poaccountx TYPE bapimepoaccountx.
  DATA:lt_return TYPE TABLE OF bapiret2.
  DATA:lt_ztpp0041 TYPE TABLE OF ztpp0041, "工序集和供应商配置表
       ls_ztpp0041 TYPE ztpp0041.

  "保存抬头数据
  DATA:lt_ztpp0042 TYPE TABLE OF ztpp0042,
       ls_ztpp0042 TYPE ztpp0042,
       "保存行项目数据
       lt_ztpp0043 TYPE TABLE OF ztpp0043,
       ls_ztpp0043 TYPE ztpp0043.

  CLEAR:lt_order.
  LOOP AT gt_create INTO gs_create WHERE sel = 'X'"选中的数据
                                     AND type = 'S'"正确的数据
                                     AND message2 = ''."未创建过数据的单据
    ls_order-snro = gs_create-snro.
    COLLECT ls_order INTO lt_order.
    CLEAR:ls_order.
  ENDLOOP.

  IF lt_order IS INITIAL.
    MESSAGE s000(zpp) WITH '请选择数据' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  " sy-batch = 'X'."设置为跑job的模式,阻止CO_XT_COMPONENT_ADD各种弹窗
  FIELD-SYMBOLS: <ft_resb_bt> TYPE ANY TABLE,
                 <fs_resb_bt> TYPE any.

  LOOP AT lt_order INTO ls_order.
    "清空变量
    CLEAR:ls_orderdata,
          ls_return,
          ls_create,
          lv_order_number.
    CLEAR:lv_error,lv_flag_err.

    CLEAR:ls_ztpp0042,lt_ztpp0042,
          ls_ztpp0043,lt_ztpp0043.
    CLEAR:gs_create.


    "这里的gs_create一定要保证是全局的
    READ TABLE gt_create INTO gs_create WITH KEY snro = ls_order-snro.
    " ls_create = gs_create.

    ls_orderdata-plant = gs_create-werks."工厂
    ls_orderdata-order_type = 'ZP05'."订单类型:委外
    ls_orderdata-basic_start_date = gs_create-gstrp."开始日期
    ls_orderdata-basic_end_date = gs_create-gltrp."结束日期
    ls_orderdata-quantity = gs_create-psmng."订单数量
    ls_orderdata-material_long = gs_create-matnr."订单物料号
    ls_orderdata-prod_version = gs_create-verid."生产版本

    "1.创建生产订单
    CALL FUNCTION 'BAPI_PRODORD_CREATE'
      EXPORTING
        orderdata    = ls_orderdata
*       FSH_PRODORD_SEASON       =
      IMPORTING
        return       = ls_return
        order_number = lv_order_number
*       ORDER_TYPE   =
      .

    IF ls_return-type = 'A' OR ls_return-type = 'E'.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

      "反写报错信息
      LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.
        <fs_cr>-type = 'E'.
        <fs_cr>-message2 = '创建生产订单失败:' && ls_return-message.
        "设置红灯
        CALL METHOD zcl_mul_tools=>set_alv_light
          EXPORTING
            i_name     = 'ICON_RED_LIGHT'
          IMPORTING
            e_icon     = <fs_cr>-icons
          EXCEPTIONS
            name_error = 1
            OTHERS     = 2.
      ENDLOOP.

      "如果错误,则继续进行下一个生产订单的创建
      CONTINUE.
    ELSE.

      "如果创建生产订单成功后需要将数据写入到自建表中
      ls_ztpp0042-aufnr = lv_order_number."生产订单
      ls_ztpp0042-dwerk = gs_create-werks."工厂
*      10 生产MO
*      20 MO组件
*      30 MO工序
*      40 MO下达
*      50 采购PO
*      90 删除
      ls_ztpp0042-zzt01 = '10'."生产MO
      ls_ztpp0042-zjhgz = gs_create-zjhgz."计划跟踪号
      ls_ztpp0042-lifnr = gs_create-lifnr."供应商
      ls_ztpp0042-zckgxj = gs_create-zckgxj."参考工序集(实际上是物料编码)
      ls_ztpp0042-matnr = gs_create-matnr."物料
      ls_ztpp0042-psmng = gs_create-psmng."数量
      ls_ztpp0042-gstrp = gs_create-gstrp."开始日期
      ls_ztpp0042-gltrp = gs_create-gltrp."结束日期
      ls_ztpp0042-ztxt01 = gs_create-txth."抬头备注
      ls_ztpp0042-ernam = sy-uname."创建人
      ls_ztpp0042-erdat = sy-datum."创建日期
      ls_ztpp0042-erzet = sy-uzeit."创建时间

      "将数据更新到表头中
      INSERT ztpp0042 FROM ls_ztpp0042.

      "行项
      LOOP AT gt_create ASSIGNING <fs_cr> WHERE  snro = ls_order-snro.
        ls_ztpp0043-aufnr = lv_order_number."生产订单
        ls_ztpp0043-rspos = <fs_cr>-rspos."行项
        ls_ztpp0043-matnr = <fs_cr>-matnr2."组件物料
        ls_ztpp0043-bdmng = <fs_cr>-bdmng."数量
        ls_ztpp0043-meins = <fs_cr>-meins."组件单位
        ls_ztpp0043-charg = <fs_cr>-charg."批次
        ls_ztpp0043-ztxt02 = <fs_cr>-txti."行项目备注
        ls_ztpp0043-lgort = <fs_cr>-lgort."投料地点
        APPEND ls_ztpp0043 TO lt_ztpp0043.
        CLEAR:ls_ztpp0043.

        "顺便将创建好的生产订单更新回内表
        <fs_cr>-aufnr = lv_order_number."生产订单
      ENDLOOP.
      INSERT ztpp0043 FROM TABLE lt_ztpp0043.

      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.
      "等待1秒
      WAIT UP TO 1 SECONDS.
    ENDIF.

    "写入抬头文本
    IF gs_create-txth IS NOT INITIAL.
      CALL FUNCTION 'ZFMPP_ADD_HEAD_TXT'
        EXPORTING
          iv_aufnr  = lv_order_number
          iv_text   = gs_create-txth
        IMPORTING
          es_return = ls_return.
    ENDIF.

    "2改写组件
    "2.1 先删除组件
    SELECT rsnum
           rspos
      INTO CORRESPONDING FIELDS OF TABLE lt_resbkeys
      FROM resb
      WHERE aufnr = lv_order_number.
    IF sy-subrc = 0.
      CLEAR:lv_error.
      CALL FUNCTION 'CO_XT_COMPONENTS_DELETE'
        EXPORTING
          it_resbkeys_to_delete = lt_resbkeys
*         IS_COMP_NR            =
        IMPORTING
          e_error_occurred      = lv_error
        TABLES
          ct_bapireturn         = lt_bapireturn
        EXCEPTIONS
          delete_failed         = 1
          OTHERS                = 2.
      IF sy-subrc <> 0.
* Implement suitable error handling here
      ENDIF.

      IF lv_error = space.

*        CALL FUNCTION 'CO_XT_ORDER_PREPARE_COMMIT'
*          IMPORTING
**           E_ORDER_KEY      =
*            es_bapireturn    = ls_return
*            e_error_occurred = lv_error
*         TABLES
*           ET_ORD_KEY_MAP   =
*           ET_BAPIRETURN    =
        .
*        IF ( ls_return-type = 'S' OR
*             ls_return-type = 'W' OR
*             ls_return-type = 'I' ) OR
*             ls_return IS INITIAL.

        "该函数主要设置no_dialog,不显示弹窗
        CALL FUNCTION 'CO_ZV_ORDER_POST'
          EXPORTING
            commit_flag    = space
            ext_flg        = 'X'
            trans_typ      = 'H'
            no_gui_message = 'X'
            no_dialog      = 'X'
          EXCEPTIONS
            no_change      = 1
            update_reject  = 2
            budget_reject  = 3
            text_error     = 4
            OTHERS         = 5.

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.
        CALL FUNCTION 'CO_XT_ORDER_INITIALIZE'."不要这行代码的话,后面添加组件会dump,原因不详
*        ELSE.
*          CLEAR: lv_error,
*          ls_return.
*          CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
*        ENDIF.

      ELSE.
        CLEAR lv_error.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

        LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.
          <fs_cr>-type = 'E'.
          <fs_cr>-message2 = '创建生产订单成功,但是处理组件失败'.
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_RED_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.
        ENDLOOP.
        "继续下一条数据
        CONTINUE.
      ENDIF.
    ENDIF.

    "2.2 增加组件
    lv_posno = '0010'.
    LOOP AT gt_create INTO ls_create WHERE snro = ls_order-snro.

      ls_requ-quantity = ls_create-bdmng."数量
      ls_requ-uom      = ls_create-meins."单位
      "单位转换
      CALL FUNCTION 'CONVERSION_EXIT_CUNIT_INPUT'
        EXPORTING
          input          = ls_requ-uom
*         LANGUAGE       = SY-LANGU
        IMPORTING
          output         = ls_requ-uom
        EXCEPTIONS
          unit_not_found = 1
          OTHERS         = 2.

      "获取订单的通用计数器以及序列
      SELECT SINGLE a~aplzl
                    a~plnfl
        INTO ( lv_operation,lv_sequence )
        FROM afvc AS a
        INNER JOIN afko AS b ON a~aufpl = b~aufpl
        WHERE b~aufnr = lv_order_number."生产订单

      "存储位置
      ls_storage_location-werks = ls_create-werks."工厂
      ls_storage_locationx-werks = 'X'.

      ls_storage_location-lgort = ls_create-lgort."投料地点
      ls_storage_locationx-lgort = 'X'.

      CALL FUNCTION 'CO_XT_COMPONENT_ADD'
        EXPORTING
          is_order_key         = lv_order_number "工单号
          i_material           = ls_create-matnr2 "组件
          is_requ_quan         = ls_requ
*         IS_CONF_QUAN         =
*         IS_CONF_QUANX        =
          i_operation          = lv_operation
          i_sequence           = lv_sequence
          is_storage_location  = ls_storage_location
          is_storage_locationx = ls_storage_locationx
          i_batch              = ls_create-charg "批次
          i_batchx             = 'X'
          i_postp              = 'L' "项目类别
          i_posno              = lv_posno
        IMPORTING
*         ES_AFPO              =
*         ES_ISSUEDATE         =
          es_bapireturn        = ls_return
          e_error_occurred     = lv_error.

      "修复序号问题
      ASSIGN ('(SAPLCOBC)RESB_BT[]') TO <ft_resb_bt>.
      IF <ft_resb_bt> IS ASSIGNED.
        LOOP AT <ft_resb_bt> ASSIGNING <fs_resb_bt>.
          DATA(lv_numc) = sy-tabix * 10.
          ASSIGN COMPONENT 'POSNR' OF STRUCTURE <fs_resb_bt> TO FIELD-SYMBOL(<fs>).
          IF sy-subrc = 0.
            " <fs_resb_bt>-posnr = lv_numc.
            <fs> = lv_numc.
            "添加前导零
            CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
              EXPORTING
                input  = <fs>
              IMPORTING
                output = <fs>.

          ENDIF.
          CLEAR lv_numc.
        ENDLOOP.
      ENDIF.

      "该函数主要设置no_dialog,不显示弹窗
      CALL FUNCTION 'CO_ZV_ORDER_POST'
        EXPORTING
          commit_flag    = space
          ext_flg        = 'X'
          trans_typ      = 'H'
          no_gui_message = 'X'
          no_dialog      = 'X'
        EXCEPTIONS
          no_change      = 1
          update_reject  = 2
          budget_reject  = 3
          text_error     = 4
          OTHERS         = 5.
      lv_posno = lv_posno + 10.

      IF lv_error EQ space.

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.
        CALL FUNCTION 'CO_XT_ORDER_INITIALIZE'."如果不加这行代码,第一个组件可能没问题,但是后面的组件会有问题

      ELSE.
        "反写报错信息
        LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.

          lv_flag_err = 'X'."表示已经产生错误
          <fs_cr>-type = 'E'.
          <fs_cr>-message2 = '创建生产订单成功,写入组件失败:' && ls_return-message.
          "设置红灯
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_RED_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.
        ENDLOOP.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

*        READ TABLE gt_create ASSIGNING <fs_cr> WITH KEY snro = ls_order-snro.
*        IF sy-subrc = 0.
*          <fs_cr>-type = 'E'.
*          <fs_cr>-message2 = '创建生产订单成功,但是处理组件失败'.
*
*          CALL METHOD zcl_mul_tools=>set_alv_light
*            EXPORTING
*              i_name     = 'ICON_RED_LIGHT'
*            IMPORTING
*              e_icon     = <fs_cr>-icons
*            EXCEPTIONS
*              name_error = 1
*              OTHERS     = 2.
*        ENDIF.

        EXIT."退出循环
      ENDIF.

      CLEAR:ls_requ,lv_operation,lv_sequence.
      CLEAR:ls_storage_location,ls_storage_locationx.
    ENDLOOP.

    IF  lv_error = 'X'.
      CONTINUE."继续执行下一条数据
    ENDIF.

    "将状态更新到抬头上
    ls_ztpp0042-zzt01 = '20'."MO组件
    UPDATE ztpp0042 SET zzt01 = '20'
                   WHERE aufnr = lv_order_number.
    COMMIT WORK AND WAIT.

    " WAIT UP TO 1 SECONDS.
    "将行项目文本更新进去
    SELECT * INTO TABLE @DATA(lt_resb)
      FROM resb
      WHERE aufnr = @lv_order_number.
    IF sy-subrc = 0.
      LOOP AT lt_resb INTO DATA(ls_resb).
        LOOP AT gt_create INTO ls_create WHERE snro = ls_order-snro
                                           AND matnr2 = ls_resb-matnr.
          IF ls_create-txti IS NOT INITIAL.
            ls_resb-ltxsp = sy-langu."语言
            ls_resb-potx1 = ls_create-txti.
            MODIFY resb FROM ls_resb.
          ENDIF.
        ENDLOOP.
      ENDLOOP.
    ENDIF.
    "将行项目文本更新到行项中
*    WAIT UP TO 1 SECONDS.
*    LOOP AT gt_create INTO gs_create WHERE zjhgz = ls_order-zjhgz.
*      IF gs_create-txti IS NOT INITIAL.
*        CALL FUNCTION 'ZFMPP_ADD_ITEM_TXT'
*          EXPORTING
*            iv_aufnr  = lv_order_number
*            iv_matnr  = gs_create-matnr2
*            iv_text   = gs_create-txti
*          IMPORTING
*            es_return = ls_return.
*      ENDIF.
*    ENDLOOP.

    "3.改写工序
    "3.1 删除当前默认的工序(保留第一条工序,因为系统要求必须要有)
    "删除工序错误的可能性较小,所以这里不考虑删除错误的情况
    "就算删除错误了,在后续还可以覆盖更新
    CALL FUNCTION 'ZFMPP_DELETE_OPERATIONS'
      EXPORTING
        iv_aufnr  = lv_order_number
      IMPORTING
        es_return = ls_return.

    WAIT UP TO 1 SECONDS."等待1秒

    "3.2 新增工序
    IF lv_flag_err IS INITIAL."未产生错误则继续进行
      CALL FUNCTION 'ZFMPP_ADD_OPERATIONS'
        EXPORTING
          iv_aufnr  = lv_order_number
          iv_werks  = gs_create-werks
          iv_zckgxj = gs_create-zckgxj
        IMPORTING
          es_return = ls_return.

      IF ls_return-type = 'E'.
        "反写报错信息
        LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.

          lv_flag_err = 'X'.
          <fs_cr>-type = 'E'.
          <fs_cr>-message2 = '创建生产订单成功,写入工序失败:' && ls_return-message.
          "设置红灯
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_RED_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.
        ENDLOOP.

        CONTINUE."继续执行下一条数据

      ELSE."写入正确,更新数据
        ls_ztpp0042-zzt01 = '30'."MO工序
        UPDATE ztpp0042 SET zzt01 = '30'
        WHERE aufnr = lv_order_number.
        COMMIT WORK AND WAIT.
      ENDIF.
    ELSE.
      CONTINUE.
    ENDIF.

    "40 生产订单下达
    IF lv_order_number IS NOT INITIAL "如果产生生产订单
     AND lv_flag_err IS INITIAL.        "
      DATA:lt_orders TYPE TABLE OF bapi_order_key,
           ls_orders TYPE bapi_order_key.
      DATA:lt_detail_return TYPE TABLE OF bapi_order_return,
           ls_detail_return TYPE bapi_order_return.
      CLEAR:lt_orders,ls_orders,
            lt_detail_return.
      CLEAR:ls_return.
      ls_orders-order_number = lv_order_number.
      APPEND ls_orders TO lt_orders.

      CALL FUNCTION 'BAPI_PRODORD_RELEASE'
        IMPORTING
          return        = ls_return
        TABLES
          orders        = lt_orders
          detail_return = lt_detail_return.
      READ TABLE lt_detail_return INTO ls_detail_return WITH KEY type = 'E'.
      IF sy-subrc = 0.
        lv_flag_err = 'X'.
        LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.
          <fs_cr>-type = 'E'.
          <fs_cr>-message2 = '创建生产订单成功,但释放生产订单失败'.
          "设置红灯
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_RED_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.
        ENDLOOP.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
        CONTINUE."接着执行
      ELSE.
        "更新单据状态
        ls_ztpp0042-zzt01 = '40'."MO下达
        UPDATE ztpp0042 SET zzt01 = '40'
        WHERE aufnr = lv_order_number.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.
      ENDIF.

    ENDIF.

    IF lv_order_number IS NOT INITIAL "如果产生生产订单
    AND lv_flag_err IS INITIAL.        "并且未产生错误,则继续创建采购订单

      "清空所需变量
      CLEAR:ls_header,ls_headerx,
            lt_poitem,ls_poitem,
            lt_poitemx,ls_poitemx,
            lt_poaccount,ls_poaccount,
            lt_poaccountx,ls_poaccountx,
            lt_return,lv_msg_err.
      CLEAR:lt_ztpp0041,ls_ztpp0041.

      DATA:lv_bukrs TYPE t001-bukrs.
      DATA:lv_ebelp TYPE ebelp."行项目
      DATA:lv_po_number TYPE bapimepoheader-po_number.

      DATA:lt_info_pur    TYPE TABLE OF bapieine,
           ls_info_pur    TYPE bapieine,
           lt_info_return TYPE TABLE OF bapireturn,
           ls_info_return TYPE bapireturn.
      "抬头数据
      "公司代码通过工厂查找
      CLEAR:lv_bukrs,lv_po_number.
      SELECT SINGLE a~bukrs
        INTO lv_bukrs
        FROM t001k AS a
        INNER JOIN t001w AS b ON a~bwkey = b~bwkey
        WHERE b~werks = gs_create-werks.

*      SELECT SINGLE * INTO ls_ztpp0041
*        FROM ztpp0041
*        WHERE werks = ls_create-werks
*          AND lifnr = ls_create-lifnr
*          AND zckgxj = ls_create-zckgxj."参考工序集

      ls_header-comp_code = lv_bukrs.   "公司代码
      ls_headerx-comp_code = 'X'."
      ls_header-doc_type = 'ZB09'."委外加工服务费采购订单 采购订单类型
      ls_headerx-doc_type = 'X'.
      ls_header-vendor = gs_create-lifnr."供应商
      ls_headerx-vendor = 'X'.
      ls_header-purch_org = ls_header-comp_code. "采购组织 = 公司代码
      ls_headerx-purch_org = 'X'.

*      "根据工厂获取采购组,如果有多条,随便取一条就行
*      SELECT SINGLE ekgrp
*        INTO ls_header-pur_group
*        FROM t026z
*        WHERE ekorg = gs_create-werks
*          AND ekgrp LIKE 'W%'.
      "采购组逻辑变更
      SELECT SINGLE ekgrp
        INTO ls_header-pur_group
        FROM marc
        WHERE werks = gs_create-werks
          AND matnr = gs_create-zckgxj."物料

      " ls_header-pur_group = ''."采购组
      ls_headerx-pur_group = 'X'.

      lv_ebelp = 10.

      "获取组件物料的采购信息记录
      CLEAR:lt_info_pur,ls_info_pur,
            lt_info_return.
      CALL FUNCTION 'BAPI_INFORECORD_GETLIST'
        EXPORTING
          vendor              = gs_create-lifnr "供应商
*         material            =
*         MAT_GRP             =
*         VEND_MAT            =
*         VEND_PART           =
*         VEND_MATG           =
          purch_org           = ls_header-comp_code "采购组织
*         INFO_TYPE           =
          plant               = gs_create-werks "工厂
*         PUR_GROUP           =
*         PURCHASINGINFOREC   =
*         DELETED_INFORECORDS = ' '
          purchorg_data       = 'X'
          general_data        = 'X'
*         MATERIAL_EVG        =
*         PURCHORG_VEND       = ' '
          material_long       = gs_create-zckgxj "参考工序集也是物料
        TABLES
*         INFORECORD_GENERAL  =
          inforecord_purchorg = lt_info_pur
*         INFORECORD_SEGMENT  =
          return              = lt_info_return.
      READ TABLE lt_info_pur INTO ls_info_pur INDEX 1.


      "行项目数据
      ls_poitem-po_item = lv_ebelp."行项目
      ls_poitemx-po_item = lv_ebelp."行项
      " ls_poitem-short_text = gs_create-lifnr && gs_create-zckgxj."供应商&&工序集
      SELECT SINGLE maktx
        INTO ls_poitem-short_text
        FROM makt
        WHERE matnr =  gs_create-zckgxj
          AND spras = '1'.
      ls_poitemx-short_text = 'X'.
      ls_poitem-material_long = gs_create-zckgxj."参考工序集
      ls_poitemx-material_long = 'X'.
      ls_poitem-plant = gs_create-werks."工厂
      ls_poitemx-plant = 'X'.
      "库存地点通过配置可以不传参
*      ls_poitem-stge_loc = ls_create-lgort."库存地点
*      ls_poitemx-stge_loc = 'X'.
*      ls_poitem-matl_group = 'Z001'."物料组
*      ls_poitemx-matl_group = 'X'.
      ls_poitem-quantity = gs_create-psmng."订单数量
      ls_poitemx-quantity = 'X'.
      ls_poitem-net_price = ls_info_pur-net_price."价格
      ls_poitemx-net_price = 'X'.

      "单位
      SELECT SINGLE meins
        INTO @DATA(lv_meins)
        FROM mara
        WHERE matnr = @gs_create-zckgxj."参考工序集
      ls_poitem-po_unit = lv_meins."单位
      ls_poitemx-po_unit = 'X'.
      ls_poitem-price_unit = ls_info_pur-price_unit."价格单位
      ls_poitemx-price_unit = 'X'.
      ls_poitem-tax_code = ls_info_pur-tax_code."税码
      ls_poitemx-tax_code = 'X'.
      ls_poitem-acctasscat = 'F'."科目分配类别
      ls_poitemx-acctasscat = 'X'.
      "[ Added by hujie 20210612 增加对该字段的赋值,逻辑来源:张静熔
      ls_poitem-unlimited_dlv = 'X'."标识:允许未限制的过量交货
      ls_poitemx-unlimited_dlv = 'X'.
      "]
      APPEND ls_poitem TO lt_poitem.
      APPEND ls_poitemx TO lt_poitemx.

      "总账科目之类
      ls_poaccount-po_item = lv_ebelp."行项
      ls_poaccountx-po_item = lv_ebelp.
*        ls_poaccount-gl_account = ''."总账科目
*        ls_poaccountx-gl_account = 'X'.
      ls_poaccount-orderid = lv_order_number."工单号
      ls_poaccountx-orderid = 'X'.
      APPEND ls_poaccount TO lt_poaccount.
      APPEND ls_poaccountx TO lt_poaccountx.


      CLEAR:ls_poitem,ls_poitemx,
            ls_poaccount,ls_poaccountx.
      " lv_ebelp = lv_ebelp + 10.

      CALL FUNCTION 'BAPI_PO_CREATE1'
        EXPORTING
          poheader         = ls_header
          poheaderx        = ls_headerx
        IMPORTING
          exppurchaseorder = lv_po_number
        TABLES
          return           = lt_return
          poitem           = lt_poitem
          poitemx          = lt_poitemx
          poaccount        = lt_poaccount
          poaccountx       = lt_poaccountx.

      LOOP AT lt_return INTO ls_return WHERE type CA 'EA'.
        lv_error = 'X'.
        lv_msg_err =  lv_msg_err && ls_return-message.
      ENDLOOP.
      IF lv_error = 'X'.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
      ELSE.
        ls_ztpp0042-zzt01 = '50'."采购PO
        UPDATE ztpp0042 SET zzt01 = '50'
                            ebeln = lv_po_number
        WHERE aufnr = lv_order_number.

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.

      ENDIF.

      LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.

        IF lv_error = 'X'.
          <fs_cr>-type = 'E'.
          <fs_cr>-message2 = '创建生产订单成功,但创建采购的失败:' && lv_msg_err.
          "设置红灯
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_RED_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.
        ELSE.
          <fs_cr>-type = 'S'.
          <fs_cr>-message2 = '创建成功'.
          <fs_cr>-ebeln = lv_po_number.
          "无需再次设置绿灯,因为原本就是绿灯
          CALL METHOD zcl_mul_tools=>set_alv_light
            EXPORTING
              i_name     = 'ICON_GREEN_LIGHT'
            IMPORTING
              e_icon     = <fs_cr>-icons
            EXCEPTIONS
              name_error = 1
              OTHERS     = 2.

        ENDIF.
      ENDLOOP.

    ENDIF.

    "更新单据信息
*    LOOP AT gt_create ASSIGNING <fs_cr> WHERE snro = ls_order-snro.
*      <fs_cr>-aufnr = lv_order_number.
*    ENDLOOP.

  ENDLOOP.

———————————————————————————————————————————

补充程序:

1.添加抬头文本ZFMPP_ADD_HEAD_TXT

 

代码:

FUNCTION zfmpp_add_head_txt.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_AUFNR) TYPE  AUFNR
*"     VALUE(IV_TEXT)
*"  EXPORTING
*"     REFERENCE(ES_RETURN) TYPE  BAPIRET2
*"----------------------------------------------------------------------

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = iv_aufnr
    IMPORTING
      output = iv_aufnr.

  DATA:ls_head TYPE thead.
  ls_head-tdobject = 'AUFK'."对象
  ls_head-tdid = 'KOPF'.
  ls_head-tdspras = sy-langu."语言
  ls_head-tdname = sy-mandt && iv_aufnr.

  DATA:lt_lines TYPE TABLE OF tline,
       ls_lines TYPE tline.

  ls_lines-tdformat = '*'.
  ls_lines-tdline = iv_text.
  APPEND ls_lines TO lt_lines.


*  CALL FUNCTION 'CREATE_TEXT'
*    EXPORTING
*      fid         = 'KOPF'
*      flanguage   = sy-langu
*      fname       = ls_head-tdname
*      fobject     = 'AUFK'
*      save_direct = 'X'
**     FFORMAT     = '*'
*    TABLES
*      flines      = lt_lines
*    EXCEPTIONS
*      no_init     = 1
*      no_save     = 2
*      OTHERS      = 3.
*  IF sy-subrc <> 0.
*    es_return-type = 'E'.
*    es_return-message = '保存失败'.
*  ELSE.
**    CALL FUNCTION 'COMMIT_TEXT'
**      EXPORTING
**        object          = ls_head-tdobject
**        name            = ls_head-tdname
**        id              = ls_head-tdid
**        language        = ls_head-tdspras
**        savemode_direct = 'X'.
**   COMMIT WORK AND WAIT .
*    SELECT SINGLE * INTO @DATA(ls_aufk)
*      FROM aufk
*      WHERE aufnr = @iv_aufnr.
*    ls_aufk-ltext = sy-langu."这句非常重要
*    MODIFY aufk FROM ls_aufk.
*
*    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
*      EXPORTING
*        wait = 'X'.
*
*    es_return-type = 'S'.
*    es_return-message = '保存成功'.
*  ENDIF.


  CALL FUNCTION 'SAVE_TEXT'
    EXPORTING
      client          = sy-mandt
      header          = ls_head
*     insert          = 'X'
      savemode_direct = 'X'
*     OWNER_SPECIFIED = ' '
*     LOCAL_CAT       = ' '
*     KEEP_LAST_CHANGED       = ' '
*   IMPORTING
*     FUNCTION        =
*     NEWHEADER       =
    TABLES
      lines           = lt_lines
    EXCEPTIONS
      id              = 1
      language        = 2
      name            = 3
      object          = 4
      OTHERS          = 5.
  IF sy-subrc <> 0.
    es_return-type = 'E'.
    es_return-message = '保存失败'.
  ELSE.
    SELECT SINGLE * INTO @DATA(ls_aufk)
       FROM aufk
       WHERE aufnr = @iv_aufnr.
    ls_aufk-ltext = sy-langu."这句非常重要
    MODIFY aufk FROM ls_aufk.
    COMMIT WORK AND WAIT.

    es_return-type = 'S'.
    es_return-message = '保存成功'.
  ENDIF.


ENDFUNCTION.

2.删除工序ZFMPP_DELETE_OPERATIONS

FUNCTION zfmpp_delete_operations.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_AUFNR) TYPE  AUFNR
*"  EXPORTING
*"     REFERENCE(ES_RETURN) TYPE  BAPIRET2
*"----------------------------------------------------------------------

************************************************************************
*  作者:胡杰
*  创建日期:2021.04.29 11:18:02
*  开发编号:
*  程序描述:删除除第一个工序以外的所有工序
************************************************************************
*  版本号  日期        作者       备注
************************************************************************
*  001.
*  002.
************************************************************************

*备注:由于工序无法全部删除,所以保留第一个工序,其他工序全删

  DATA: BEGIN OF record,
* data element: AUFNR
          aufnr_001(012),
* data element: FLG_OVIEW
          flg_oview_002(001),
* data element: GAMNG
          gamng_003(017),
* data element: CO_GMEIN
          gmein_004(003),
* data element: CO_GLTRP
          gltrp_005(010),
* data element: CO_GLUZP
          gluzp_006(005),
* data element: CO_GSTRP
          gstrp_007(010),
* data element: CO_GSUZP
          gsuzp_008(005),
* data element: TERMKZ
          terkz_009(001),
* data element: FLG_SEL
          flg_sel_01_010(001),
        END OF record.

  "添加前导零
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = iv_aufnr
    IMPORTING
      output = iv_aufnr.

  "获取工序,如果工序的数量大于2,则执行删除
  SELECT a~aufpl,
         a~aplzl
  INTO TABLE @DATA(lt_afvc)
  FROM afvc AS a
  INNER JOIN afko AS b ON a~aufpl = b~aufpl
  WHERE b~aufnr = @iv_aufnr.

  IF lines( lt_afvc ) < 2.
    es_return-type = 'S'.
    es_return-message = '仅有一条工序,无需删除'.
    RETURN.
  ENDIF.

  record-aufnr_001 = iv_aufnr."工单号
  record-flg_oview_002 = 'X'.

  CLEAR:bdcdata[]."清空全局变量,不然会影响到后面调用

  PERFORM bdc_dynpro      USING 'SAPLCOKO1' '0110'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
        'CAUFVD-AUFNR'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
        '=ENTK'.
  PERFORM bdc_field       USING 'CAUFVD-AUFNR'
                                record-aufnr_001.
  PERFORM bdc_field       USING 'R62CLORD-FLG_OVIEW'
                                record-flg_oview_002.
  PERFORM bdc_dynpro      USING 'SAPLCOKO1' '0115'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=VGUE'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'CAUFVD-GAMNG'.
*PERFORM bdc_field       USING 'CAUFVD-GAMNG'
*                               record-gamng_003.
*PERFORM bdc_field       USING 'CAUFVD-GMEIN'
*                               record-gmein_004.
*PERFORM bdc_field       USING 'CAUFVD-GLTRP'
*                               record-gltrp_005.
*PERFORM bdc_field       USING 'CAUFVD-GLUZP'
*                               record-gluzp_006.
*PERFORM bdc_field       USING 'CAUFVD-GSTRP'
*                               record-gstrp_007.
*PERFORM bdc_field       USING 'CAUFVD-GSUZP'
*                               record-gsuzp_008.
*PERFORM bdc_field       USING 'CAUFVD-TERKZ'
*                               record-terkz_009.
  PERFORM bdc_dynpro      USING 'SAPLCOVG' '0100'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'AFVGD-VORNR(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=AMAK'.
  PERFORM bdc_dynpro      USING 'SAPLCOVG' '0100'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'AFVGD-VORNR(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=LOE'.
  PERFORM bdc_field       USING 'RC27X-FLG_SEL(01)'
                                record-flg_sel_01_010.
  PERFORM bdc_dynpro      USING 'SAPLSPO2' '0200'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=OPT1'.
  PERFORM bdc_dynpro      USING 'SAPLCOVG' '0100'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'AFVGD-VORNR(01)'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=BU'.
  PERFORM bdc_transaction_co02 USING 'CO02'.

  READ TABLE gt_messtab INTO gs_messtab WITH KEY msgtyp = 'E'.
  IF sy-subrc = 0.
    es_return-type = 'E'.
    es_return-message = '删除工序失败'.
  ELSE.
    es_return-type = 'S'.
    es_return-message = '删除工序成功'.
  ENDIF.


ENDFUNCTION.
FORM bdc_transaction_co02  USING   tcode..


  DATA: ctumode TYPE ctu_params-dismode,
        cupdate TYPE ctu_params-updmode.

  ctumode = 'N'.
  cupdate = 'B'.

  CLEAR:gt_messtab.
  CALL TRANSACTION tcode USING bdcdata
        MODE   ctumode"A:调试 N:不显示 E:错误时调试
        UPDATE cupdate"A:异步 B:同步 L:本地更新
        MESSAGES INTO gt_messtab.

*  IF messtab IS INITIAL.
*    WRITE: / '删除成功'.
*  ELSE.
*    LOOP AT messtab INTO ls_messtab.
*      WRITE: / ls_messtab-msgv1, / ls_messtab-msgv2, / ls_messtab-msgv3.
*
*    ENDLOOP.
*
*  ENDIF.

ENDFORM.

DATA: bdcdata LIKE bdcdata    OCCURS 0 WITH HEADER LINE.

 DATA: gt_messtab    TYPE TABLE OF  bdcmsgcoll,
       gs_messtab TYPE  bdcmsgcoll.

FORM bdc_dynpro  USING  program dynpro.
  CLEAR bdcdata.
  bdcdata-program  = program.
  bdcdata-dynpro   = dynpro.
  bdcdata-dynbegin = 'X'.
  APPEND bdcdata.

ENDFORM.

FORM bdc_field  USING fnam fval.
  " IF FVAL <> NODATA.
  CLEAR bdcdata.
  bdcdata-fnam = fnam.
  bdcdata-fval = fval.
  APPEND bdcdata.
  " ENDIF.
ENDFORM.

3.新增工序ZFMPP_ADD_OPERATIONS

FUNCTION zfmpp_add_operations.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_AUFNR) TYPE  AUFNR
*"     VALUE(IV_WERKS) TYPE  WERKS_D
*"     VALUE(IV_ZCKGXJ) TYPE  ZECKGXJ
*"  EXPORTING
*"     REFERENCE(ES_RETURN) TYPE  BAPIRET2
*"----------------------------------------------------------------------
************************************************************************
*  作者:胡杰
*  创建日期:2021.04.29 13:56:30
*  开发编号:
*  程序描述:增加工序
************************************************************************
*  版本号  日期        作者       备注
************************************************************************
*  001.
*  002.
************************************************************************

  "尝试使用CO_SE_PRODORD_CHANGE来新增工序

  "对入参进行检查
  IF iv_aufnr IS INITIAL.
    es_return-type = 'E'.
    es_return-message = '请输入生产订单号'.
    RETURN.
  ENDIF.

  IF iv_werks IS INITIAL.
    es_return-type = 'E'.
    es_return-message = '请输入工厂'.
    RETURN.
  ENDIF.

  IF iv_zckgxj IS INITIAL.
    es_return-type = 'E'.
    es_return-message = '请输入参考工序集'.
    RETURN.
  ENDIF.

  "添加前导零
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = iv_aufnr
    IMPORTING
      output = iv_aufnr.

  DATA:lt_ztpp0040 TYPE TABLE OF ztpp0040,
       ls_ztpp0040 TYPE ztpp0040.


  DATA:lt_operation TYPE cose_t_operation,
       ls_operation LIKE LINE OF lt_operation.
  DATA:ls_return TYPE bapiret2.
  DATA:lv_posnr TYPE vornr.

  SELECT a~aufpl,
         a~aplzl
  INTO TABLE @DATA(lt_afvc)
        FROM afvc AS a
        INNER JOIN afko AS b ON a~aufpl = b~aufpl
        WHERE b~aufnr = @iv_aufnr.

  "lv_posnr =  lines( lt_afvc ) * 10 + 10.
  lv_posnr =  lines( lt_afvc ) * 10."实现将组件10替换

  "读取配置表数据
  SELECT *
    INTO TABLE lt_ztpp0040
    FROM ztpp0040
    WHERE werks = iv_werks "工厂
      AND zckgxj = iv_zckgxj. "工序集
  IF sy-subrc <> 0.
    es_return-type = 'E'.
    es_return-message = '未读取到配置表信息'.
    RETURN.
  ENDIF.
  SORT lt_ztpp0040 BY zgxjxm.

  "需要读取工序的行数,然后将工序写入到程序中去
  LOOP AT lt_ztpp0040 INTO ls_ztpp0040.
    ls_operation-operation = lv_posnr."
    ls_operation-control_key = 'BTR1'."控制码
    ls_operation-work_center = ls_ztpp0040-arbpl."工作中心
    ls_operation-work_center_x = 'X'.
    "ls_operation-short_text = ls_ztpp0040-zgxjms."短文本
    "取工作中心短文本
    SELECT SINGLE a~ktext
      INTO ls_operation-short_text
      FROM crtx AS a
      INNER JOIN crhd AS b ON a~objid = b~objid
      WHERE b~werks = iv_werks
        AND b~arbpl = ls_operation-work_center.
    ls_operation-short_text_x = 'X'.
    APPEND ls_operation TO lt_operation.
    CLEAR:ls_operation.
    lv_posnr = lv_posnr + 10.
  ENDLOOP.

  CALL FUNCTION 'CO_SE_PRODORD_CHANGE'
    EXPORTING
      iv_order_number = iv_aufnr
*     IS_HEADER       =
*     IT_HDR_USER_STATUS       =
*     IT_SEQUENCE     =
      it_operation    = lt_operation
*     IT_OPR_USER_STATUS       =
*     IT_PRT          =
*     IV_COMMIT       =
    IMPORTING
      es_return       = ls_return.

  MOVE-CORRESPONDING ls_return TO es_return.
  IF ls_return-type = 'E'.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.
    ls_return-type = 'S'.
    ls_return-message = '执行成功'.
  ENDIF.

  "BREAK-POINT.


ENDFUNCTION.

4.跳转到ME23N

"跳转到ME23N
        CALL FUNCTION 'ME_DISPLAY_PURCHASE_DOCUMENT'
          EXPORTING
            i_ebeln              = <fs_cr>-ebeln
*           I_EBELP              =
*           I_ENJOY              = 'X'
*           I_PREVIEW            =
*           I_DATA_FROM_BUFFER   =
*           I_BSTYP              =
*           I_DISPLAY_ONLY       = ' '
*           I_EDIT               = ' '
*           I_ETENR              =
*           I_DOC_INITIATOR      =
*           I_COMMIT_WAIT        =
          EXCEPTIONS
            not_found            = 1
            no_authority         = 2
            invalid_call         = 3
            preview_not_possible = 4
            OTHERS               = 5.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/323770
推荐阅读
  

闽ICP备14008679号