본문 바로가기
ABAP/개발Tip

[개발Tip] CL_GUI_SIMPLE_TREE 사용 방법

by name_text 2023. 10. 16.

CL_GUI_SIMPLE_TREE

 

SIMPLE_TREE는 단일 컬럼으로 계층구조의 데이터를 표현하는 가장 단순한 형태의 트리 컨트롤입니다.

사용방법은 현재 노드에 부모 노드를 지정하여 계층구조로 데이터를 만들어서 트리형태로 표시하게 됩니다.

 

#1. 노드 데이터

자주 사용하는 필드에 대한 설명

필드명 설명
NODE_KEY 노드의 키값으로 중복 금지  
RELATKEY 상위 노드의 키값  
HIDDEN 숨김 여부 'X' : 숨김, ' ' : 표시
DISABLED 트리 이벤트 비활성화 여부 'X' : 이벤트 비활성화, ' ' : 활성화
ISFOLDER 폴더 여부 'X' : 폴더, ' ' : Leaf
N_IMAGE 기본 이미지(아이콘) ICONNAME 형식
EXP_IMAGE 폴더가 펼쳐졌을때 이미지(아이콘) ICONNAME 형식
STYLE 텍스트 스타일 CL_TREE_CONTROL_BASE=>STYLE_DEFAULT              "Normal
CL_TREE_CONTROL_BASE=>STYLE_INACTIVE             "Grey
CL_TREE_CONTROL_BASE=>STYLE_INTENSIFD_CRITICAL   "Red
CL_TREE_CONTROL_BASE=>STYLE_INTENSIFIED          "Blue
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED           "Yellow background
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_NEGATIVE  "Red background
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_POSITIVE  "Green background
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_A         "Blue background
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_B         "Grey background
CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_C         "Orange background
TEXT 텍스트  

 

#2. 이벤트

 -. Double Click, Drag 등 여러 이벤트가 지원되며 NODE_DOUBLE_CLICK은 거의 필수로 사용한다

 -. 트리의 Set_registered_events 메소드를 통해 이벤트를 등록해야 이벤드 핸들러 호출이 가능하며,

    이벤트 등록(set_registered_events)시 APPL_EVENT =  'X' 지정하면 GUI_STATUS 이벤트처럼 PBO/PAI가 호출된다

GO_GUI_SIMPLE_TREE->SET_REGISTERED_EVENTS(
    EXPORTING EVENTS = VALUE #( ( EVENTID = CL_GUI_SIMPLE_TREE=>EVENTID_NODE_DOUBLE_CLICK
                                  APPL_EVENT = ' ' ) ) ).     "APPL_EVENT : X = 애플리케이션 이벤트가 되므로 PBO 및 PAI가 호출됨

 

#3. 소스코드 예시

관리회계의 각종 그룹(코스트센터 등)을 트리로 보여주는 리포트

P_CLASS로 표시할 그룹 선택 

  > 0101 : 코스트센터 그룹

  > 0102 : 원가요소 그룹

  > 0106 : 손익센터 그룹

REPORT YSAND_BOX_001.

* 트리관련 전역 변수
  DATA: GO_GUI_SIMPLE_TREE TYPE REF TO CL_GUI_SIMPLE_TREE.
  DATA: GT_NODES TYPE STANDARD TABLE OF MTREESNODE.   "트리에 표시할 노드

* Selection Screen
  PARAMETERS: P_KOKRS TYPE TKA01-KOKRS OBLIGATORY MEMORY ID CAC,
              P_CLASS TYPE SETHEADER-SETCLASS OBLIGATORY DEFAULT '0101'.

* 트리 이벤트
  CLASS LCL_TREE_EVENT_RECEIVER DEFINITION.
    PUBLIC SECTION.
      METHODS: HANDLE_NODE_DOUBLE_CLICK FOR EVENT NODE_DOUBLE_CLICK OF CL_GUI_SIMPLE_TREE IMPORTING NODE_KEY.
  ENDCLASS.
  CLASS LCL_TREE_EVENT_RECEIVER IMPLEMENTATION.
    METHOD HANDLE_NODE_DOUBLE_CLICK.
      IF GT_NODES[ NODE_KEY = NODE_KEY ]-ISFOLDER EQ 'X'. "현재 노드가 폴더면 펼치기
        GO_GUI_SIMPLE_TREE->EXPAND_NODE(
          EXPORTING
            NODE_KEY            = NODE_KEY
*            LEVEL_COUNT         =
*            EXPAND_SUBTREE      =
          EXCEPTIONS
            FAILED              = 1
            ILLEGAL_LEVEL_COUNT = 2
            CNTL_SYSTEM_ERROR   = 3
            NODE_NOT_FOUND      = 4
            CANNOT_EXPAND_LEAF  = 5
            others              = 6
               ).
        IF SY-SUBRC NE 0.

        ENDIF.
*        "현재 노드의 펼침여부에 따라 펼치기/접기 구분 처리
*        DATA LT_NODES TYPE TREEV_NKS.
*
*        GO_GUI_SIMPLE_TREE->GET_EXPANDED_NODES(
**          EXPORTING
**            NO_HIDDEN_NODES   =
*          CHANGING
*            NODE_KEY_TABLE    = LT_NODES
*          EXCEPTIONS
*            CNTL_SYSTEM_ERROR = 1
*            DP_ERROR          = 2
*            FAILED            = 3
*            others            = 4
*               ).
*        IF SY-SUBRC <> 0.
**         Implement suitable error handling here
*        ENDIF.
*
*        IF LINE_EXISTS( LT_NODES[ TABLE_LINE = NODE_KEY ] ).
*          LT_NODES = VALUE #( ( NODE_KEY ) ).
*          GO_GUI_SIMPLE_TREE->COLLAPSE_NODES(
*            EXPORTING
*              NODE_KEY_TABLE          = LT_NODES
*            EXCEPTIONS
*              FAILED                  = 1
*              CNTL_SYSTEM_ERROR       = 2
*              ERROR_IN_NODE_KEY_TABLE = 3
*              DP_ERROR                = 4
*              others                  = 5
*                 ).
*        ELSE.
*          GO_GUI_SIMPLE_TREE->EXPAND_NODE(
*            EXPORTING
*              NODE_KEY            = NODE_KEY
**              LEVEL_COUNT         =
**              EXPAND_SUBTREE      =
*            EXCEPTIONS
*              FAILED              = 1
*              ILLEGAL_LEVEL_COUNT = 2
*              CNTL_SYSTEM_ERROR   = 3
*              NODE_NOT_FOUND      = 4
*              CANNOT_EXPAND_LEAF  = 5
*              others              = 6
*                 ).
*        ENDIF.
      ELSE.     "노드가 폴더가 아닌 경우
        MESSAGE I000(0K) WITH NODE_KEY.
      ENDIF.

    ENDMETHOD.
  ENDCLASS.

START-OF-SELECTION.

  SELECT SINGLE
    *
  FROM TKA01
  WHERE KOKRS EQ @P_KOKRS
  INTO @DATA(LS_TKA01).
  IF SY-SUBRC NE 0.
    EXIT.
  ENDIF.
  DATA(LV_KHINR) = SWITCH #( P_CLASS WHEN '0101' THEN LS_TKA01-KHINR    "코스트센터 그룹
                                     WHEN '0106' THEN LS_TKA01-PHINR    "손익센터 그룹
                                     WHEN '0102' THEN 'K8000'           "원가요소그룹
                                     ).
  DATA(LV_SUBCLASS) = SWITCH #( P_CLASS WHEN '0102' THEN LS_TKA01-KTOPL
                                        ELSE P_KOKRS ).

  CHECK LV_KHINR IS NOT INITIAL. 

  "트리에 표시할 노드 데이터
  CLEAR GT_NODES.
  PERFORM SET_NODES USING P_KOKRS
                          P_CLASS
                          LV_SUBCLASS
                          LV_KHINR.

  "트리가 포함된 스크린 호출
  SKIP.   "Parent를 CL_GUI_CONTAINER=>SCREEN0 를 사용하기 위해 공백 삽입
  PERFORM CREATE_SIMPLE_TREE.

*&---------------------------------------------------------------------*
*&      Form  SET_NODES
*&---------------------------------------------------------------------*
*       SET 데이터를 이용하여 트리형태 구성
*----------------------------------------------------------------------*
*      -->P_0050   text
*----------------------------------------------------------------------*
FORM SET_NODES  USING   P_KOKRS
                        P_SETCLASS
                        P_SUBCLASS
                        P_SETNAME.
  DATA(LS_MASTER_DATA) = VALUE GRPHP1( MDCHECK  = 'X'
                                       BREAKINT = 'X'
                                       SHOWTXT  = 'X' ).
  DATA: LT_NODES        TYPE GSETH_NODE_TAB,
        LT_VALUES_STD   TYPE GSETH_VAL_TAB,
        LT_MASTER_STD   TYPE GSETH_MD_TAB,
        LT_VALUES       TYPE SORTED TABLE OF GSETH_VAL_LINE WITH NON-UNIQUE KEY SETID,
        LT_MASTER_DATA  TYPE SORTED TABLE OF GSETH_MD_LINE WITH NON-UNIQUE KEY NAME,
        LS_INFO         TYPE GRPHINFO,
        LV_OVERWRITE    TYPE SY-DATAR VALUE 'X',
        LV_SETID        TYPE SETHIER-SETID,
        LV_RELATKEY     TYPE TV_NODEKEY,
        LV_TABIX        TYPE SY-TABIX.
  RANGES LR_LEAF FOR SETLEAF-VALFROM.

  LV_SETID = |{ P_SETCLASS }{ P_SUBCLASS }{ P_SETNAME }|.

  CALL FUNCTION 'K_HIERARCHY_TABLES_READ'
    EXPORTING
      E_CLASS                           = P_SETCLASS
      E_SETID                           = LV_SETID
      E_KOKRS                           = P_KOKRS
      E_MASTER_DATA                     = LS_MASTER_DATA
    TABLES
      T_NODES                           = LT_NODES
      T_VALUES                          = LT_VALUES_STD
      T_MASTER_DATA                     = LT_MASTER_STD
    CHANGING
      C_INFO                            = LS_INFO
      C_OVERWRITE                       = LV_OVERWRITE
    EXCEPTIONS
      NO_CONTROLLING_AREA               = 1
      NO_CHART_OF_ACCOUNT               = 2
      DIFFERENT_CONTROLLING_AREAS       = 3
      DIFFERENT_CHART_OF_ACCOUNTS       = 4
      SET_NOT_FOUND                     = 5
      ILLEGAL_FIELD_REPLACEMENT         = 6
      ILLEGAL_TABLE_REPLACEMENT         = 7
      FM_RAISE                          = 8
      CONVERT_ERROR                     = 9
      NO_OVERWRITE_STANDARD_HIER        = 10
      NO_BUKRS_FOR_KOKRS                = 11
      OTHERS                            = 12
            .
  IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    EXIT.
  ENDIF.

  LT_VALUES = CORRESPONDING #( LT_VALUES_STD ).
  LT_MASTER_DATA = CORRESPONDING #( LT_MASTER_STD ).

  LOOP AT LT_NODES INTO DATA(LS_NODES).
    LV_TABIX = SY-TABIX.

    "상위노드 찾기
    CLEAR LV_RELATKEY.
    IF LS_NODES-HLEVEL > 0.
      WHILE LV_TABIX > 1.
        ADD -1 TO LV_TABIX.
        IF LT_NODES[ LV_TABIX ]-HLEVEL EQ LS_NODES-HLEVEL - 1.
          LV_RELATKEY = LT_NODES[ LV_TABIX ]-SHORTNAME.
          EXIT.
        ENDIF.
      ENDWHILE.
    ENDIF.

    "CLASS
      "CL_GUI_COLUMN_TREE=>ITEM_CLASS_TEXT.
      "CL_GUI_COLUMN_TREE=>ITEM_CLASS_CHECKBOX.
      "CL_GUI_COLUMN_TREE=>ITEM_CLASS_BUTTON.
      "CL_GUI_COLUMN_TREE=>ITEM_CLASS_LINK.
    "STYLE
      "CL_TREE_CONTROL_BASE=>STYLE_DEFAULT              "Normal
      "CL_TREE_CONTROL_BASE=>STYLE_INACTIVE             "Grey
      "CL_TREE_CONTROL_BASE=>STYLE_INTENSIFD_CRITICAL   "Red
      "CL_TREE_CONTROL_BASE=>STYLE_INTENSIFIED          "Blue
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED           "Yellow background
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_NEGATIVE  "Red background
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_POSITIVE  "Green background
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_A         "Blue background
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_B         "Grey background
      "CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_C         "Orange background

    "노드 추가
    APPEND VALUE #( NODE_KEY  = LS_NODES-SHORTNAME      "노드키
                    RELATKEY  = LV_RELATKEY       "상위 노드키
                    HIDDEN    = ' '         "숨김 여부
                    DISABLED  = ' '         "이벤트 비활성화 여부
                    ISFOLDER  = 'X'         "폴더 여부 (SPACE는 Leaf로 표시)
                    N_IMAGE   = ICON_TREE         "기본 이미지
                    EXP_IMAGE = ICON_TREE         "펼쳤을때 이미지
                    STYLE     = SWITCH #( LS_NODES-HLEVEL WHEN 0 THEN CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_POSITIVE
                                                                 ELSE CL_TREE_CONTROL_BASE=>STYLE_EMPHASIZED_C )
                    TEXT      = |{ LS_NODES-SHORTNAME }{ COND #( WHEN LS_NODES-DESCRIPT IS NOT INITIAL THEN | - { LS_NODES-DESCRIPT }| ) }| ) TO GT_NODES.

    CLEAR LR_LEAF[].
    LOOP AT LT_VALUES INTO DATA(LS_VALUES) WHERE SETID EQ LS_NODES-SETID.
      APPEND VALUE #( SIGN = 'I'  OPTION = 'BT'
                      LOW  = LS_VALUES-VFROM
                      HIGH = LS_VALUES-VTO ) TO LR_LEAF.
    ENDLOOP.

    IF LR_LEAF[] IS NOT INITIAL.
      "노드(리프) 추가
      LOOP AT LT_MASTER_DATA INTO DATA(LS_LEAF) WHERE NAME IN LR_LEAF.
        APPEND VALUE #( NODE_KEY  = LS_LEAF-NAME      "노드키
                        RELATKEY  = LS_NODES-SHORTNAME       "상위 노드키
                        HIDDEN    = ' '         "숨김 여부
                        DISABLED  = ' '         "이벤트 비활성화 여부
                        ISFOLDER  = ' '         "폴더 여부 (SPACE는 Leaf로 표시)
                        N_IMAGE   = SWITCH #( P_SETCLASS WHEN '0101' THEN ICON_COST_CENTER WHEN '0106' THEN ICON_PROFIT_CENTER )         "기본 이미지
                        TEXT      = |{ CONDENSE( |{ LS_LEAF-NAME ALPHA = OUT }| ) }{ COND #( WHEN LS_LEAF-TEXT IS NOT INITIAL THEN | - { LS_LEAF-TEXT }| ) }| ) TO GT_NODES.
      ENDLOOP.
    ENDIF.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  CREATE_SIMPLE_TREE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM CREATE_SIMPLE_TREE .
  CHECK GO_GUI_SIMPLE_TREE IS INITIAL.

  DATA LCL_TREE_EVENT TYPE REF TO LCL_TREE_EVENT_RECEIVER.

*  "트리를 표시한 컨테이너 생성
*  DATA LO_SPLITTER_CONTAINER  TYPE REF TO CL_GUI_SPLITTER_CONTAINER.
*  CREATE OBJECT LO_SPLITTER_CONTAINER
*    EXPORTING
*      PARENT  = CL_GUI_CONTAINER=>SCREEN0
*      ROWS    = 1
*      COLUMNS = 2
*    EXCEPTIONS
*      CNTL_ERROR        = 1
*      CNTL_SYSTEM_ERROR = 2
*      others            = 3.
*  IF SY-SUBRC <> 0.
*    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*               WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
*    EXIT.
*  ENDIF.
*
*  DATA(LO_GUI_CONTAINER1) = LO_SPLITTER_CONTAINER->GET_CONTAINER( EXPORTING ROW = 1 COLUMN = 1 ).
*  DATA(LO_GUI_CONTAINER2) = LO_SPLITTER_CONTAINER->GET_CONTAINER( EXPORTING ROW = 1 COLUMN = 2 ).
*
*  LO_SPLITTER_CONTAINER->SET_COLUMN_WIDTH( EXPORTING ID = 1 WIDTH = 20 ).

  "트리 오브젝트 생성
  CREATE OBJECT GO_GUI_SIMPLE_TREE
    EXPORTING
*      LIFETIME                    =
      PARENT                      = CL_GUI_CONTAINER=>SCREEN0   "트리를 표시할 컨테이너
*      SHELLSTYLE                  =
      NODE_SELECTION_MODE         = CL_GUI_SIMPLE_TREE=>NODE_SEL_MODE_SINGLE
*      HIDE_SELECTION              =
*      NAME                        =
    EXCEPTIONS
      LIFETIME_ERROR              = 1
      CNTL_SYSTEM_ERROR           = 2
      CREATE_ERROR                = 3
      FAILED                      = 4
      ILLEGAL_NODE_SELECTION_MODE = 5
      others                      = 6
      .
  IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
               WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    EXIT.
  ENDIF.

  "트리 이벤트 등록
  GO_GUI_SIMPLE_TREE->SET_REGISTERED_EVENTS(
    EXPORTING EVENTS = VALUE #( ( EVENTID = CL_GUI_SIMPLE_TREE=>EVENTID_NODE_DOUBLE_CLICK
                                  APPL_EVENT = ' ' ) ) ).     "APPL_EVENT : X = 애플리케이션 이벤트가 되므로 PBO 및 PAI가 호출됨

  CREATE OBJECT LCL_TREE_EVENT.
  SET HANDLER LCL_TREE_EVENT->HANDLE_NODE_DOUBLE_CLICK FOR GO_GUI_SIMPLE_TREE.

  "트리에 노드 추가
  GO_GUI_SIMPLE_TREE->ADD_NODES(
    EXPORTING
      TABLE_STRUCTURE_NAME           = 'MTREESNODE'
      NODE_TABLE                     = GT_NODES
    EXCEPTIONS
      ERROR_IN_NODE_TABLE            = 1
      FAILED                         = 2
      DP_ERROR                       = 3
      TABLE_STRUCTURE_NAME_NOT_FOUND = 4
      others                         = 5
         ).
  IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    EXIT.
  ENDIF.

  "루트 노드 펼치기
  GO_GUI_SIMPLE_TREE->EXPAND_ROOT_NODES( EXPORTING LEVEL_COUNT = 1 ).
ENDFORM.

 

댓글