본문 바로가기
ABAP

엑셀 업로드 + BDC

by clode 2023. 2. 16.
728x90
반응형

과제

엑셀을 인터널 테이블에 업로드 한 뒤 인터널테이블로 BDC를 돌려 DB를 변경한다. 자재 내역필드를 변경해본다.

사실 엑셀 업로드 로직과 BDC로직을 합친 뒤 두가지만 변경해주면 된다. 자세한건 프로그램 로직에서 덧붙이겠다.

[업로드할 엑셀파일]

한건만 아니면 되고 변경되는지 확인만 하면 되니까.... 두건만 했다.
강사님 : 🤦‍♀️

[프로그램 로직]


[TOP]

TYPES : gty_bdc TYPE bdcdata,
        gty_msg TYPE bdcmsgcoll.


DATA:     gt_bdc TYPE STANDARD TABLE OF gty_bdc,  "레코딩 담을 int
          gs_bdc LIKE  LINE OF gt_bdc, "레코딩 데이터 입력 위한 wa
          gt_msg TYPE STANDARD TABLE OF gty_msg, "처리결과 담을 int
          gs_msg LIKE  LINE OF gt_msg. "처리 결과 메세지 입력 위한 wa

DATA:     gs_opt TYPE ctu_params,"call transaction 옵션을 넣어줄 wa
          gv_move LIKE ctu_params-dismode VALUE 'N',     "display 메세지 옵션,메세지 옵션 주려고
          gv_message LIKE bapireturn-message.          "실질적으로 메세지 담기는 변수



TYPES truxs_t_text_data(4096) TYPE c OCCURS 0.

TYPES : BEGIN OF itab,
        matnr TYPE mara-matnr,
        maktx  TYPE makt-maktx,
        END OF itab.

DATA : gv_rc      TYPE i,
       gv_file    TYPE localfile,
       gt_file    TYPE filetable,
       gv_data    TYPE truxs_t_text_data,
       g_salv     TYPE REF TO cl_salv_table,      "salv용
       g_frontend TYPE REF TO cl_gui_frontend_services.     "업로드용 파일 선택창

DATA : gs_tab   TYPE mara,
       gt_tab   TYPE TABLE OF mara,
       gs_itab  TYPE itab,
       gt_itab  TYPE TABLE OF itab,
       gs_excel TYPE alsmex_tabline,      "엑셀 업로드 데이터 담을 work area
       gt_excel TYPE TABLE OF alsmex_tabline.     "엑셀 업로드 데이터 담을 인터널 테이블

CONSTANTS : c_filter TYPE string VALUE
            'EXCEL FILES (*.XLSX)|*.XLSX|EXCEL FILES (*.XLS)|*.XLS|'.

FIELD-SYMBOLS <fs>.

"화면 구성 
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-000.
PARAMETERS : p_file TYPE localfile.     "파일 선택
SELECTION-SCREEN END OF BLOCK b2.

SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE TEXT-001.
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS : p_alsm RADIOBUTTON GROUP rd1 DEFAULT 'X'.      "엑설형식 파일
SELECTION-SCREEN COMMENT 4(30) TEXT-c01.

PARAMETERS : p_text RADIOBUTTON GROUP rd1.      "텍스트형식 파일
SELECTION-SCREEN COMMENT 38(30) TEXT-c02.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK b3.

BDC프로그램에선 입력한 파라미터 값을 받아 BDC를 돌려 DB를 변경했지만 이번엔 엑셀 업로드 한뒤 인터널테이블에서 값을 받아서 변경하기 때문에 BDC 셀렉션 스크린 로직은 지워주었다.



[FORM]

FORM get_filepath .

  CLEAR : gv_rc, gt_file[].
  CALL METHOD g_frontend->file_open_dialog
    EXPORTING
      file_filter       = c_filter
      initial_directory = 'C:'
      default_filename  = space
    CHANGING
      file_table        = gt_file
      rc                = gv_rc
    EXCEPTIONS
      OTHERS            = 1.

  CLEAR p_file.
  READ TABLE gt_file INTO p_file INDEX 1.

ENDFORM.                    " GET_FILEPATH
*&---------------------------------------------------------------------*
*&      Form  CALL_FUNC1
*&---------------------------------------------------------------------*
FORM call_func1 .
  " 엑셀 업로드
  CLEAR gt_excel[].
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = p_file
      i_begin_col             = 1
      i_begin_row             = 2
      i_end_col               = 3
      i_end_row               = 10000
    TABLES
      intern                  = gt_excel[]
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.

  " 업로드된 엑셀을 LINE/COL 별로 MOVE
  IF gt_excel[] IS NOT INITIAL.
    CLEAR gt_itab[].
    LOOP AT gt_excel INTO gs_excel.
      UNASSIGN <fs>.
      ASSIGN COMPONENT gs_excel-col OF STRUCTURE gs_itab TO <fs>.

      IF <fs> IS ASSIGNED.
        <fs> = gs_excel-value.
      ENDIF.

      AT END OF row.
        APPEND gs_itab TO gt_itab.
        CLEAR gs_itab.
      ENDAT.
    ENDLOOP.
  ENDIF.

ENDFORM.                    " CALL_FUNC1
*&---------------------------------------------------------------------*
*&      Form  CALL_FUNC2
*&---------------------------------------------------------------------*
*       TEXT_CONVERT_XLS_TO_SAP
*----------------------------------------------------------------------*
FORM call_func2 .
  CLEAR gt_itab[].
  CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
    EXPORTING
      i_line_header        = 'X'         " 첫라인 삭제
      i_tab_raw_data       = gv_data
      i_filename           = p_file
    TABLES
      i_tab_converted_data = gt_itab[]
    EXCEPTIONS
      conversion_failed    = 1
      OTHERS               = 2.


ENDFORM.                    " CALL_FUNC2


FORM bdc_run .
  DATA: lv_index TYPE sy-index.  "카운트를 위한 변수, 레코드가 몇건인지 확인할수 있는 변수
  CLEAR: gs_bdc, gt_bdc, gs_opt, gt_msg, gs_msg.      "찌거기 데이터를 제거하기 위해 데이터 오브젝트 클리어

*옵션 설정
  gs_opt-dismode = 'E'.     "E 에러가 발생할 때 화면 표시, A는 전체
  gs_opt-updmode = 'A'.     "비동기
  gs_opt-defsize = 'X'.      "기본 윈도우

*bdc 프로세스 시작
PERFORM bdc_data USING:  'X' 'SAPLMGMM' '0060' , "시작, 프로그램명, 화면번호
                        '' 'BDC_OKCODE' '=ENTR' ,
                          '' 'RMMG1-MATNR' gs_itab-matnr ,    
                          'X' 'SAPLMGMM' '0070' ,
                          '' 'BDC_OKCODE' '=ENTR' ,
                          '' 'MSICHTAUSW-KZSEL(01)' 'X',
                          'X' 'SAPLMGMM' '4004' ,
                          '' 'BDC_OKCODE' '=BU' ,
                          '' 'BDC_SUBSCR' 'SAPLMGMM',
                          '' 'BDC_SUBSCR' 'SAPLMGD1 ',
                          '' 'BDC_CURSOR' 'MAKT-MAKTX',
                          '' 'MAKT-MAKTX' gs_itab-maktx, 
                          '' 'BDC_SUBSCR' 'SAPLMGD1',
                          '' 'MARA-MEINS' 'EA',
                          '' 'MARA-MATKL' 'P010',
                          '' 'MARA-SPART' '10'.


"트랜잭션 호출
  CALL TRANSACTION 'MM02'
          USING gt_bdc "BDC레코딩 데이터
          OPTIONS FROM gs_opt "옵션
          MESSAGES INTO gt_msg. "처리결과 메세지

* 메세지INT 마지막 라인 읽기
  CLEAR: lv_index.
  DESCRIBE TABLE gt_msg LINES lv_index. "INT 라인수
  READ TABLE gt_msg INTO gs_msg INDEX lv_index. "마지막 라인의 값 읽기

  CHECK sy-subrc = 0.
*  메세지 생성 펑션
        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       = gv_message  . "처리결과 메세지
                         .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form BDC_DATA
*&-----------------------------------------------
FORM bdc_data  USING pv_check pv_name pv_value. "using : perform using 상수값 메모리 같이씀

  CLEAR: gs_bdc.      "work area 클리어
  IF pv_check EQ 'X'.     "bdc 시작 체크
    gs_bdc-program = pv_name.     "프로그램 명
    gs_bdc-dynpro = pv_value.     "화면 번호
    gs_bdc-dynbegin = pv_check.     "시작
  ELSE.
    gs_bdc-fnam = pv_name.     "입력 필드 이름
    gs_bdc-fval = pv_value.     "입력 값
  ENDIF.

  APPEND gs_bdc TO gt_bdc.      "bdc 인터널 테이블 append

ENDFORM.

BDC프로세스가 시작하는 PERFORM bdc_data에서 파라미터값을 받아왔던 p_matnr과 p_maktx를 gs_itab의 matnr과 maktx로 변경해준다. 이게 변경할 첫번째 내용이다.😃



[프로그램]


INCLUDE zs1d11_027_top.
INCLUDE zs1d11_027_f01.


INITIALIZATION.
  CREATE OBJECT g_frontend.   " OBJECT 생성

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  PERFORM get_filepath.   " 파일 경로 조회

START-OF-SELECTION.
  CHECK p_file IS NOT INITIAL.
  IF p_alsm = 'X'.
    PERFORM call_func1.
  ELSE.
    PERFORM call_func2.
  ENDIF.

 END-OF-SELECTION.
  CHECK gt_itab[] IS NOT INITIAL.

  LOOP AT gt_itab INTO gs_itab.
     PERFORM bdc_run. 
  ENDLOOP.

INCLUDE문은 제일 위에 있어야 하고 그중에서도 데이터선언부인 TOP이 제일 위에 있어야한다. 프로그램은 위에서부터 차례대로 읽기때문에 FORM이 더 위에 있으면 자꾸 변수들이 알수 없다고 오류가 난다.

엑셀 데이터는 한건이 아닌 여러건이기 때문에 BDC를 여러번 돌것이다. 그래서 BDC 로직을 수행하는 FORM인 BDC_RUC에 LOOP를 돌려준다. 이게 두번째 변경사항이다!

처음엔 어떻게 해야될지 막막해서 일단 두개를 합치고 로직을 보기 쉽게 정리부터 했다. 그러고 처음부터 차근차근 생각하니 엑셀을 먼저 업로드해서 인터널테이블에 잘 들어갔는지 디버깅으로 확인해보고 BDC할때 받아야될값을 생각해보니 인터널테이블이어서 파라미터 대신 인터널테이블을 참조하는 WA를 사용했다. 그리고 여러줄이라 LOOP를 돌려줬다. 하고나서 보니 별거 아닌거같지만 고뇌의 연속이었다. 🤦‍♂️💻

[실행 화면]

탐색도움말을 눌러 바탕화면에 있는 엑셀파일을 불러온다. 실행 후 저장하면

엑셀파일의 마지막 항목인 자재번호가 나오면서 성공했다는 메세지가 뜬다. DB가서 변경됐는지 확인해보자. 두근두근

자재내역인 MAKTX 필드가 있는 MAKT 테이블에서 확인한다.

변경됐다. 하하하

다른자재도 변경이 됐다. 🎃

728x90
반응형

'ABAP' 카테고리의 다른 글

ALV 2 (이벤트)  (0) 2023.02.16
ALV  (0) 2023.02.16
엑셀 업로드  (2) 2023.02.16
BDC 프로그램  (0) 2023.02.16
Field-symbols 2  (0) 2023.02.16

댓글