최초 작성일: 2024-09-22
최종 작성일: 2024-09-22
목표: 엑셀업로드프로그램 이해하기
i_callback_pf_status_set = 'PF_STATUS_SET'
i_callback_user_command = 'USER_COMMAND'
i_callback_pf_status_set = 'PF_STATUS_SET' =>> perform pf_status_set 연결 =>PBO (PROCESS BEFORE OUTPUT -=> 버튼, 툴바 => 출력전에 실행 ==>>resue_alv grid siplay 펑션을 타서 출력하기전에 실행한다.
i_callback_user_command = 'USER_COMMAND' =>> Perform usser_command 연결 =>PAI -> Process after input => 버튼을 눌렀을 때 실행된다. 버튼 눌렀을때 실행한다
FORM pf_status_set USING extab TYPE slis_t_extab.
SET PF-STATUS 'STANDARD'.
ENDFORM.
-> 툴바를 만들어 줘야 실행이 가능함
FORM user_command USING p_ucomm TYPE sy-ucomm
p_selfield TYPE slis_selfield.
DATA : p_confirm TYPE c.
DATA : p_button TYPE c.
CASE p_ucomm.
WHEN '&EDIT'.
PERFORM fieldcat_edit CHANGING it_fieldcat.
IF togl = ''.
togl = 'X'.
ELSE.
CLEAR togl.
ENDIF.
PERFORM alv_grid.
WHEN '&BA'.
LEAVE PROGRAM.
WHEN '&DATA_SAVE'.
IF togl = 'X'.
p_button = 'S'.
IF it_zscarrcp[] NE it_zscarr[].
PERFORM popup_confirm USING p_button CHANGING p_confirm.
IF p_confirm = '1'.
PERFORM f_save_data.
PERFORM get_data.
p_selfield-refresh = 'X'.
p_selfield-row_stable = 'X'.
p_selfield-col_stable = 'X'.
ELSE.
LEAVE SCREEN.
ENDIF.
ELSE.
MESSAGE '변경할 데이터가 없습니다.' TYPE 'I'.
ENDIF.
ELSE.
MESSAGE '조회모드입니다.' TYPE 'I'.
ENDIF.
WHEN '&DEL'.
READ TABLE it_zscarr WITH KEY box = 'X'.
IF sy-subrc = '0'.
p_button = 'D'.
* READ TABLE it_zscarr INTO wa_zscarr INDEX p_selfield-tabindex.
PERFORM popup_confirm USING p_button CHANGING p_confirm.
IF p_confirm = '1'.
PERFORM f_delete_data.
PERFORM get_data.
p_selfield-refresh = 'X'.
p_selfield-row_stable = 'X'.
p_selfield-col_stable = 'X'.
ELSE.
LEAVE SCREEN.
ENDIF.
ELSE.
MESSAGE '삭제할 데이터가 없습니다.' TYPE 'I'.
ENDIF.
ENDCASE.
ENDFORM.
TYPES: BEGIN OF t_zscarr.
INCLUDE TYPE zscarr.
TYPES: box.
TYPES: END OF t_zscarr.
FORM build_layout .
ls_layout-zebra = 'X'.
ls_layout-no_input = 'X'.
ls_layout-box_fieldname = 'box'.
ENDFORM.
->삭제할때
행을 선택했을때 그 행에 box 필드에 x 값을 넣어주는 기능히다
선택한 행을 삭제해야한다면 box에 x가 들어간 것만 읽어서 삭제한다
DATA: it_zscarrcp TYPE TABLE OF t_zscarr WITH HEADER LINE, =>> 변경되기 전에 데이터를 비교하려고 복사할것
it_changes TYPE TABLE OF t_zscarr WITH HEADER LINE, =>> 변경한 것만 저장해서 몇건인지 세서 메시지 출력
it_deletes TYPE TABLE OF t_zscarr WITH HEADER LINE. =>> 삭제한것만 저장해서 몇건 삭제했는지 세서 메시지 출력
DATA: togl TYPE c. ==>> 편집 모드와 조회 모드를 구분하는 역할 ( 편집 모드일떄는 x를 선택, 조회모드일때는 빈값으로 둠)
start-of-selection
조회화면이 없을 때는 실행하면 바로 탄다/ 굳이 선언하지 않아도 탄다
FORM get_data .
SELECT * FROM zscarr INTO TABLE it_zscarr.
it_zscarrcp[] = it_zscarr[].
ENDFORM.
->[]은 테이블을 의미함
lv_index = lv_index + 1. =>> col pos를 자동으로 증가하게 하려고
wa_fieldcat-fieldname = 'CARRNAME'. ==>> 필드이름
wa_fieldcat-seltext_m = 'CARRNAME'. =>> 컬럼 제목
wa_fieldcat-col_pos = lv_index. =>>컬럼순서
wa_fieldcat-outputlen = 20. =>>넓이 _colwidth_optimize가 없으면 보여지는 넓이, 있으면 편집기능이 있을때 들어가는 자리수=>>타입의 자리수를 넣는다.
* wa_fieldcat-key = 'X'. =>> 키 필드 표시 하늘색으로 변경
wa_fieldcat-just = 'L'. =>> 정렬 왼쪽 오른쪽 중앙 L R C
*wa_fieldcat-edit = 'X'. =>> 편집 모드를 바꾸는 거고 나중에 버튼을 누르면 이거를 적용할거다
wa_fieldcat-lowercase ='X'. =>> 편집 모드할때 소문자가 대문자로 자동으로 바뀌어 버린다. 소문자로 유지하려고 해당 옵션 선택함
FORM user_command USING p_ucomm TYPE sy-ucomm
p_selfield TYPE slis_selfield.
DATA : p_confirm TYPE c.
DATA : p_button TYPE c.
Structure RS_SELFIELD contains the following information:
- tabname : Name of the internal output table
- tabindex : Index of the internal output table
- fieldname: Field name
- endsum : Cursor is located on the totals line
- sumindex : If >0, the cursor is located on a subtotals line
- value : Value of the field on the list
- refresh : (Exporting) List should be set up again
- col_stable:(Exporting) Keep column position when list is set up again
- row_stable:(Exporting) Keep row position when list is set up again
- exit :(Exporting) Exit list (and ALV)
- before_action: Call before standard action execution
- after_action : Call after standard action execution, before list setup
- ignore_multi : Internal use
- sel_tab_field: Internal use
FORM fieldcat_edit CHANGING p_it_fieldcat TYPE slis_t_fieldcat_alv.
LOOP AT p_it_fieldcat INTO wa_fieldcat.
CASE wa_fieldcat-fieldname.
WHEN 'CARRNAME' OR 'CURRCODE' OR 'URL'. -> 키 값이 아닐때
IF togl = ''. -> 토클이 비워있다면(조회모드 라면)
wa_fieldcat-edit = 'X'. -> edit를 켜줘
ELSE.
wa_fieldcat-edit = ''. -> 조회모드로 변경
ENDIF.
WHEN OTHERS.
wa_fieldcat-edit = ''.
ENDCASE.
MODIFY it_fieldcat FROM wa_fieldcat. ->it_fieldcat을 수정할 것
ENDLOOP.
ENDFORM.
edit 필드를 모두 비워주면 조회 모드가 된것
alv_grid는 뒤로가기 할때 그 전의 값을 모두 누적시킴 (캔슬 값을 한번 실행해보면 무슨 말인지 알 수 있음)
->
WHEN '&BA'.
LEAVE PROGRAM.
-> leave program으로 해야 누적된 화면 이슈를 해결할 수 있음
WHEN '&DATA_SAVE'.
IF togl = 'X'. -> 편집 모드일때만 저장하겠다
p_button = 'S'. -> 팝업을 띄울때 저장,삭제 관련한 질문과 버튼 텍스트를 바꿔주기 위해서 하는 것
IF it_zscarrcp[] NE it_zscarr[]. -> 변경 되기 전과 후를 비교해서 다르면 저장하겠다.
PERFORM popup_confirm USING p_button CHANGING p_confirm. -> 확인하는 팝업을 띄워준다
IF p_confirm = '1'. -> 저장버튼을 눌렀다면?
PERFORM f_save_data. -> 저장해줘라
PERFORM get_data. -> 저장후에 데이터를 다시 불러와야함 (변경이 되었으니 기준정보를 바꿔주는 부분이다)
p_selfield-refresh = 'X'. -> 다시 alv를 출력하지 않아도 바뀐대로 새로고침해주는 기능
p_selfield-row_stable = 'X'. ->새로 고침 하기 전에 행의 위치 그대로 출력
p_selfield-col_stable = 'X'. ->새로 고침 하기 전에 열의 위치 그대로 출력
ELSE. -> 취소버튼을 눌렀다면?
LEAVE SCREEN. -> 원래 화면으로 돌아가라
ENDIF.
ELSE. -> 전과 후가 같으면
MESSAGE '변경할 데이터가 없습니다.' TYPE 'I'. ->변경할게 없다고 메시지 출력
ENDIF.
ELSE. -> 조회모드(편집모드가 아닐때) 라면
MESSAGE '조회모드입니다.' TYPE 'I'. -> 메시지 출력
ENDIF.
PERFORM popup_confirm USING p_button CHANGING p_confirm.
FORM popup_confirm USING p_button CHANGING p_confirm. "POPUP 함수
DATA: text_q TYPE string,
text_b1 TYPE string.
IF p_button = 'S'.
text_q = '변경된 데이터가 있습니다.저장하시겠습니까?'.
text_b1 = '저장'.
ELSEIF p_button = 'D'.
text_q = '정말 삭제하시겠습니까?'.
text_b1 = '삭제'.
ENDIF.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = 'POPUP' -> 팝업의 타이틀 부분 텍스트
text_question = text_q -> 팝업의 질문
text_button_1 = text_b1 -> 첫번째 버튼 텍스트
icon_button_1 = 'ICON_CHECKED' -> 첫번째 버튼 아이콘
text_button_2 = '취소' -> 두번째 버튼 텍스트
icon_button_2 = 'ICON_INCOMPLETE' -> 두번째 버튼 아이콘
default_button = '1' -> 버튼마우스 오버를 해놓는 위치, 첫번째 버튼으로 하겠다. 저장 버튼, 삭제 버튼
display_cancel_button = space -> 1번과 2번 버튼 말고 취소버튼을 만들것이냐? space는 안만들것이다
IMPORTING
answer = p_confirm. "1:Continew / 2:Cancel ->1번째 버튼은 컨티뉴, 취소 버튼은취소
ENDFORM.
FORM f_save_data.
DATA: wa_zscarrcp TYPE t_zscarr, ->> 행 비교를 하기 위해서 복사한 테이블
wa_zscarr_tmp TYPE zscarr. ->>zscarr랑 똑같은 구조에 담아서 modify 하기위해서 선언
CLEAR it_changes[].
READ TABLE it_zscarr WITH KEY carrname = ''. -> carrname이 비워 있는 것을 긁고 오는 것 (carrname은 key 값이니까)
IF sy-subrc = '0'. -> 비워 있는 것이 있음
MESSAGE '입력하지 않은 값이 있습니다.' TYPE 'I'.
LEAVE SCREEN. -> 밑에 안타고 바로 빠져나옴 밑에 안타고 화면 빠져나옴 하나라도 에러가 있으면 무조건 빠져나와서 저장이 안되게 막는다.
ENDIF.
READ TABLE it_zscarr WITH KEY currcode = ''.
IF sy-subrc = '0'.
MESSAGE '입력하지 않은 값이 있습니다.' TYPE 'I'.
LEAVE SCREEN.
ENDIF.
READ TABLE it_zscarr WITH KEY url = ''.
IF sy-subrc = '0'.
MESSAGE '입력하지 않은 값이 있습니다.' TYPE 'I'.
LEAVE SCREEN.
ENDIF.
DATA : it_scurx TYPE TABLE OF scurx.
DATA : wa_scurx TYPE scurx. -> 행의 만들어줘
SELECT * FROM scurx INTO TABLE it_scurx. ->currcode의 체크테이블 scurx에 데이터가 있는가?
LOOP AT it_zscarr INTO wa_zscarr.
READ TABLE it_scurx INTO wa_scurx WITH KEY currkey = wa_zscarr-currcode.
IF sy-subrc <> 0. ==>> 체크테이블에 없으면 에러
MESSAGE 'CURRCODE에 들어있지 않은 값을 넣었습니다' TYPE 'I'.
LEAVE SCREEN.
ENDIF.
ENDLOOP.
LOOP AT it_zscarr INTO wa_zscarr. => 에러가 없다면 루프 돌리면서 저장해라
READ TABLE it_zscarrcp INTO wa_zscarrcp INDEX sy-tabix. => 변경 전에 데이터 그 한행과 변경 후 데이터 같은 행 비교하기 위해서같은 행번호로 불러온다 ( 루프를 돌리때는 한행씩 불러오고 내가 불러오는 행의 번호가 sy-tabix로 가져옴.)
IF wa_zscarrcp NE wa_zscarr. -> 변경 전의 행과 변경 후의 행이 같지 않은 경우에만 저장해라
MOVE-CORRESPONDING wa_zscarr TO wa_zscarr_tmp. -> insert와 동일함 db에다가 직접 modify하기 위해서는 테이블 구조와 똑같은 구조로 넣어야해서 그 구조로 옮겨주는작업
MODIFY zscarr FROM wa_zscarr_tmp. -> zscarr 테이블에 수정을 한다 where 조건을 넣어도 되지만, 이렇게만 해도 알아서 수정해준다(알아서 키 값 찾아서 수정해줌)
IF sy-subrc = 0. -> zscarr에 정상적으로 수정이 되었 다면
APPEND wa_zscarr TO it_changes. -> 그 수정한내용을 테이블에 담아라
ELSE. -> 에러가 나면
MESSAGE '테이블 저장 중 에러가 발생했습니다.' TYPE 'I'. -> 메시지 출력
LEAVE SCREEN. -> 화면 나가고
ENDIF.
ENDIF.
CLEAR wa_zscarrcp.
ENDLOOP.
DESCRIBE TABLE it_changes LINES DATA(lines). -> 타이블 바에 행의 갯수를 세주었을 때 사용한 구문임/ 변경된 테이블의 행의 갯수를 세준다
MESSAGE lines && '건의 데이터가 저장되었습니다.' TYPE 'S'. -> 몇건의 데이터가 저장되었다고 출력
ENDFORM.
f_data 후에 get_data를 하는 이유 -> 변경이 일어난 이후에
기준정보는 변경전의 데이터를 말하는 것(전역변수)
WHEN '&DEL'.
READ TABLE it_zscarr WITH KEY box = 'X'. -> 선택한게 있는지를 확인
IF sy-subrc = '0'. -> 선택한게 있다면
p_button = 'D'. -> 팝업 질문 선택 삭제 모드
* READ TABLE it_zscarr INTO wa_zscarr INDEX p_selfield-tabindex.
PERFORM popup_confirm USING p_button CHANGING p_confirm. -> 확인 팝업 띄운다
IF p_confirm = '1'. -> 삭제버튼 눌렀다면
PERFORM f_delete_data. -> 삭제해줘라
PERFORM get_data. -> 삭제가 되었기때문에 복사한 데이터 수정 ( 복사한 테이블 정보를다시 바꿔 주기 위해서 삭제한 상태로 다시 새로고침 해주기 위해서)
p_selfield-refresh = 'X'. -> 새로고침
p_selfield-row_stable = 'X'. -> 행 위치 그대로
p_selfield-col_stable = 'X'. -> 열 위치 그대로
ELSE. -> 취소 버튼을 눌렀다면
LEAVE SCREEN. -> 화면 나오고
ENDIF.
ELSE. -> 선택한게 없다면
MESSAGE '삭제할 데이터가 없습니다.' TYPE 'I'. -> 메세지 출력
ENDIF.
ENDCASE.
ENDFORM.
*box대신 add 1 to 변수를 써도괜춘/ 좀더 잘만드려면 삭제한 테이블을 보여주는 것도 좋음 -> 삭제한 테이블을 다시 출력해서 보여줄 수도 있기 때문에 이거를 테이블에 담아서 메시지도 출력하지만, 다시 보여주고 원상복구도 가능함
COMMIT WORK
ROLLBACK
'SAP > ABAP' 카테고리의 다른 글
/복습/[엑셀 업로드 프로그램 이해하기] 편집프로그램(툴바 복사) (2) | 2024.09.29 |
---|---|
SAP GUI 단축키 (0) | 2024.09.10 |
/WIP/[엑셀 업로드 프로그램 이해하기]PERFORM UPLOAD_FROM_EXCEL 디버깅(2/2) (0) | 2024.08.20 |
[엑셀 업로드 프로그램 이해하기]PERFORM UPLOAD_FROM_EXCEL 디버깅(1/2) (0) | 2024.08.18 |
[엑셀 업로드 프로그램 이해하기-3/N ]PBO,PAI (0) | 2024.08.18 |