본문 바로가기

SAP/ABAP

/WIP/[엑셀 업로드 프로그램 이해하기] 편집프로그

최초 작성일: 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.

 

 

TYPESBEGIN OF t_zscarr.
         INCLUDE TYPE zscarr.
         TYPES: box.
TYPESEND 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가 들어간 것만 읽어서 삭제한다

 

 

 

DATAit_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.    =>> 삭제한것만 저장해서 몇건 삭제했는지 세서 메시지 출력
DATAtogl 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 함수
  DATAtext_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.
  DATAwa_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