Dialog 프로그램 화면이 복잡해지면 한 화면에 모든 항목을 넣을 수 없습니다. 공통 영역 + 탭별로 바뀌는 영역 으로 분할하거나, 메인 폼 + 하단에 ALV 목록 식으로 영역을 나누는 게 자연스러운데, SAP 가 이를 위해 제공하는 표준 메커니즘이 SubScreen 입니다.
핵심은 메인 화면 안에 빈 영역(SubScreen Area) 을 두고, 그 영역에 다른 화면을 끼워넣는 것. 호출은 ABAP Flow Logic 의 CALL SUBSCREEN area INCLUDING program dynnr 한 줄. 정적으로 고정 SubScreen 을 호출할 수도 있고, Tabstrip Control 과 결합하면 탭마다 다른 화면을 동적으로 표시할 수 있습니다.
이 글은 SubScreen 영역 생성·CALL SUBSCREEN 정적/동적 호출·Tabstrip 결합·PAI 분기·자주 빠뜨리는 함정 까지 한 번에 정리한 메모입니다.
핵심 원리
SubScreen 의 위치와 ALV/Custom Container 와의 차이.
| 방법 | 특징 | 언제 쓰나 |
|---|---|---|
| SubScreen | 화면 안에 다른 Dialog Screen 임베드 (입력 필드 포함) | 입력 폼 분할 — 공통 + 탭별 |
| Custom Container | GUI 컨트롤(ALV·Tree·HTML) 임베드 | ALV·HTML 그릴 영역 |
| Tabstrip Control | 탭 컨테이너 — 각 탭이 SubScreen 영역 | 여러 화면을 탭으로 전환 |
| POP-UP (Modal Dialog) | 별도 창에 자식 화면 | 메인을 가린 채 입력 받을 때 |
핵심 트레이드오프: 입력 항목이 너무 많아 한 화면이 답답 하면 SubScreen 으로 영역 분할이 정답. 같은 메인 안에 여러 화면을 전환 해야 하면 Tabstrip + SubScreen 조합. ALV/Tree 등 컨트롤 만 필요하면 Custom Container 가 더 맞습니다.
1단계 — 메인 화면에 SubScreen 영역 그리기
Screen Painter(SE51) 에서 메인 화면(예: SCREEN 0100) 을 열고 요소 종류: 서브스크린영역(Subscreen Area) 으로 빈 영역을 그립니다.
| 설정 | 내용 |
|---|---|
| 요소 종류 | 서브스크린영역 선택 (드롭다운에서 선택) |
| 이름 | 예) MAINAREA — 코드에서 이 이름으로 호출 |
| 크기 | 자식 화면이 들어갈 크기 (라인 × 컬럼) — 자식 화면 크기 ≤ 영역 크기 |
| 참조필드 (Tabstrip 시) | 탭 PUSH BUTTON 속성에서 이 SubScreen 이름을 지정해야 탭과 영역 연결 |

2단계 — 자식 화면 생성 (Screen Type = Subscreen)
자식 화면(예: SCREEN 0110) 을 만들 때 화면 속성에서 Screen Type: Subscreen 으로 설정합니다.
SE51 → 화면 0110 생성
속성 → Screen Type: ○ Normal Screen
● Subscreen ← 이걸 선택
○ Modal Dialog Box
○ Selection Screen
Next Screen: 0 (Subscreen 은 자체적으로 다음 화면 없음)
핵심 차이:
- Subscreen 은 자체적으로 PF-STATUS 없음 — 메인 화면이 STATUS 제공
- Subscreen 의 PAI 는 메인 PAI 와 함께 호출됨
LEAVE TO SCREEN 0같은 흐름 제어는 메인에서만
이 자식 화면 안에 입력 필드·라벨 등 일반 화면 요소를 그리고 PROCESS BEFORE/AFTER 에서 module 호출합니다.
3단계 — CALL SUBSCREEN 정적 호출
가장 단순한 패턴 — 고정된 자식 화면 N개 를 메인의 SubScreen 영역에 한 번에 호출.
PROCESS BEFORE OUTPUT.
MODULE status_0100.
" 영역마다 자식 화면 매핑 (정적)
CALL SUBSCREEN sub_scr INCLUDING sy-repid '0110'.
CALL SUBSCREEN sub_scr2 INCLUDING sy-repid '0120'.
CALL SUBSCREEN sub_scr3 INCLUDING sy-repid '0130'.
PROCESS AFTER INPUT.
" ★ PAI 도 같이 호출 — 안 하면 자식 화면 입력값이 ABAP 으로 안 들어옴
CALL SUBSCREEN sub_scr.
CALL SUBSCREEN sub_scr2.
CALL SUBSCREEN sub_scr3.
MODULE user_command_0100.
핵심 포인트:
CALL SUBSCREEN area INCLUDING program dynnr형식 — area 는 SubScreen 영역명, program/dynnr 은 자식 화면- 같은 메인 프로그램이면
sy-repid, 다른 프로그램이면 그 프로그램명 (보통 함수그룹) 지정 - PAI 에도 반드시
CALL SUBSCREEN area.— 빠뜨리면 자식 입력값이 메인 변수로 안 들어옴
4단계 — Tabstrip Control + 동적 화면 전환
탭을 클릭할 때마다 메인의 SubScreen 영역에 다른 자식 화면을 끼워넣는 패턴.
" ─── TOP 인클루드 ─────────────────────────
DATA: gv_screen TYPE sy-dynnr, " 현재 보여줄 자식 화면 번호
ok_code TYPE sy-ucomm.
CONTROLS: g_tabstrip TYPE TABSTRIP. " Tabstrip 컨트롤
" 화면용 컨테이너·ALV 등도 보통 같이 선언
DATA: go_con TYPE REF TO cl_gui_custom_container,
go_grid TYPE REF TO cl_gui_alv_grid.
" ─── 메인 100 Flow Logic ─────────────────
PROCESS BEFORE OUTPUT.
MODULE status_0100.
CALL SUBSCREEN mainarea INCLUDING sy-repid gv_screen. " ★ 동적 호출
PROCESS AFTER INPUT.
CALL SUBSCREEN mainarea. " 빈 인자 → 현재 활성 자식 화면의 PAI 자동 실행
MODULE user_command_0100.
" ─── STATUS_0100 (PBO) ───────────────────
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STD'.
SET TITLEBAR 'T100'.
" 현재 활성 탭에 따라 보여줄 자식 화면 번호 결정
CASE g_tabstrip-activetab.
WHEN 'TAB1'. gv_screen = '0110'.
WHEN 'TAB2'. gv_screen = '0120'.
WHEN 'TAB3'. gv_screen = '0130'.
WHEN OTHERS. gv_screen = '0110'. " 디폴트
ENDCASE.
ENDMODULE.
" ─── USER_COMMAND_0100 (PAI) ─────────────
MODULE user_command_0100 INPUT.
" 탭 클릭은 ok_code 로 들어옴 → 활성 탭 갱신
g_tabstrip-activetab = ok_code.
CASE ok_code.
WHEN 'BACK' OR 'EXIT' OR 'CANC'.
LEAVE TO SCREEN 0.
ENDCASE.
CLEAR ok_code.
ENDMODULE.
핵심 포인트:
CONTROLS g_tabstrip TYPE TABSTRIP— Tabstrip 전용 선언g_tabstrip-activetab에 현재 선택된 탭의 FCODE 가 들어옴- 탭 PUSH BUTTON 의 참조필드 속성에 SubScreen 영역명(
MAINAREA) 을 적어야 영역과 탭이 연결됨
5단계 — 자식 화면 PBO 모듈 (ALV 임베드 예시)
자식 화면 안에서 ALV·HTML 같은 컨트롤을 띄우는 패턴 — SubScreen 안에 Custom Container 까지 임베드 가능합니다.
" ─── 자식 화면 0110 PBO 모듈 ─────────────
MODULE create_alv110 OUTPUT.
" 데이터 준비
SELECT * INTO TABLE @DATA(lt_scarr)
FROM scarr.
" ALV 인스턴스 1회만 생성
IF go_con1 IS INITIAL.
go_con1 = NEW #( container_name = 'CON1' ). " Screen 0110 안의 Custom Container 이름
go_grid1 = NEW #( i_parent = go_con1 ).
go_grid1->set_table_for_first_display(
EXPORTING
i_structure_name = 'SCARR'
CHANGING
it_outtab = lt_scarr ).
ENDIF.
ENDMODULE.
자식 화면들의 PBO 에서 각각 자기만의 ALV 를 띄우는 식. 객체 인스턴스는 한 번만 생성하고 재사용 — IF IS INITIAL 패턴 필수.
흔히 빠뜨리는 함정
PAI 의 CALL SUBSCREEN 누락
PBO 에만 CALL SUBSCREEN 쓰고 PAI 에 빠뜨리면, 자식 화면 입력 필드의 값이 ABAP 변수로 안 들어옴. 입력만 보이고 저장 안 되는 가장 흔한 원인.
자식 화면을 Subscreen Type 으로 안 만들기
기본 Normal Screen 으로 만든 뒤 CALL SUBSCREEN 으로 호출하면 런타임 덤프(SCREEN_TYPES_INCOMPATIBLE). 속성에서 반드시 Subscreen 선택.
SubScreen 영역 크기 < 자식 화면 크기
자식 화면이 영역보다 크면 잘려서 표시. 영역 크기 ≥ 모든 자식 화면 크기 가 되도록 가장 큰 자식에 맞춰 디자인.
Tab 의 참조필드 미설정
Tabstrip 의 각 탭(PUSH BUTTON) 속성에서 참조필드 에 SubScreen 영역명(MAINAREA) 지정 안 하면 탭 클릭해도 화면 전환 안 됨.
g_tabstrip-activetab 초기값 비어있음
프로그램 시작 시 activetab 이 비어있으면 첫 진입 시 빈 화면. CASE OTHERS 에 디폴트 자식 화면 설정 또는 시작 직전 g_tabstrip-activetab = 'TAB1'.
CALL SUBSCREEN 안에서 LEAVE TO SCREEN 0
자식 화면에서 화면 전환(LEAVE TO SCREEN·SET SCREEN) 하면 안 됨 — 메인 화면에서만 제어. 자식은 흐름 제어 안 함.
Custom Container 객체를 매 PBO 마다 새로 생성
PBO 는 매번 호출되므로 그때마다 NEW cl_gui_custom_container 하면 메모리 누수·GUI 컨트롤 중복. IF go_con IS INITIAL. 가드로 1회만.
TOP 인클루드 분리 안 됨
여러 자식 화면이 같은 변수(gv_screen·g_tabstrip·컨테이너 참조) 를 공유해야 함. TOP 인클루드 1개에 모든 글로벌 변수 두고 모든 화면 모듈에서 접근.
ok_code CLEAR 안 함
PAI 끝에서 CLEAR ok_code 안 하면 다음 화면에서 옛 FCODE 가 살아있어 의도치 않은 분기. 항상 CASE 끝나면 CLEAR.
전체 코드 — 복사용 통합본
위 단계를 함수그룹/리포트 한 세트로 합친 통합본입니다. SE38 신규 리포트 + SE51 메인 화면(0100, SubScreen 영역 MAINAREA + Tabstrip TAB1/TAB2/TAB3) + 자식 화면 3개(0110·0120·0130, Subscreen Type) 생성 후 사용합니다.
*&---------------------------------------------------------------------*
*& SubScreen + Tabstrip Control 표준 패턴
*&---------------------------------------------------------------------*
REPORT zexample_subscreen.
* ========== TOP 인클루드 — 글로벌 선언 ==========
TABLES: scarr.
DATA: gv_screen TYPE sy-dynnr,
ok_code TYPE sy-ucomm.
CONTROLS: g_tabstrip TYPE TABSTRIP.
" Custom Container 참조 (자식 화면 안의 ALV 용)
DATA: go_con1 TYPE REF TO cl_gui_custom_container,
go_grid1 TYPE REF TO cl_gui_alv_grid,
go_con2 TYPE REF TO cl_gui_custom_container,
go_grid2 TYPE REF TO cl_gui_alv_grid,
go_con3 TYPE REF TO cl_gui_custom_container,
go_grid3 TYPE REF TO cl_gui_alv_grid.
DATA: gt_scarr TYPE TABLE OF scarr,
gt_spfli TYPE TABLE OF spfli,
gt_sflight TYPE TABLE OF sflight.
START-OF-SELECTION.
CALL SCREEN 100.
* ======================================================================
* SCREEN 100 (메인) Flow Logic — SE51 에서 입력
* ----------------------------------------------------------------------
* PROCESS BEFORE OUTPUT.
* MODULE status_0100.
* CALL SUBSCREEN mainarea INCLUDING sy-repid gv_screen. " 동적
*
* PROCESS AFTER INPUT.
* CALL SUBSCREEN mainarea.
* MODULE user_command_0100.
* ======================================================================
* ========== 메인 100 PBO ==========
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STD'.
SET TITLEBAR 'T100'.
" 활성 탭에 따라 표시할 자식 화면 결정
CASE g_tabstrip-activetab.
WHEN 'TAB1'. gv_screen = '0110'.
WHEN 'TAB2'. gv_screen = '0120'.
WHEN 'TAB3'. gv_screen = '0130'.
WHEN OTHERS. gv_screen = '0110'. " 디폴트
ENDCASE.
ENDMODULE.
* ========== 메인 100 PAI ==========
MODULE user_command_0100 INPUT.
" 탭 클릭 → activetab 갱신
IF ok_code CP 'TAB*'.
g_tabstrip-activetab = ok_code.
ENDIF.
CASE ok_code.
WHEN 'BACK' OR 'EXIT' OR 'CANC'.
LEAVE TO SCREEN 0.
ENDCASE.
CLEAR ok_code.
ENDMODULE.
* ======================================================================
* 자식 화면 0110 PBO (SCARR 조회 ALV)
* ----------------------------------------------------------------------
* PROCESS BEFORE OUTPUT.
* MODULE create_alv110.
*
* PROCESS AFTER INPUT.
* MODULE user_command_0110.
* ======================================================================
MODULE create_alv110 OUTPUT.
SELECT * INTO TABLE gt_scarr FROM scarr.
IF go_con1 IS INITIAL.
go_con1 = NEW #( container_name = 'CON1' ).
go_grid1 = NEW #( i_parent = go_con1 ).
go_grid1->set_table_for_first_display(
EXPORTING
i_structure_name = 'SCARR'
CHANGING
it_outtab = gt_scarr ).
ENDIF.
ENDMODULE.
MODULE user_command_0110 INPUT.
" 자식 화면 PAI 는 메인 PAI 와 함께 호출됨 — 여기선 자식 전용 처리만
ENDMODULE.
* ======================================================================
* 자식 화면 0120 PBO (SPFLI 조회 ALV)
* ======================================================================
MODULE create_alv120 OUTPUT.
SELECT * INTO TABLE gt_spfli FROM spfli UP TO 50 ROWS.
IF go_con2 IS INITIAL.
go_con2 = NEW #( container_name = 'CON2' ).
go_grid2 = NEW #( i_parent = go_con2 ).
go_grid2->set_table_for_first_display(
EXPORTING
i_structure_name = 'SPFLI'
CHANGING
it_outtab = gt_spfli ).
ENDIF.
ENDMODULE.
* ======================================================================
* 자식 화면 0130 PBO (SFLIGHT 조회 ALV)
* ======================================================================
MODULE create_alv130 OUTPUT.
SELECT * INTO TABLE gt_sflight FROM sflight UP TO 50 ROWS.
IF go_con3 IS INITIAL.
go_con3 = NEW #( container_name = 'CON3' ).
go_grid3 = NEW #( i_parent = go_con3 ).
go_grid3->set_table_for_first_display(
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
it_outtab = gt_sflight ).
ENDIF.
ENDMODULE.
* ※ Screen Painter 준비:
* 1) 화면 0100 (Normal Screen)
* - 요소: SubScreen Area "MAINAREA"
* - 요소: Tabstrip Control 그 위에 (탭 3개: TAB1/TAB2/TAB3)
* - 각 탭 PUSH BUTTON 속성 → 참조필드 = "MAINAREA"
* - Flow Logic 에 PBO/PAI 모듈 호출
* 2) 화면 0110/0120/0130 (Screen Type = Subscreen)
* - 각 화면에 Custom Container "CON1"/"CON2"/"CON3"
* - Flow Logic: PBO → MODULE create_alvXXX
* 3) PF-STATUS 'STD' + Title 'T100' (메인용)
요약
| 단계 | 처리 | 핵심 |
|---|---|---|
| 1 | SubScreen 영역 | 메인 화면에 빈 영역(MAINAREA) 그리기 — 요소 종류: 서브스크린영역 |
| 2 | 자식 화면 생성 | Screen Type = Subscreen 으로 생성 (필수) |
| 3 | 정적 호출 | CALL SUBSCREEN area INCLUDING sy-repid '0110' + PAI 도 CALL SUBSCREEN area. |
| 4 | Tabstrip 동적 | CONTROLS g_tabstrip TYPE TABSTRIP + gv_screen CASE 분기 |
| 5 | PAI 분기 | g_tabstrip-activetab = ok_code + 메인에서만 LEAVE TO SCREEN |
SubScreen 은 복잡한 Dialog 화면을 공통 영역 + 가변 영역 으로 분할하는 표준 도구입니다. 정적 호출(CALL SUBSCREEN area INCLUDING program dynnr) 만 알면 화면 분할은 끝나고, Tabstrip Control 과 결합하면 한 화면 안에서 여러 자식 화면을 탭으로 전환할 수 있습니다. PAI 에서도 반드시 CALL SUBSCREEN 부르기·자식 화면을 Subscreen Type 으로 생성·Custom Container 객체는 IF IS INITIAL 로 1회만 생성 — 이 세 가지만 챙기면 SubScreen 패턴의 90% 가 안정적으로 동작합니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다. CALL SUBSCREEN·CONTROLS ... TYPE TABSTRIP·cl_gui_custom_container·cl_gui_alv_grid 는 SAP NetWeaver 표준 ABAP 객체로 시스템 버전 의존 없이 동작합니다. 다만 SubScreen 은 SAP GUI for Windows 기준 동작을 가정하며, Web GUI / Fiori 환경에서는 Dialog 화면 자체의 사용성이 달라질 수 있습니다. Screen Painter 의 요소 속성·참조필드 설정 단계가 코드 못지않게 중요하므로, 운영 적용 전 화면 진입 / 탭 전환 / 입력값 반영 / 메모리 누수(컨테이너 객체) 등 시나리오를 충분히 테스트하시기 바랍니다.
'ABAP 문법 & 기법 > Dialog & Screen Painter' 카테고리의 다른 글
| [SAP ABAP] Screen Painter 입력 필드 이력 남기는 법 — Def.Length + SAP GUI 이력 설정 매칭 (0) | 2026.05.14 |
|---|