SAP BOM的操作

這個程序是根據條件把某些工廠的某些物料的某些BOM,Copy到別外的工廠,當目標工廠存在要複製的BOM的時候,用源BOM代替目標BOM,當目標BOM不存在的時候,就根據源BOM創建目標BOM。

這個程序用到了BOM的一些常用Function和BAPI
BAPI_MATERIAL_BOM_GROUP_CREATE
CSAP_MAT_BOM_READ
CSAP_MAT_BOM_OPEN
CSAP_BOM_ITEM_MAINTAIN
CSAP_MAT_BOM_CLOSE

REPORT  zppinf1001.

INCLUDE <icon>.

*----------------------------------------------------------------------*
*       變量定義
*----------------------------------------------------------------------*
TABLES mast.
TYPES: ty_tab_matnr TYPE mara-matnr OCCURS 0,
       ty_tab_plant TYPE marc-werks OCCURS 0,
       ty_tab_stpo2 TYPE stpo_api02 OCCURS 0,
       ty_tab_stko2 TYPE stko_api02 OCCURS 0,
       ty_tab_s_mat TYPE s_matnr OCCURS 0.
TYPES: BEGIN OF ty_mast,
        matnr TYPE mast-matnr,
        werks TYPE mast-werks,
        stlan TYPE mast-stlan,
        stlnr TYPE mast-stlnr,
        stlal TYPE mast-stlal,
       END OF ty_mast.
TYPES: BEGIN OF ty_material,
        matnr TYPE mara-matnr,
        werks TYPE marc-werks,
       END OF ty_material.
TYPES ty_tab_mast TYPE ty_mast OCCURS 0.
TYPES ty_tab_messages TYPE messages OCCURS 0.
TYPES ty_tab_material TYPE ty_material OCCURS 0.
DATA: g_valid_from TYPE csap_mbom-datuv.

*----------------------------------------------------------------------*
*       選擇屏幕設計
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME TITLE text-000.
SELECT-OPTIONS: s_matnr  FOR mast-matnr,
                s_stlan  FOR mast-stlan NO-EXTENSION NO INTERVALS OBLIGATORY,
                s_stlal  FOR mast-stlal NO-EXTENSION NO INTERVALS OBLIGATORY,
                s_source FOR mast-werks NO-EXTENSION NO INTERVALS OBLIGATORY.
SELECTION-SCREEN SKIP.
SELECT-OPTIONS: s_target FOR mast-werks,
                s_stlan2 FOR mast-stlan NO-EXTENSION NO INTERVALS OBLIGATORY,
                s_stlal2 FOR mast-stlal NO-EXTENSION NO INTERVALS OBLIGATORY.
PARAMETERS p_exist TYPE c AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK blk.

*----------------------------------------------------------------------*
*       CLASS lcl_bom DEFINITION
*----------------------------------------------------------------------*
*       BOM的處理類定義
*----------------------------------------------------------------------*
CLASS lcl_bom DEFINITION FINAL.
  PUBLIC SECTION.
    METHODS write_header_text  "輸出結果列表的選擇條件的相關信息
      IMPORTING
        pt_plant TYPE ty_tab_plant.
    METHODS check_exist_bom     "檢驗指定條件的物料是否存在BOM
      IMPORTING
        p_material    TYPE csap_mbom-matnr  "料號
        p_plant       TYPE csap_mbom-werks  "工廠
        p_bom_usage   TYPE csap_mbom-stlan  "BOM Usage
        p_alternative TYPE csap_mbom-stlal  "Alternative BOM
        pt_target     TYPE ty_tab_mast
      RETURNING
        value(p_flag) TYPE char01.        "檢查結果返回標識,X代表存在
    METHODS get_data                      "根據條件查詢數據
      EXPORTING
        value(pt_source) TYPE ty_tab_mast
        value(pt_target) TYPE ty_tab_mast.
    METHODS get_target_plant
      RETURNING
        value(pt_plant) TYPE ty_tab_plant.
    METHODS check_matnr                    "檢查指定的物料是否在指定的工廠存在
      IMPORTING
        p_matnr       TYPE mast-matnr
        p_plant       TYPE mast-werks
      RETURNING
        value(p_flag) TYPE char01.
    METHODS check_component                "檢查指定的組件是否在指定的工廠存在
      IMPORTING
        p_matnr       TYPE mast-matnr
        p_plant       TYPE mast-werks
        pt_stpo       TYPE ty_tab_stpo2
      RETURNING
        value(p_flag) TYPE char01.
    METHODS set_log.                        "設置Log,可以事務碼SLG1查看
    METHODS get_current_log                 "取得當前Log信息
      RETURNING
        value(pt_messages) TYPE ty_tab_messages.
    METHODS read_bom                        "查看BOM信息
      IMPORTING
        p_material     TYPE csap_mbom-matnr
        p_plant        TYPE csap_mbom-werks
        p_bom_usage    TYPE csap_mbom-stlan
        p_alternative  TYPE csap_mbom-stlal
        p_valid_from   TYPE csap_mbom-datuv
      EXPORTING
        value(pt_stpo) TYPE ty_tab_stpo2
        value(pt_stko) TYPE ty_tab_stko2
        value(p_flag)  TYPE char01.
    METHODS create_bom                      "創建BOM
        IMPORTING
          p_material    TYPE csap_mbom-matnr
          p_plant       TYPE csap_mbom-werks
          pt_stpo       TYPE ty_tab_stpo2
          pt_stko       TYPE ty_tab_stko2
        RETURNING
          value(p_flag) TYPE char01.
    METHODS maintain_bom                      "維護BOM
        IMPORTING
          p_material    TYPE csap_mbom-matnr
          p_plant       TYPE csap_mbom-werks
          p_usage       TYPE csap_mbom-stlan
          p_alternative TYPE csap_mbom-stlal
          p_valid       TYPE csap_mbom-datuv
          pt_stpo       TYPE ty_tab_stpo2
          pt_stko       TYPE ty_tab_stko2
        RETURNING
          value(p_flag) TYPE char01.
    METHODS constructor.                      "構造方法
    "類的全局變量
    DATA: BEGIN OF lwa_mat_wer,
            matnr TYPE mara-matnr,
            werks TYPE marc-werks,
          END OF lwa_mat_wer.
    DATA: lt_mat_wer2  LIKE TABLE OF lwa_mat_wer.
  PRIVATE SECTION.
    DATA: lt_mat_wer  LIKE TABLE OF lwa_mat_wer.
ENDCLASS.                    "lcl_bom DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_bom IMPLEMENTATION
*----------------------------------------------------------------------*
*       BOM的處理類實現
*----------------------------------------------------------------------*
CLASS lcl_bom IMPLEMENTATION.
*輸出結果列表的選擇條件的相關信息
  METHOD write_header_text.
    DATA: l_temp TYPE i VALUE 1,
          l_plant TYPE marc-werks.
    FORMAT COLOR 1 ON.
    IF s_matnr IS INITIAL.
      WRITE: 'BOM Material: All'.
    ELSEIF s_matnr-low IS NOT INITIAL AND s_matnr-high IS NOT INITIAL.
      WRITE: / 'BOM Material:',s_matnr-low,'To',s_matnr-high.
    ELSEIF s_matnr-high IS INITIAL.
      WRITE: / 'BOM Material:',s_matnr-low.
    ENDIF.
    WRITE: / 'Source Plant:',s_source-low.
    WRITE: / 'BOM Usage:',s_stlan-low.
    WRITE: / 'Alternative BOM:',s_stlal-low.
    SKIP.
    WRITE / 'Target Plant:'.
    LOOP AT pt_plant INTO l_plant.
      IF l_temp > 15.
        WRITE /16 l_plant.
        l_temp = 2.
        CONTINUE.
      ENDIF.
      WRITE l_plant.
      l_temp = l_temp + 1.
    ENDLOOP.
    WRITE: / 'BOM Usage:',s_stlan2-low.
    WRITE: / 'Alternative BOM:',s_stlal2-low.
    IF p_exist = 'X'.
      WRITE / 'Skip if target plant exist'.
    ENDIF.
    FORMAT COLOR OFF.
    ULINE.
  ENDMETHOD.                    "wwrite_header_text

*檢驗指定條件的物料是否存在BOM
  METHOD check_exist_bom.
    DATA l_alternative LIKE p_alternative.

    READ TABLE pt_target WITH KEY matnr = p_material
                                  werks = p_plant
                                  stlan = p_bom_usage
                                  stlal = p_alternative
                         TRANSPORTING NO FIELDS.
    IF sy-subrc = 0.
      p_flag = 'X'.
    ENDIF.
  ENDMETHOD.                    "check_exist_bom

*根據條件取得所有要複製到其他工廠的BOM的物料
  METHOD get_data.
    "取得表MAST的數據
    SELECT DISTINCT matnr
                    werks
                    stlan
                    stlnr
                    stlal
    INTO TABLE pt_source FROM mast
    WHERE matnr IN s_matnr.

    pt_target = pt_source.

    DELETE pt_source WHERE NOT ( werks IN s_source AND stlan IN s_stlan AND stlal IN s_stlal ).
    DELETE pt_target WHERE NOT ( werks IN s_target AND stlan IN s_stlan2 AND stlal IN s_stlal2 ).
  ENDMETHOD.                    "get_data

*根據條件取得目標工廠
  METHOD get_target_plant.
    SELECT werks INTO TABLE pt_plant FROM t001w
                 WHERE werks IN s_target.
  ENDMETHOD.                    "get_target_plant

*判斷指定的料號在指定的工廠是否存在
  METHOD check_matnr.
    "根據條件取得物料和工廠的內表
    IF lt_mat_wer IS INITIAL.
      SELECT mara~matnr
             marc~werks
      INTO TABLE lt_mat_wer
      FROM mara
      INNER JOIN marc ON mara~matnr = marc~matnr
      WHERE mara~matnr IN s_matnr
        AND marc~werks IN s_target.
    ENDIF.

    "查詢內表,判斷指定料號是否在指定的工廠裏
    READ TABLE lt_mat_wer WITH KEY matnr = p_matnr
                                   werks = p_plant
                          TRANSPORTING NO FIELDS.
    "存在
    IF sy-subrc = 0.
      p_flag = 'X'.
    ENDIF.
  ENDMETHOD.                    "check_matnr

*檢查指定的組件是否在指定的工廠存在
  METHOD check_component.
    DATA: l_matnr TYPE mara-matnr,
          lt_matnr LIKE RANGE OF l_matnr,
          lwa_matnr LIKE LINE OF lt_matnr,
          lwa_stpo LIKE LINE OF pt_stpo.
    "組織選擇內表
    LOOP AT pt_stpo INTO lwa_stpo.
      lwa_matnr-sign   = 'I'.
      lwa_matnr-option = 'EQ'.
      CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
        EXPORTING
          input  = lwa_stpo-component
        IMPORTING
          output = lwa_stpo-component.
      lwa_matnr-low    = lwa_stpo-component.
      lwa_matnr-high   = ''.
      APPEND lwa_matnr TO lt_matnr.
    ENDLOOP.
    "根據條件取得物料和工廠的內表
    IF lt_mat_wer2 IS INITIAL.
      SELECT mara~matnr
             marc~werks
      INTO TABLE lt_mat_wer2
      FROM mara
      INNER JOIN marc ON mara~matnr = marc~matnr
      WHERE mara~matnr IN lt_matnr
        AND marc~werks = p_plant.
    ENDIF.

    "查詢內表,判斷指定料號是否在指定的工廠裏
    READ TABLE lt_mat_wer2 WITH KEY matnr = p_matnr
                           TRANSPORTING NO FIELDS.
    "存在
    IF sy-subrc = 0.
      p_flag = 'X'.
    ENDIF.
  ENDMETHOD.                    "check_component

*設置Log,可以用事務碼SLG1查看
  METHOD set_log.
    CALL FUNCTION 'CALO_INIT_API'
      EXCEPTIONS
        log_object_not_found     = 1
        log_sub_object_not_found = 2
        other_error              = 3
        OTHERS                   = 4.
  ENDMETHOD.                    "set_log

*取得當前Log信息
  METHOD get_current_log.
    CALL FUNCTION 'CALO_LOG_READ_MESSAGES'
      TABLES
        messages_and_parameters = pt_messages
      EXCEPTIONS
        warning                 = 1
        error                   = 2
        OTHERS                  = 3.
  ENDMETHOD.                    "get_current_log

*讀取指定的BOM
  METHOD read_bom.
    "調用FM查看指定的物料的BOM
    CALL FUNCTION 'CSAP_MAT_BOM_READ'
      EXPORTING
        material    = p_material
        plant       = p_plant
        bom_usage   = p_bom_usage
        alternative = p_alternative
        valid_from  = p_valid_from
      TABLES
        t_stpo      = pt_stpo
        t_stko      = pt_stko
      EXCEPTIONS
        error       = 1.
    "判斷是否查看bom數據成功
    IF sy-subrc = 0.
      p_flag = 'X'.
    ELSE.
      p_flag = ''.
    ENDIF.
  ENDMETHOD.                    "read_bom

*創建BOM
  METHOD create_bom.
    DATA: lwa_bomgroup TYPE bapi1080_bgr_c,
          lt_bomgroup  LIKE TABLE OF lwa_bomgroup,
          lwa_variant  TYPE bapi1080_bom_c,
          lt_variant   LIKE TABLE OF lwa_variant,
          lwa_items    TYPE bapi1080_itm_c,
          lt_items     LIKE TABLE OF lwa_items,
          lwa_mbm      TYPE bapi1080_mbm_c,
          lt_mbm       LIKE TABLE OF lwa_mbm,
          lwa_itemass  TYPE bapi1080_rel_itm_bom_c,
          lt_itemass   LIKE TABLE OF lwa_itemass,
          lwa_return   TYPE bapiret2,
          lt_return    LIKE TABLE OF lwa_return.
    DATA: l_alternative TYPE stpo_api02-bom_alt,
          l_component   TYPE stpo_api02-component,
          l_error       TYPE string.
    CONSTANTS: bom_group_identification TYPE bapi1080_bgr_c-bom_group_identification
                                        VALUE 'BAPI_SMP_COL4',
               object_id TYPE bapi1080_bgr_c-object_id VALUE 'SIMPLE1'.
    FIELD-SYMBOLS: <fs_stko> LIKE LINE OF pt_stko,
                   <fs_stpo> LIKE LINE OF pt_stpo.

    "循環內表pt_stpo
    LOOP AT pt_stpo ASSIGNING <fs_stpo>.
      "在Component前面添零
      CLEAR l_component.
      CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
        EXPORTING
          input  = <fs_stpo>-component
        IMPORTING
          output = l_component.

      "添加BOM Items
      CLEAR lwa_items.
      lwa_items-bom_group_identification = bom_group_identification.
      lwa_items-object_type = 'ITM'.
      lwa_items-object_id = object_id.
      lwa_items-item_no = <fs_stpo>-item_no.
      lwa_items-item_cat = <fs_stpo>-item_categ.
      lwa_items-component = l_component.
      lwa_items-comp_qty = <fs_stpo>-comp_qty.
      lwa_items-comp_unit = <fs_stpo>-comp_unit.
      lwa_items-valid_from_date = sy-datum.
      APPEND lwa_items TO lt_items.
    ENDLOOP.

    "循環內表
    LOOP AT pt_stko ASSIGNING <fs_stko>.
      "添加BOM Group信息
      CLEAR lwa_bomgroup.
      lwa_bomgroup-bom_group_identification = bom_group_identification.
      lwa_bomgroup-object_type = 'BGR'.
      lwa_bomgroup-object_id = object_id.
      lwa_bomgroup-bom_usage = s_stlan2-low.
      lwa_bomgroup-bom_group = <fs_stko>-bom_group.
      lwa_bomgroup-created_in_plant = p_plant.
      lwa_bomgroup-auth_group = <fs_stko>-auth_group.
      lwa_bomgroup-technical_type = ' '.
      lwa_bomgroup-ltxt_lang = sy-langu.
      lwa_bomgroup-bom_text = <fs_stko>-bom_text.
      APPEND lwa_bomgroup TO lt_bomgroup.

      "添加Variant信息
      CLEAR lwa_variant.
      lwa_variant-bom_group_identification = bom_group_identification.
      lwa_variant-object_type = 'BOM'.
      lwa_variant-object_id = object_id.
      lwa_variant-alternative_bom = s_stlal2-low.
      lwa_variant-bom_status = <fs_stko>-bom_status.
      lwa_variant-deletion_ind = <fs_stko>-delete_ind.
      lwa_variant-base_qty = <fs_stko>-base_quan.
      lwa_variant-base_unit = <fs_stko>-base_unit.
      lwa_variant-lab_design = <fs_stko>-laboratory.
      lwa_variant-ltxt_lang = sy-langu.
      lwa_variant-alt_text = <fs_stko>-alt_text.
      lwa_variant-valid_from_date = sy-datum.
      lwa_variant-change_no = <fs_stko>-chg_no.
      lwa_variant-function = 'NEW'.
      APPEND lwa_variant TO lt_variant.
    ENDLOOP.

    CLEAR lwa_mbm.
    lwa_mbm-bom_group_identification = bom_group_identification.
    lwa_mbm-material = p_material.
    lwa_mbm-bom_usage = s_stlan2-low.
    lwa_mbm-plant = p_plant.
    lwa_mbm-alternative_bom = s_stlal2-low.
    APPEND lwa_mbm TO lt_mbm.

    CLEAR lwa_itemass.
    lwa_itemass-bom_group_identification = bom_group_identification.
    lwa_itemass-sub_object_type = 'ITM'.
    lwa_itemass-sub_object_id = object_id.
    lwa_itemass-super_object_type = 'BOM'.
    lwa_itemass-super_object_id = object_id.
    lwa_itemass-valid_from_date = sy-datum.
    lwa_itemass-function = 'NEW'.
    APPEND lwa_itemass TO lt_itemass.

    "調用BAPI創建BOM
    CALL FUNCTION 'BAPI_MATERIAL_BOM_GROUP_CREATE'
      EXPORTING
        all_error         = 'X'
      TABLES
        bomgroup          = lt_bomgroup
        variants          = lt_variant
        items             = lt_items
        materialrelations = lt_mbm
        itemassignments   = lt_itemass
        return            = lt_return.

    p_flag = 'X'.
    LOOP AT lt_return INTO lwa_return WHERE type = 'A' OR type = 'E'.
      p_flag = ''.
      l_error = lwa_return-message.
      EXPORT p1 = l_error TO MEMORY ID 'CREATE'.
      EXIT.
    ENDLOOP.

    IF p_flag = 'X'.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
    ELSE.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ENDIF.

    FREE: lt_bomgroup,
          lt_variant,
          lt_items,
          lt_mbm,
          lt_itemass,
          lt_return.
  ENDMETHOD.                    "create_bom

*維護BOM
  METHOD maintain_bom.
    DATA: lwa_stpo      LIKE LINE OF pt_stpo,
          l_material    LIKE p_material,
          lt_stpo2      TYPE ty_tab_stpo2,
          lt_stpo2_temp TYPE ty_tab_stpo2,
          lt_messages   TYPE ty_tab_messages,
          lwa_messages  LIKE LINE OF lt_messages,
          l_error       TYPE string.
    FIELD-SYMBOLS <fs_stpo> LIKE LINE OF pt_stpo.
    "補0
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = p_material
      IMPORTING
        output = l_material.

    p_flag = 'X'.

    "Log
    CALL METHOD me->set_log.
    "打開BOM維護
    CALL FUNCTION 'CSAP_MAT_BOM_OPEN'
      EXPORTING
        material    = l_material
        plant       = p_plant
        bom_usage   = p_usage
        alternative = p_alternative
        valid_from  = p_valid
      TABLES
        t_stpo      = lt_stpo2
      EXCEPTIONS
        error       = 1.

    IF sy-subrc = 0.
      "先把所有目標工廠的BOM數據打上刪除標記
      lwa_stpo-fldelete = 'X'.
      MODIFY lt_stpo2 FROM lwa_stpo TRANSPORTING fldelete WHERE fldelete <> 'X'.

      LOOP AT pt_stpo INTO lwa_stpo.
        READ TABLE lt_stpo2 ASSIGNING <fs_stpo> WITH KEY component = lwa_stpo-component.
        IF sy-subrc = 0.
          "找到則是需要修改的
          lwa_stpo-itm_ident  = <fs_stpo>-itm_ident.
          lwa_stpo-bom_no     = <fs_stpo>-bom_no.
          lwa_stpo-item_node  = <fs_stpo>-item_node.
          lwa_stpo-item_count = <fs_stpo>-item_count.
          lwa_stpo-valid_from = p_valid.
          APPEND lwa_stpo TO lt_stpo2_temp.
          "刪除lt_stpo3裏修改的記錄,剩下的就是刪除的
          DELETE lt_stpo2 WHERE itm_ident = <fs_stpo>-itm_ident.
        ELSE.
          "找不到的則是新增的
          lwa_stpo-itm_ident = ''.
          lwa_stpo-bom_no = ''.
          lwa_stpo-item_node = ''.
          lwa_stpo-item_count = ''.
          lwa_stpo-valid_from = p_valid.
          APPEND lwa_stpo TO lt_stpo2_temp.
        ENDIF.
      ENDLOOP.
      "把lt_stpo2剩下的,即是刪除的添加內表lt_stpo2_temp
      APPEND LINES OF lt_stpo2 TO lt_stpo2_temp.
    ELSE.
      p_flag = ''.
      lt_messages = me->get_current_log( ).
      LOOP AT lt_messages INTO lwa_messages WHERE msg_type = 'E'
                                            OR msg_type = 'A'.
        l_error = lwa_messages-msg_txt.
        EXPORT p1 = l_error TO MEMORY ID 'MAINTAIN'.
        EXIT.
      ENDLOOP.
      EXIT.
    ENDIF.

    "循環處理BOM Item
    LOOP AT lt_stpo2_temp INTO lwa_stpo.
      "補零
      CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
        EXPORTING
          input  = lwa_stpo-component
        IMPORTING
          output = lwa_stpo-component.
      CALL FUNCTION 'CSAP_BOM_ITEM_MAINTAIN'
        EXPORTING
          i_stpo = lwa_stpo
        EXCEPTIONS
          error  = 1.
      IF sy-subrc <> 0.
        p_flag = ''.
        lt_messages = me->get_current_log( ).
        LOOP AT lt_messages INTO lwa_messages WHERE msg_type = 'E'
                                              OR msg_type = 'A'.
          EXPORT p1 = lwa_messages-msg_txt TO MEMORY ID 'MAINTAIN'.
          EXIT.
        ENDLOOP.
        EXIT.
      ENDIF.
    ENDLOOP.
    "關閉BOM維護
    CALL FUNCTION 'CSAP_MAT_BOM_CLOSE'
      EXCEPTIONS
        error = 1.
    IF sy-subrc <> 0.
      p_flag = ''.
      EXIT.
    ENDIF.

    FREE: lt_stpo2,
          lt_stpo2_temp.
  ENDMETHOD.                    "maintain_bom

*構造方法
  METHOD constructor.
    "格式化有限日期
    CONCATENATE sy-datum+6(2)
                sy-datum+4(2)
                sy-datum+0(4)
    INTO g_valid_from SEPARATED BY '.'.
  ENDMETHOD.                    "contructor

ENDCLASS.                    "lcl_bom IMPLEMENTATION

*&---------------------------------------------------------------------*
*&      Form  f_set_clock
*&---------------------------------------------------------------------*
*       程序處理時狀態欄顯示的小時鐘
*----------------------------------------------------------------------*
*      -->P_PERCENTAGE  時鐘顯示的百分比
*----------------------------------------------------------------------*
FORM f_set_clock USING p_percentage.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = p_percentage.
ENDFORM.                    "f_set_clock

*&---------------------------------------------------------------------*
*&      Form  f_main
*&---------------------------------------------------------------------*
*       子程序。整合所有方法,執行並輸出結果
*----------------------------------------------------------------------*
FORM f_main.
  DATA: lt_source TYPE ty_tab_mast,
        lwa_source LIKE LINE OF lt_source,
        lt_target  TYPE ty_tab_mast,
        lwa_target LIKE LINE OF lt_target,
        lt_plant   TYPE ty_tab_plant,
        lt_stpo2   TYPE ty_tab_stpo2,
        lwa_stpo2  LIKE LINE OF lt_stpo2,
        lt_stko2   TYPE ty_tab_stko2.
  DATA: l_flag,
        l_error  TYPE string,
        l_count  TYPE string,
        l_count1 TYPE i,    "成功的記錄數
        l_count2 TYPE i,    "失敗的記錄數
        l_werks  LIKE LINE OF lt_plant.
  DATA: lr_bom   TYPE REF TO lcl_bom.

*創建類LCL_BOM對象
  CREATE OBJECT lr_bom.

*篩選選擇的物料
  CALL METHOD lr_bom->get_data
    IMPORTING
      pt_source = lt_source
      pt_target = lt_target.

  PERFORM f_set_clock USING 10.

*取得目標工廠內表
  lt_plant = lr_bom->get_target_plant( ).

  IF lt_source IS INITIAL
    OR lt_plant IS INITIAL.
    MESSAGE s003(zmm).
    EXIT.
  ENDIF.
  PERFORM f_set_clock USING 50.
*輸出選擇條件文本
  lr_bom->write_header_text( lt_plant ).

  SORT lt_source BY werks.

  "按工廠處理BOM
  LOOP AT lt_plant INTO l_werks.
    CLEAR: l_count1,l_count2.
    "如果源BOM和目標BOM相同,跳過
    IF s_source-low = l_werks
      AND s_stlan-low = s_stlan2-low
      AND s_stlal-low = s_stlal2-low.
      CONTINUE.
    ENDIF.
    WRITE:/ 'Start plant',l_werks.
    "循環源物料內表,處理指定工廠的物料
    LOOP AT lt_source INTO lwa_source.
      "查看BOM數據
      CALL METHOD lr_bom->read_bom
        EXPORTING
          p_material    = lwa_source-matnr
          p_plant       = s_source-low
          p_bom_usage   = s_stlan-low
          p_alternative = s_stlal-low
          p_valid_from  = g_valid_from
        IMPORTING
          pt_stpo       = lt_stpo2
          pt_stko       = lt_stko2
          p_flag        = l_flag.
      "查得數據成功
      IF sy-subrc = 0 AND l_flag = 'X'.
        "如果BOM的Item爲空
        IF lt_stpo2 IS INITIAL.
          FORMAT COLOR 6 ON.
          WRITE: /3 icon_cancel AS ICON,
                    'Material',
                    lwa_source-matnr+10(8),
                    'BOM Usage',
                    s_stlan-low,
                    'not found in source plant',
                    s_source-low.
          FORMAT COLOR 6 OFF.
          l_count2 = l_count2 + 1.
          CONTINUE.
        ENDIF.

        "判斷當前物料是否在目標工廠中存在
        l_flag = lr_bom->check_matnr(
          p_matnr = lwa_source-matnr
          p_plant = l_werks
        ).
        "物料不在目標工廠就跳過
        IF l_flag <> 'X'.
          WRITE: /3 icon_skip AS ICON,
                    'Material',
                    lwa_source-matnr+10(8),
                    'not found in target plant',
                    l_werks.
          l_count2 = l_count2 + 1.
          CONTINUE.
        ENDIF.

        " 判斷組件是否在目標工廠中存在
        CLEAR lr_bom->lt_mat_wer2.
        LOOP AT lt_stpo2 INTO lwa_stpo2.
          "補零
          CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
            EXPORTING
              input  = lwa_stpo2-component
            IMPORTING
              output = lwa_stpo2-component.
          l_flag = lr_bom->check_component(
            p_matnr = lwa_stpo2-component
            p_plant = l_werks
            pt_stpo = lt_stpo2
          ).
          IF l_flag <> 'X'.
            WRITE: /3 icon_skip AS ICON,
                      'Component',
                      lwa_stpo2-component+10(8),
                      'not found in target plant',
                      l_werks.
            l_count2 = l_count2 + 1.
            EXIT.
          ENDIF.
        ENDLOOP.
        "如果組件在目標工廠不存在,跳過
        CHECK l_flag = 'X'.

        "判斷目標BOM是否存在
        l_flag = lr_bom->check_exist_bom(
          p_material    = lwa_source-matnr
          p_plant       = l_werks
          p_bom_usage   = s_stlan2-low
          p_alternative = s_stlal2-low
          pt_target     = lt_target
        ).
        "目標BOM存在
        IF l_flag = 'X'.
          "存在是否跳過
          IF p_exist <> 'X'.
            "維護BOM
            l_flag = lr_bom->maintain_bom(
                p_material = lwa_source-matnr
                p_plant = l_werks
                p_usage = s_stlan2-low
                p_alternative = s_stlal2-low
                p_valid = g_valid_from
                pt_stpo = lt_stpo2
                pt_stko = lt_stko2
             ).
            IF l_flag = 'X'.
*              WRITE: /3 icon_okay AS ICON,
*                        'Material',
*                        lwa_source-matnr+10(8),
*                        'copy success to plant',
*                        l_werks.
              l_count1 = l_count1 + 1.
            ELSE.
              "從內存取得錯誤文本
              IMPORT p1 = l_error FROM MEMORY ID 'MAINTAIN'.
              IF sy-subrc = 0.
                FORMAT COLOR 6 ON.
                WRITE: /3 icon_cancel AS ICON,l_error.
                FORMAT COLOR 6 OFF.
                FREE MEMORY ID 'MAINTIAN'.
                l_count2 = l_count2 + 1.
                CONTINUE.
              ENDIF.
            ENDIF.
          ELSE.
            WRITE: /3 icon_skip AS ICON,
                      'Material',
                      lwa_source-matnr+10(8),
                      'BOM exists and skip copy to plant',
                      l_werks.
            l_count2 = l_count2 + 1.
          ENDIF.
        ELSE.
          "BOM不存在,創建BOM
          l_flag = lr_bom->create_bom(
              p_material = lwa_source-matnr
              p_plant = l_werks
              pt_stpo = lt_stpo2
              pt_stko = lt_stko2
          ).
          IF l_flag = 'X'.
*            "輸出成功創建BOM的信息
*            WRITE: /3 icon_okay AS ICON,
*                      'Material',
*                      lwa_source-matnr+10(8),
*                      'copy success to plant',
*                      l_werks.
            l_count1 = l_count1 + 1.
          ELSE.
            IMPORT p1 = l_error FROM MEMORY ID 'CREATE'.
            IF sy-subrc = 0.
              FORMAT COLOR 6 ON.
              WRITE: /3 icon_cancel AS ICON,
                        l_error.
              FREE MEMORY ID 'CREATE'.
              l_count2 = l_count2 + 1.
            ENDIF.

            FORMAT COLOR 6 OFF.
            CONTINUE.
          ENDIF.
        ENDIF.
      ENDIF.
    ENDLOOP.
    l_count = l_count1.
    WRITE:/ l_count,'material copied success'.
    l_count = l_count2.
    WRITE:/ l_count,'material copied fail'.
    SKIP.
  ENDLOOP.
  WRITE / '-- End of Report --'.

  FREE: lt_source,
        lt_target,
        lt_plant,
        lt_stpo2,
        lt_stko2.
ENDFORM.                    "f_main

*----------------------------------------------------------------------*
*       執行事件
*----------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM f_main.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章