본문 바로가기
ALV · 화면 · 리포트

[SAP ABAP] CL_GUI_CUSTOM_CONTAINER 로 ALV 표시 — SE51 Custom Control 과 container_name 매칭 (컨테이너 기본)

by Song.sh 2026. 5. 29.

ABAP 에서 OO 방식 ALV 그리드를 화면에 올릴 때 가장 기본이 되는 컨테이너가 CL_GUI_CUSTOM_CONTAINER 입니다. Splitter · Easy Splitter · Docking · Dialogbox 등 다른 컨테이너들도 결국 이 Custom Container 패턴에서 출발하기 때문에, ALV 컨테이너의 "기본 원형" 이라고 부를 수 있습니다.

 

가장 큰 특징은 SE51 화면에 Custom Control 을 직접 그려서, 그 이름과 ABAP 객체를 연결한다는 점입니다. Docking 컨테이너가 SE51 Layout 을 빈 상태로 두고 코드만으로 영역을 만든다면, Custom Container 는 반대로 SE51 에 Custom Control 영역을 먼저 배치하고 그 이름(CONTAINER_NAME) 으로 연결합니다. 영역 위치/크기를 화면 페인터에서 시각적으로 잡을 수 있어 레이아웃 제어가 직관적입니다.

 

이 글에서는 Custom Container 의 컨테이너 계층 → SE51 Custom Control 배치 → 5단계 생성 흐름 → CONTAINER_NAME 매칭 → SELECT-OPTIONS 조회까지 정리합니다. 데이터는 SAP 표준 학습 환경 테이블 SFLIGHT(항공편) 예시.

핵심 — Custom Container 의 3단 계층

계층 구성 역할
1. Custom Control SE51 Screen 100 의 'CON1' 화면 페인터에서 그린 영역 (이름 = CON1)
2. Custom Container cl_gui_custom_container 'CON1' 과 ABAP 객체를 연결 (container_name)
3. ALV Grid cl_gui_alv_grid Container 안에 ALV 부착 (i_parent = go_con)

그림으로 정리하면:

Screen 100
  └ Custom Control 'CON1'  (SE51 화면 페인터에서 직접 그림)
      └ go_con (cl_gui_custom_container · container_name = 'CON1')
          └ go_grid (cl_gui_alv_grid · i_parent = go_con)

컨테이너 시리즈에서 Custom Container 의 위치를 비교하면 다음과 같습니다.

컨테이너 SE51 Custom Control 특징
Custom 필요 (직접 그림) 기본 원형 · 레이아웃 시각 제어
Docking 불필요 코드만으로 화면 한 쪽에 자동 부착
Splitter 필요 (또는 Docking 위에) 한 영역을 N분할
Dialogbox 불필요 떠 있는 별도 팝업 윈도우

1단계 — SE51 Screen 100 에 Custom Control 'CON1' 배치

Custom Container 패턴의 핵심 단계. Docking 과 달리 SE51 Layout 에 Custom Control 을 직접 그려야 합니다.

[1] T-Code SE51 → Program · Screen 100 (없으면 신규)

[2] Layout 편집기 진입

[3] 도구 모음의 "Custom Control" 아이콘 클릭 후 화면에 드래그
    └ 원하는 위치·크기로 영역 그림

[4] 그린 영역의 Name 속성을 'CON1' 로 지정
    └ 이 이름이 ABAP 의 container_name 과 매칭됨

[5] Flow Logic 에 모듈 연결:
    PROCESS BEFORE OUTPUT.
      MODULE status_0100.
      MODULE create_alv.
    PROCESS AFTER INPUT.
      MODULE user_command_0100.

[6] 활성화

여기서 정한 'CON1' 이라는 이름이 ABAP 코드의 container_name = 'CON1' 과 정확히 일치해야 합니다. 이름이 다르면 컨테이너 생성 시점에 에러가 납니다.


2단계 — DATA 선언 + SELECT-OPTIONS

ALV 한 개 패턴이라 Grid · Container · Field Catalog · 데이터 테이블 각 한 세트. 조회 조건으로 SELECT-OPTIONS 도 함께 선언합니다.

TABLES sflight.

DATA: go_grid TYPE REF TO cl_gui_alv_grid,
      go_con  TYPE REF TO cl_gui_custom_container,
      g_layo  TYPE lvc_s_layo,
      g_sort  TYPE lvc_s_sort,
      gt_fcat TYPE lvc_t_fcat,
      gs_fcat TYPE lvc_s_fcat.

DATA: gt_data TYPE TABLE OF sflight,
      ok_code TYPE sy-ucomm.

* 조회 조건 — 항공사 코드
SELECT-OPTIONS: s_carrid FOR sflight-carrid.

go_con 이 Custom Container 참조. TABLES sflight 는 SELECT-OPTIONS 가 sflight-carrid 를 참조하기 위한 헤더 선언입니다.


3단계 — INITIALIZATION → 조회 → 중복 제거 → CALL SCREEN

INITIALIZATION.
* 조회 조건 기본값 — 항공사 'AA'
  s_carrid[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'AA' ) ).

START-OF-SELECTION.
  SELECT *
    INTO TABLE @gt_data
    FROM sflight
   WHERE carrid IN @s_carrid.

* 정렬 + 중복 제거
  SORT gt_data BY carrid.
  DELETE ADJACENT DUPLICATES FROM gt_data COMPARING carrid.

END-OF-SELECTION.
  CALL SCREEN 100.

INITIALIZATION 에서 SELECT-OPTIONS 기본값을 세팅하고, 조회 후 SORT + DELETE ADJACENT DUPLICATES 로 정렬·중복 제거. DELETE ADJACENT DUPLICATES반드시 SORT 가 선행되어야 인접 중복이 제거됩니다.


4단계 — PBO 모듈에서 Custom Container + ALV 생성

PBO 의 두 모듈. status_0100 에서 GUI Status / Titlebar 를 세팅하고, create_alv 에서 컨테이너 + 그리드를 생성.

MODULE status_0100 OUTPUT.
  SET PF-STATUS 'S100'.
  SET TITLEBAR  'T100' WITH '100화면'.
ENDMODULE.

MODULE create_alv OUTPUT.

  IF go_con IS NOT BOUND.              " 첫 PBO 에서만 1회 생성

* 1) Custom Container 생성 — SE51 의 'CON1' 과 연결
    go_con = NEW #( container_name = 'CON1' ).

* 2) ALV Grid 를 Container 안에 부착
    go_grid = NEW #( i_parent = go_con ).

* 3) ALV 표시 — i_structure_name 으로 Field Catalog 자동 생성
    go_grid->set_table_for_first_display(
      EXPORTING
        i_structure_name = 'SFLIGHT'
      CHANGING
        it_fieldcatalog = gt_fcat
        it_outtab       = gt_data ).

  ENDIF.

ENDMODULE.

CONTAINER_NAME 매칭이 핵심

CL_GUI_CUSTOM_CONTAINER 의 생성자에서 CONTAINER_NAME필수 파라미터 입니다. 다른 컨테이너(Docking·Dialogbox) 는 좌표나 side 로 영역을 정하지만, Custom Container 는 SE51 에서 그린 Custom Control 의 이름으로 연결됩니다.

파라미터 필수 의미
container_name O SE51 Custom Control 이름 (반드시 일치)
parent X 상위 컨테이너 (보통 생략)
repid X 소속 프로그램 (라이프타임)
dynnr X 소속 화면 번호 (라이프타임)

IS NOT BOUND 가드로 첫 PBO 한 번만 생성하고, 이후엔 데이터만 refresh_table_display 로 갱신합니다.


5단계 — PAI 모듈 (BACK / EXIT / CANCEL 처리)

MODULE user_command_0100 INPUT.

  CASE sy-ucomm.
    WHEN 'BACK' OR 'CANC' OR 'EXIT'.
      LEAVE TO SCREEN 0.
  ENDCASE.

ENDMODULE.

LEAVE TO SCREEN 0 으로 화면 종료. GUI Status 'S100' 에 BACK/EXIT/CANCEL 펑션키를 미리 설정해두어야 동작합니다.


자주 빠뜨리는 함정

CONTAINER_NAME 불일치

가장 흔한 실수. SE51 에서 그린 Custom Control 이름과 코드의 container_name 이 다르면(대소문자 포함) 컨테이너 생성 시 CNTL_ERROR 발생. 보통 Custom Control 이름은 대문자로 지정하므로 코드에서도 'CON1' 대문자로 맞춰야 합니다.

SE51 Custom Control 자체를 안 그림

Docking 패턴에 익숙해진 뒤 Custom Container 를 쓰면 SE51 에 Custom Control 그리는 단계를 빠뜨리기 쉽습니다. Custom Container 는 반드시 SE51 Layout 에 Custom Control 영역이 있어야 합니다.

IS NOT BOUND 가드 누락

PBO 가드 없이 매번 NEW 하면 컨테이너가 중복 생성됨. IF go_con IS NOT BOUND 가드 필수.

DELETE ADJACENT DUPLICATES 전에 SORT 누락

DELETE ADJACENT DUPLICATES 는 "인접한" 중복만 제거하므로, 같은 키가 떨어져 있으면 안 지워집니다. 반드시 같은 키 기준으로 SORT 를 먼저 해야 합니다.

Field Catalog 미설정 — 컬럼 제어 불가

i_structure_name 만 넘기면 자동 Field Catalog 가 생성되지만, 컬럼 숨김/순서/제목 변경이 필요하면 LVC_FIELDCAT_MERGE FM 으로 gt_fcat 을 채운 뒤 수정해서 넘겨야 합니다.

Background 실행 시 덤프

이 패턴은 Dialog 전용. 배치 잡으로 돌리면 SAPGUI 가 없어서 컨테이너 생성 시점에 덤프 발생. 배치 호환이 필요하면 "[SAP ABAP] ALV 백그라운드 DUMP 방지" 글의 cl_gui_alv_grid=>offline( ) 분기 패턴을 함께 적용.


전체 코드 — 복사용 통합본

아래 통합본은 SE38 에 그대로 붙여 활성화 가능. SE51 에서 Screen 100 에 Custom Control 'CON1' 을 그린 뒤, Flow Logic 에 status_0100 · create_alv · user_command_0100 모듈 연결 + GUI Status 'S100' + Titlebar 'T100' 등록만 추가하면 완성.

*&---------------------------------------------------------------------*
*& Report ZRXX_ALV_CUSTOM_CONTAINER (예시)
*&---------------------------------------------------------------------*
*& Custom Container — SE51 Custom Control 'CON1' 에 ALV 부착
*&---------------------------------------------------------------------*
REPORT zrxx_alv_custom_container.

TABLES sflight.

* ★ 1) DATA 선언
DATA: go_grid TYPE REF TO cl_gui_alv_grid,
      go_con  TYPE REF TO cl_gui_custom_container,
      g_layo  TYPE lvc_s_layo,
      g_sort  TYPE lvc_s_sort,
      gt_fcat TYPE lvc_t_fcat,
      gs_fcat TYPE lvc_s_fcat.

DATA: gt_data TYPE TABLE OF sflight,
      ok_code TYPE sy-ucomm.

* ★ 2) 조회 조건
SELECT-OPTIONS: s_carrid FOR sflight-carrid.

* ★ 3) INITIALIZATION — 조회 조건 기본값
INITIALIZATION.
  s_carrid[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'AA' ) ).

* ★ 4) 데이터 조회 + 정렬/중복 제거 → CALL SCREEN
START-OF-SELECTION.
  SELECT *
    INTO TABLE @gt_data
    FROM sflight
   WHERE carrid IN @s_carrid.

  SORT gt_data BY carrid.
  DELETE ADJACENT DUPLICATES FROM gt_data COMPARING carrid.

END-OF-SELECTION.
  CALL SCREEN 100.

* ★ 5) PBO — Status / Titlebar
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'S100'.
  SET TITLEBAR  'T100' WITH '100화면'.
ENDMODULE.

* ★ 6) ★ 핵심: PBO — Custom Container + ALV 생성
MODULE create_alv OUTPUT.

  IF go_con IS NOT BOUND.              " 첫 PBO 에서만 1회 생성

* 6-1) Custom Container — SE51 'CON1' 과 연결 (이름 일치 필수)
    go_con = NEW #( container_name = 'CON1' ).

* 6-2) ALV Grid 를 Container 안에 부착
    go_grid = NEW #( i_parent = go_con ).

* 6-3) ALV 표시 (Field Catalog 자동)
    go_grid->set_table_for_first_display(
      EXPORTING
        i_structure_name = 'SFLIGHT'
      CHANGING
        it_fieldcatalog = gt_fcat
        it_outtab       = gt_data ).

  ENDIF.

ENDMODULE.

* ★ 7) PAI — BACK / EXIT / CANCEL 처리
MODULE user_command_0100 INPUT.

  CASE sy-ucomm.
    WHEN 'BACK' OR 'CANC' OR 'EXIT'.
      LEAVE TO SCREEN 0.
  ENDCASE.

ENDMODULE.

요약

단계 위치 핵심 행동
1 SE51 Screen 100 Custom Control 'CON1' 직접 그리기 (이름 지정)
2 DATA + SELECT-OPTIONS go_con + go_grid + s_carrid
3 INITIALIZATION + START-OF-SELECTION 조건 기본값 + SELECT + SORT/DELETE ADJACENT DUPLICATES
4 PBO create_alv (IS NOT BOUND 가드) custom_container(container_name='CON1') → go_grid
5 PAI user_command_0100 BACK/EXIT/CANCLEAVE TO SCREEN 0

Custom Container 의 본질은 "SE51 에 그린 Custom Control 이름과 ABAP 객체를 연결해 그 영역에 ALV 붙이기" 한 줄. container_name 이 SE51 Custom Control 이름과 정확히 일치해야 하고, IS NOT BOUND 가드로 PBO 재실행을 보호합니다. 컨테이너 시리즈의 기본 원형이라 여기를 이해하면 Splitter·Easy Splitter 로 확장이 자연스럽고, SE51 없이 코드만으로 영역을 만들고 싶으면 "[SAP ABAP] CL_GUI_DOCKING_CONTAINER" 패턴으로 넘어가면 됩니다.


Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.

CL_GUI_CUSTOM_CONTAINER 의 생성자 파라미터(container_name·parent·repid·dynnr) 는 NetWeaver 표준 정의(ECC 6.0 / S/4HANA on-premise 기준) 입니다. 적용 환경 버전에 따라 일부 차이가 있을 수 있으니 실제 적용 시 SE24 의 클래스 정의를 확인하시기 바랍니다. SFLIGHT 는 SAP 표준 학습 환경(IDES) 테이블이라 운영 시스템에는 없을 수 있으니, 실무 적용 시 운영 테이블로 교체하시기 바랍니다.