참고 https://blog.naver.com/yury223/223046540489

PBO 모듈
MODULE SET_TREE_600 OUTPUT.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
IF G_TREE IS INITIAL.
PERFORM: CREATE_TREE_CONTAINER,
CREATE_NODE_EVENT,
BUILD_NODE_TABLE.
ENDIF.
ENDMODULE.
FORM CREATE_TREE_CONTAINER.
//* 트리
CREATE OBJECT GO_CUSTOM_CONTAINER_610
EXPORTING
CONTAINER_NAME = 'GV_CUSTOM_CONTAINER_610'.
CREATE OBJECT G_TREE
EXPORTING
PARENT = GO_CUSTOM_CONTAINER_610
NODE_SELECTION_MODE = CL_GUI_LIST_TREE=>NODE_SEL_MODE_SINGLE.
//* ALV
CREATE OBJECT GO_CUSTOM_CONTAINER_620
EXPORTING
CONTAINER_NAME = 'GV_CUSTOM_CONTAINER_620'.
ENDFORM.
FORM CREATE_NODE_EVENT.
DATA: LT_EVENTS TYPE CNTL_SIMPLE_EVENTS,
LS_EVENT TYPE CNTL_SIMPLE_EVENT.
CREATE OBJECT GO_NODE_EVENT_RECEIVER.
// 더블 클릭 시
SET HANDLER:
GO_NODE_EVENT_RECEIVER->HANDLE_NODE_DOUBLE_CLICK FOR G_TREE.
LS_EVENT-EVENTID = CL_GUI_SIMPLE_TREE=>EVENTID_NODE_DOUBLE_CLICK.
LS_EVENT-APPL_EVENT = 'X'.
APPEND LS_EVENT TO LT_EVENTS.
CALL METHOD G_TREE->SET_REGISTERED_EVENTS
EXPORTING
EVENTS = LT_EVENTS.
ENDFORM.
트리 노드 채우기
FORM BUILD_NODE_TABLE.
DATA LS_NODE LIKE MTREESNODE.
//* 부모노드
LS_NODE-NODE_KEY = 'PARENT1'. //"부모노드는 최상위라 RELATKEY가 필요없다.
LS_NODE-RELATKEY = ''.
LS_NODE-ISFOLDER = 'X'. //"폴더모양 / 설정하지 않으면 LEAF로 보여준다.
LS_NODE-TEXT = '근태'.
LS_NODE-EXPANDER = 'X'. //" 펼치냐 접냐
APPEND LS_NODE TO GT_NODE.
//* 자식노드1
CLEAR LS_NODE.
LS_NODE-NODE_KEY = 'CHILD1'.
LS_NODE-RELATKEY = 'PARENT1'.
LS_NODE-TEXT = '연차 가불'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
//* 자식노드2
CLEAR LS_NODE.
LS_NODE-NODE_KEY = 'CHILD2'.
LS_NODE-RELATKEY = 'PARENT1'.
LS_NODE-TEXT = '연차'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
//* 자식노드3
CLEAR LS_NODE.
LS_NODE-NODE_KEY = 'CHILD3'.
LS_NODE-RELATKEY = 'PARENT1'.
LS_NODE-TEXT = '보건휴가'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
//* 부모노드2
LS_NODE-NODE_KEY = 'PARENT2'.
LS_NODE-RELATKEY = ''.
LS_NODE-ISFOLDER = 'X'.
LS_NODE-TEXT = '연도'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
//* 자식노드2-1
CLEAR LS_NODE.
LS_NODE-NODE_KEY = 'P2_2025'.
LS_NODE-RELATKEY = 'PARENT2'.
LS_NODE-ISFOLDER = 'X'.
LS_NODE-TEXT = '2025'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
//* 자식노드2-2
CLEAR LS_NODE.
LS_NODE-NODE_KEY = 'P2_2024'.
LS_NODE-RELATKEY = 'PARENT2'.
LS_NODE-ISFOLDER = 'X'.
LS_NODE-TEXT = '2024'.
LS_NODE-EXPANDER = 'X'.
APPEND LS_NODE TO GT_NODE.
CALL METHOD G_TREE->ADD_NODES
EXPORTING
TABLE_STRUCTURE_NAME = 'MTREESNODE'
NODE_TABLE = GT_NODE.
ENDFORM.
//** 600번 SUB SCREEN
SELECTION-SCREEN BEGIN OF SCREEN 0610 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK B6 WITH FRAME." TITLE TEXT-000.
SELECTION-SCREEN BEGIN OF LINE.
//* 사원번호
SELECTION-SCREEN POSITION 15.
*SELECT-OPTIONS : RT_PER FOR ZPDCTTST4-PERNR NO INTERVALS NO-EXTENSION MODIF ID T01.
PARAMETERS : RT_PER TYPE ZPDCTTST4-PERNR MODIF ID T01.
SELECTION-SCREEN COMMENT 5(10) TEXT-001 MODIF ID T01.
SELECTION-SCREEN PUSHBUTTON 30(10) TEXT-013 USER-COMMAND DISP MODIF ID T01.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK B6.
SELECTION-SCREEN END OF SCREEN 0610.
지금은 좀 다르게 정리했던 거 같은데..
FORM ALV_NODE_DOUBLE_CLICK_1 USING PV_NODE_KEY.
DATA: LV_YEAR(5) TYPE C,
LV_NODE_KEY(5) TYPE C.
//" 유저커맨드로 가져갈 노드 키 값
GV_SELECTED_NODE_KEY = PV_NODE_KEY.
//* PTO_GUBUN
PERFORM GET_ZPDCTTST4_600_GUBUN USING PV_NODE_KEY.
//* 연도 노드키값에 p2_20이 포함되면
IF PV_NODE_KEY CP 'P2_20*'.
LV_NODE_KEY = PV_NODE_KEY+3(4).
CONCATENATE LV_NODE_KEY '%' INTO LV_YEAR.
CLEAR GT_ZPDCTTST4_600.
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PTO_DATE LIKE LV_YEAR.
//* 탭
ELSEIF PV_NODE_KEY CP 'PARENT3'.
PERFORM CLEAR_ZPDCTTST4_600.
PERFORM GET_ZPDCTTST4_600_TAB.
ENDIF.
IF G_ALV IS INITIAL.
CREATE OBJECT G_ALV
EXPORTING
I_PARENT = GO_CUSTOM_CONTAINER_620.
ENDIF.
PERFORM SET_FIELD_CATALOGS_600.
CLEAR RT_PER.
CALL METHOD G_ALV->set_table_for_first_display
CHANGING
IT_OUTTAB = GT_ZPDCTTST4_600[]
IT_FIELDCATALOG = GT_FIELDCAT6[].
ENDFORM.
FORM GET_ZPDCTTST4_600_GUBUN USING PV_NODE_KEY.
CASE PV_NODE_KEY.
WHEN 'PARENT1' OR 'PARENT2'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600.
WHEN 'CHILD1'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PTO_GUBUN = '00023'.
WHEN 'CHILD2'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PTO_GUBUN = '00001'.
WHEN 'CHILD3'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PTO_GUBUN = '00004'.
ENDCASE.
ENDFORM.
CASE SAVE_OK.
WHEN 'DISP'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
PERFORM GET_ZPDCTTST4_600_ALV.
ENDCASE.
FORM GET_ZPDCTTST4_600_ALV.
DATA: LV_YEAR(5) TYPE C,
LV_NODE_KEY(5) TYPE C,
GS_DATA TYPE ZPDCTTST4,
LT_FILTER_DATA TYPE TABLE OF ZPDCTTST4.
//* 노드 키 값 가져오기
LV_NODE_KEY = GV_SELECTED_NODE_KEY+3(4).
CONCATENATE LV_NODE_KEY '%' INTO LV_YEAR.
IF RT_PER IS INITIAL.
MESSAGE I000(ZMCPD) WITH '사원 번호를 입력해주세요.'.
EXIT.
ENDIF.
IF GV_SELECTED_NODE_KEY IS INITIAL.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PERNR = RT_PER.
//" 연도
ELSEIF GV_SELECTED_NODE_KEY CP 'P2_20*'.
CLEAR: GT_ZPDCTTST4_600, GT_ZPDCTTST4_600[].
SELECT *
FROM ZPDCTTST4
INTO TABLE GT_ZPDCTTST4_600
WHERE PERNR = RT_PER
AND PTO_DATE LIKE LV_YEAR.
//" 근태구분
ELSE.
PERFORM GET_ZPDCTTST4_600_GUBUN USING GV_SELECTED_NODE_KEY.
LOOP AT GT_ZPDCTTST4_600 INTO GS_DATA.
IF GS_DATA-PERNR = RT_PER.
APPEND GS_DATA TO LT_FILTER_DATA.
ENDIF.
ENDLOOP.
CLEAR GT_ZPDCTTST4_600.
GT_ZPDCTTST4_600[] = LT_FILTER_DATA[].
ENDIF.
IF SY-SUBRC <> 0.
MESSAGE I000(ZMCPD) WITH '해당하는 근태 정보가 없습니다.'.
RETURN.
ENDIF.
CALL METHOD G_ALV->set_table_for_first_display
CHANGING
IT_OUTTAB = GT_ZPDCTTST4_600[]
IT_FIELDCATALOG = GT_FIELDCAT6[].
ENDFORM.