树状导航程序本来只是我一次午饭后随手写的一个程序,一个中午加一个晚上做的,但是有兄弟觉着还不错,于是就有了第二版,改进了很多内容。第二版发布后又有兄弟提出了一些建议,于是更改了第三版,改进点大概有下面几点:
1、添加了完善的文档功能,并支持文档由电脑直接拖到SAP界面
2、添加新的节点后,不再重新在数据库读数刷新表,大大提升程序效率
3、优化用户操作细节
4、优化代码
界面:
*&---------------------------------------------------------------------*
*& Report ZNAVI_TREE
*&---------------------------------------------------------------------*
*& 可配置树状导航
*& Baitianzhen
*&---------------------------------------------------------------------*
REPORT znavi_tree NO STANDARD PAGE HEADING.
TABLES:zum1.
CLASS lcl_receiver DEFINITION DEFERRED.
DATA: go_container TYPE REF TO cl_gui_custom_container,
go_spliter TYPE REF TO cl_gui_splitter_container,
go_cont_tree TYPE REF TO cl_gui_container,
go_cont_imag TYPE REF TO cl_gui_container,
go_tree TYPE REF TO cl_gui_alv_tree,
go_grid TYPE REF TO cl_gui_alv_grid,
go_dragdrop TYPE REF TO cl_dragdrop,
go_toolbar TYPE REF TO cl_gui_toolbar,
go_picture TYPE REF TO cl_gui_picture,
go_receiver TYPE REF TO lcl_receiver,
gt_fldtree TYPE lvc_t_fcat,
gt_fldpop TYPE lvc_t_fcat,
gv_okcode TYPE sy-ucomm,
gv_picurl TYPE char255,
gv_fflag TYPE c, "文件夹标识
gv_swidth TYPE i,
gv_hwidth TYPE i.
DATA: gs_out TYPE zum1,
gt_out TYPE TABLE OF zum1,
gt_top TYPE TABLE OF zum1,
gt_all TYPE TABLE OF zum1
WITH NON-UNIQUE SORTED KEY k1 COMPONENTS upnod posnr.
DATA: BEGIN OF gs_atta OCCURS 0,
fname TYPE string,
fleng TYPE i,
erdat TYPE erdat,
erzet TYPE erzet,
ernam TYPE ernam,
seled TYPE c,
fcont TYPE w3mimetabtype,
END OF gs_atta.
DATA: gt_atta LIKE TABLE OF gs_atta.
*----------------------------------------------------------------------*
* CLASS lcl_dragdropobj DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_dragdropobj DEFINITION.
PUBLIC SECTION.
DATA: ls_out TYPE zum1,
lv_nkey TYPE lvc_nkey, "拖动的KEY
lv_pkey TYPE lvc_nkey. "父KEY
ENDCLASS. "lcl_dragdropobj DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_receiver DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_receiver DEFINITION.
PUBLIC SECTION.
METHODS grid_drop_external_files
FOR EVENT drop_external_files OF cl_gui_alv_grid
IMPORTING files.
METHODS on_drop_external_files
FOR EVENT on_drop_external_files OF cl_gui_alv_tree
IMPORTING node_key files.
METHODS handle_node_double_click
FOR EVENT node_double_click OF cl_gui_alv_tree
IMPORTING node_key sender.
METHODS handle_item_double_click
FOR EVENT item_double_click OF cl_gui_alv_tree
IMPORTING fieldname node_key sender.
METHODS handle_link_click
FOR EVENT link_click OF cl_gui_alv_tree
IMPORTING node_key fieldname sender.
METHODS handle_drag
FOR EVENT on_drag OF cl_gui_alv_tree
IMPORTING sender node_key fieldname drag_drop_object.
METHODS handle_drop
FOR EVENT on_drop OF cl_gui_alv_tree
IMPORTING sender drag_drop_object node_key.
METHODS on_function_selected
FOR EVENT function_selected OF cl_gui_toolbar
IMPORTING fcode.
METHODS on_dropdown_clicked
FOR EVENT dropdown_clicked OF cl_gui_toolbar
IMPORTING fcode posx posy.
ENDCLASS. "lcl_receiver DEFINITION
SELECT-OPTIONS: s_nodid FOR zum1-nodid NO INTERVALS.
SELECT-OPTIONS: s_exnod FOR zum1-nodid NO INTERVALS.
PARAMETERS: p_objid TYPE w3objid DEFAULT 'ENJOYSAP_LOGO',
p_title TYPE cua_tit_tx DEFAULT '可配置树状导航'(t00),
p_auchk AS CHECKBOX DEFAULT 'X',
p_chang AS CHECKBOX DEFAULT 'X',
p_ddrop AS CHECKBOX DEFAULT 'X',
p_exall AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN SKIP.
PARAMETERS var TYPE raldb_vari MODIF ID v.
SELECTION-SCREEN BEGIN OF SCREEN 1001 AS WINDOW.
PARAMETERS: p_ndtxt TYPE zum1-ndtxt OBLIGATORY,
p_ntype TYPE zum1-ntype
AS LISTBOX VISIBLE LENGTH 20 OBLIGATORY MODIF ID a,
p_tcode TYPE zum1-tcode OBLIGATORY MODIF ID a,
p_nicon TYPE zum1-nicon MODIF ID a,
p_kverm TYPE zum1-kverm,
p_w3url TYPE zum1-w3url.
SELECTION-SCREEN END OF SCREEN 1001.
INITIALIZATION.
PERFORM catset TABLES gt_fldtree
USING: 'NTYPE' '类型'(f01),
'TCODE' '事务/报表/维护表等'(f02),
'KVERM' '备注'(f03),
'W3URL' '链接'(f04),
'NODID' '节点ID'(f05).
AT SELECTION-SCREEN OUTPUT.
%_s_nodid_%_app_%-text = '要显示的节点'(t01).
%_s_exnod_%_app_%-text = '排除节点'(t02).
%_p_auchk_%_app_%-text = '检查TCODE权限'(t03).
%_p_chang_%_app_%-text = '修改模式'(t04).
%_p_ddrop_%_app_%-text = '允许拖放'(t05).
%_p_exall_%_app_%-text = '默认展开所有节点'(t06).
%_p_objid_%_app_%-text = '图片ID(SMW0上传)'(t07).
%_p_title_%_app_%-text = '导航界面Title'(t08).
%_p_ndtxt_%_app_%-text = '节点描述'(t09).
%_p_ntype_%_app_%-text = '功能类型'(t10).
%_p_tcode_%_app_%-text = '事务/报表/维护表'(t11).
%_p_nicon_%_app_%-text = '图标'(t12).
%_p_kverm_%_app_%-text = '备注'(t13).
%_p_w3url_%_app_%-text = '链接'(t14).
%_var_%_app_%-text = '传递变式用,请勿修改'(t15).
LOOP AT SCREEN.
IF gv_fflag = 'F' AND screen-group1 CA 'A'.
screen-active = '0'.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
IF sy-dynnr = '1001'.
PERFORM selscr_exfcode USING 'GET SPOS'.
SET CURSOR FIELD 'P_NDTXT'.
ENDIF.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_nicon.
CALL FUNCTION 'ICON_SHOW'
IMPORTING
icon_id = p_nicon
EXCEPTIONS
OTHERS = 1.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_tcode.
PERFORM tcodef4 CHANGING p_tcode.
START-OF-SELECTION.
IF var IS NOT INITIAL.
SUBMIT (sy-repid) USING SELECTION-SET var.
ELSE.
PERFORM get_all.
CALL SCREEN 200.
ENDIF.
*&---------------------------------------------------------------------*
*& Module STATUS_0200 OUTPUT
*&---------------------------------------------------------------------*
MODULE status_0200 OUTPUT.
SET PF-STATUS 'MAIN'.
SET TITLEBAR 'T001' WITH p_title.
CHECK go_container IS INITIAL.
PERFORM init_tree.
ENDMODULE. "status_0200 OUTPUT
*&---------------------------------------------------------------------*
*& MODULE user_command_0200 INPUT
*&---------------------------------------------------------------------*
MODULE user_command_0200 INPUT.
CASE gv_okcode.
WHEN 'EXIT' OR 'CANC'.
go_spliter->get_column_width( EXPORTING id = 1
IMPORTING result = gv_swidth ).
go_tree->get_hierarchy_header_width( IMPORTING e_width = gv_hwidth ).
cl_gui_cfw=>flush( ).
EXPORT swidth = gv_swidth
twidth = gv_hwidth TO DATABASE indx(nt) ID sy-uname.
LEAVE PROGRAM.
ENDCASE.
CLEAR gv_okcode.
ENDMODULE. "user_command_0200 INPUT
*&---------------------------------------------------------------------*
*& Form get_all
*&---------------------------------------------------------------------*
FORM get_all.
CLEAR: gt_all,gt_top.
IF s_exnod[] IS INITIAL.
SELECT * INTO TABLE gt_all FROM zum1.
ELSE.
SELECT * INTO TABLE gt_all FROM zum1
WHERE nodid NOT IN s_exnod.
ENDIF.
IF s_nodid[] IS INITIAL.
SELECT * INTO TABLE gt_top FROM zum1
WHERE upnod EQ '' AND
ntype EQ ''.
ELSE.
SELECT * INTO TABLE gt_top FROM zum1
WHERE nodid IN s_nodid AND
ntype EQ ''.
LOOP AT s_nodid. "根据S_NODID的顺序显示TOPNODE
READ TABLE gt_top INTO zum1 WITH KEY nodid = s_nodid-low.
IF sy-subrc = 0.
DELETE gt_top INDEX sy-tabix.
APPEND zum1 TO gt_top.
ENDIF.
ENDLOOP.
ENDIF.
ENDFORM. "get_all
*&---------------------------------------------------------------------*
*& TREE自带工具栏添加按钮
*&---------------------------------------------------------------------*
FORM add_toolbar_button.
go_tree->get_toolbar_object( IMPORTING er_toolbar = go_toolbar ).
PERFORM add_button USING: ' ' ' ' 3 ' ' '',
'FC_REFR' '@42@' 0 ' ' '刷新'(t20),
' ' ' ' 3 ' ' '',
'FC_ATTA' '@0S@' 0 '文档'(t34) '显示节点文档'(t35).
IF p_chang = 'X'.
PERFORM add_button USING: ' ' ' ' 3 ' ' '',
'FC_NEW ' '@0Y@' 2 '新建'(t21) '',
'FC_EDIT' '@0Z@' 0 ' ' '修改节点数据'(t22),
'FC_DELE' '@11@' 0 ' ' '删除节点及子节点'(t23).
ENDIF.
ENDFORM. "add_toolbar_button
*&---------------------------------------------------------------------*
*& Form add_button
*&---------------------------------------------------------------------*
FORM add_button USING pv_fcode pv_icon pv_type pv_text pv_info.
go_toolbar->add_button( EXPORTING
fcode = pv_fcode
icon = pv_icon
butn_type = pv_type
text = pv_text
quickinfo = pv_info ).
ENDFORM. "add_button
*&---------------------------------------------------------------------*
*& 获取图片URL,图片使用SMW0上传
*&---------------------------------------------------------------------*
FORM get_pic_url USING pv_mimenam CHANGING cv_url.
DATA lt_query TYPE TABLE OF w3query.
DATA ls_query TYPE w3query.
DATA lt_html TYPE TABLE OF w3html.
DATA lv_code TYPE w3param-ret_code.
DATA lv_type TYPE w3param-cont_type.
DATA lv_length TYPE w3param-cont_len.
DATA lt_picture TYPE TABLE OF w3mime.
DATA lv_size TYPE i.
ls_query-name = '_OBJECT_ID'.
ls_query-value = pv_mimenam. "'ENJOYSAP_LOGO'.
APPEND ls_query TO lt_query.
CALL FUNCTION 'WWW_GET_MIME_OBJECT'
TABLES
query_string = lt_query
html = lt_html
mime = lt_picture
CHANGING
return_code = lv_code
content_type = lv_type
content_length = lv_length
EXCEPTIONS
OTHERS = 3.
IF sy-subrc = 0.
lv_size = lv_length.
ELSE.
RETURN.
ENDIF.
CALL FUNCTION 'DP_CREATE_URL'
EXPORTING
type = 'image'
subtype = cndp_sap_tab_unknown
size = lv_size
lifetime = cndp_lifetime_transaction
TABLES
data = lt_picture
CHANGING
url = cv_url
EXCEPTIONS
OTHERS = 1.
ENDFORM. "get_pic_url
*&---------------------------------------------------------------------*
*& Form register_events
*&---------------------------------------------------------------------*
FORM register_events.
DATA: lt_event TYPE cntl_simple_events,
ls_event TYPE cntl_simple_event.
go_tree->get_registered_events( IMPORTING events = lt_event ).
ls_event-eventid = cl_gui_column_tree=>eventid_node_double_click.
APPEND ls_event TO lt_event.
ls_event-eventid = cl_gui_column_tree=>eventid_item_double_click.
APPEND ls_event TO lt_event.
ls_event-eventid = cl_gui_column_tree=>eventid_link_click.
APPEND ls_event TO lt_event.
ls_event-eventid = cl_gui_column_tree=>eventid_on_drop_external_files.
APPEND ls_event TO lt_event.
go_tree->set_registered_events( events = lt_event ).
CREATE OBJECT go_receiver.
SET HANDLER go_receiver->on_drop_external_files FOR go_tree.
SET HANDLER go_receiver->handle_node_double_click FOR go_tree.
SET HANDLER go_receiver->handle_item_double_click FOR go_tree.
SET HANDLER go_receiver->handle_link_click FOR go_tree.
SET HANDLER go_receiver->handle_drag FOR go_tree.
SET HANDLER go_receiver->handle_drop FOR go_tree.
SET HANDLER go_receiver->on_function_selected FOR go_toolbar.
SET HANDLER go_receiver->on_dropdown_clicked FOR go_toolbar.
ENDFORM. "register_events
*&---------------------------------------------------------------------*
*& Form init_tree
*&---------------------------------------------------------------------*
FORM init_tree.
DATA: ls_hhead TYPE treev_hhdr,
ls_varnt TYPE disvariant,
lt_exfun TYPE ui_functions.
CREATE OBJECT go_container
EXPORTING
container_name = 'CONT1'.
CREATE OBJECT go_spliter
EXPORTING
parent = go_container
rows = 1
columns = 2.
gv_swidth = 35.
gv_hwidth = 45.
IMPORT swidth = gv_swidth
twidth = gv_hwidth FROM DATABASE indx(nt) ID sy-uname.
go_spliter->set_column_width( id = 1 width = gv_swidth ).
go_cont_tree = go_spliter->get_container( row = 1 column = 1 ).
CREATE OBJECT go_tree
EXPORTING
parent = go_cont_tree
no_html_header = 'X'.
ls_hhead-heading = '功能选择'(t30).
ls_hhead-width = gv_hwidth.
ls_varnt-report = sy-repid.
APPEND cl_gui_alv_tree=>mc_fc_calculate TO lt_exfun.
go_tree->set_table_for_first_display(
EXPORTING
is_hierarchy_header = ls_hhead
is_variant = ls_varnt
it_toolbar_excluding = lt_exfun
i_save = 'A'
CHANGING
it_fieldcatalog = gt_fldtree
it_outtab = gt_out ).
PERFORM add_toolbar_button.
PERFORM register_events.
CREATE OBJECT go_dragdrop.
IF p_ddrop = 'X'.
go_dragdrop->add( EXPORTING
flavor = 'TREE'
dragsrc = 'X'
droptarget = 'X'
effect = cl_dragdrop=>move ).
ENDIF.
IF gt_all IS NOT INITIAL AND gt_top IS NOT INITIAL.
PERFORM fill_tree.
ENDIF.
IF p_objid IS NOT INITIAL.
PERFORM get_pic_url USING p_objid CHANGING gv_picurl.
IF gv_picurl IS NOT INITIAL.
go_cont_imag = go_spliter->get_container( row = 1 column = 2 ).
CREATE OBJECT go_picture
EXPORTING
parent = go_cont_imag.
go_picture->set_display_mode( cl_gui_picture=>display_mode_fit_center ).
go_picture->load_picture_from_url( url = gv_picurl ).
ENDIF.
ENDIF.
ENDFORM. "init_tree
*&---------------------------------------------------------------------*
*& Form fill_tree
*&---------------------------------------------------------------------*
FORM fill_tree.
DATA: lv_topkey TYPE lvc_nkey.
DATA: lt_expnod TYPE TABLE OF lvc_nkey.
LOOP AT gt_top INTO zum1.
PERFORM add_node_single USING zum1 '' CHANGING lv_topkey.
PERFORM add_node_recs USING zum1-nodid lv_topkey.
INSERT lv_topkey INTO lt_expnod INDEX 1.
ENDLOOP.
IF p_exall = 'X'.
LOOP AT lt_expnod INTO lv_topkey.
go_tree->expand_node( i_node_key = lv_topkey
i_expand_subtree = 'X' ).
ENDLOOP.
ENDIF.
go_tree->column_optimize( ).
go_tree->set_alv_tree_focus( ).
go_tree->frontend_update( ).
ENDFORM. "fill_tree
*&---------------------------------------------------------------------*
*& 递归的方式添加NODE
*&---------------------------------------------------------------------*
FORM add_node_recs USING value(pv_upnod) TYPE guid_22
value(pv_upkey).
DATA: lv_dndh TYPE i,
ls_layn TYPE lvc_s_layn,
lt_layi TYPE lvc_t_layi,
ls_layi TYPE lvc_s_layi.
DATA: lv_okey TYPE lvc_nkey.
LOOP AT gt_all INTO gs_out USING KEY k1 WHERE upnod = pv_upnod.
PERFORM add_node_single USING gs_out pv_upkey CHANGING lv_okey.
PERFORM add_node_recs USING gs_out-nodid lv_okey.
ENDLOOP.
ENDFORM. "add_node_recs
*&---------------------------------------------------------------------*
*& 添加单个节点
*&---------------------------------------------------------------------*
FORM add_node_single USING ps_wa TYPE zum1 pv_upkey
CHANGING cv_okey.
DATA: lv_dndh TYPE i,
ls_layn TYPE lvc_s_layn,
lt_layi TYPE lvc_t_layi,
ls_layi TYPE lvc_s_layi.
IF ps_wa-ntype = ''.
ls_layn-isfolder = 'X'.
ELSE.
ls_layi-fieldname = cl_gui_alv_tree=>c_hierarchy_column_name.
ls_layi-class = cl_gui_column_tree=>item_class_link. "HOTSPOT
APPEND ls_layi TO lt_layi.
IF ps_wa-nicon IS INITIAL.
ls_layn-n_image = '@15@'.
ELSE.
ls_layn-n_image = ps_wa-nicon.
ENDIF.
ENDIF.
go_dragdrop->get_handle( IMPORTING handle = lv_dndh ).
ls_layn-dragdropid = lv_dndh.
go_tree->add_node(
EXPORTING
i_relat_node_key = pv_upkey "上层NODEKEY
i_relationship = cl_gui_column_tree=>relat_last_child
i_node_text = ps_wa-ndtxt
is_outtab_line = ps_wa
is_node_layout = ls_layn
it_item_layout = lt_layi
IMPORTING
e_new_node_key = cv_okey ).
ENDFORM. "add_node_single
*&---------------------------------------------------------------------*
*& Form catset
*&---------------------------------------------------------------------*
FORM catset TABLES t_fldcat USING pv_field pv_text.
DATA: ls_fldcat TYPE lvc_s_fcat.
ls_fldcat-fieldname = pv_field. "字段名
ls_fldcat-coltext = pv_text. "列描述
ls_fldcat-col_opt = 'A'.
CASE ls_fldcat-fieldname.
WHEN 'W3URL'.
ls_fldcat-hotspot = 'X'.
WHEN 'FNAME'.
ls_fldcat-outputlen = '60'.
ls_fldcat-col_opt = ''.
ENDCASE.
APPEND ls_fldcat TO t_fldcat.
ENDFORM. "catset
*&---------------------------------------------------------------------*
*& Form execute
*&---------------------------------------------------------------------*
FORM execute USING pr_sender TYPE REF TO cl_gui_alv_tree pv_node.
PERFORM get_node_line USING pv_node CHANGING gs_out.
CASE gs_out-ntype.
WHEN 'C'.
CHECK gs_out-tcode NE ''.
CALL 'AUTH_CHECK_TCODE'
ID 'TCODE' FIELD gs_out-tcode.
IF sy-subrc = 0 OR p_auchk = ''.
CALL TRANSACTION gs_out-tcode.
ELSE.
MESSAGE s000(oo) WITH '无权限'(m01).
ENDIF.
WHEN 'R'.
PERFORM submit USING gs_out-tcode.
WHEN 'T'.
PERFORM mt_view USING gs_out-tcode.
WHEN 'S'.
PERFORM call_spro USING gs_out-tcode.
WHEN 'U'.
CALL FUNCTION 'CALL_BROWSER'
EXPORTING
url = gs_out-tcode.
ENDCASE.
ENDFORM. "at_item_dbclik
*&---------------------------------------------------------------------*
*& FORM call_spro
*&---------------------------------------------------------------------*
FORM call_spro USING pv_img.
DATA: lv_img_act TYPE cus_img_ac.
lv_img_act = pv_img.
CALL FUNCTION 'SPROJECT_TR_SET_MEMORY'
EXPORTING
project_id = ''
img_activity = lv_img_act.
CALL FUNCTION 'S_CUS_IMG_ACTIVITY_EXECUTE'
EXPORTING
img_activity = lv_img_act
project_id = ''.
CALL FUNCTION 'SPROJECT_TR_RESET_MEMORY'.
ENDFORM. "call_spro
*&---------------------------------------------------------------------*
*& FORM submit report
*&---------------------------------------------------------------------*
FORM submit USING repid.
DATA: ls_trdir TYPE trdir.
SELECT SINGLE * INTO ls_trdir FROM trdir
WHERE name EQ repid AND
subc EQ '1'.
IF sy-subrc = 0.
SUBMIT (repid) VIA SELECTION-SCREEN AND RETURN.
ELSE.
MESSAGE s000(oo) WITH '程序不存在:'(m02) .
ENDIF.
ENDFORM. "submit
*&---------------------------------------------------------------------*
*& FORM maintain_table
*&---------------------------------------------------------------------*
FORM mt_view USING viewname.
DATA: lv_vnam TYPE dd02v-tabname.
lv_vnam = viewname.
CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
EXPORTING
action = 'U'
view_name = lv_vnam
EXCEPTIONS
OTHERS = 15.
IF sy-subrc NE 0.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. "mt_view
*&---------------------------------------------------------------------*
*& CONFIRM sy-subrc=0:是 =4:否 =8:取消
*&---------------------------------------------------------------------*
FORM confirm USING pv_title pv_question pv_button.
DATA: lv_cflag TYPE char1.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = pv_title
text_question = pv_question
default_button = pv_button
IMPORTING
answer = lv_cflag.
IF lv_cflag = '1'.
sy-subrc = 0.
ELSEIF lv_cflag = '2'.
sy-subrc = 4.
ELSE.
sy-subrc = 8.
ENDIF.
ENDFORM. "confirm
*&---------------------------------------------------------------------*
*& 弹出选择屏幕屏蔽按钮
*&---------------------------------------------------------------------*
FORM selscr_exfcode USING exfcode.
DATA: lt_exttab TYPE slis_t_extab.
SPLIT exfcode AT space INTO TABLE lt_exttab.
CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
EXPORTING
p_status = '%_CSP'
TABLES
p_exclude = lt_exttab.
ENDFORM. "selscreen_ext
*&---------------------------------------------------------------------*
*& get_node_line
*&---------------------------------------------------------------------*
FORM get_node_line USING pv_node CHANGING ps_out.
go_tree->get_outtab_line( EXPORTING
i_node_key = pv_node
IMPORTING
e_outtab_line = ps_out
EXCEPTIONS
node_not_found = 1 ).
ENDFORM. "get_node_line
*&---------------------------------------------------------------------*
*& Search help
*&---------------------------------------------------------------------*
FORM tcodef4 CHANGING pv_tcode.
DATA: lv_tcode TYPE tstc-tcode.
DATA: lv_prog TYPE rs38m-programm.
DATA: ls_dynp TYPE dynpread.
DATA: lt_dynp TYPE TABLE OF dynpread.
DATA: ls_retab TYPE ddshretval.
DATA: lt_retab TYPE TABLE OF ddshretval.
CALL FUNCTION 'DYNP_VALUES_READ'
EXPORTING
dyname = sy-repid
dynumb = sy-dynnr
request = 'A'
TABLES
dynpfields = lt_dynp.
READ TABLE lt_dynp INTO ls_dynp WITH KEY fieldname = 'P_NTYPE'.
CASE ls_dynp-fieldvalue.
WHEN 'C'.
CALL FUNCTION 'F4_TRANSACTION'
IMPORTING
result = lv_tcode.
pv_tcode = lv_tcode.
WHEN 'R'.
CALL FUNCTION 'REPOSITORY_INFO_SYSTEM_F4'
EXPORTING
object_type = 'PROG'
suppress_selection = 'X'
IMPORTING
object_name_selected = lv_prog
EXCEPTIONS
cancel = 01.
CHECK sy-subrc = 0.
pv_tcode = lv_prog.
WHEN 'T'.
CALL FUNCTION 'F4IF_FIELD_VALUE_REQUEST'
EXPORTING
tabname = ''
fieldname = ''
searchhelp = 'VIEWMAINT'
TABLES
return_tab = lt_retab
EXCEPTIONS
OTHERS = 5.
IF sy-subrc = 0.
READ TABLE lt_retab INTO ls_retab INDEX 1.
pv_tcode = ls_retab-fieldval.
ENDIF.
WHEN OTHERS.
MESSAGE s000(oo) WITH '仅C、R、T支持搜索帮助功能'(m09).
ENDCASE.
ENDFORM. " TCODEF4
*&---------------------------------------------------------------------*
*& 1001屏幕的值赋给ZUM1
*&---------------------------------------------------------------------*
FORM paratozum1 USING pv_nodid pv_posnr pv_upnod.
IF pv_nodid IS INITIAL.
CALL FUNCTION 'GUID_CREATE'
IMPORTING
ev_guid_22 = zum1-nodid.
SELECT MAX( posnr ) INTO zum1-posnr FROM zum1
WHERE upnod = gs_out-nodid.
zum1-posnr = zum1-posnr + 1.
ELSE.
zum1-nodid = pv_nodid.
zum1-posnr = pv_posnr.
ENDIF.
zum1-upnod = pv_upnod.
zum1-ndtxt = p_ndtxt.
zum1-kverm = p_kverm.
zum1-w3url = p_w3url.
zum1-ntype = p_ntype.
zum1-tcode = p_tcode.
zum1-nicon = p_nicon.
zum1-aedat = sy-datum.
zum1-aezet = sy-uzeit.
zum1-aenam = sy-uname.
IF zum1-ntype CA 'CRTS'.
TRANSLATE zum1-tcode TO UPPER CASE.
ENDIF.
ENDFORM. "paratozum1
*&---------------------------------------------------------------------*
*& 双击展开/折叠文件夹,执行功能节点
*&---------------------------------------------------------------------*
FORM exp_coll_node USING pr_sender TYPE REF TO cl_gui_alv_tree pv_nodkey.
DATA: lt_child TYPE lvc_t_nkey.
DATA: lt_exped TYPE lvc_t_nkey.
pr_sender->get_children( EXPORTING
i_node_key = pv_nodkey
IMPORTING
et_children = lt_child ).
IF lt_child IS INITIAL.
PERFORM execute USING pr_sender pv_nodkey.
ELSE.
pr_sender->get_expanded_nodes( CHANGING ct_expanded_nodes = lt_exped ).
READ TABLE lt_exped TRANSPORTING NO FIELDS WITH KEY table_line = pv_nodkey.
IF sy-subrc = 0.
pr_sender->collapse_subtree( i_node_key = pv_nodkey ).
ELSE.
pr_sender->expand_node( i_node_key = pv_nodkey
i_expand_subtree = 'X' ).
ENDIF.
ENDIF.
ENDFORM. "exp_coll_node
*&---------------------------------------------------------------------*
*& 删除NODID及其下层,同时删除文档
*&---------------------------------------------------------------------*
FORM delete_node_recs USING value(pv_nodid) TYPE guid_22.
DELETE gt_all WHERE nodid = pv_nodid.
DELETE FROM zum1 WHERE nodid = pv_nodid.
DELETE FROM DATABASE indx(nt) ID pv_nodid.
LOOP AT gt_all INTO gs_out USING KEY k1 WHERE upnod = pv_nodid.
PERFORM delete_node_recs USING gs_out-nodid.
ENDLOOP.
ENDFORM. "delete_node_recs
*&---------------------------------------------------------------------*
*& 上传节点的文档
*&---------------------------------------------------------------------*
FORM upload_node_atta USING pv_nodkey pv_fiels.
DATA: BEGIN OF ls_files,
fullpath TYPE string,
filename TYPE string,
extnamee TYPE string,
END OF ls_files.
DATA: lt_files LIKE TABLE OF ls_files.
DATA: lt_infile TYPE TABLE OF string.
DATA: lv_infile TYPE string.
DATA: lt_atta LIKE gt_atta.
IF pv_nodkey IS NOT INITIAL.
CLEAR gt_atta.
PERFORM get_node_line USING pv_nodkey CHANGING gs_out.
IMPORT atta = gt_atta FROM DATABASE indx(nt) ID gs_out-nodid.
ENDIF.
SPLIT pv_fiels AT ';' INTO TABLE lt_infile.
LOOP AT lt_infile INTO lv_infile.
ls_files-fullpath = lv_infile.
FIND REGEX '([^/\\]+)$' IN ls_files-fullpath
SUBMATCHES ls_files-filename. "文件名
FIND REGEX '([^.]+)$' IN ls_files-filename
SUBMATCHES ls_files-extnamee. "扩展名
APPEND ls_files TO lt_files.
ENDLOOP.
LOOP AT lt_files INTO ls_files.
IF cl_gui_frontend_services=>file_exist( ls_files-fullpath ) = ''.
MESSAGE i000(oo) WITH '不支持文件夹的上传:'(m17) ls_files-fullpath.
CONTINUE.
ENDIF.
cl_gui_frontend_services=>file_get_size(
EXPORTING
file_name = ls_files-fullpath
IMPORTING
file_size = gs_atta-fleng
EXCEPTIONS
OTHERS = 5 ).
cl_gui_cfw=>flush( ).
IF gs_atta-fleng > '10000000'.
MESSAGE i000(oo) WITH '文档大于10M:'(m15) ls_files-fullpath.
CONTINUE.
ENDIF.
gs_atta-fname = ls_files-filename.
gs_atta-erdat = sy-datum.
gs_atta-erzet = sy-uzeit.
gs_atta-ernam = sy-uname.
gs_atta-seled = ''.
CALL FUNCTION 'GUI_UPLOAD'
EXPORTING
filename = ls_files-fullpath
filetype = 'BIN'
IMPORTING
filelength = gs_atta-fleng
TABLES
data_tab = gs_atta-fcont
EXCEPTIONS
OTHERS = 17.
IF sy-subrc NE 0.
MESSAGE e000(oo) WITH '上传文件失败'(m10) ls_files-fullpath.
ELSE.
APPEND gs_atta TO lt_atta.
ENDIF.
ENDLOOP.
CHECK lt_atta IS NOT INITIAL.
APPEND LINES OF lt_atta TO gt_atta.
EXPORT atta = gt_atta TO DATABASE indx(nt) ID gs_out-nodid.
IF sy-subrc = 0.
MESSAGE s000(oo) WITH '文档保存成功,节点:'(m12) gs_out-ndtxt.
IF pv_nodkey IS INITIAL.
go_grid->refresh_table_display( ).
ENDIF.
ELSE.
MESSAGE s000(oo) WITH '文档保存失败'(m13).
ENDIF.
ENDFORM. "upload_node_atta
*&---------------------------------------------------------------------*
*& Form atta_popup
*&---------------------------------------------------------------------*
FORM atta_popup.
DATA lt_fdcat TYPE lvc_t_fcat.
DATA ls_slayt TYPE lvc_s_layo.
DATA lt_event TYPE lvc_t_evts.
DATA ls_event TYPE lvc_s_evts.
ls_slayt-zebra = 'X'.
ls_slayt-box_fname = 'SELED'.
ls_event-name = 'CALLER_EXIT'.
ls_event-form = 'REG_EVENT'.
APPEND ls_event TO lt_event.
PERFORM catset TABLES lt_fdcat
USING: 'FNAME' '文件名'(f06),
'FLENG' '文件大小'(f07),
'ERDAT' '创建日期'(f08),
'ERZET' '时间'(f09),
'ERNAM' '账号'(f10).
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat_lvc = lt_fdcat
it_events = lt_event
is_layout_lvc = ls_slayt
i_callback_program = sy-repid
i_callback_user_command = 'POPUP_USER_COMMAND'
i_callback_pf_status_set = 'POPUP_SET_STATUS'
i_screen_start_column = 20
i_screen_start_line = 2
i_screen_end_column = 120
i_screen_end_line = 16
TABLES
t_outtab = gt_atta
EXCEPTIONS
program_error = 1.
ENDFORM. "atta_popup
*&---------------------------------------------------------------------*
*& Form reg_event
*&---------------------------------------------------------------------*
FORM reg_event USING po_grid TYPE slis_data_caller_exit.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = go_grid.
go_grid->drag_accept_files( EXPORTING b_accept = 1 EXCEPTIONS OTHERS = 1 ).
SET HANDLER go_receiver->grid_drop_external_files FOR go_grid.
ENDFORM. "reg_event
*&---------------------------------------------------------------------*
*& Form POPUP_SET_STATUS
*&---------------------------------------------------------------------*
FORM popup_set_status USING pt_extab TYPE slis_t_extab.
IF p_chang = ''.
APPEND 'DELE' TO pt_extab.
ENDIF.
SET PF-STATUS 'POPUPBX' EXCLUDING pt_extab.
SET TITLEBAR 'T001' WITH gs_out-ndtxt.
ENDFORM. "popup_set_status
*&---------------------------------------------------------------------*
*& Form POPUP_USER_COMMAND
*&---------------------------------------------------------------------*
FORM popup_user_command USING pv_ucomm TYPE sy-ucomm
pv_field TYPE slis_selfield.
READ TABLE gt_atta INTO gs_atta INDEX pv_field-tabindex.
CASE pv_ucomm.
WHEN '&IC1'.
PERFORM show_atta USING gs_atta.
WHEN 'DOWN'.
"
WHEN 'DELE'.
PERFORM delete_atta.
pv_field-row_stable = 'X'.
pv_field-col_stable = 'X'.
pv_field-refresh = 'X'.
ENDCASE.
ENDFORM. "POPUP_USER_COMMAND
*&---------------------------------------------------------------------*
*& 下载节点文档到本地并打开
*&---------------------------------------------------------------------*
FORM show_atta USING ps_atta LIKE gs_atta.
DATA: lv_localfile TYPE string.
cl_gui_frontend_services=>get_temp_directory( CHANGING temp_dir = lv_localfile ).
cl_gui_cfw=>flush( ).
lv_localfile = lv_localfile && '\' && ps_atta-fname.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
bin_filesize = ps_atta-fleng
filename = lv_localfile
filetype = 'BIN'
TABLES
data_tab = ps_atta-fcont
EXCEPTIONS
OTHERS = 22.
IF sy-subrc NE 0.
MESSAGE s000(oo) WITH '下载文档失败'(m11).
ELSE.
cl_gui_frontend_services=>execute(
EXPORTING
document = lv_localfile
EXCEPTIONS
OTHERS = 1 ).
ENDIF.
ENDFORM. "show_atta
*&---------------------------------------------------------------------*
*& Form delete_atta
*&---------------------------------------------------------------------*
FORM delete_atta.
READ TABLE gt_atta TRANSPORTING NO FIELDS WITH KEY seled = 'X'.
IF sy-subrc NE 0.
MESSAGE s000(oo) WITH '请选择需要删除的行'(m16).
ELSE.
PERFORM confirm USING '确认'(m07) '确认删除选中的文档'(m18) 'C'.
CHECK sy-subrc = 0.
DELETE gt_atta WHERE seled = 'X'.
IF gt_atta IS INITIAL.
DELETE FROM DATABASE indx(nt) ID gs_out-nodid.
ELSE.
EXPORT atta = gt_atta TO DATABASE indx(nt) ID gs_out-nodid.
ENDIF.
MESSAGE s000(oo) WITH 'Deleted'.
ENDIF.
ENDFORM. "delete_atta
*----------------------------------------------------------------------*
* CLASS lcl_receiver IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_receiver IMPLEMENTATION.
METHOD grid_drop_external_files.
CHECK p_chang = 'X'.
PERFORM upload_node_atta USING '' files.
ENDMETHOD. "handle_node_double_click
METHOD on_drop_external_files.
CHECK p_chang = 'X'.
PERFORM upload_node_atta USING node_key files.
ENDMETHOD. "handle_node_double_click
METHOD handle_node_double_click.
PERFORM exp_coll_node USING sender node_key.
ENDMETHOD. "handle_node_double_click
METHOD handle_item_double_click.
PERFORM exp_coll_node USING sender node_key.
ENDMETHOD. "handle_ITEM_DOUBLE_CLICK
METHOD handle_link_click.
CASE fieldname.
WHEN 'W3URL'.
PERFORM get_node_line USING node_key CHANGING gs_out.
CHECK gs_out-w3url IS NOT INITIAL.
CALL FUNCTION 'CALL_BROWSER'
EXPORTING
url = gs_out-w3url.
WHEN OTHERS.
PERFORM execute USING sender node_key.
ENDCASE.
ENDMETHOD. "handle_link_click
METHOD handle_drag.
DATA: lr_obj TYPE REF TO lcl_dragdropobj.
CREATE OBJECT lr_obj.
lr_obj->lv_nkey = node_key.
PERFORM get_node_line USING node_key CHANGING lr_obj->ls_out.
sender->get_parent( EXPORTING
i_node_key = node_key
IMPORTING
e_parent_node_key = lr_obj->lv_pkey ).
drag_drop_object->object = lr_obj.
ENDMETHOD. "handle_drag
METHOD handle_drop.
DATA: lr_obj TYPE REF TO lcl_dragdropobj.
DATA: lv_pkey TYPE lvc_nkey. "父KEY(所在文件夹NODEKEY)
DATA: ls_parent TYPE zum1.
DATA: lt_child TYPE lvc_t_nkey.
DATA: lv_child TYPE lvc_nkey.
DATA: lv_posnr TYPE zum1-posnr.
DATA: lv_tabix TYPE sy-tabix.
DATA: lt_save TYPE TABLE OF zum1.
TRY.
lr_obj ?= drag_drop_object->object. "源NODE
CATCH cx_root.
drag_drop_object->abort( ).
MESSAGE e000(oo) WITH '有错误发生'(m03).
ENDTRY.
IF lr_obj->ls_out-upnod = ''.
MESSAGE s000(oo) WITH '顶层节点不可以拖动'(m04).
RETURN.
ENDIF.
PERFORM get_node_line USING node_key CHANGING gs_out.
IF gs_out-ntype = ''. "拖到了文件夹上
lv_pkey = node_key.
ELSE. "非文件夹上
sender->get_parent( EXPORTING
i_node_key = node_key
IMPORTING
e_parent_node_key = lv_pkey ).
ENDIF.
PERFORM get_node_line USING lv_pkey CHANGING ls_parent.
sender->get_children( EXPORTING
i_node_key = lv_pkey
IMPORTING
et_children = lt_child ).
IF lv_pkey = lr_obj->lv_pkey. "在同一个文件夹内移动
DELETE lt_child WHERE table_line = lr_obj->lv_nkey.
ENDIF.
IF gs_out-ntype = ''. "拖到了文件夹上
INSERT lr_obj->lv_nkey INTO lt_child INDEX 1. "放节点最上面
ELSE.
READ TABLE lt_child TRANSPORTING NO FIELDS WITH KEY table_line = node_key.
lv_tabix = sy-tabix + 1.
INSERT lr_obj->lv_nkey INTO lt_child INDEX lv_tabix."放目标节点下面
ENDIF.
CLEAR: zum1.
LOOP AT lt_child INTO lv_child.
lv_posnr = sy-tabix.
PERFORM get_node_line USING lv_child CHANGING zum1.
zum1-posnr = lv_posnr.
zum1-upnod = ls_parent-nodid.
zum1-aedat = sy-datum.
zum1-aezet = sy-uzeit.
zum1-aenam = sy-uname.
APPEND zum1 TO lt_save.
go_tree->delete_subtree( i_node_key = lv_child ).
ENDLOOP.
MODIFY zum1 FROM TABLE lt_save.
SORT lt_save BY nodid.
LOOP AT gt_all INTO gs_out.
READ TABLE lt_save INTO zum1 WITH KEY nodid = gs_out-nodid BINARY SEARCH.
IF sy-subrc = 0.
gs_out = zum1.
MODIFY gt_all FROM gs_out.
ENDIF.
ENDLOOP.
go_tree->delete_subtree( EXPORTING
i_node_key = lr_obj->lv_nkey
EXCEPTIONS
OTHERS = 2 ).
PERFORM add_node_recs USING ls_parent-nodid lv_pkey.
go_tree->expand_node( i_node_key = lv_pkey
i_expand_subtree = 'X' ).
go_tree->frontend_update( ).
ENDMETHOD. "handle_drop
METHOD on_function_selected.
DATA: lt_nodes TYPE lvc_t_nkey,
lv_node TYPE lvc_nkey,
lv_tnode TYPE lvc_nkey.
go_tree->get_selected_nodes( CHANGING ct_selected_nodes = lt_nodes ).
IF lt_nodes IS INITIAL.
go_tree->get_selected_item(
IMPORTING
e_selected_node = lv_node
EXCEPTIONS
OTHERS = 4 ).
ELSE.
READ TABLE lt_nodes INTO lv_node INDEX 1.
ENDIF.
IF lv_node IS INITIAL AND 'FC_TOPF FC_REFR' NS fcode AND fcode(3) = 'FC_'.
MESSAGE s000(oo) WITH '请选中一个节点'(m05).
RETURN.
ELSE.
PERFORM get_node_line USING lv_node CHANGING gs_out.
ENDIF.
CLEAR: p_ndtxt,p_ntype,p_tcode,p_nicon,p_kverm,p_w3url,gv_fflag,zum1.
CASE fcode.
WHEN 'FC_TOPF'.
gv_fflag = 'F'.
CALL SELECTION-SCREEN 1001 STARTING AT 10 5.
CHECK sy-subrc = 0.
PERFORM paratozum1 USING '' '' ''.
INSERT zum1 FROM zum1.
APPEND zum1 TO gt_all.
COMMIT WORK.
PERFORM add_node_single USING zum1 '' CHANGING lv_tnode.
go_tree->frontend_update( ).
WHEN 'FC_FOLD' OR 'FC_NODE'.
IF fcode = 'FC_FOLD'.
gv_fflag = 'F'.
ENDIF.
IF gs_out-ntype = ''.
CALL SELECTION-SCREEN 1001 STARTING AT 10 5.
CHECK sy-subrc = 0.
PERFORM paratozum1 USING '' '' gs_out-nodid.
INSERT zum1 FROM zum1.
APPEND zum1 TO gt_all.
COMMIT WORK.
PERFORM add_node_single USING zum1 lv_node CHANGING lv_tnode.
go_tree->expand_node( i_node_key = lv_node ).
go_tree->frontend_update( ).
ELSE.
MESSAGE s000(oo) WITH '只能在文件夹下面创建'(m06).
ENDIF.
WHEN 'FC_EDIT'.
IF gs_out-ntype = ''.
gv_fflag = 'F'.
ENDIF.
p_ndtxt = gs_out-ndtxt.
p_ntype = gs_out-ntype.
p_tcode = gs_out-tcode.
p_nicon = gs_out-nicon.
p_kverm = gs_out-kverm.
p_w3url = gs_out-w3url.
CALL SELECTION-SCREEN 1001 STARTING AT 10 5.
CHECK sy-subrc = 0.
PERFORM paratozum1 USING gs_out-nodid gs_out-posnr gs_out-upnod.
MODIFY zum1 FROM zum1.
COMMIT WORK.
go_tree->change_node(
EXPORTING
i_node_key = lv_node
i_outtab_line = zum1
i_node_text = zum1-ndtxt
i_u_node_text = 'X'
EXCEPTIONS
node_not_found = 1
OTHERS = 2 ).
go_tree->frontend_update( ).
WHEN 'FC_DELE'.
PERFORM confirm USING '确认'(m07) '确认删除?如有下层节点将一起从数据库删除'(m08) 'C'.
CHECK sy-subrc = 0.
PERFORM delete_node_recs USING gs_out-nodid.
go_tree->delete_subtree( i_node_key = lv_node ).
go_tree->frontend_update( ).
WHEN 'FC_ATTA'.
CLEAR gt_atta.
IMPORT atta = gt_atta FROM DATABASE indx(nt) ID gs_out-nodid.
IF sy-subrc = 0.
PERFORM atta_popup.
ELSE.
MESSAGE s000(oo) WITH '文档不存在。如需上载,请拖放文档到节点上'(m14).
ENDIF.
WHEN 'FC_REFR'.
go_tree->delete_all_nodes( ).
PERFORM get_all.
PERFORM fill_tree.
ENDCASE.
ENDMETHOD. "on_function_selected
METHOD on_dropdown_clicked.
DATA lo_menu TYPE REF TO cl_ctmenu.
CREATE OBJECT lo_menu.
CASE fcode.
WHEN 'FC_NEW'.
lo_menu->add_function( EXPORTING
fcode = 'FC_TOPF'
text = '顶层文件夹'(t31) ).
lo_menu->add_function( EXPORTING
fcode = 'FC_FOLD'
text = '下层文件夹'(t32) ).
lo_menu->add_function( EXPORTING
fcode = 'FC_NODE'
text = '功能节点'(t33) ).
go_toolbar->track_context_menu( EXPORTING
context_menu = lo_menu
posx = posx
posy = posy ).
ENDCASE.
ENDMETHOD. "on_dropdown_clicked
ENDCLASS. "lcl_receiver IMPLEMENTATION