ALV 리포트
ALV란?
ALV(ABAP List Viewer)는 SAP에서 데이터를 표, 그리드 형태로 출력하는 표준 도구입니다. 정렬, 필터, 합계, 엑셀 다운로드 등 풍부한 기능을 기본 제공하여, 실무에서 가장 많이 사용하는 출력 방식입니다.
ALV Grid vs ALV List 비교
| 구분 | CL_GUI_ALV_GRID | REUSE_ALV_GRID_DISPLAY | REUSE_ALV_LIST_DISPLAY |
|---|
| 방식 | OOP (클래스) | 함수 모듈 | 함수 모듈 |
| 화면 | Grid (스프레드시트) | Grid | Classic List |
| 편집 | 가능 | 제한적 | 불가 |
| 이벤트 | 풍부 | 기본 제공 | 기본 제공 |
| 유연성 | 높음 | 중간 | 낮음 |
| 권장 | 신규 개발 시 | 간단한 리포트 | 레거시 호환 |
이 포스트에서는 실무에서 가장 많이 사용하는 REUSE_ALV_GRID_DISPLAY 함수 모듈을 중심으로 설명합니다.
Field Catalog
Field Catalog은 ALV 각 컬럼의 속성(이름, 길이, 정렬, 편집 가능 여부 등)을 정의합니다.
자동 생성 (DDIC 참조)
DDIC 구조체를 참조하면 Field Catalog을 자동으로 생성할 수 있습니다.
1DATA: lt_fieldcat TYPE slis_t_fieldcat_alv.
2
3
4CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
5 EXPORTING
6 i_structure_name = 'MARA'
7 CHANGING
8 ct_fieldcat = lt_fieldcat
9 EXCEPTIONS
10 OTHERS = 1.
수동 생성
실무에서는 필요한 컬럼만 선택적으로 수동 생성하는 경우가 많습니다.
1DATA: lt_fieldcat TYPE slis_t_fieldcat_alv,
2 ls_fieldcat TYPE slis_fieldcat_alv.
3
4
5CLEAR ls_fieldcat.
6ls_fieldcat-fieldname = 'MATNR'.
7ls_fieldcat-seltext_l = '자재번호'.
8ls_fieldcat-col_pos = 1.
9ls_fieldcat-outputlen = 18.
10ls_fieldcat-key = 'X'.
11APPEND ls_fieldcat TO lt_fieldcat.
12
13
14CLEAR ls_fieldcat.
15ls_fieldcat-fieldname = 'MAKTX'.
16ls_fieldcat-seltext_l = '자재내역'.
17ls_fieldcat-col_pos = 2.
18ls_fieldcat-outputlen = 30.
19APPEND ls_fieldcat TO lt_fieldcat.
20
21
22CLEAR ls_fieldcat.
23ls_fieldcat-fieldname = 'MENGE'.
24ls_fieldcat-seltext_l = '수량'.
25ls_fieldcat-col_pos = 3.
26ls_fieldcat-outputlen = 15.
27ls_fieldcat-do_sum = 'X'.
28APPEND ls_fieldcat TO lt_fieldcat.
29
30
31CLEAR ls_fieldcat.
32ls_fieldcat-fieldname = 'NETPR'.
33ls_fieldcat-seltext_l = '단가'.
34ls_fieldcat-col_pos = 4.
35ls_fieldcat-edit = 'X'.
36ls_fieldcat-hotspot = 'X'.
37ls_fieldcat-emphasize = 'C500'.
38APPEND ls_fieldcat TO lt_fieldcat.
주요 Field Catalog 속성
| 속성 | 설명 | 값 예시 |
|---|
FIELDNAME | 내부 테이블 필드명 | 'MATNR' |
SELTEXT_L | 컬럼 헤더 (긴 텍스트) | '자재번호' |
SELTEXT_M | 컬럼 헤더 (중간 텍스트) | '자재No' |
SELTEXT_S | 컬럼 헤더 (짧은 텍스트) | 'No' |
COL_POS | 컬럼 위치 순서 | 1, 2, 3 |
OUTPUTLEN | 출력 길이 | 18 |
KEY | 키 컬럼 여부 (고정) | 'X' |
EDIT | 편집 가능 여부 | 'X' |
CHECKBOX | 체크박스 표시 | 'X' |
HOTSPOT | 클릭 가능 링크 | 'X' |
NO_OUT | 숨김 컬럼 | 'X' |
DO_SUM | 합계 표시 | 'X' |
EMPHASIZE | 컬럼 색상 강조 | 'C500' |
JUST | 정렬 (L/R/C) | 'R' (우측) |
REF_TABLE | DDIC 참조 테이블 | 'MARA' |
REF_FIELD | DDIC 참조 필드 | 'MATNR' |
Layout 설정
Layout은 ALV 전체의 표시 옵션을 설정합니다.
1DATA: ls_layout TYPE slis_layout_alv.
2
3ls_layout-zebra = 'X'.
4ls_layout-colwidth_optimize = 'X'.
5ls_layout-grid_title = '자재 목록 리포트'.
6ls_layout-sel_mode = 'A'.
주요 Layout 속성
| 속성 | 설명 | 값 |
|---|
ZEBRA | 줄무늬 배경 | 'X' |
COLWIDTH_OPTIMIZE | 컬럼 너비 자동 조정 | 'X' |
SEL_MODE | 행 선택 모드 | 'A', 'B', 'C', 'D' |
GRID_TITLE | ALV 상단 제목 | '리포트 제목' |
NO_TOOLBAR | 툴바 숨김 | 'X' |
EDIT | 전체 편집 모드 | 'X' |
SEL_MODE (선택 모드) 옵션
| 모드 | 설명 |
|---|
A | 행 + 컬럼 + 셀 단위 선택 가능 |
B | 단일 행 선택 |
C | 복수 행 선택 |
D | 셀 단위 선택 |
Event 처리
ALV에서 사용자 액션(더블클릭, 핫스팟 클릭 등)을 처리하려면 이벤트를 등록해야 합니다.
주요 이벤트 목록
| 이벤트 | 설명 | 발생 시점 |
|---|
USER_COMMAND | 사용자 액션 (더블클릭 포함) | 행 더블클릭, 버튼 클릭 |
TOP_OF_PAGE | 헤더 출력 | ALV 상단에 정보 표시 |
PF_STATUS_SET | 상태바 설정 | ALV 표시 전 |
DATA_CHANGED | 데이터 변경 | 편집 모드에서 셀 값 변경 시 |
DOUBLE_CLICK / USER_COMMAND 이벤트
1
2DATA: lt_events TYPE slis_t_event,
3 ls_event TYPE slis_alv_event.
4
5ls_event-name = 'USER_COMMAND'.
6ls_event-form = 'ON_USER_COMMAND'.
7APPEND ls_event TO lt_events.
8
9ls_event-name = 'TOP_OF_PAGE'.
10ls_event-form = 'ON_TOP_OF_PAGE'.
11APPEND ls_event TO lt_events.
12
13
14CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
15 EXPORTING
16 it_fieldcat = lt_fieldcat
17 is_layout = ls_layout
18 it_events = lt_events
19 i_callback_program = sy-repid
20 TABLES
21 t_outtab = lt_materials
22 EXCEPTIONS
23 OTHERS = 1.
24
25
26FORM on_user_command USING uv_ucomm TYPE sy-ucomm
27 ls_selfield TYPE slis_selfield.
28 CASE uv_ucomm.
29 WHEN '&IC1'.
30
31 READ TABLE lt_materials INTO ls_material INDEX ls_selfield-tabindex.
32 IF sy-subrc = 0.
33
34 SET PARAMETER ID 'MAT' FIELD ls_material-matnr.
35 CALL TRANSACTION 'MM03' AND SKIP FIRST SCREEN.
36 ENDIF.
37 ENDCASE.
38ENDFORM.
39
40
41FORM on_top_of_page.
42 DATA: lt_header TYPE slis_t_listheader,
43 ls_header TYPE slis_listheader.
44
45
46 ls_header-typ = 'H'.
47 ls_header-info = '자재 목록 리포트'.
48 APPEND ls_header TO lt_header.
49
50
51 CLEAR ls_header.
52 ls_header-typ = 'S'.
53 ls_header-key = '실행일'.
54 ls_header-info = sy-datum.
55 APPEND ls_header TO lt_header.
56
57 CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
58 EXPORTING
59 it_list_commentary = lt_header.
60ENDFORM.
Toolbar 커스터마이징
커스텀 버튼 추가
PF_STATUS_SET 이벤트를 통해 커스텀 GUI Status를 설정하거나, REUSE_ALV_GRID_DISPLAY의 I_CALLBACK_PF_STATUS_SET 파라미터를 사용합니다.
1
2CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
3 EXPORTING
4 it_fieldcat = lt_fieldcat
5 is_layout = ls_layout
6 i_callback_program = sy-repid
7 i_callback_pf_status_set = 'SET_PF_STATUS'
8 i_callback_user_command = 'ON_USER_COMMAND'
9 TABLES
10 t_outtab = lt_materials
11 EXCEPTIONS
12 OTHERS = 1.
13
14
15FORM set_pf_status USING pt_extab TYPE slis_t_extab.
16
17 SET PF-STATUS 'ZSTATUS' EXCLUDING pt_extab.
18ENDFORM.
기본 Toolbar 버튼 제거
특정 표준 버튼을 숨기려면 IT_EXCLUDING 파라미터를 사용합니다.
1DATA: lt_excluding TYPE slis_t_extab,
2 ls_excluding TYPE slis_extab.
3
4
5ls_excluding-fcode = '&PRINT'.
6APPEND ls_excluding TO lt_excluding.
7
8
9ls_excluding-fcode = '&XXL'.
10APPEND ls_excluding TO lt_excluding.
11
12CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
13 EXPORTING
14 it_fieldcat = lt_fieldcat
15 it_excluding = lt_excluding
16 TABLES
17 t_outtab = lt_materials.
Variant 저장/불러오기
Variant는 사용자가 설정한 ALV 레이아웃(컬럼 순서, 필터, 정렬 등)을 저장하고 재사용할 수 있는 기능입니다.
Variant 설정
1DATA: ls_variant TYPE disvariant.
2
3ls_variant-report = sy-repid.
4ls_variant-username = sy-uname.
5
6CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
7 EXPORTING
8 it_fieldcat = lt_fieldcat
9 is_layout = ls_layout
10 is_variant = ls_variant
11 i_save = 'A'
12 i_default = 'X'
13 TABLES
14 t_outtab = lt_materials.
I_SAVE 옵션
| 옵션 | 설명 |
|---|
'A' | 전체 허용 (사용자별 + 전체 공용) |
'U' | 사용자별 Variant만 저장 허용 |
'X' | 전체 공용 Variant만 저장 허용 |
' ' | 저장 불가 (빈 문자열) |
실무 예제: 편집 가능한 ALV 구매오더 리포트
CL_GUI_ALV_GRID를 사용하여 편집 가능한 ALV를 구현하는 종합 예제입니다.
1REPORT Z_ALV_PO_REPORT.
2
3
4
5
6TYPES: BEGIN OF ty_po_item,
7 sel TYPE c LENGTH 1,
8 ebeln TYPE ebeln,
9 ebelp TYPE ebelp,
10 matnr TYPE matnr,
11 maktx TYPE maktx,
12 menge TYPE bstmg,
13 meins TYPE bstme,
14 netpr TYPE bprei,
15 netwr TYPE bwert,
16 lifnr TYPE elifn,
17 status TYPE c LENGTH 10,
18 END OF ty_po_item.
19
20
21
22
23TABLES: ekko.
24
25
26
27
28SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
29 SELECT-OPTIONS: so_ebeln FOR ekko-ebeln,
30 so_lifnr FOR ekko-lifnr.
31 PARAMETERS: p_ekorg TYPE ekorg DEFAULT '1000'.
32SELECTION-SCREEN END OF BLOCK b1.
33
34
35
36
37DATA: lt_po_items TYPE TABLE OF ty_po_item,
38 ls_po_item TYPE ty_po_item.
39
40DATA: lt_fieldcat TYPE slis_t_fieldcat_alv,
41 ls_fieldcat TYPE slis_fieldcat_alv,
42 ls_layout TYPE slis_layout_alv,
43 ls_variant TYPE disvariant,
44 lt_events TYPE slis_t_event,
45 ls_event TYPE slis_alv_event.
46
47
48
49
50START-OF-SELECTION.
51
52 SELECT a~ebeln b~ebelp b~matnr b~menge b~meins
53 b~netpr b~netwr a~lifnr
54 FROM ekko AS a
55 INNER JOIN ekpo AS b
56 ON a~ebeln = b~ebeln
57 INTO CORRESPONDING FIELDS OF TABLE lt_po_items
58 WHERE a~ebeln IN so_ebeln
59 AND a~lifnr IN so_lifnr
60 AND a~ekorg = p_ekorg
61 AND b~loekz = ' '.
62
63 IF sy-subrc <> 0.
64 MESSAGE '조회된 데이터가 없습니다.' TYPE 'S' DISPLAY LIKE 'E'.
65 RETURN.
66 ENDIF.
67
68
69 DATA: lt_makt TYPE TABLE OF makt,
70 ls_makt TYPE makt.
71
72 IF lt_po_items IS NOT INITIAL.
73 SELECT matnr maktx
74 FROM makt
75 INTO TABLE lt_makt
76 FOR ALL ENTRIES IN lt_po_items
77 WHERE matnr = lt_po_items-matnr
78 AND spras = sy-langu.
79 ENDIF.
80
81
82 FIELD-SYMBOLS: <ls_po> TYPE ty_po_item.
83 LOOP AT lt_po_items ASSIGNING <ls_po>.
84 READ TABLE lt_makt INTO ls_makt
85 WITH KEY matnr = <ls_po>-matnr.
86 IF sy-subrc = 0.
87 <ls_po>-maktx = ls_makt-maktx.
88 ENDIF.
89 <ls_po>-status = '정상'.
90 ENDLOOP.
91
92
93
94
95 PERFORM set_fieldcat.
96
97
98
99
100 ls_layout-zebra = 'X'.
101 ls_layout-colwidth_optimize = 'X'.
102 ls_layout-sel_mode = 'A'.
103 ls_layout-box_fieldname = 'SEL'.
104
105
106
107
108 ls_variant-report = sy-repid.
109 ls_variant-username = sy-uname.
110
111
112
113
114 ls_event-name = 'USER_COMMAND'.
115 ls_event-form = 'ON_USER_COMMAND'.
116 APPEND ls_event TO lt_events.
117
118 ls_event-name = 'TOP_OF_PAGE'.
119 ls_event-form = 'ON_TOP_OF_PAGE'.
120 APPEND ls_event TO lt_events.
121
122
123
124
125 CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
126 EXPORTING
127 i_callback_program = sy-repid
128 i_callback_pf_status_set = 'SET_PF_STATUS'
129 it_fieldcat = lt_fieldcat
130 is_layout = ls_layout
131 is_variant = ls_variant
132 i_save = 'A'
133 it_events = lt_events
134 TABLES
135 t_outtab = lt_po_items
136 EXCEPTIONS
137 OTHERS = 1.
138
139
140
141
142FORM set_fieldcat.
143 CLEAR ls_fieldcat.
144 ls_fieldcat-fieldname = 'EBELN'.
145 ls_fieldcat-seltext_l = '구매오더'.
146 ls_fieldcat-col_pos = 1.
147 ls_fieldcat-key = 'X'.
148 ls_fieldcat-hotspot = 'X'.
149 APPEND ls_fieldcat TO lt_fieldcat.
150
151 CLEAR ls_fieldcat.
152 ls_fieldcat-fieldname = 'EBELP'.
153 ls_fieldcat-seltext_l = '항목'.
154 ls_fieldcat-col_pos = 2.
155 APPEND ls_fieldcat TO lt_fieldcat.
156
157 CLEAR ls_fieldcat.
158 ls_fieldcat-fieldname = 'MATNR'.
159 ls_fieldcat-seltext_l = '자재번호'.
160 ls_fieldcat-col_pos = 3.
161 APPEND ls_fieldcat TO lt_fieldcat.
162
163 CLEAR ls_fieldcat.
164 ls_fieldcat-fieldname = 'MAKTX'.
165 ls_fieldcat-seltext_l = '자재내역'.
166 ls_fieldcat-col_pos = 4.
167 ls_fieldcat-outputlen = 25.
168 APPEND ls_fieldcat TO lt_fieldcat.
169
170 CLEAR ls_fieldcat.
171 ls_fieldcat-fieldname = 'MENGE'.
172 ls_fieldcat-seltext_l = '수량'.
173 ls_fieldcat-col_pos = 5.
174 ls_fieldcat-do_sum = 'X'.
175 APPEND ls_fieldcat TO lt_fieldcat.
176
177 CLEAR ls_fieldcat.
178 ls_fieldcat-fieldname = 'MEINS'.
179 ls_fieldcat-seltext_l = '단위'.
180 ls_fieldcat-col_pos = 6.
181 APPEND ls_fieldcat TO lt_fieldcat.
182
183 CLEAR ls_fieldcat.
184 ls_fieldcat-fieldname = 'NETPR'.
185 ls_fieldcat-seltext_l = '단가'.
186 ls_fieldcat-col_pos = 7.
187 ls_fieldcat-edit = 'X'.
188 APPEND ls_fieldcat TO lt_fieldcat.
189
190 CLEAR ls_fieldcat.
191 ls_fieldcat-fieldname = 'NETWR'.
192 ls_fieldcat-seltext_l = '금액'.
193 ls_fieldcat-col_pos = 8.
194 ls_fieldcat-do_sum = 'X'.
195 ls_fieldcat-emphasize = 'C300'.
196 APPEND ls_fieldcat TO lt_fieldcat.
197
198 CLEAR ls_fieldcat.
199 ls_fieldcat-fieldname = 'LIFNR'.
200 ls_fieldcat-seltext_l = '공급업체'.
201 ls_fieldcat-col_pos = 9.
202 APPEND ls_fieldcat TO lt_fieldcat.
203
204 CLEAR ls_fieldcat.
205 ls_fieldcat-fieldname = 'STATUS'.
206 ls_fieldcat-seltext_l = '상태'.
207 ls_fieldcat-col_pos = 10.
208 APPEND ls_fieldcat TO lt_fieldcat.
209ENDFORM.
210
211FORM set_pf_status USING pt_extab TYPE slis_t_extab.
212 SET PF-STATUS 'ZSTATUS' EXCLUDING pt_extab.
213ENDFORM.
214
215FORM on_user_command USING uv_ucomm TYPE sy-ucomm
216 ls_selfield TYPE slis_selfield.
217 CASE uv_ucomm.
218 WHEN '&IC1'.
219 READ TABLE lt_po_items INTO ls_po_item
220 INDEX ls_selfield-tabindex.
221 IF sy-subrc = 0.
222 SET PARAMETER ID 'BES' FIELD ls_po_item-ebeln.
223 CALL TRANSACTION 'ME23N' AND SKIP FIRST SCREEN.
224 ENDIF.
225 WHEN 'ZREFRESH'.
226 PERFORM refresh_data.
227 ls_selfield-refresh = 'X'.
228 ENDCASE.
229ENDFORM.
230
231FORM on_top_of_page.
232 DATA: lt_header TYPE slis_t_listheader,
233 ls_header TYPE slis_listheader.
234
235 ls_header-typ = 'H'.
236 ls_header-info = '구매오더 리포트'.
237 APPEND ls_header TO lt_header.
238
239 CLEAR ls_header.
240 ls_header-typ = 'S'.
241 ls_header-key = '구매조직'.
242 ls_header-info = p_ekorg.
243 APPEND ls_header TO lt_header.
244
245 CLEAR ls_header.
246 ls_header-typ = 'S'.
247 ls_header-key = '실행일시'.
248 ls_header-info = |{ sy-datum DATE = USER } { sy-uzeit TIME = USER }|.
249 APPEND ls_header TO lt_header.
250
251 CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
252 EXPORTING
253 it_list_commentary = lt_header.
254ENDFORM.
255
256FORM refresh_data.
257
258 CLEAR lt_po_items.
259
260ENDFORM.
이 예제에서는 Field Catalog 수동 설정, Layout(ZEBRA, 선택 모드, 체크박스), 이벤트(더블클릭, TOP_OF_PAGE), 커스텀 Toolbar, Variant 저장 등 ALV의 핵심 기능을 모두 활용했습니다.
Disclaimer — 이 포스트는 AI(Claude)를 활용하여 작성된 초안을 바탕으로 검수 및 보완하여 작성되었습니다. 내용 중 오류나 오타가 있다면 댓글로 알려주시면 감사하겠습니다.