과제
엑셀을 인터널 테이블에 업로드 한 뒤 인터널테이블로 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 테이블에서 확인한다.
변경됐다. 하하하
다른자재도 변경이 됐다. 🎃
'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 |
댓글