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

[SAP ABAP] ALV 필터 코드로 거는 법 — set_filter_criteria + 더블클릭 자동 필터 (LVC_T_FILT)

by Song.sh 2026. 5. 20.

ALV 화면을 쓰다 보면 "사용자가 그리드의 어떤 셀을 더블 클릭하면 그 값을 기준으로 자동 필터가 걸리게 해 달라" 는 요청이 자주 들어옵니다. 자재번호 컬럼의 셀을 더블 클릭하면 그 자재번호만 보이게, 플랜트 컬럼을 더블 클릭하면 그 플랜트만 남게 — Excel 의 자동 필터 비슷한 인터랙션을 ALV 에도 넣는 것입니다.

 

이 동작의 핵심은 cl_gui_alv_grid 의 표준 메소드 SET_FILTER_CRITERIA 입니다. LVC_T_FILT 타입의 필터 조건 테이블을 만들어 메소드에 넘기면 사용자가 화면에서 직접 필터를 거는 것과 동일한 결과가 나옵니다. 더블 클릭 이벤트(HANDLE_DOUBLE_CLICK) 와 결합하면 위에 말한 "셀 더블 클릭 → 자동 필터" 흐름이 한 화면 안에서 동작.

 

이 글은 SET_FILTER_CRITERIA 의 기본 호출 패턴 → 더블 클릭 자동 필터 → 필터 해제 → 흔히 빠뜨리는 함정(특히 REFRESH_TABLE_DISPLAYI_SOFT_REFRESH 주의사항) 까지 한 화면에 모은 실무 메모입니다.


핵심 — LVC_T_FILT 구조와 필드 한눈 비교

필터 조건 한 줄은 SELECT-OPTIONS 의 RANGES 줄과 거의 같은 구조입니다.

필드 의미 예시 값
FIELDNAME 필터를 걸 ALV 컬럼명 (Fieldcat 의 FIELDNAME) MATNR · WERKS
SIGN 포함 / 제외 I(Include) / E(Exclude)
OPTION 비교 연산자 EQ · BT · CP · GE · LE
LOW 시작값 (또는 단일값) 'TEST-MAT-001'
HIGH 끝값 (BT 등에서만 사용) 'TEST-MAT-999'

핵심 한 줄: SELECT-OPTIONS 의 RANGES 줄을 그대로 만들어 set_filter_criteria 에 넘긴 뒤 refresh. 사용자가 ALV 의 필터 아이콘으로 입력한 것과 동일한 결과가 화면에 적용됩니다.


1단계 — 기본 호출 패턴 (정적 필터)

가장 단순한 형태. ALV 화면 진입 시점에 특정 플랜트(예: 0001) 만 보이게 미리 필터를 걸어두는 경우.

DATA: gt_filter TYPE lvc_t_filt,
      ls_filter TYPE lvc_s_filt.

" 필터 한 줄 채우기
ls_filter-fieldname = 'WERKS'.
ls_filter-sign      = 'I'.       " Include
ls_filter-option    = 'EQ'.      " Equal
ls_filter-low       = '0001'.
APPEND ls_filter TO gt_filter.

" ALV 에 적용
CALL METHOD go_alvgrid->set_filter_criteria
  EXPORTING
    it_filter = gt_filter.

" 화면 새로고침 (★ I_SOFT_REFRESH 빈 값 유지 — 5단계 참조)
CALL METHOD go_alvgrid->refresh_table_display.

 

여러 조건을 동시에 걸려면 gt_filter 에 여러 줄을 APPEND 하면 됩니다. 같은 필드를 여러 줄로 넣으면 OR, 다른 필드끼리는 AND 로 묶입니다(SELECT-OPTIONS 와 동일).

" 자재 유형 'FERT' 또는 'HALB' + 플랜트 '0001'
APPEND VALUE #( fieldname = 'MTART' sign = 'I' option = 'EQ' low = 'FERT' ) TO gt_filter.
APPEND VALUE #( fieldname = 'MTART' sign = 'I' option = 'EQ' low = 'HALB' ) TO gt_filter.
APPEND VALUE #( fieldname = 'WERKS' sign = 'I' option = 'EQ' low = '0001' ) TO gt_filter.

" → (MTART = FERT OR HALB) AND WERKS = 0001

2단계 — 더블 클릭 이벤트로 자동 필터

ALV 의 DOUBLE_CLICK 이벤트를 잡아 사용자가 더블 클릭한 셀의 컬럼명·값으로 자동으로 필터를 거는 패턴.

" === 이벤트 핸들러 클래스 ===
CLASS lcl_event_handler DEFINITION.
  PUBLIC SECTION.
    METHODS handle_double_click
      FOR EVENT double_click OF cl_gui_alv_grid
      IMPORTING e_row e_column es_row_no.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.
  METHOD handle_double_click.

    DATA: lt_filter TYPE lvc_t_filt,
          ls_filter TYPE lvc_s_filt,
          lv_value  TYPE string.

    " 1) 더블 클릭한 행에서 셀 값 추출
    READ TABLE gt_data INTO DATA(ls_row) INDEX es_row_no-row_id.
    IF sy-subrc <> 0.
      RETURN.
    ENDIF.

    " 2) 클릭한 컬럼의 값을 동적으로 가져오기
    ASSIGN COMPONENT e_column-fieldname OF STRUCTURE ls_row TO FIELD-SYMBOL(<fs_val>).
    IF NOT <fs_val> IS ASSIGNED.
      RETURN.
    ENDIF.
    lv_value = <fs_val>.

    " 3) 필터 조건 한 줄 만들기
    ls_filter-fieldname = e_column-fieldname.
    ls_filter-sign      = 'I'.
    ls_filter-option    = 'EQ'.
    ls_filter-low       = lv_value.
    APPEND ls_filter TO lt_filter.

    " 4) ALV 에 적용
    CALL METHOD go_alvgrid->set_filter_criteria
      EXPORTING
        it_filter = lt_filter.

    " 5) Refresh (★ I_SOFT_REFRESH 빈 값)
    CALL METHOD go_alvgrid->refresh_table_display.

  ENDMETHOD.
ENDCLASS.

 

 

이벤트 핸들러 등록은 ALV 생성 직후에 한 번:

DATA(lo_handler) = NEW lcl_event_handler( ).
SET HANDLER lo_handler->handle_double_click FOR go_alvgrid.

이렇게 해 두면 사용자가 ALV 의 어느 셀이든 더블 클릭하는 순간 그 컬럼·값으로 자동 필터가 걸려 다른 행이 모두 사라집니다. Excel 의 자동 필터를 ABAP 으로 재현하는 셈.


3단계 — 필터 해제 (전체 행 다시 보이게)

사용자가 다시 모든 행을 보고 싶을 때는 빈 lt_filter 를 넘기면 됩니다.

" 필터 모두 해제
DATA(lt_filter_empty) = VALUE lvc_t_filt( ).   " 빈 테이블

CALL METHOD go_alvgrid->set_filter_criteria
  EXPORTING
    it_filter = lt_filter_empty.

CALL METHOD go_alvgrid->refresh_table_display.

GUI Status 의 "필터 초기화" 버튼 같은 USER_COMMAND 분기에서 이 코드를 호출하면 사용자가 한 번에 모든 필터를 해제할 수 있습니다.


4단계 — 현재 적용된 필터 가져오기

반대로 "현재 어떤 필터가 걸려 있는지" 도 표준 메소드로 조회 가능합니다. 화면을 저장하거나 변형을 만들 때 유용.

DATA lt_current_filter TYPE lvc_t_filt.

CALL METHOD go_alvgrid->get_filter_criteria
  IMPORTING
    et_filter = lt_current_filter.

LOOP AT lt_current_filter INTO DATA(ls_cur).
  WRITE: / |필드: { ls_cur-fieldname } 조건: { ls_cur-option } 값: { ls_cur-low }|.
ENDLOOP.

사용자가 화면에서 직접 필터를 걸어 둔 경우에도 같은 메소드로 조회됩니다.


5단계 — ★ REFRESH 시 I_SOFT_REFRESH 주의사항

가장 흔하게 빠뜨리는 함정이자 노트의 핵심. refresh_table_display 에는 I_SOFT_REFRESH 파라미터가 있습니다.

I_SOFT_REFRESH 동작 필터 적용 시
(빈 값) / ' ' Full Refresh — 행 구조 재계산 + 정렬·필터·소계 재적용 ✅ 정상 — 필터된 행만 보임
'X' Soft Refresh — 셀 값만 다시 그림 / 행 구조 유지 ❌ 필터가 적용 안 되어 보임 — 행이 그대로 다 보임
" ❌ 잘못된 호출 — 필터가 안 먹는 것처럼 보임
CALL METHOD go_alvgrid->refresh_table_display
  EXPORTING
    is_stable      = VALUE #( row = 'X' col = 'X' )
    i_soft_refresh = 'X'.     " ★ 이 한 줄 때문에 필터 무시

" ✅ 정상 호출 — i_soft_refresh 안 넘기거나 빈 값
CALL METHOD go_alvgrid->refresh_table_display.

왜 이런 동작인가: Soft Refresh 는 "표시되는 행 집합은 변경 없이 셀 값만 다시 그리겠다" 는 의도이므로, 필터로 행 집합이 바뀌어야 하는 케이스와는 어울리지 않습니다. 정렬·소계·필터 변경 후 호출하는 refresh_table_display항상 i_soft_refresh 를 빈 값으로 둬야 의도한 대로 동작합니다.

성능을 이유로 다른 곳에서 i_soft_refresh = 'X' 를 쓰고 있다면, 필터 변경 직후 한 번만은 빈 값으로 새로고침해야 화면이 정확하게 갱신됩니다.


흔히 빠뜨리는 함정

I_SOFT_REFRESH 잘못 설정

5단계에서 다룬 함정. 가장 자주 마주치는 사고. "필터를 거는 코드는 잘 짰는데 화면에 적용이 안 되는 것 같다" 는 증상이면 99% i_soft_refresh = 'X' 가 어딘가에 박혀 있는 경우.

FIELDNAME 대소문자 / 컬럼 미존재

ls_filter-fieldname = 'matnr'.   " ❌ 소문자
ls_filter-fieldname = 'MATNR_X'. " ❌ Fieldcat 에 없는 필드명

FIELDNAME 은 ALV Fieldcat 의 FIELDNAME 과 대문자로 정확히 일치 해야 합니다. 다르면 메소드는 에러 없이 통과하지만 필터는 안 걸립니다.

OPTION 값 잘못 입력

ls_filter-option = '='.    " ❌ '=' 아니라 'EQ'
ls_filter-option = '<>'.   " ❌ 'NE'

SELECT-OPTIONS 와 같이 EQ·NE·GT·GE·LT·LE·BT·NB·CP·NP 만 유효.

누적 필터 의도치 않음

" 새 필터 추가하려는데 기존 필터까지 같이 적용됨
DATA(lt_old_filter) = ... .  " 이전 필터
APPEND ls_new TO lt_old_filter.  " ❌ 이전 필터 위에 추가

set_filter_criteria전달된 필터로 통째 교체(전부 덮어쓰기) 입니다. 누적이 아닙니다. 이전 필터를 유지하면서 추가하고 싶다면 먼저 get_filter_criteria 로 현재 상태 받아온 뒤 그 위에 APPEND 해서 다시 SET.

빈 LOW 로 EQ 호출

ls_filter-option = 'EQ'.
ls_filter-low    = ''.    " ❌ 빈 값으로 EQ 필터

빈 값으로 EQ 필터를 걸면 "공백 행만 표시" 가 되어 거의 모든 행이 사라진 것처럼 보입니다. 더블 클릭 이벤트에서 셀이 비어 있을 가능성을 미리 분기로 처리.

IF lv_value IS INITIAL.
  RETURN.   " 빈 값은 필터 무시
ENDIF.

더블 클릭 이벤트 등록 누락

CLASS lcl_handler DEFINITION.
  METHODS handle_double_click ...
ENDCLASS.

" ❌ SET HANDLER 안 함 → 메소드 정의만 있고 안 불림

이벤트 핸들러 메소드를 만들었다면 반드시 SET HANDLER lo_handler->handle_double_click FOR go_alvgrid 으로 ALV 인스턴스에 등록해야 동작.

cl_salv_table 사용 시

DATA(lo_salv) = ... .   " cl_salv_table 사용 중
lo_salv->set_filter_criteria( ... ).   " ❌ 메소드 없음

set_filter_criteriacl_gui_alv_grid 전용. SALV(cl_salv_table) 환경에서는 cl_salv_filtersadd_filter( ) 메소드로 대체.


전체 코드 — 복사용 통합본

ALV 더블 클릭 자동 필터 + 필터 해제 버튼 + 정적 초기 필터까지 모두 들어간 미니 리포트 예제.

REPORT zr_alv_filter_demo.

TABLES: mara.

DATA: gt_data    TYPE TABLE OF mara,
      go_alvgrid TYPE REF TO cl_gui_alv_grid,
      go_dock    TYPE REF TO cl_gui_docking_container.

* === 이벤트 핸들러 클래스 ===
CLASS lcl_handler DEFINITION.
  PUBLIC SECTION.
    METHODS handle_double_click
      FOR EVENT double_click OF cl_gui_alv_grid
      IMPORTING e_row e_column es_row_no.

    METHODS handle_user_command
      FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING e_ucomm.
ENDCLASS.

CLASS lcl_handler IMPLEMENTATION.

  METHOD handle_double_click.
    DATA: lt_filter TYPE lvc_t_filt,
          lv_value  TYPE string.

    READ TABLE gt_data INTO DATA(ls_row) INDEX es_row_no-row_id.
    IF sy-subrc <> 0.
      RETURN.
    ENDIF.

    ASSIGN COMPONENT e_column-fieldname OF STRUCTURE ls_row TO FIELD-SYMBOL(<fs_val>).
    IF NOT <fs_val> IS ASSIGNED.
      RETURN.
    ENDIF.
    lv_value = <fs_val>.

    " 빈 값 분기
    IF lv_value IS INITIAL.
      RETURN.
    ENDIF.

    " 필터 한 줄
    APPEND VALUE #(
      fieldname = e_column-fieldname
      sign      = 'I'
      option    = 'EQ'
      low       = lv_value ) TO lt_filter.

    " 적용
    CALL METHOD go_alvgrid->set_filter_criteria
      EXPORTING it_filter = lt_filter.

    " ★ i_soft_refresh 빈 값 (Full Refresh)
    CALL METHOD go_alvgrid->refresh_table_display.
  ENDMETHOD.

  METHOD handle_user_command.
    CASE e_ucomm.
      WHEN 'FILTER_CLEAR'.
        " 필터 모두 해제
        DATA(lt_empty) = VALUE lvc_t_filt( ).
        CALL METHOD go_alvgrid->set_filter_criteria
          EXPORTING it_filter = lt_empty.
        CALL METHOD go_alvgrid->refresh_table_display.

        MESSAGE '모든 필터가 해제되었습니다.' TYPE 'S'.
    ENDCASE.
    CLEAR sy-ucomm.
  ENDMETHOD.

ENDCLASS.

* === 메인 로직 ===
START-OF-SELECTION.

  SELECT * FROM mara INTO TABLE gt_data UP TO 100 ROWS.

  CALL SCREEN 100.

* === 화면 100 PBO ===
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'STATUS_0100'.

  IF go_alvgrid IS INITIAL.
    " 1) ALV 그리드 생성
    CREATE OBJECT go_dock
      EXPORTING
        repid = sy-repid
        dynnr = sy-dynnr
        side  = cl_gui_docking_container=>dock_at_left
        ratio = 90.

    CREATE OBJECT go_alvgrid
      EXPORTING i_parent = go_dock.

    " 2) ALV 표시
    CALL METHOD go_alvgrid->set_table_for_first_display
      EXPORTING
        i_structure_name = 'MARA'
      CHANGING
        it_outtab        = gt_data.

    " 3) 이벤트 핸들러 등록
    DATA(lo_handler) = NEW lcl_handler( ).
    SET HANDLER lo_handler->handle_double_click FOR go_alvgrid.
    SET HANDLER lo_handler->handle_user_command FOR go_alvgrid.

    " 4) 초기 정적 필터 (예: 자재유형 = FERT 만)
    DATA(lt_init_filter) = VALUE lvc_t_filt(
      ( fieldname = 'MTART' sign = 'I' option = 'EQ' low = 'FERT' ) ).

    CALL METHOD go_alvgrid->set_filter_criteria
      EXPORTING it_filter = lt_init_filter.

    CALL METHOD go_alvgrid->refresh_table_display.
  ENDIF.
ENDMODULE.

* === 화면 100 PAI ===
MODULE user_command_0100 INPUT.
  CASE sy-ucomm.
    WHEN 'EXIT' OR 'BACK' OR 'CANCEL'.
      LEAVE PROGRAM.
  ENDCASE.
  CLEAR sy-ucomm.
ENDMODULE.

GUI Status STATUS_0100 의 Application Toolbar 에 FILTER_CLEAR 버튼만 추가하면 끝. 실행 후 ALV 의 어느 셀이든 더블 클릭하면 그 컬럼 값으로 자동 필터되고, 툴바의 "필터 초기화" 버튼으로 한 번에 해제됩니다.


요약

단계 작업 핵심
1 LVC_T_FILT 구조 채우기 FIELDNAME · SIGN · OPTION · LOW · HIGH
2 set_filter_criteria 호출 cl_gui_alv_grid 인스턴스 메소드 — 전체 교체
3 refresh_table_display I_SOFT_REFRESH 반드시 빈 값
4 더블 클릭 자동 필터 handle_double_click + ASSIGN COMPONENT
5 필터 해제 / 조회 lt_filter 전달 / get_filter_criteria

set_filter_criteria 는 ALV 의 사용성을 한 단계 끌어올리는 작은 메소드입니다. 사용자가 화면에서 직접 필터 아이콘을 눌러 입력하지 않아도, 더블 클릭 한 번으로 같은 결과를 만들 수 있습니다. 코드는 한 줄 같지만 잊기 쉬운 함정 한 가지(I_SOFT_REFRESH) 만 조심하면 안정적으로 운영 가능하고, 같은 패턴을 정렬 자동화·소계 자동화에도 응용할 수 있습니다.


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

cl_gui_alv_gridset_filter_criteria · get_filter_criteria · refresh_table_display 메소드와 DOUBLE_CLICK 이벤트는 SAP 표준 ALV Grid 제어 메커니즘으로 ECC 6.0 / S/4HANA on-premise 환경에서 동일하게 동작합니다. refresh_table_displayi_soft_refresh = 'X' 옵션은 ITAB 의 셀 값만 변경된 케이스에서 성능을 위해 사용하며, 필터·정렬·소계처럼 행 구조가 변경되는 경우에는 반드시 빈 값으로 호출해야 합니다(SAP 표준 동작).

 

SALV(cl_salv_table) 기반 ALV 에서는 cl_salv_filtersadd_filter( ) 메소드로 동일 개념을 구현할 수 있으며, Fiori / SAPUI5 환경에서는 sap.ui.model.Filter 객체로 대체됩니다.