포스팅 목적
ABAP 공부를 하면서 ALV 리포트를 처음 만들게 되었는데,
그 구조가 어떻게 흘러가는지 단계별로 정리한 내용을 기록한다.
등장 개념
`아밥타입`, `데이터타입`, `내부 테이블`, `행`, `필드 카탈로그`, `구조체`
출력할 ALV 리포트

전체 코드
SCARR 테이블의 정보를 ALV로 출력하는 코드
!abap
*&---------------------------------------------------------------------*
*& Report Z2WEEK_ALV000_SCARR
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT Z2WEEK_ALV000_SCARR.
TABLES: scarr.
TYPE-POOLS: slis.
*Data Declaration: 데이터 담기 (엑셀에 첫 행 구성)
*----------------
TYPES: BEGIN OF t_scarr,
mandt TYPE scarr-mandt,
carrid TYPE scarr-carrid,
carrname TYPE scarr-carrname,
currcode TYPE scarr-currcode,
url TYPE scarr-url,
END OF t_scarr.
*it_scarr로 표를 만든거임. internal-table
DATA: it_scarr TYPE STANDARD TABLE OF t_scarr INITIAL SIZE 0.
*ALV data declarations
DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE,
gd_tab_group TYPE slis_t_sp_group_alv,
gd_layout TYPE slis_layout_alv,
gd_repid LIKE sy-repid.
************************************************************************
*Start-of-selection.
START-OF-SELECTION.
PERFORM data_retrieval.
PERFORM build_fieldcatalog.
PERFORM build_layout.
PERFORM display_alv_report.
*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
* Build Fieldcatalog for ALV Report
*----------------------------------------------------------------------*
*제목을 붙이는 작업
FORM build_fieldcatalog.
fieldcatalog-fieldname = 'MANDT'.
fieldcatalog-seltext_m = 'Client'.
fieldcatalog-col_pos = 0.
fieldcatalog-outputlen = 10.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CARRID'.
fieldcatalog-seltext_m = 'Airline Code'.
fieldcatalog-col_pos = 1.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CARRNAME'.
fieldcatalog-seltext_m = 'Airline name'.
fieldcatalog-col_pos = 2.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CURRCODE'.
fieldcatalog-seltext_m = 'Local currency of airline'.
fieldcatalog-col_pos = 3.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'URL'.
fieldcatalog-seltext_m = 'Airline URL'.
fieldcatalog-col_pos = 4.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
ENDFORM. " BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*& Form BUILD_LAYOUT
*&---------------------------------------------------------------------*
* Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM build_layout.
gd_layout-no_input = 'X'.
gd_layout-colwidth_optimize = 'X'.
gd_layout-zebra = 'X'.
ENDFORM. " BUILD_LAYOUT
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
* Display report using ALV grid
*----------------------------------------------------------------------*
FORM display_alv_report.
gd_repid = sy-repid.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = gd_repid
is_layout = gd_layout "위에 붙인 3가지 옵션(build_layout)
it_fieldcat = fieldcatalog[] "필드별 제목 넣었던 거
i_save = 'X'
TABLES
t_outtab = it_scarr "내가 담은 테이블 출력
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDFORM. " DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
*& Form DATA_RETRIEVAL
*&---------------------------------------------------------------------*
FORM data_retrieval.
SELECT mandt carrid carrname currcode url
UP TO 10 ROWS
FROM scarr "항공사 테이블
INTO TABLE it_scarr.
ENDFORM. " DATA_RETRIEVAL
코드 구역별 설명
1) 데이터 선언부
!abap
REPORT Z2WEEK_ALV000_SCARR.
TABLES: scarr.
TYPE-POOLS: slis.
*Data Declaration: 데이터 담기 (엑셀에 첫 행 구성)
*----------------
TYPES: BEGIN OF t_scarr,
mandt TYPE scarr-mandt,
carrid TYPE scarr-carrid,
carrname TYPE scarr-carrname,
currcode TYPE scarr-currcode,
url TYPE scarr-url,
END OF t_scarr.
*it_scarr로 표를 만든거임. internal-table
DATA: it_scarr TYPE STANDARD TABLE OF t_scarr INITIAL SIZE 0.
*ALV data declarations
DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE,
gd_tab_group TYPE slis_t_sp_group_alv,
gd_layout TYPE slis_layout_alv,
gd_repid LIKE sy-repid.
- 프로그램 이름은 `Z2WEEK_ALV000_SCARR`
- `scarr`라는 테이블 사용
- `slis`는 ALV 출력을 위해 SAP가 제공하는 타입 풀. fieldcatalog, layout, 그룹핑 등 ALV 관련 구조와 테이블 타입들이 정의되어 있음
- `BEGIN OF ... END OF` 구문은 구조체(structure) 타입을 정의
=> `scarr` 테이블의 일부 필드인 `mandt`, `carrid`, `carname`, `currcode`, `url`을 사용하여, 한 행을 표현하는 `t_scarr` 구조 타입 정의
- `it_scarr`는 `t_scarr` 구조를 행으로 갖는 내부 테이블
- `fieldcatalog`는 `slis_t_fieldcat_alv` 타입의 내부 테이블
- `slis_t_fieldcat_alv`는 출력할 필드의 속성을 정의하는 데 사용됨
- `gd_tab_group`은 필드를 논리적으로 그룹핑하는 데 사용 (이 프로그램에서는 선언만 되고 사용은 x)
- `gd_repid`는 현재 실행중인 프로그램 이름을 담기 위해 `sy-repid`와 같은 타입으로 선언된 변수
- `sy`에 하이픈(-)으로 접근하면, 시스템 변수 사용 가능
2) 실행부 `START-OF-SELECTION`
!abap
*Start-of-selection.
START-OF-SELECTION.
PERFORM data_retrieval.
PERFORM build_fieldcatalog.
PERFORM build_layout.
PERFORM display_alv_report.
- 실행부.
- 검색화면이 없는 경우, PERFORM 문을 통해 로직이 순차적으로 실행됨
- 검색화면이 있는 경우, 검색화면에서 실행부분을 누르면 그 다음 로직이 순차적으로 실행됨
3) 서브루틴 `data_retrieval`
!abap
*&---------------------------------------------------------------------*
*& Form DATA_RETRIEVAL
*&---------------------------------------------------------------------*
FORM data_retrieval.
SELECT mandt carrid carrname currcode url
UP TO 10 ROWS
FROM scarr "항공사 테이블
INTO TABLE it_scarr.
ENDFORM. " DATA_RETRIEVAL
- scarr 테이블에서 `mandt` ~ `url` 필드 조회하여, 미리 선언해둔 내부 테이블 `it_scarr`에 최대 10개 행을 한 번에 일괄 주입함
4) 서브루틴 `build_fieldcatalog`
!abap
*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
* Build Fieldcatalog for ALV Report
*----------------------------------------------------------------------*
*제목을 붙이는 작업
FORM build_fieldcatalog.
fieldcatalog-fieldname = 'MANDT'.
fieldcatalog-seltext_m = 'Client'.
fieldcatalog-col_pos = 0.
fieldcatalog-outputlen = 10.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CARRID'.
fieldcatalog-seltext_m = 'Airline Code'.
fieldcatalog-col_pos = 1.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CARRNAME'.
fieldcatalog-seltext_m = 'Airline name'.
fieldcatalog-col_pos = 2.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'CURRCODE'.
fieldcatalog-seltext_m = 'Local currency of airline'.
fieldcatalog-col_pos = 3.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
fieldcatalog-fieldname = 'URL'.
fieldcatalog-seltext_m = 'Airline URL'.
fieldcatalog-col_pos = 4.
APPEND fieldcatalog TO fieldcatalog.
CLEAR fieldcatalog.
ENDFORM. " BUILD_FIELDCATALOG
- 미리 선언된 `fieldcatalog`에 각 필드의 속성을 정의하여 추가한다.
- `fieldname`은 실제 데이터 테이블의 필드 이름
- `seltext_m`은 ALV 컬럼 헤더에 표시되는 텍스트(한글도 가능)
- `col_pos`는 ALV 컬럼의 출력 순서 (0부터 시작, 왼쪽부터)
- `APPEND fieldcatalog TO fieldcatalog`에서 첫번째 `fieldcatalog`는 행(work area), 두번째는 테이블을 의미한다. 따라서 테이블에 행을 주입한다. 이후 fieldcatalog(행)을 `clear`하여 다음 행 (work area) 주입 전에 값 초기화
5) 서브루틴 `build_layout`
!abap
*&---------------------------------------------------------------------*
*& Form BUILD_LAYOUT
*&---------------------------------------------------------------------*
* Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM build_layout.
gd_layout-no_input = 'X'.
gd_layout-colwidth_optimize = 'X'.
gd_layout-zebra = 'X'.
ENDFORM. " BUILD_LAYOUT
- ALV 그리드 출력 시 사용될 레이아웃(`gd_layout`) 설정 값을 지정하는 작업
- `no_input = 'X'` : ALV 그리에서 셀 수정 불가
- `colwidth_potimize = 'X'` : 컬럼 너비 자동 조정
- `zebra = 'X'` : 짝수/홀수 행에 색상 차이 주어 가독성 향상
6) 서브루틴 `display_alv_report`
!abap
*&---------------------------------------------------------------------*
*& Form DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
* Display report using ALV grid
*----------------------------------------------------------------------*
FORM display_alv_report.
gd_repid = sy-repid.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = gd_repid
is_layout = gd_layout "위에 붙인 3가지 옵션(build_layout)
it_fieldcat = fieldcatalog[] "필드별 제목 넣었던 거
i_save = 'X'
TABLES
t_outtab = it_scarr "내가 담은 테이블 출력
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDFORM. " DISPLAY_ALV_REPORT
- ALV 리스트를 그리드 형태로 출력 (`REUSE_ALV_GRID_DISPLAY` 함수 모듈 이용)
- 출력에 필요한 요소를 `EXPORTING`과 `TABLES` 파라미터로 전달
1) 프로그램 이름 : `sy-repid`로 프로그램 이름을 가져올 수 있음. 이를 `gd_repid` 변수에 담아 전달
2) 레이아웃 옵션 : `build_layout` 서브루틴에서 구성한 `gd_layout` 구조체 사용
3) 데이터 : `build_fieldcatalog` 서브루틴에서 구성한 `fieldcatalog[]` 테이블 전체 전달
4) 테이블 : `data_retrieval` 서브루틴에서 조회한 결과인 실제 데이터가 담긴 내부 테이블 `it_scarr`
정리
ALV 리포트는 데이터 + 필드 정의 + 화면 설정 + 출력 호출 흐름으로 구성된다.
이번 포스팅에서는
1) 필요한 데이터를 먼저 불러오고,
2) 내부 테이블과 행(구조체) 개념을 이해하고,
3) 필드를 어떻게 ALV에 넣는지
정리해보았다.
원하는 데이터를 어떻게 선언하고 어떻게 다뤄야 ALV에서 출력이 되는지를 이해하는 것이 가장 중요한 것 같다.