본문 바로가기

SAP&ABAP/ABAP

(작업중)EASY ABAP - 11. Report Program (With ALV)

728x90

Report Program?

- 데이터베이스에서 원하는 데이터를 추출하여 원하는 형태로 가공하여 리포트 형식으로 조회하는 프로그램

- Type-1 Program이나 Executable Program이라고 한다.

- 아래 그림의 흐름대로 프로그램이 처리된다.

Executable Program (Report Program) Flow

Report Program의 흐름

1. runtime environment가 INITIALIZATION 이벤트를 생성하고 이에 대응하면 이벤트 블럭(소스코드에서 INITIALIZATION  구문 영역)을 호출한다. 보통 선언된 변수들을 날짜에 맞게 초기화하는 등의 작업을 한다.

2. selection screen이 정의되어 있다면  control(SAP GUI)은 selection screen processor를 반환한다. 이 processor는 이에 대응하는 이벤트 블럭인 AT-SELECTION SCREEN 구문을 호출한다. 사용자에게 조회 조건 입력하는 화면을 출력하여 보여준다.

3. control은 reporting processor로 넘어간다. 이 processor는 START-OF-SELECTION 이벤트를 생성하고 이에 대응하는 이벤트 블럭(START-OF-SELECTION)을 호출한다.

4. Logical Database를 사용한다면 이벤트 블럭을 여기서 더 호출하게 된다.(LDB : 사용 빈도가 높은 테이블의 데이터를 조회하기 위해서 JOIN이 자주 사용되고 조회 조건이 유사한 경우를 하나의 패키지로 생성하여 재사용)

5. reporting processor는 END-OF-SELECTION 이벤트를 호출하고 대응하는 이벤트 블럭을 호출한다.

6. List 관련 소스코드가 있다면 control은 List Processor로 넘어간다. 이 Processor는 ABAP 프로그램에 정의된 리스트르를 출력한다. List Processor는 리스트에 대한 유저 action을 토대로 각 이벤트를 호출하여 실행한다. 

7. selection screen이 선언부에 있으면 같은 프로그램이 종료되면 자동적으로 호출된다.(Shift+F3으로 종료하면 다시 조회 조건 입력화면에서부터 다시 시작한다는 뜻인 듯)

 

 

프로그램 구조

- Report program은 다음과 같이 크게 3가지 구조로 분류할 수 있다.

1. 데이터 선언부와 조회 선택 화면(SELECTION SCREEN)

2. 실행 시점까지의 Event

3. 데이터를 뿌려주는 List Event

 

 

1. 데이터 선언부와 조회 선택 화면

*&---------------------------------------------------------------------*
*& REPORT  ZBCR0040
*&
*&---------------------------------------------------------------------*
*&라이센스 관리를 위한 유저 현황 리포트
*&
*&---------------------------------------------------------------------*

REPORT ZBCR0040.

TYPE-POOLS: icon. " TYPE-GROUP을 사용하기 위해 선언

" SALV 사용을 위한 관련 타입 변수 선언
DATA : ALV_TABLE TYPE REF TO CL_SALV_TABLE.
DATA : ALV_COLUMNS TYPE REF TO CL_SALV_COLUMNS_TABLE.
DATA : SINGLE_COLUMN TYPE REF TO CL_SALV_COLUMN.

" 개별 계정 현황 집계 테이블
TYPES : BEGIN OF T_INDI_USER,

          BNAME        LIKE USER_ADDR-BNAME,      " SAP아이디
          BNAME_NM     LIKE USER_ADDR-NAME_TEXTC, " 사용자이름
          KOSTL        LIKE CSKT-KOSTL,           " 코스트센터
          KOSTL_NM     LIKE CSKT-KTEXT,           " 코스트센터 내역
          LIC_TYPE     LIKE USR06-LIC_TYPE,       " 라이센스
          LIC_TYPE_NM  LIKE TUTYP-UTYPTEXT,       " 라이센스 내역
          UFLAG        LIKE USR02-UFLAG,          " 잠금생타값
          UFLAG_NM     TYPE ICON_D,               " 잠금상태아이콘
          TRDAT        LIKE USR02-TRDAT,          " 마지막 로그온 일자
          GLTGB        LIKE USR02-GLTGB,          " 효력종료일

  END OF T_INDI_USER.

DATA : GT_INDI_USER TYPE TABLE OF T_INDI_USER.
DATA : GS_INDI_USER LIKE LINE OF GT_INDI_USER.

" 코스트 센터별 현황
TYPES : BEGIN OF T_KOSTL_USER,
          BUKRS        LIKE CSKS-BUKRS, " 회사
          BUTXT        LIKE T001-BUTXT, " 회사명
          KOSTL        LIKE CSKS-KOSTL, " 코스트센터
          KOSTL_NM     LIKE CSKT-KTEXT, " 코스트센터명
          TOTAL_CNT    TYPE I,          " 발급 계정 수
          LOCKED_CNT   TYPE I,          " 잠긴 계정 수
          OPEN_CNT     TYPE I,          " 열린 계정 수
  END OF T_KOSTL_USER.


DATA : GT_KOSTL_USER TYPE TABLE OF T_KOSTL_USER.
DATA : GS_KOSTL_USER LIKE LINE OF GT_KOSTL_USER.

" 회사코드별 현황
TYPES : BEGIN OF T_BUKRS_USER,
          BUKRS        LIKE CSKS-BUKRS, " 회사
          BUTXT        LIKE T001-BUTXT, " 회사명
          TOTAL_CNT    TYPE I,          " 발급 계정 수
          LOCKED_CNT   TYPE I,          " 잠긴 계정 수
          OPEN_CNT     TYPE I,          " 열린 계정 수
  END OF T_BUKRS_USER.

DATA : GT_BUKRS_USER TYPE TABLE OF T_BUKRS_USER.
DATA : GS_BUKRS_USER LIKE LINE OF GT_BUKRS_USER.

" 라이센스별 현황
TYPES : BEGIN OF T_LIC_USER,

          LIC_TYPE     LIKE USR06-LIC_TYPE,  " 라이센스
          LIC_TYPE_NM  LIKE TUTYP-UTYPTEXT,  " 라이센스 내역
          TOTAL_CNT    TYPE I,               " 발급 계정 수
          LOCKED_CNT   TYPE I,               " 잠긴 계정 수
          OPEN_CNT     TYPE I,               " 열린 계정 수

  END OF T_LIC_USER.

DATA : GT_LIC_USER TYPE TABLE OF T_LIC_USER.
DATA : GS_LIC_USER  LIKE LINE OF GT_LIC_USER.


" 리포트 프로그램에서 SELECTION SCREEN은 프로그래머가 직접 정의하지 않아도
" 자동으로 스크린을 생성하고 FLOW LOGIC을 구현하도록 도와준다.
SELECTION-SCREEN BEGIN OF BLOCK BLOCK1 WITH FRAME TITLE TEXT-001.
SELECTION-SCREEN BEGIN OF LINE.

" PARAMETERS는 사용자가 값을 입력하도록 INPUT 필드를 정의한다.
" 통계 종류 라디오 버튼
PARAMETERS : P_RADI_1 RADIOBUTTON GROUP RADI USER-COMMAND UCOM1  DEFAULT 'X'. " 파라미터 선언
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_1.  " PARAMETERS와 SELECT-OPTIONS의 내역을 나타내기 위한 selection text
PARAMETERS : P_RADI_2 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_2.
PARAMETERS : P_RADI_3 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_3.
PARAMETERS : P_RADI_4 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_4.


SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK BLOCK1.


SELECTION-SCREEN BEGIN OF BLOCK BLOCK2 WITH FRAME TITLE TEXT-002. " 선택 블럭의 제목을 적기 위한 텍스트 심볼 선언
SELECTION-SCREEN BEGIN OF LINE.

SELECTION-SCREEN COMMENT (12) FOR FIELD S_TRDAT MODIF ID ID1. " MODIF ID를 부여하여 조회 조건을 그룹화 할 수 있다.

" SELECT-OPTIONS는 2개의 INPUT 필드를 통해 다양한 조건 값을 입력받을 수 있다.
" RANGE변수와 같은 구조(인터널 테이블)를 가지고 있다.
SELECT-OPTIONS : S_TRDAT FOR GS_INDI_USER-TRDAT MODIF ID ID1.

SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK BLOCK2.


" 이벤트 중 프로그램을 실행했을 때 가장 먼저 수행되는 이벤트
" SELECTION-SCREEN이 조회되기 전에 작동하므로 변수에 초기값을 지정할 때 사용
INITIALIZATION.
  S_TRDAT-SIGN = 'I'.
  S_TRDAT-OPTION = 'BT'.
  S_TRDAT-HIGH = SY-DATUM.

  S_TRDAT-LOW = SY-DATUM - 50.

  APPEND S_TRDAT.

" SELECTION-SCREEN OUTPUT은 사용자가 버튼을 클릭했을 때 작동
" SCREEN은 STRUCTURE이며 LOOP AT SCREEN을 수행할 때 스크린 필드의 MODIF ID가져옴 
" MODIF ID를 통해 스크린 필드 제어
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.

    IF P_RADI_1 EQ 'X' AND SCREEN-GROUP1 EQ 'ID1'.
      SCREEN-ACTIVE = '1'.
      MODIFY SCREEN.

    ELSEIF P_RADI_1 NE 'X' AND SCREEN-GROUP1 EQ 'ID1'.
      SCREEN-ACTIVE = '0'. " 그룹화한 MODIF ID로 묶인 필드들을 활성화/비활성화
      MODIFY SCREEN.
    ENDIF.

  ENDLOOP.

 

 

2. 실행 시점까지의 Event

START-OF-SELECTION. " 데이터베이스에서 원하는 데이터를 가져오는 작업 수행

    SELECT A~BNAME      AS BNAME
           B~NAME_TEXTC AS BNAME_NM
           B~KOSTL      AS KOSTL
           C~LIC_TYPE   AS LIC_TYPE
       "    D~UTYPTEXT   AS LIC_TYPE_NM
           A~TRDAT      AS TRDAT
           A~GLTGB      AS GLTGB
           A~UFLAG      AS UFLAG
 
      INTO CORRESPONDING FIELDS OF TABLE GT_INDI_USER
      FROM USR02 AS A
     LEFT OUTER JOIN USER_ADDR AS B
        ON A~BNAME EQ B~BNAME
     LEFT OUTER JOIN USR06 AS C
        ON A~BNAME EQ C~BNAME
     WHERE A~TRDAT IN S_TRDAT
      .
 
 
 
    DATA : LV_KTEXT LIKE CSKT-KTEXT.
 
    LOOP AT GT_INDI_USER INTO GS_INDI_USER.
 
      SELECT SINGLE UTYPTEXT
        INTO GS_INDI_USER-LIC_TYPE_NM
        FROM TUTYP AS A
       WHERE A~USERTYP EQ GS_INDI_USER-LIC_TYPE
         AND A~LANGU EQ '3'
        .
 
      IF GS_INDI_USER-UFLAG IS INITIAL OR GS_INDI_USER-UFLAG EQ 0.
        GS_INDI_USER-UFLAG_NM = ICON_UNLOCKED.
      ELSE.
        GS_INDI_USER-UFLAG_NM = ICON_LOCKED.
      ENDIF.
 
 
      CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
        EXPORTING
          INPUT  = GS_INDI_USER-KOSTL
        IMPORTING
          OUTPUT = GS_INDI_USER-KOSTL.
 
      SELECT SINGLE KTEXT
        FROM CSKT
        INTO LV_KTEXT
       WHERE KOSTL EQ GS_INDI_USER-KOSTL
         AND SPRAS EQ '3'
         AND DATBI GT SY-DATUM.
 
      IF SY-SUBRC = 0.
        GS_INDI_USER-KOSTL_NM = LV_KTEXT.
 
      ENDIF.
 
      MODIFY GT_INDI_USER FROM GS_INDI_USER.
      CLEAR LV_KTEXT.
    ENDLOOP.
 
    
 

 

3.1 데이터를 뿌려주는 List Event(여기서는 SALV)

END-OF-SELECTION. "  실행 환경에서 호출되는 마지막 이벤트. 데이터를 화면에 뿌려준다.  

  PERFORM DISPLAY_SETTINGS_1 USING GT_INDI_USER.  "  DISPLAY하기 위한 세팅

  PERFORM DISPLAY_ALV_REPORT.
 
 
FORM DISPLAY_SETTINGS_1 CHANGING PT.
    DATA : ERR_MESSAGE TYPE REF TO CX_SALV_MSG.
 
    TRY.
        CL_SALV_TABLE=>FACTORY(
        IMPORTING
          R_SALV_TABLE = ALV_TABLE
          CHANGING
            T_TABLE = PT ).
 
 
        ALV_COLUMNS = ALV_TABLE->GET_COLUMNS( ).
        ALV_COLUMNS->SET_OPTIMIZE( 'X' ).
        " ALV_COLUMNS->SET_COLOR_COLUMN( 'LINE_COLOR' ).
 
        PERFORM BUILD_LAYOUT.
 
        IF P_RADI_1 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_1. " 필드 카탈로그 세팅
        ELSEIF P_RADI_2 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_2.
        ELSEIF P_RADI_3 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_3.
        ELSEIF P_RADI_4 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_4.
        ENDIF.
 
        PERFORM BUILD_TOOLBAR. " 툴바 세팅
        PERFORM HIDE_COLUMNS.  " 숨길 컬럼 세팅
        PERFORM REPORT_SETTINGS. 
 
      CATCH CX_SALV_MSG INTO ERR_MESSAGE.
    ENDTRY.
 
  ENDFORM.
 
  FORM BUILD_LAYOUT.
    DATA : LAYOUT TYPE REF TO CL_SALV_LAYOUT.
    DATA : LAYOUT_KEY TYPE SALV_S_LAYOUT_KEY.
 
    LAYOUT = ALV_TABLE->GET_LAYOUT( ).
 
    LAYOUT_KEY-REPORT = SY-REPID.
    LAYOUT->SET_KEY( LAYOUT_KEY ).
 
    LAYOUT->SET_SAVE_RESTRICTION( IF_SALV_C_LAYOUT=>RESTRICT_NONE ).
 
  ENDFORM.
 
  FORM BUILD_FIELDCATALOG_1.
    DATA : ERR_NOTFOUND TYPE REF TO CX_SALV_NOT_FOUND.
 
    TRY.
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'BNAME' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 10 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'BNAME_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 25 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'KOSTL_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 25 ).
 
 
        SINGLE_COLUMN ?= ALV_COLUMNS->GET_COLUMN( 'LIC_TYPE' ).
        SINGLE_COLUMN->set_SIGN( ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 8 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'LIC_TYPE_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 20 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'UFLAG_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '잠금상태' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '잠긍상태' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '잠금상태' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 8 ).
 
      CATCH CX_SALV_NOT_FOUND INTO ERR_NOTFOUND.
    ENDTRY.
 
  ENDFORM.
 
 
FORM BUILD_TOOLBAR.

    DATA : TOOLBAR_FUNCTIONS TYPE REF TO CL_SALV_FUNCTIONS_LIST.
 
    TOOLBAR_FUNCTIONS = ALV_TABLE->GET_FUNCTIONS( ).
    TOOLBAR_FUNCTIONS->SET_ALL( ).
 
  ENDFORM.
 
  FORM HIDE_COLUMNS.
 
 
 
  ENDFORM.
 
  FORM REPORT_SETTINGS.
    DATA : REPORT_SETTINGS TYPE REF TO CL_SALV_DISPLAY_SETTINGS.
 
    REPORT_SETTINGS = ALV_TABLE->GET_DISPLAY_SETTINGS( ).
    REPORT_SETTINGS->SET_STRIPED_PATTERN( IF_SALV_C_BOOL_SAP=>TRUE ).
 
 
    IF P_RADI_1 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '사용자 통계' ).
    ELSEIF P_RADI_2 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '코스트 센터별 통계' ).
 
    ELSEIF P_RADI_3 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '회사코드별 통계' ).
    ELSEIF P_RADI_4 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '라이센스별 통계' ).
    ENDIF.
 
 
 
  ENDFORM.
 
 
  FORM DISPLAY_ALV_REPORT.
 
    IF P_RADI_1 NE 'X'.
 
      ALV_TABLE->get_aggregations( )->add_aggregation( 'TOTAL_CNT' ).
      ALV_TABLE->get_aggregations( )->add_aggregation( 'LOCKED_CNT' ).
      ALV_TABLE->get_aggregations( )->add_aggregation( 'OPEN_CNT' ).
 
    ENDIF.
 
    ALV_TABLE->DISPLAY( ).
  ENDFORM.
 

 

 

3.2 EASY ABAP의 List Process 이벤트 설명

728x90

'SAP&ABAP > ABAP' 카테고리의 다른 글

EASY ABAP - 10. FIELD SYMBOL(필드 심볼)  (1) 2024.06.05
(작업중)EASY ABAP - 9-1. ABAP Dictionary  (0) 2024.04.24