카테고리 없음

ABAP - EXCEL UPLOAD, BDC, BAPI

프라임콩 2023. 1. 30. 14:34

대량의 데이터를 유지보수 할 때 사용하는 standard 기능이다. Recording 기능으로 알려져 있다.

▶ BDC 프로그램 실행 방법

1. Batch Input 세션을 생성하여 실행하는 방법

   대량의 데이터를 전송할 때 사용

   (외부 데이터(파일 같은 형태)를 읽어서 BDC 테이블로 구성하고, Batch Input 세션에 데이터를 저장한 후 큐에 전달)

2. 프로그램 내에서 CALL, TRANSACTION으로 트랜젝션 호출하는 방법

   실시간 데이터 전송할 때 사용

   모든 Batch Input 프로세스가 프로그램 내에서 실시간으로 수행된다

   (Batch Input 세션을 생성하지 않고 ABAP 프로그램 내에서 CALL TRANSACTION으로 데이터를 입력)

 

 

 

실습1) BDC를 통한 자재 생성

 

BDC 수행 기본 작업

TOP에 필요한 데이터 선언.

*&---------------------------------------------------------------------*
*& BDC
*&---------------------------------------------------------------------*
DATA: ctu_params LIKE ctu_params,
      gt_bdc     LIKE TABLE OF bdcdata,
      gs_bdc     LIKE bdcdata,
      gt_msg     LIKE TABLE OF bdcmsgcoll,
      gs_msg     LIKE bdcmsgcoll.

 

BDC수행이 가능한지 체크하는 퍼폼문 작성.

*&---------------------------------------------------------------------*
*&  START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  IF p_rad1 = 'X'.
    PERFORM get_data.
  ELSE.
    PERFORM excel_upload.
    PERFORM check_bdc_data.   "BDC수행 가능한지 체크
  ENDIF.

  CALL SCREEN '0100'.
*&---------------------------------------------------------------------*
*& Form get_data
*&---------------------------------------------------------------------*
FORM get_data .

  SELECT a~matnr,
       a~mbrsh,
       a~mtart,
       a~meins,
       a~matkl,
       a~spart,
       a~prdha,
       a~profl,
       a~mtpos_mara,
       b~maktx
 INTO CORRESPONDING FIELDS OF TABLE @gt_alv
  FROM mara AS a
   LEFT OUTER JOIN makt AS b
    ON a~matnr = b~matnr
   AND b~spras = @sy-langu
 WHERE a~matnr IN @s_matnr
   AND a~mbrsh IN @s_mbrsh
   AND a~mtart IN @s_mtart
   AND a~meins IN @s_meins
   AND a~matkl IN @s_matkl
   AND a~spart IN @s_spart
   AND a~prdha IN @s_prdha
   AND a~profl IN @s_profl
   AND a~mtpos_mara IN @s_mtpos.
  LOOP AT gt_alv INTO gs_alv.
    gs_alv-icon = icon_led_green.
    MODIFY gt_alv FROM gs_alv.
  ENDLOOP.
ENDFORM.

 

*&---------------------------------------------------------------------*
*& Form check_bdc_data
*&---------------------------------------------------------------------*
FORM check_bdc_data .
  "수행할 트랜잭션에 적합하게 데이터 검증을 해 준다.
  "실습에서 새로운 자재번호를 등록할 예정이기 때문에 DB에 동일한 자재번호는 존재하면 안 되고,
  "다른 항목들은 다른 트랜잭션을 통해 등록하기 때문에 현재 존재하는 값인지 확인한다.
  "일반제품구조는 데이터 형식이 자재번호와 같은 Char 형식 18자리지만
  "Domain에서 CONVERSION_EXIT 속성을 갖고 있지 않아서 변환해주지 않았다
  "CONVERSION_EXIT 속성은 테이블-필드명-도메인더블클릭-ROUTINE을 통해 확인할 수 있다.

  DATA: lv_matnr     TYPE mara-matnr,      "자재번호
        lv_matkx     TYPE makt-maktx,      "자재내역
        lv_mbrsh     TYPE mara-mbrsh,      "산업부문
        lv_mtart     TYPE mara-mtart,      "자재유형
        lv_meins     TYPE mara-meins,      "기본단위
        lv_matkl     TYPE mara-matkl,      "자재그룹
        lv_spart     TYPE mara-spart,      "제품군
        lv_mpos_mara TYPE mara-mtpos_mara. "일반품목범주GR

  IF gt_alv IS INITIAL.
    MESSAGE s000 DISPLAY LIKE 'E' WITH '데이터가 없습니다.'.
  ENDIF.

  LOOP AT gt_alv INTO gs_alv.

    "자재번호 체크
    IF gs_alv-matnr IS INITIAL.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '자재번호는 필수사항입니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    SELECT SINGLE matnr
      INTO lv_matnr
      FROM mara
     WHERE matnr = gs_alv-matnr.

    IF sy-subrc = 0.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '해당하는 자재번호가 이미 존재합니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    "자재내역체크
    "자재내역은 자유롭게 입력하는 항목이기 때문에 단순히 데이터가 존재하는지만 체크한다.
    IF gs_alv-maktx IS INITIAL.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '자재내역은 필수사항입니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    "산업부문체크
    SELECT SINGLE mbrsh
      INTO lv_mbrsh
      FROM t137
     WHERE mbrsh = gs_alv-mbrsh.

    IF sy-subrc NE 0.
      IF gs_alv-mbrsh IS INITIAL.
      ELSE.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 산업부문이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "자재유형체크
    SELECT SINGLE mtart
      INTO lv_mtart
      FROM t134
     WHERE mtart = gs_alv-mtart.

    IF sy-subrc NE 0.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '해당하는 자재유형이 존재하지 않습니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    "기본단위체크
    SELECT SINGLE msehi
      INTO lv_meins
      FROM t006
     WHERE msehi = gs_alv-meins.

    IF sy-subrc NE 0.
      IF gs_alv-meins IS INITIAL.
      ELSE.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 기본단위가 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "자재그룹체크
    SELECT SINGLE matkl
      INTO lv_matkl
      FROM t023
     WHERE matkl = gs_alv-matkl.

    IF sy-subrc NE 0.
      IF gs_alv-matkl IS INITIAL.
      ELSE.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 자재그룹이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "제품군체크
    SELECT SINGLE spart
      INTO lv_spart
      FROM tspa
     WHERE spart = gs_alv-spart.

    IF sy-subrc NE 0.
      IF gs_alv-spart IS INITIAL.
      ELSE.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 제품군이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "일반품목범주GR체크
    SELECT SINGLE mtpos
      INTO lv_mpos_mara
      FROM tptm
     WHERE mtpos = gs_alv-mtpos_mara.

    IF sy-subrc NE 0.
      IF gs_alv-mtpos_mara IS INITIAL.
      ELSE.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 일반품목범주 GR이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    MODIFY gt_alv FROM gs_alv.
    CLEAR  gs_alv.

  ENDLOOP.
ENDFORM.

 

점검 테이블 확인하는 방법

 

 

트랜잭션 레코딩

▪ Batch Input을 수행하기 위해서는 Batch Input 프로그램이 있어야 한다.

▪ 이 프로그램을 만들려면 전송한 데이터가 어떤 Transaction 을 수행해야 하는지 결정하는 Recording 작업이 선행되어야 한다.

▪ 레코딩 작업의 주목적은 BDC 프로그램 작성을 위한 것이라고 볼 수 있다.

▪ 용도

   - Batch Input 또는 Call Transaction 을 실행하는 데이터 프로그램 생성

   - Batch Input 세션 생성

   - 테스트 데이터 생성

   - Function Module 생성

▪ 특징

   - F1, F4(PROCESS ON HELP-REQUEST, PROCESS ON VALUE-REQUEST)는 레코딩되지 않는다.

   - 에러나 WARNING 은 레코딩 되지 않는다. 이는 현 화면에서 성공적으로 다음 프로세스 진행 할 수 있도록

     하기 위해서다.

 

1. T-code : SHDB

New recording 클릭한 후 레코딩명과 트랜잭션 코드 입력 -> Start recording

 

  • 뷰 선택에서 스크롤을 내린 후에 선택하면 다른 뷰가 선택되어 레코딩 될 수 있다.  
  • 화면에 나오지 않는 스크롤 밑의 뷰를 선택하고 싶을 때에는 키보드의 페이지 다운 버튼을 누른 후 선택한다.

 

  •  레코딩에 필요한 필수 항목들을 입력한다.
  • 레코딩할 때에는 불필요한 작업을 전부 생략하고, 가장 기본적인 행위로만 입력한다.
  • 실제 레코딩을 저장하기 전에 레코딩 과정을 연습해두면 좋다.

 

  • 레코딩에 관계없는 BDC_SUBSCR과 BDC_CURSOR 항목을 제거해 준다.
  • 삭제 후 저장, 저장 후 프로세스 버튼 클릭
  • 프로세스 버튼을 누르면 레코딩이 어떤 순서로 실행되고 성공적으로 수행되는지 확인할 수 있다.

 

  • 레코딩 성공시 하단에 나오는 메시지 타입(S), 메시지 아이디(M3), 메시지 번호(800)를 기억해 둔다.
  • 메시지 확인 SE91 에서 확인 가능하다.

 

 

BDC 실행

스크린100에 BDC 아이콘을 생성하고, BDC 실행 폼문 작성

*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.

  CASE gv_okcode.
    WHEN 'REFRESH'.
      PERFORM refresh_grid.

    WHEN 'BDC'.
      " icon이 Yellow인 것만 퍼폼문을 타게 만들었음.
      READ TABLE gt_alv INTO gs_alv WITH KEY icon = icon_led_yellow.

      IF sy-subrc = 0.
        PERFORM push_bdc.
      ELSE.
        MESSAGE s000 WITH '생성할 자재가 없습니다.' DISPLAY LIKE 'E'.
      ENDIF.

    WHEN 'BAPI'.
      PERFORM push_bapi.
  ENDCASE.

ENDMODULE.
*&---------------------------------------------------------------------*
*& Form push_bdc
*&---------------------------------------------------------------------*
FORM push_bdc .
  PERFORM confirm_popup USING '자재생성 BDC'
                            '자재생성 BDC 실행하시겠습니까?'
                            space
                            space
                      CHANGING gv_answer.

  IF gv_answer = 1.
    PERFORM bdc_process.
  ELSE.
    MESSAGE s000 WITH '취소되었습니다.'.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form confirm_popup
*&---------------------------------------------------------------------*
FORM confirm_popup  USING    p_title p_text p_canc p_type
                    CHANGING p_answer.
  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      titlebar              = p_title
      text_question         = p_text
      text_button_1         = '예'
      icon_button_1         = 'ICON_CHECKED'
      text_button_2         = '아니오'
      icon_button_2         = 'ICON_INCOMPLETE'
      default_button        = '2'
      display_cancel_button = p_canc
      start_column          = 25
      start_row             = 6
      popup_type            = p_type
    IMPORTING
      answer                = p_answer
    EXCEPTIONS
      text_not_found        = 1
      OTHERS                = 2.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form bdc_process
*&---------------------------------------------------------------------*
FORM bdc_process .
  "데이터 검증에서 성공한 노란색 신호등만 BDC를 실행한다.
  "BDC의 절차를 단계별로 알아보기 위해서 서브루틴을 세분화 하였다.
  CLEAR: ctu_params.
  ctu_params-dismode = p_mode.
  ctu_params-updmode = 'L'.

  LOOP AT gt_data INTO gs_data WHERE icon = icon_led_yellow.

    PERFORM bdc_mapping.
    PERFORM bdc_execute.
    PERFORM bdc_result.

    MODIFY gt_data FROM gs_data.
    CLEAR gs_data.

    PERFORM refresh_grid.
  ENDLOOP.

  IF sy-subrc NE 0.
    MESSAGE s000 WITH 'BDC를 수행할 행이 하나도 없습니다.'.
  ENDIF.
ENDFORM.

 

PERFORM bdc_mapping. 에서 SHDB에서 작업한 레코드를 바탕으로 입력하고자 하는 변수를 넣어 작성한다.

*&---------------------------------------------------------------------*
*& Form bdc_mapping
*&---------------------------------------------------------------------*
FORM bdc_mapping .
  "T-Code : SHDB에서 작업한 레코드를 바탕으로 입력하고자 하는 변수를 넣어 작성한다.
  CLEAR: gt_bdc, gs_bdc.
  PERFORM bdc_append_data USING:
        'X' 'SAPLMGMM'    '0060',
        ' ' 'BDC_OKCODE'  '=AUSW',
        ' ' 'RMMG1-MATNR' gs_alv-matnr,
        ' ' 'RMMG1-MBRSH' gs_alv-mbrsh,
        ' ' 'RMMG1-MTART' gs_alv-mtart.

  PERFORM bdc_append_data USING:
        'X' 'SAPLMGMM'           '0070',
        ' ' 'BDC_OKCODE'         '=ENTR',
        ' ' 'MSICHTAUSW-KZSEL(01)' 'X',
        ' ' 'MSICHTAUSW-KZSEL(02)' 'X'.

  PERFORM bdc_append_data USING:
        'X' 'SAPLMGMM'   '4004',
        ' ' 'BDC_OKCODE' '/00',
        ' ' 'MAKT-MAKTX' gs_alv-maktx,
        ' ' 'MARA-MEINS' gs_alv-meins,
        ' ' 'MARA-MATKL' gs_alv-matkl,
        ' ' 'MARA-SPART' gs_alv-spart,
        ' ' 'MARA-MTPOS_MARA' gs_alv-mtpos_mara.

  PERFORM bdc_append_data USING:
        'X' 'SAPLMGMM'   '4004',
        ' ' 'BDC_OKCODE' '/00',
        ' ' 'MAKT-MAKTX' gs_alv-maktx.

  PERFORM bdc_append_data USING:
        'X' 'SAPLSPO1'   '0300',
        ' ' 'BDC_OKCODE' '=YES'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bdc_append_data
*&---------------------------------------------------------------------*
FORM bdc_append_data  USING   p_dynbegin
                              p_name
                              p_value.
  CLEAR: gs_bdc.
  IF p_dynbegin = 'X'.
    gs_bdc-program  = p_name.
    gs_bdc-dynpro   = p_value.
    gs_bdc-dynbegin = p_dynbegin.
  ELSE.
    gs_bdc-fnam  = p_name.
    gs_bdc-fval  = p_value.
  ENDIF.
  APPEND gs_bdc TO gt_bdc.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bdc_execute
*&---------------------------------------------------------------------*
FORM bdc_execute .
  CLEAR: gs_msg, gt_msg.

  CALL TRANSACTION 'MM01' USING gt_bdc
                          OPTIONS FROM ctu_params
                          MESSAGES INTO gt_msg.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bdc_result
*&---------------------------------------------------------------------*
FORM bdc_result .
  "BDC 결과를 gt_alv-message에 표시한다.
  "에러 메시지가 여러 개일 경우 전부 표시하도록 하였다.
  "성공하였을 때 메시지인 메시지 타입 S, 메시지 아이디 M3, 메시지 번호 800은
  "자재 생성 성공시 하단에 성공 메시지가 나올 경우 더블 클릭하면 확인 가능하다.
  DATA: l_outtext TYPE char100.
  READ TABLE gt_msg INTO gs_msg WITH KEY msgtyp = 'S'
                                         msgid  = 'M3'
                                         msgnr  = '800'.
  IF sy-subrc EQ 0.
    gs_alv-icon = icon_led_green.
    CALL FUNCTION 'MESSAGE_TEXT_BUILD'
      EXPORTING
        msgid               = gs_msg-msgid
        msgnr               = gs_msg-msgnr
        msgv1               = gs_msg-msgv1
        msgv2               = gs_msg-msgv2
        msgv3               = gs_msg-msgv3
        msgv4               = gs_msg-msgv4
      IMPORTING
        message_text_output = gs_alv-message.

  ELSE.
    gs_alv-icon = icon_led_red.
    LOOP AT gt_msg INTO gs_msg.
      gs_alv-message = 'BDC실패'.
      CALL FUNCTION 'MESSAGE_TEXT_BUILD'
        EXPORTING
          msgid               = gs_msg-msgid
          msgnr               = gs_msg-msgnr
          msgv1               = gs_msg-msgv1
          msgv2               = gs_msg-msgv2
          msgv3               = gs_msg-msgv3
          msgv4               = gs_msg-msgv4
        IMPORTING
          message_text_output = l_outtext.
      CONCATENATE gs_alv-message '/' l_outtext INTO gs_alv-message.
      CLEAR gs_msg.
    ENDLOOP.
  ENDIF.
ENDFORM.

 

실습 확인을 위해 다운 받은 엑셀 양식에 연습용 데이터를 작성한 후에 업로드 해보면 됨.

더보기
실습하기 위해 만든 엑셀 양식에 데이터를 넣어보았다.

 

엑셀파일을 가져와 업로드하면 BDC를 통해 새로운 자재를 생성할 수 있는 것만 노란불이 들어온다.

엑셀 업로드는 하면 BDC가 실행되기 전에 각 필드별로 체크를 하게 된다.
이에 따라 항목이 부적절할 경우 빨간색 아이콘, 적절할 경우에는 노란색 아이콘이 뜬다.

 

'자재 생성 BDC 실행' 버튼을 누르면 확인 창이 뜨고 '예' 선택시 BDC 실행이 가능한 노란불의 자재만 BDC 실행이 성공되어 초록불로 바뀌었다.

 

셀렉션 스크린에서 조회 모드로 들어갔을 때 해당 자재가 있는 것을 확인되었다.

 

MM03에서도 확인 가능.

 

 


 

 

실습2) BAPI를 통한 자재 변경

하나의 프로그램에 BDC, BAPI 연습하기 위해 라디오버튼을 하나 더 만들어서 실습함.

 

TOP에 BAPI를 사용하기 위해 필요한 데이터 선언.

*-------------------------------------------------------
" BAPI_MATERIAL_SAVEDATA
*-------------------------------------------------------
DATA: gs_headdata            LIKE bapimathead, " 헤더 데이터
      gs_clientdata          LIKE bapi_mara,   " 변경할 데이터
      gs_clientdatax         LIKE bapi_marax,  "변경할 데이터 체크
      gt_materialdescription LIKE TABLE OF bapi_makt,
      gs_materialdescription LIKE bapi_makt,
      gt_returnmessages      LIKE TABLE OF bapi_matreturn2,
      gs_returnmessages      LIKE bapi_matreturn2,
      gs_return              LIKE bapiret2.

 

BAPI수행이 가능한지 체크하는 퍼폼문 작성. ( PERFORM check_bapi_data. )

*&---------------------------------------------------------------------*
*&  START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  IF p_rad1 = 'X'.
    PERFORM get_data.
  ELSEIF p_rad2 = 'X'.
    PERFORM excel_upload.
    PERFORM check_bdc_data.   "BDC수행 가능한지 체크
  ELSE.
    PERFORM excel_upload.
    PERFORM check_bapi_data.  "BAPI수행 가능한지 체크
  ENDIF.

  CALL SCREEN '0100'.
*&---------------------------------------------------------------------*
*& Form check_bapi_data
*&---------------------------------------------------------------------*
FORM check_bapi_data .
  DATA: lv_matnr TYPE mara-matnr, "자재번호
        lv_maktx TYPE makt-maktx, "자재내역
        lv_meins TYPE mara-meins, "기본단위
        lv_matkl TYPE mara-matkl, "자재그룹
        lv_spart TYPE mara-spart, "제품군
        lv_prdha TYPE mara-prdha. "일반제품구조

  IF gt_alv IS INITIAL.
    MESSAGE s000 WITH '데이터가 없습니다.' DISPLAY LIKE 'E'.
  ENDIF.

  LOOP AT gt_alv INTO gs_alv.

    "자재번호 체크
    IF gs_alv-matnr IS INITIAL.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '자재번호는 필수사항입니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    SELECT SINGLE matnr
      INTO lv_matnr
      FROM mara
     WHERE matnr = gs_alv-matnr.

    IF sy-subrc NE 0.
      gs_alv-icon = icon_led_red.
      CONCATENATE gs_alv-message '해당 자재번호가 존재하지 않습니다.'
      INTO gs_alv-message SEPARATED BY space.
    ENDIF.

    "기본단위체크
    IF gs_alv-meins IS NOT INITIAL.
      SELECT SINGLE msehi
      INTO lv_meins
      FROM t006
     WHERE msehi = gs_alv-meins.

      IF sy-subrc NE 0.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 기본단위가 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "자재그룹체크
    IF gs_alv-matkl IS NOT INITIAL.
      SELECT SINGLE matkl
      INTO lv_matkl
      FROM t023
     WHERE matkl = gs_alv-matkl.

      IF sy-subrc NE 0.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 자재그룹이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "제품군체크
    IF gs_alv-spart IS NOT INITIAL.
      SELECT SINGLE spart
      INTO lv_spart
      FROM tspa
     WHERE spart = gs_alv-spart.

      IF sy-subrc NE 0.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 제품군이 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    "일반제품구조 체크
    IF gs_alv-prdha IS NOT INITIAL.
      SELECT SINGLE prodh
      INTO lv_prdha
      FROM t179
     WHERE prodh = gs_alv-prdha.

      IF sy-subrc NE 0.
        gs_alv-icon = icon_led_red.
        CONCATENATE gs_alv-message '해당하는 일반제품구조가 존재하지 않습니다.'
        INTO gs_alv-message SEPARATED BY space.
      ENDIF.
    ENDIF.

    MODIFY gt_alv FROM gs_alv.
    CLEAR  gs_alv.
  ENDLOOP.
ENDFORM.

 

 

'자재 변경 BAPI실행' 버튼 생성

*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.

  CASE gv_okcode.
    WHEN 'REFRESH'.
      PERFORM refresh_grid.
    WHEN 'BDC'.
      IF gs_alv-icon = icon_led_yellow.
        PERFORM push_bdc.
      ELSE.
        MESSAGE s000 WITH '생성할 자재가 없습니다.' DISPLAY LIKE 'E'.
    WHEN 'BAPI'.
      PERFORM push_bapi.
  ENDCASE.

ENDMODULE.
*&---------------------------------------------------------------------*
*& Form push_bapi
*&---------------------------------------------------------------------*
FORM push_bapi .
  PERFORM confirm_popup USING '자재 변경'
                              '자재 변경 BAPI를 실행하시겠습니까?'
                              space
                              space
                        CHANGING gv_answer.
  IF gv_answer = 1.
    PERFORM bapi_process.
  ELSE.
    MESSAGE s000 WITH '취소되었습니다.'.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bapi_process
*&---------------------------------------------------------------------*
FORM bapi_process .
  LOOP AT gt_alv INTO gs_alv WHERE icon = icon_led_yellow.
    CLEAR: gs_headdata, gs_clientdata, gs_clientdatax,
           gt_materialdescription, gs_materialdescription,
           gt_returnmessages, gs_returnmessages, gs_return.

    "gs_headdata 는 프로그램의 메인 키값 역할을 한다.
    "따라서 matnr, mbrsh, mtart 3가지는 변경되지 않는 값이다.
    gs_headdata-material   = gs_alv-matnr.
    gs_headdata-ind_sector = gs_alv-mbrsh.
    gs_headdata-matl_type  = gs_alv-mtart.

    "gs_clientdata 는 gs_clientdatax에서 값을( ‘X’ ) 넣음으로써
    "변경이 가능하게 할 수 있는 필드를 나타낸다.
    gs_clientdata-matl_group = gs_alv-matkl.
    gs_clientdata-base_uom   = gs_alv-meins.
    gs_clientdata-division   = gs_alv-spart.
    gs_clientdata-prod_hier  = gs_alv-prdha.

    gs_clientdatax-matl_group = 'X'.
    gs_clientdatax-base_uom   = 'X'.
    gs_clientdatax-division   = 'X'.
    gs_clientdatax-prod_hier  = 'X'.

    gs_materialdescription-matl_desc = gs_alv-maktx.
    gs_materialdescription-langu     = sy-langu.
    " 하드코딩으로 처음에 3을 줬는데 3은 한글이라 조회했을 때 안바뀌었음...
    " 그래서 시스템변수로 바꿨더니 잘 변경되고 잘 조회 됨.
    APPEND gs_materialdescription TO gt_materialdescription.

    CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
      EXPORTING
        headdata            = gs_headdata
        clientdata          = gs_clientdata
        clientdatax         = gs_clientdatax
      IMPORTING
        return              = gs_return
      TABLES
        materialdescription = gt_materialdescription
        returnmessages      = gt_returnmessages.

    IF gs_return IS INITIAL.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

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

      READ TABLE gt_returnmessages INTO gs_returnmessages WITH KEY id = 'M3'.
      gs_alv-message = gs_returnmessages-message.

      "입력한 데이터를 바탕으로 BAPI_MATERIAL_SAVEDATA를 실행하고,
      "실행결과를 gs_returnmessages에 넣어주었다.
      " gs_returnmessages의 id, type, number 값으로 성공, 실패 여부를 확인할 수 있다.
      IF gs_returnmessages-type = 'S'.
        IF gs_returnmessages-number = '810'. "변경사항이 없으면..
*        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          gs_alv-icon = icon_led_yellow.
        ELSE.
*        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
*          EXPORTING
*            wait = 'X'.
          gs_alv-icon = icon_led_green.
        ENDIF.

      ELSE.
        gs_alv-icon = icon_led_red.

      ENDIF.

      MODIFY gt_alv FROM gs_alv.
      CLEAR  gs_alv.

    ENDIF.

  ENDLOOP.
  PERFORM refresh_grid.

  IF sy-subrc NE 0.
    MESSAGE s000 WITH '변경할 라인이 존재하지 않습니다.'.
  ENDIF.
ENDFORM.

 

 

 

READ TABLE gt_returnmessages INTO gs_returnmessages WITH KEY id 'M3'.