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

[SAP ABAP] SALV 두 개를 한 화면에 위·아래 분할 — SPLITTER + default_screen (CL_SALV_TABLE factory)

by Song.sh 2026. 6. 2.

SALV(CL_SALV_TABLE) 두 개를 한 화면에 위/아래로 나란히 띄우고 싶을 때 가장 짧게 짤 수 있는 패턴이 CL_GUI_SPLITTER_CONTAINER + cl_gui_container=>default_screen 조합입니다. SE51 에서 화면을 만들 필요도 없고 모듈풀로 짜지 않아도 됩니다 — 단순 REPORT 하나면 끝.

 

핵심 트릭은 parent = cl_gui_container=>default_screen 입니다. SAP GUI 의 리스트 출력 영역(WRITE 명령이 그려지는 화면) 을 곧바로 Splitter 의 부모로 잡아 행/열로 쪼개면, 각 영역이 CL_SALV_TABLE 의 컨테이너로 그대로 쓸 수 있게 됩니다.

 

이 글에서는 SALV 두 개를 위/아래로 띄우는 가장 짧은 패턴을 단계별로 정리합니다. 데이터는 SAP 스탠다드 학습 환경 테이블 SCARR(항공사 마스터) + SPFLI(항공편 스케줄) 예시.

핵심 — SALV + Splitter 의 컨테이너 계층

계층 클래스 역할
1. 화면 영역 cl_gui_container=>default_screen SAP GUI 리스트 출력 영역 (WRITE 가 그려지는 곳)
2. Splitter cl_gui_splitter_container 화면을 N×M 분할 (rows·columns 지정)
3. 영역 cl_gui_container (top / bottom) Splitter get_container( row column ) 로 잡은 각 칸
4. SALV cl_salv_table FACTORY 호출 시 r_container 인자에 영역 전달
5. 출력 REPORT 의 list-processing cl_abap_list_layout=>suppress_toolbar( ) + WRITE : space

전체 흐름을 그림으로 정리하면:

SAP GUI 리스트 화면 (default_screen)
        ↓ parent
cl_gui_splitter_container (rows=2 columns=1)
        ↓ get_container( row=1 column=1 )      get_container( row=2 column=1 )
   o_container_top                         o_container_bottom
        ↓ r_container                            ↓ r_container
   cl_salv_table FACTORY (it_scarr)         cl_salv_table FACTORY (it_spfli)
        ↓ display( )                             ↓ display( )
   상단 Airline ALV                          하단 Flight schedule ALV

핵심은 두 가지. (1) parent = cl_gui_container=>default_screen — Custom Container 만들 필요 없이 list-processing 화면을 그대로 잡아 씁니다. (2) CL_SALV_TABLE=>FACTORYr_container — SALV 가 어느 영역에 그려질지 지정. 두 개 인스턴스를 만들고 display 만 호출하면 끝.


1단계 — 데이터 준비

상단 / 하단에 띄울 두 인터널 테이블을 미리 채워 둡니다.

* 상단 — 항공사 마스터
SELECT * FROM scarr INTO TABLE @DATA(it_scarr).

* 하단 — 항공편 스케줄
SELECT * FROM spfli INTO TABLE @DATA(it_spfli).

테이블 타입 선언 없이 @DATA(it_scarr) 인라인 선언으로 받으면 코드가 짧아집니다. CL_SALV_TABLE=>FACTORYt_table 파라미터는 STANDARD TABLE 이면 어떤 구조든 받습니다.


2단계 — Splitter 컨테이너 생성

parent = cl_gui_container=>default_screen 으로 Splitter 를 만들고 2행 1열로 분할.

DATA : o_splitter_main    TYPE REF TO cl_gui_splitter_container,
       o_container_top    TYPE REF TO cl_gui_container,
       o_container_bottom TYPE REF TO cl_gui_container.

o_splitter_main = NEW #(
  parent                  = cl_gui_container=>default_screen
  no_autodef_progid_dynnr = abap_true
  rows                    = 2
  columns                 = 1 ).

* 첫 행 높이를 30 으로 (전체 100 기준)
o_splitter_main->set_row_height( id = 1 height = 30 ).

* 두 영역 참조 받기
o_container_top    = o_splitter_main->get_container( row = 1 column = 1 ).
o_container_bottom = o_splitter_main->get_container( row = 2 column = 1 ).
파라미터 의미
parent cl_gui_container=>default_screen = SAP GUI 의 리스트 출력 영역
no_autodef_progid_dynnr abap_true — Splitter 가 자기 프로그램/화면을 자동으로 잡지 않도록 (REPORT 에서는 화면이 없으니 필수)
rows / columns 행/열 개수 (2×1 이면 위/아래 두 칸)
set_row_height 전체 100 기준 비율 — 30 이면 상단이 30%, 하단이 70%

no_autodef_progid_dynnr = abap_true 가 가장 중요한 옵션입니다. 빠뜨리면 Splitter 가 자기 부모 화면을 등록하려다 실패해서 컨테이너가 그려지지 않습니다. REPORT 출력 패턴에서는 무조건 박아두는 게 안전.


3단계 — CL_SALV_TABLE FACTORY 두 번 호출

각 영역에 SALV 인스턴스를 하나씩 생성. r_container 인자에 위에서 잡은 영역 참조를 넘기면 됩니다.

DATA : o_salv_top    TYPE REF TO cl_salv_table,
       o_salv_bottom TYPE REF TO cl_salv_table.

* 상단 — SCARR
cl_salv_table=>factory(
  EXPORTING r_container  = o_container_top
  IMPORTING r_salv_table = o_salv_top
  CHANGING  t_table      = it_scarr ).

* 하단 — SPFLI
cl_salv_table=>factory(
  EXPORTING r_container  = o_container_bottom
  IMPORTING r_salv_table = o_salv_bottom
  CHANGING  t_table      = it_spfli ).

CL_SALV_TABLE=>FACTORY 는 인터널 테이블 구조를 보고 컬럼 카탈로그를 자동으로 만들어 줍니다. SCARR 면 CARRID·CARRNAME·CURRCODE·URL 4컬럼 자동, SPFLI 면 CARRID·CONNID·CITYFROM·AIRPFROM·CITYTO·AIRPTO·FLTIME 등 자동.


4단계 — SALV 표준 설정

생성된 SALV 인스턴스에 자주 쓰는 4가지 설정을 박아 줍니다. get_functions·get_columns·get_display_settings·get_selections 메소드로 각 설정 객체를 얻은 뒤 짧은 setter 호출.

* 상단 SALV
o_salv_top->get_functions(        )->set_all( abap_true ).                    " 표준 툴바 다 켜기
o_salv_top->get_columns(          )->set_optimize( abap_true ).               " 컬럼 폭 자동
o_salv_top->get_display_settings( )->set_list_header( 'Airline' ).            " 헤더 텍스트
o_salv_top->get_display_settings( )->set_striped_pattern( abap_true ).        " 줄무늬
o_salv_top->get_selections(       )->set_selection_mode(
                                       if_salv_c_selection_mode=>row_column ).

o_salv_top->display( ).

* 하단 SALV — 같은 패턴
o_salv_bottom->get_functions(        )->set_all( abap_true ).
o_salv_bottom->get_columns(          )->set_optimize( abap_true ).
o_salv_bottom->get_display_settings( )->set_list_header( 'Flight schedule' ).
o_salv_bottom->get_display_settings( )->set_striped_pattern( abap_true ).
o_salv_bottom->get_selections(       )->set_selection_mode(
                                          if_salv_c_selection_mode=>row_column ).

o_salv_bottom->display( ).
설정 객체 자주 쓰는 setter
get_functions( ) set_all(스탠다드 툴바 표시) / set_default(기본만)
get_columns( ) set_optimize(폭 자동) / get_column(개별 컬럼)
get_display_settings( ) set_list_header(제목) / set_striped_pattern(줄무늬)
get_selections( ) set_selection_mode(row_column = 셀 클릭, multiple = 다중 선택)

5단계 — 화면 출력: suppress_toolbar + WRITE : space

SALV 두 개를 display( ) 만 하면 끝일 것 같지만, REPORT 의 list-processing 화면이 실제로 떠야 그 위에 그려진 SALV 가 보입니다. WRITE : space 한 줄 이 그 역할.

* 표준 list 툴바 숨기기 (SALV 가 자체 툴바를 띄우므로 중복 방지)
cl_abap_list_layout=>suppress_toolbar( ).

* list-processing 화면 진입 — 빈 출력이지만 화면은 떠야 함
WRITE : space.

cl_abap_list_layout=>suppress_toolbar( ) 는 SAP 스탠다드 list-processing 의 회색 툴바를 안 보이게. SALV 두 개가 각자 툴바를 띄우므로 위에 또 다른 표준 툴바가 깔리면 화면이 답답해집니다.

WRITE : space 는 실제로 보이는 출력은 없지만 ABAP 런타임이 "출력이 있다" 고 판단해서 list-processing 화면을 띄우게 만듭니다. SALV 의 display 만으로는 화면이 안 뜹니다.


자주 빠뜨리는 함정

no_autodef_progid_dynnr 누락

REPORT 에서 Splitter 를 만들 때 no_autodef_progid_dynnr = abap_true 를 빠뜨리면 Splitter 가 자기 프로그램/화면 ID 를 자동으로 등록하려다 실패합니다. 화면이 없으니 당연. 이 옵션은 default_screen 패턴에서 거의 필수.

WRITE : space 누락

display 호출만 하면 SALV 인스턴스는 생성되지만 화면이 안 뜹니다. list-processing 진입을 위해 WRITE : space 같은 출력 한 줄이 반드시 필요. 실수로 빠뜨리면 화면 자체가 안 떠서 SALV 가 보이지 않습니다.

suppress_toolbar 위치

cl_abap_list_layout=>suppress_toolbar( )WRITE 명령 전에 호출해야 적용됩니다. 순서를 바꾸면 무시되고 표준 툴바가 떠 버립니다.

CHANGING 인자 — STANDARD TABLE 필수

CL_SALV_TABLE=>FACTORYt_tableSTANDARD TABLE 만 받습니다. SORTED 나 HASHED 테이블을 넘기면 컴파일 시점에 못 잡고 런타임에 덤프. SELECT ... INTO TABLE @DATA(it_xx) 는 기본이 STANDARD 라 안전합니다.

set_row_height 비율

set_row_height( id height ) 의 height 는 픽셀이 아니라 전체 100 기준 비율. 30 이면 30%. 너무 작으면(예: 10) 헤더만 보이고 데이터가 잘립니다.

데이터 갱신 시 추가 호출 필요

data 가 바뀐 후 다시 보여주려면 o_salv_top->refresh( ) 호출. 단순히 인터널 테이블 내용만 바꿔서는 화면이 갱신되지 않습니다.

Splitter 인스턴스 보관

o_splitter_main 참조를 지역 변수에 두고 함수가 끝나면 GC 가 회수해버립니다. 글로벌 DATA 에 보관해야 화면이 떠 있는 동안 안전합니다.


전체 코드 — 복사용 통합본

SE38 에 그대로 붙여 활성화하면 됩니다. CALL SCREEN 없이 단일 REPORT 한 블록.

*&---------------------------------------------------------------------*
*& Report ZRXX_SALV_SPLITTER
*&---------------------------------------------------------------------*
REPORT zrxx_salv_splitter.

* ---------- 컨테이너 참조 ----------
DATA : o_splitter_main    TYPE REF TO cl_gui_splitter_container,
       o_container_top    TYPE REF TO cl_gui_container,
       o_container_bottom TYPE REF TO cl_gui_container.

* ---------- SALV 참조 ----------
DATA : o_salv_top    TYPE REF TO cl_salv_table,
       o_salv_bottom TYPE REF TO cl_salv_table.

START-OF-SELECTION.

* 1) 데이터
  SELECT * FROM scarr INTO TABLE @DATA(it_scarr).
  SELECT * FROM spfli INTO TABLE @DATA(it_spfli).

* 2) Splitter — default_screen 분할
  o_splitter_main = NEW #(
    parent                  = cl_gui_container=>default_screen
    no_autodef_progid_dynnr = abap_true
    rows                    = 2
    columns                 = 1 ).

  o_splitter_main->set_row_height( id = 1 height = 30 ).

  o_container_top    = o_splitter_main->get_container( row = 1 column = 1 ).
  o_container_bottom = o_splitter_main->get_container( row = 2 column = 1 ).

* 3) 상단 SALV — SCARR
  cl_salv_table=>factory(
    EXPORTING r_container  = o_container_top
    IMPORTING r_salv_table = o_salv_top
    CHANGING  t_table      = it_scarr ).

  o_salv_top->get_functions(        )->set_all( abap_true ).
  o_salv_top->get_columns(          )->set_optimize( abap_true ).
  o_salv_top->get_display_settings( )->set_list_header( 'Airline' ).
  o_salv_top->get_display_settings( )->set_striped_pattern( abap_true ).
  o_salv_top->get_selections(       )->set_selection_mode(
                                         if_salv_c_selection_mode=>row_column ).

  o_salv_top->display( ).

* 4) 하단 SALV — SPFLI
  cl_salv_table=>factory(
    EXPORTING r_container  = o_container_bottom
    IMPORTING r_salv_table = o_salv_bottom
    CHANGING  t_table      = it_spfli ).

  o_salv_bottom->get_functions(        )->set_all( abap_true ).
  o_salv_bottom->get_columns(          )->set_optimize( abap_true ).
  o_salv_bottom->get_display_settings( )->set_list_header( 'Flight schedule' ).
  o_salv_bottom->get_display_settings( )->set_striped_pattern( abap_true ).
  o_salv_bottom->get_selections(       )->set_selection_mode(
                                            if_salv_c_selection_mode=>row_column ).

  o_salv_bottom->display( ).

* 5) list-processing 화면 진입 + 표준 툴바 숨기기
  cl_abap_list_layout=>suppress_toolbar( ).
  WRITE : space.


요약

단계 위치 핵심
1 데이터 SELECT INTO TABLE @DATA(it_xx) 인라인 STANDARD TABLE
2 Splitter parent = cl_gui_container=>default_screen + no_autodef_progid_dynnr = abap_true
3 FACTORY cl_salv_table=>factory( r_container · r_salv_table · t_table )
4 설정 get_functions·get_columns·get_display_settings·get_selections + display( )
5 출력 cl_abap_list_layout=>suppress_toolbar( ) + WRITE : space

SALV + Splitter 의 본질은 "list-processing 의 default_screen 을 Splitter 로 쪼개고, 각 영역을 CL_SALV_TABLE FACTORY 의 r_container 로 넘기기". CALL SCREEN 도 없고 SE51 화면도 없고 모듈풀도 아닙니다. no_autodef_progid_dynnr = abap_true 와 마지막 WRITE : space 두 줄만 챙기면 SAP 스탠다드 SALV 의 모든 기능(정렬·필터·합계·엑셀 다운로드) 을 두 ALV 에서 모두 쓸 수 있습니다. 마스터/디테일 조회 화면을 가장 빠르게 만드는 패턴.


Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다. CL_SALV_TABLE·CL_GUI_SPLITTER_CONTAINER·CL_GUI_CONTAINER · CL_ABAP_LIST_LAYOUT · IF_SALV_C_SELECTION_MODE 는 NetWeaver 스탠다드 정의(ECC 6.0 / S/4HANA on-premise 기준) 입니다. SCARR·SPFLI 는 SAP 스탠다드 학습 환경(IDES) 테이블이며, 실무 적용 시 운영 테이블로 교체하시기 바랍니다. default_screen 패턴은 단순 조회 리포트에 적합하며, 편집 ALV / 사용자 입력이 필요한 화면은 SE51 Custom Screen 또는 Docking Container 패턴을 사용하시기 바랍니다.