If you’ve written something in SAP from scratch, you (probably) haven’t bothered to understand what someone else has already done (Part 5 of “Event-Driven” Tutorial on WD-ABAP Component WDR_TEST_UI_ELEMENTS)
For those new to this tutorial, the preceding four parts were:
Part 4 of “Event-Driven” Tutorial on the WD-ABAP Component WDR_TEST_UI_ELEMENTS.
The class infrastructure of WDR_UI_TEST_ELEMENTS is exquisite for lazy cloning and change-ups.
Experiential vs Procedural Tutorials: “Breaking” WDR_TEST_UI_ELEMENTS to Learn From It.
At the end of the last of these, we were able to get the root node of a tree to display in the right-hand side
tree-view
when a link is selected from the “
Logical Database
” tray in the left-hand side
tray-view
. We now want to make the right-hand tree-view display not only the root-node, but also the complete hiearchical tree structure of the Logical Database that has been selected. For example, if the user selects the “
Vendor Database
” link from the “
Logical Database
” tray, we want the hierarchical tree structure of the LDB “
KDF
” to display just as it does when one displays the internal structure of “
KDF”
using the standard transaction SE36.
To accomplish this goal, we will create two new methods in the clone cclass
ZCL_WDR_ALL_IN_ONE_UIELEM
,
create_lgcldb_tree
and
create_lgcldb_nodes
, and place a
CASE
statement into the
create
method of this class so that it invokes
create_lgcldb_tree
instead of
create_aggregations
when a link in the Logical Database Tray is selected. Although it turns out that we only have to steal less than 100 lines of code from
create_aggregations
and
create_aggregatee
to “code up” our two new methods, there is some prior housekeeping that has to be done in order to ensure that these two new methods have the metadata they need from the SAP-delivered table
ldbn
. All of this housekeeping is included in the steps outlined below.
Step 1.
What
: Make the Title of the right-hand side tree view read
“Navigation Guide to Selected Object”
rather than
“Hierarchy of Aggregations”
Why
: To get a more meaningul and less mysterious title (remember – we will eventually
not
want our clone component to display the UI Element libraries displayed by the origiginal component
WDR_TEST_UI_ELEMENTS
, but
only
our three new libraries (
Logical Databases
,
Programming Trees
, and
Report Sets
).
How
: In the
Layout
panel for the
Main
view of
ZWDR_TEST_UI_ELEMENTS
, click
VIEWELEMENT
and then
HIERARCHY
. Then in the “properties” panel that displays for
HIERARCHY
, change the title. Save and activate.
Step 2.
What
: Get the “
Logical Database
” tray in the left-hand-side tray view to display expanded (instead of the “
Standard
” tray) when the
Main
view first opens, and also pre-select “
Vendor Database
” so that this logical database will display in the right-hand side tree-view when the
Main
view first opens.
Why
: Easier to run the debugger, i.e. we’ll reach the break-points we want the first time around, not the second.
How
:
Step 2a
: In
ClassBuilder (SE24)
, bring up the clone component
ZCL_WDR_ALL_IN_ONE_UTIL
, then select the
Methods
tab, and then select the
init_view2
method. In this method, find the code that reads:
********************************************************
-
create a new tray
concatenate current_library ‘_LIB’ into tray_id.
if current_library = ‘STANDARD’.
is_expanded = abap_true.
else.
is_expanded = abap_false.
endif.
*******************************************************
and change the literal
‘STANDARD’
to the literal
‘LGCLDBS’
.
Step 2b
: In the same method, find the code at the bottom that reads:
************************************************************
-
set the default ui element and library
m_cur_library = ‘STANDARD’.
m_cur_ui_element = ‘BUTTON’.
***********************************************************
Replace
‘STANDARD’
with
‘LGCLDBS’
and
‘BUTTON’
with
‘KDF’
. Save and activate.
Step 3.
What
: Prepare the Logical Database metadata that the clone component will need to display the internal hierarchical tree structure of any logical database.
Why
: We could just use the SAP-delivered table
ldbn
for this purpose, but this table doesn’t have a column indicating whether a given
ldbnode
has any children, i.e whether it is a
maximal
(leaf) node or not. If we create such a column in a clone of
ldbn
, it will be easier to steal what we need from the SAP-delivered methods
create_aggregations
and
create_aggregatee
of
CL_WDR_ALL_IN_ONE_UIELEM
for the two new methods
create_lgcldb_tree
and
create_lgcldb_nodes
of the clone class
ZCL_WDR_TEST_ALL_IN_ONE_UIELEM
How
:
Step 3a
: Using
Dictionary Maintenance (SE11)
, create TWO copies of
ldbn
named
zldbnw
and
zldbn
.
Step 3b
: Add an index to the work table
zldbnw
consisting of the two columns
ldbname
and
parentnode
.
Step 3c
: Add a
char1
column to the table
zldbn
called
ismax
.
Step 3d
: Run the following program, which backloads the SAP-delivered table
ldbn
to a local PC *.csv file. ( Those folks who have a “playground” XI instance of SAP will find that they’ll often have to do this kind of backload because their “playground” instance won’t necessarily have the metadata they need.)
&—-
REPORT Z_GET_LDBN.
TYPES:
t_ldbn_out_line(100) TYPE c,
t_ldbn_out TYPE
TABLE OF t_ldbn_out_line
INITIAL SIZE 0.
DATA:
i_ldbn_out TYPE t_ldbn_out,
wa_ldbn_out TYPE t_ldbn_out_line,
wa_ldbn TYPE ldbn,
i_ldbn TYPE STANDARD TABLE OF ldbn,
v_lfile1(30) TYPE c,
v_fn_out TYPE string,
v_currnumb(4) TYPE c,
v_inclnumb(4) TYPE c,
v_work_len22(22) TYPE c,
v_work_len4(4) TYPE c.
v_lfile1 = ‘C:ldbn.csv’.
v_fn_out = v_lfile1.
SELECT * FROM ldbn INTO wa_ldbn.
v_work_len22 = wa_ldbn-currnumb.
WRITE v_work_len22 to v_work_len4 RIGHT-JUSTIFIED.
SHIFT v_work_len4 LEFT DELETING LEADING SPACE.
v_currnumb = v_work_len4.
v_work_len22 = wa_ldbn-inclnumb.
WRITE v_work_len22 to v_work_len4 RIGHT-JUSTIFIED.
SHIFT v_work_len4 LEFT DELETING LEADING SPACE.
v_inclnumb = v_work_len4.
CONCATENATE wa_ldbn-ldbname
wa_ldbn-ldbnode
wa_ldbn-parentnode
v_currnumb
wa_ldbn-structure
wa_ldbn-type
wa_ldbn-typepool
v_inclnumb
INTO wa_ldbn_out
SEPARATED
BY ‘,’.
APPEND wa_ldbn_out TO i_ldbn_out.
ENDSELECT.
CALL FUNCTION ‘GUI_DOWNLOAD’
EXPORTING
filename = v_fn_out
filetype = ‘ASC’
TABLES
data_tab = i_ldbn_out
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
OTHERS = 22.
&—-
Step 3e
: Run the following program, which loads the worktable
zldbnw
with its index on
ldbname/parentnode
, and then uses this worktable to load the final metadata table
zldbn
with its
ismax
column.
&—-
REPORT Z_FILL_ZLDBN.
*
TYPES:
t_row_data(100) TYPE c,
t_data TYPE
TABLE OF t_row_data
INITIAL SIZE 0.
DATA:
i_data TYPE t_data,
wa_data TYPE t_row_data,
v_path LIKE rlgrap-filename,
wa_zldbnw TYPE zldbnw,
wa_zldbn TYPE zldbn,
i_zldbnw TYPE STANDARD TABLE of zldbnw,
i_zldbn TYPE STANDARD TABLE of zldbn,
splitsep(1) VALUE ‘,’,
v_level(2) TYPE n,
v_cntr TYPE i,
v_root(24) TYPE c,
v_cnc(4) TYPE c,
v_inc(4) TYPE c,
v_cnt TYPE i.
DELETE FROM zldbn WHERE ldbname <> ”.
COMMIT WORK.
DELETE FROM zldbnw WHERE ldbname <> ”.
COMMIT WORK.
v_path = ‘C:ldbn.csv’.
CALL FUNCTION ‘UPLOAD’
EXPORTING
filename = v_path
TABLES
data_tab = i_data
EXCEPTIONS
conversion_error = 1
invalid_table_width = 2
invalid_type = 3
no_batch = 4
unknown_error = 5
gui_refuse_filetransfer = 6
OTHERS = 7.
LOOP AT i_data INTO wa_data.
SPLIT wa_data
AT splitsep
INTO wa_zldbnw-ldbname
wa_zldbnw-ldbnode
wa_zldbnw-parentnode
v_cnc
wa_zldbnw-structure
wa_zldbnw-type
wa_zldbnw-typepool
v_inc.
wa_zldbnw-currnumb = v_cnc.
wa_zldbnw-inclnumb = v_inc.
INSERT INTO zldbnw VALUES wa_zldbnw.
ENDLOOP.
COMMIT WORK.
SELECT * FROM zldbnw INTO TABLE i_zldbnw.
LOOP AT i_zldbnw INTO wa_zldbnw.
MOVE-CORRESPONDING wa_zldbnw TO wa_zldbn.
SELECT
COUNT( * )
FROM zldbnw
INTO v_cnt
WHERE ldbname = wa_zldbnw-ldbname
AND parentnode = wa_zldbnw-ldbnode.
IF v_cnt = 0.
wa_zldbn-ismax = ‘Y’.
ELSE.
wa_zldbn-ismax = ‘N’.
ENDIF.
INSERT INTO zldbn VALUES wa_zldbn.
ENDLOOP.
COMMIT WORK.
&—-
Step 4.
What
: Declare the
types
and
data
we will need to process the new metadata from
zldbn
.
Why
: We will have to work with rows from
zldbn
in the two new methods
create_lgcldb_tree
and
create_lgcldb_nodes
of the clone class
ZCL_WDR_ALL_IN_ONE_UIELEM
How
: In
ClassBuilder (SE24)
, bring up the clone component
ZCL_WDR_ALL_IN_ONE_UIELEM
, then select
Implementation
, and then
Public
. In the code that appears, add the following type declaration and class-data declaration (the two items in boldface):
&—-
class ZCL_WDR_ALL_IN_ONE_UIELEM definition
public
final
create public .
“ public components of class ZCL_WDR_ALL_IN_ONE_UIELEM
“ do not include other source files here!!!
public section.
types:
tt_zldbn type standard table of zldbn.
types:
tt_ui_elem_def_srt type sorted table of zwdy_ui_elem_def with unique key library_name definition_name .
types:
tt_ui_prop_def_srt type sorted table of wdy_ui_prop_def with unique key library_name definition_name property_name .
types:
tt_ui_aggr_def_srt type sorted table of wdy_ui_aggr_def with unique key library_name definition_name aggregation_name .
types:
tt_ui_event_def_srt type sorted table of wdy_ui_event_def with unique key library_name definition_name event_name .
types:
tt_ui_evpar_def_srt type sorted table of wdy_ui_evpar_def with unique key library_name definition_name event_name parameter_name .
class-data MT_ZLDBN type TT_ZLDBN read-only .
class-data MT_UI_AGGR_DEF type TT_UI_AGGR_DEF_SRT read-only .
. . .
&—-
Step 5.
What
: Make the metadata in
zldbn
available to the clone component
ZWDR_TEST_UI_ELEMENTS
, or more properly, to its supporting class
ZCL_WDR_ALL_IN_ONE_UIELEM
.
Why
: This metadata is, in effect, what will be displayed in the right-hand-side tree-view of
ZWDR_TEST_UI_ELEMENTS
when a link is selected from the
Logical Database
tray in the left-hand-side tray-view.
How
:
Step 5a
: In
ClassBuilder (SE24)
, bring up the clone component
ZCL_WDR_ALL_IN_ONE_UIELEM
, then select the
Methods
tab, and then select the
init_meta_data
method. In this method, find the code that reads:
***************************************************
-
get all libraries
select * from zwdy_ui_library into table mt_ui_library
order by primary key.
-
get all view elements – below we will build the final list
select * from zwdy_ui_elem_def into table mt_ui_elem_def_all.
**************************************
and add this select statement to these two:
****************************************
* get LDB data from zldbn
select * from zldbn into table mt_zldbn.
*****************************************
Save and activate.
Step 5b
: Now bring up the method
create
, and find the code that reads:
****************************************
-
create the different areas
create_settings( ).
create_events( ).
create_aggregations( ).
****************************************
Change this code to read:
****************************************
-
create the different areas
create_settings( ).
create_events( ).
like line of mt_zldbn. ” Part 5 20060908
-
” Part 5 20060908 (declarations from create_aggregatee. except what’s been declared above)
data:
initial_path type string,
lr_hier_tree_context_node type ref to if_wd_context_node,
lr_hier_tree_context_element type ref to if_wd_context_element,
lr_save_tree_context_element type ref to if_wd_context_element, ” Part 5 20060908
icon type string.
-
*****************
-
to let root node of tree be expanded by code below
m_hier_tree_context_element->set_attribute( name = ‘EXPANDED’ value = abap_true ).
m_hier_tree_context_element->set_attribute( name = ‘HAS_CHILDREN’ value = abap_true ).
loop at mt_zldbn assigning .
**************************************************
-
this is from original create_aggregations
concatenate m_prefix mc_aggr_explaination_id bind_element( new_item = lr_context_element set_initial_elements = abap_false ).
**************************************************
**************************************************
-
this is from original create_aggregatee
lr_hier_tree_context_node = m_hier_tree_context_element->get_child_node( ‘UI_ELEMENT_HIER_REC’ ).
lr_hier_tree_context_element = lr_hier_tree_context_node->create_element( ).
lr_hier_tree_context_node->bind_element( new_item = lr_hier_tree_context_element set_initial_elements = abap_false ).
set_attribute( name = ‘ICON’ value = icon ).
*************************************************
**************************************************
-
this is from original create_aggregations
-
set the lead selection of the aggregation node to the currently aggregated view element
index = sy-tabix.
lr_aggregation_node->set_lead_selection_index( index ).
**************************************************
-
the remaining 6 lines are “new”
lr_hier_tree_context_element->get_attribute( EXPORTING name = ‘HAS_CHILDREN’ IMPORTING value = v_hasch ).
IF v_hasch = abap_true.
lr_save_tree_context_element = m_hier_tree_context_element.
m_hier_tree_context_element = lr_hier_tree_context_element.
create_lgcldb_nodes( ).
m_hier_tree_context_element = lr_save_tree_context_element.
ENDIF.
endloop.
like line of mt_zldbn. ” Part 5 20060908
-
” Part 5 20060908 (declarations from create_aggregatee. except what’s been declared above)
data:
initial_path type string,
lr_hier_tree_context_node type ref to if_wd_context_node,
lr_hier_tree_context_element type ref to if_wd_context_element,
lr_save_tree_context_element type ref to if_wd_context_element, ” Part 5 2 20060908
icon type string.
-
“
m_hier_tree_context_element->get_attribute( EXPORTING name = ‘TEXT’ IMPORTING value = v_ldbnode ).
loop at mt_zldbn assigning .
**************************************************
-
this is from original create_aggregations
concatenate m_prefix mc_aggr_explaination_id bind_element( new_item = lr_context_element set_initial_elements = abap_false ).
**************************************************
**************************************************
-
this is from original create_aggregatee
lr_hier_tree_context_node = m_hier_tree_context_element->get_child_node( ‘UI_ELEMENT_HIER_REC’ ).
lr_hier_tree_context_element = lr_hier_tree_context_node->create_element( ).
lr_hier_tree_context_node->bind_element( new_item = lr_hier_tree_context_element set_initial_elements = abap_false ).
IF set_attribute( name = ‘ICON’ value = icon ).
*************************************************
**************************************************
-
this is from original create_aggregations
-
set the lead selection of the aggregation node to the currently aggregated view element
index = sy-tabix.
lr_aggregation_node->set_lead_selection_index( index ).
**************************************************
lr_hier_tree_context_element->get_attribute( EXPORTING name = ‘HAS_CHILDREN’ IMPORTING value = v_hasch ).
IF v_hasch = abap_true.
lr_save_tree_context_element = m_hier_tree_context_element.
m_hier_tree_context_element = lr_hier_tree_context_element.
create_lgcldb_nodes( ).
m_hier_tree_context_element = lr_save_tree_context_element.
ENDIF.
endloop.
endmethod.