Graphical BOM Explosion

Graphical BOM Explosion

This coding shows how a BOM can be exploded in ABAP with FUBA CS_BOM_EXPL_MAT_V2 and be displayed in an ALV-Tree. Therefore the SAP-Samle code BCALV_TREE_02 was enhanced.

How to install:

You have to do following to run this report:

  1. Create Report in SE80 and paste code

  2. Create a structure „zbomexplode“ (see bottom of page)

  3. Create Dynpro 0100 with a custom container „CCONTAINER1“

  4. Create a GUI-Status „MAIN100“ with „BACK“, „EXIT“, „CANCEL“

  5. Create a GUI-Title „MAINTITLE“

  6. Activate and Run

OR

  1. Copy report BCALV_TREE_02 into a Z-Report

  2. Delete coding

  3. Paste my coding

  4. Create a structure „zbomexplode“ (see bottom of page)

  5. Activate and Run

What you can „learn“ from this example:

  • How to use CS_BOM_EXPL_MAT_V2

  • How to work with the output of CS_BOM_EXPL_MAT_V2

  • How to use ALV-Tree

  • How to use Events of ALV-Tree

  • How to read a column double clicked by the user

REPORT z_mm_bom_explosion_column.

*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

* Explosion of Multilevel-BOM and

* Graphical Display in ALV-Tree

*

* M. Fettinger 2012

* Original SAP-Example BCALV_TREE_02 was enhanced for this

* purpose

*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,

g_custom_container TYPE REF TO cl_gui_custom_container.

DATA: gt_outtab TYPE TABLE OF zbomexplode, "Output-Table

gt_fieldcatalog TYPE lvc_t_fcat,

ok_code LIKE sy-ucomm,

save_ok LIKE sy-ucomm.

DATA: gt_stb TYPE roij_stpox_t,

gt_matcat TYPE TABLE OF cscmat,

gs_topmat TYPE cstmat.

*###############################################################

* LOCAL CLASSES

*###############################################################

*§1. Define a (local) class for event handling

CLASS lcl_tree_event_receiver DEFINITION.

PUBLIC SECTION.

*§2. Define an event handler method for each event you want to react to.

METHODS:

handle_node_double_click

FOR EVENT node_double_click OF cl_gui_alv_tree

IMPORTING node_key sender,

* 'sender' is an implicit event parameter that is provided by

* ABAP Objects runtime system. It contains a reference to the

* object that fired the event. You may directly use it to

* call methods of this instance.

handle_item_double_click

FOR EVENT item_double_click OF cl_gui_alv_tree

IMPORTING fieldname

node_key.

ENDCLASS. "lcl_tree_event_receiver DEFINITION

******************************************************************

CLASS lcl_tree_event_receiver IMPLEMENTATION.

*§3. Implement your event handler methods.

METHOD handle_node_double_click.

DATA: lt_children TYPE lvc_t_nkey.

*first check if the node is a leaf, i.e. can not be expanded

CALL METHOD sender->get_children

EXPORTING

i_node_key = node_key

IMPORTING

et_children = lt_children.

IF NOT lt_children IS INITIAL.

CALL METHOD sender->expand_node

EXPORTING

i_node_key = node_key

i_level_count = 2.

ENDIF.

ENDMETHOD. "handle_node_double_click

METHOD handle_item_double_click.

DATA: outtab_line TYPE zbomexplode,

node_text TYPE lvc_value,

item_layout TYPE lvc_t_layi,

node_layout TYPE lvc_s_layn.

CALL METHOD g_alv_tree->get_outtab_line

EXPORTING

i_node_key = node_key

IMPORTING

e_outtab_line = outtab_line

e_node_text = node_text

et_item_layout = item_layout

es_node_layout = node_layout.

CASE fieldname.

WHEN '&Hierarchy'.

WHEN 'STLNR'.

SET PARAMETER ID 'MAT' FIELD outtab_line-idnrk.

SET PARAMETER ID 'WRK' FIELD outtab_line-werks.

SET PARAMETER ID 'CSV' FIELD outtab_line-stlan.

CALL TRANSACTION 'CS03' AND SKIP FIRST SCREEN.

WHEN 'IDNRK'.

SET PARAMETER ID 'MAT' FIELD outtab_line-idnrk.

SET PARAMETER ID 'MXX' FIELD 'K'. "Grunddaten

CALL TRANSACTION 'MM03' AND SKIP FIRST SCREEN.

ENDCASE.

ENDMETHOD. "handle_ITEM_DOUBLE_CLICK

ENDCLASS. "lcl_tree_event_receiver IMPLEMENTATION

*##################################################################

PARAMETERS: pa_matnr TYPE matnr OBLIGATORY,

pa_werks TYPE werks_d OBLIGATORY,

pa_datum TYPE datuv DEFAULT sy-datlo OBLIGATORY,

pa_stlan TYPE stlan OBLIGATORY,

pa_stlal TYPE stlal DEFAULT '01'.

START-OF-SELECTION.

DATA: ret TYPE sy-subrc.

PERFORM get_bom_data CHANGING ret.

IF ret = 0.

CALL SCREEN 100.

ENDIF.

*&---------------------------------------------------------------------*

*& Module PBO OUTPUT

*&---------------------------------------------------------------------*

* process before output

*----------------------------------------------------------------------*

MODULE pbo OUTPUT.

SET PF-STATUS 'MAIN100'.

SET TITLEBAR 'MAINTITLE'.

IF g_alv_tree IS INITIAL.

PERFORM init_tree.

CALL METHOD cl_gui_cfw=>flush

EXCEPTIONS

cntl_system_error = 1

cntl_error = 2.

IF sy-subrc NE 0.

CALL FUNCTION 'POPUP_TO_INFORM'

EXPORTING

titel = 'Automation Queue failure'(801)

txt1 = 'Internal error:'(802)

txt2 = 'A method in the automation queue'(803)

txt3 = 'caused a failure.'(804).

ENDIF.

ENDIF.

ENDMODULE. " PBO OUTPUT

*&---------------------------------------------------------------------*

*& Module PAI INPUT

*&---------------------------------------------------------------------*

* process after input

*----------------------------------------------------------------------*

MODULE pai INPUT.

save_ok = ok_code.

CLEAR ok_code.

CASE save_ok.

WHEN 'BACK'.

PERFORM exit_program USING 'X'.

WHEN 'EXIT' OR 'CANC'.

PERFORM exit_program USING ''.

WHEN OTHERS.

* §5. Call dispatch to process toolbar functions

* Toolbar events are registered in constructur method of

* CL_ALV_TREE_BASE as application events. So the dispatch call

* is a must if you want to use the standard toolbar.

CALL METHOD cl_gui_cfw=>dispatch.

ENDCASE.

CALL METHOD cl_gui_cfw=>flush.

ENDMODULE. " PAI INPUT

*&---------------------------------------------------------------------*

*& Form init_tree

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* --> p1 text

* <-- p2 text

*----------------------------------------------------------------------*

FORM init_tree.

* create container for alv-tree

DATA: l_tree_container_name(30) TYPE c.

l_tree_container_name = 'CCONTAINER1'.

CREATE OBJECT g_custom_container

EXPORTING

container_name = l_tree_container_name

EXCEPTIONS

cntl_error = 1

cntl_system_error = 2

create_error = 3

lifetime_error = 4

lifetime_dynpro_dynpro_link = 5.

IF sy-subrc <> 0.

MESSAGE x208(00) WITH 'ERROR'(100).

ENDIF.

* create tree control

CREATE OBJECT g_alv_tree

EXPORTING

parent = g_custom_container

node_selection_mode = cl_gui_column_tree=>node_sel_mode_single

item_selection = 'X'

no_html_header = 'X'

no_toolbar = ''

EXCEPTIONS

cntl_error = 1

cntl_system_error = 2

create_error = 3

lifetime_error = 4

illegal_node_selection_mode = 5

failed = 6

illegal_column_name = 7.

IF sy-subrc <> 0.

MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT

ENDIF.

DATA l_hierarchy_header TYPE treev_hhdr.

PERFORM build_hierarchy_header CHANGING l_hierarchy_header.

* Hide columns and sum up values initially using the fieldcatalog

PERFORM build_fieldcatalog.

* IMPORTANT: Table 'gt_outtab' must be empty. Do not change this table

* (even after this method call). You can change data of your table

* by calling methods of CL_GUI_ALV_TREE.

* Furthermore, the output table 'gt_outtab' must be global and can

* only be used for one ALV Tree Control.

CALL METHOD g_alv_tree->set_table_for_first_display

EXPORTING

is_hierarchy_header = l_hierarchy_header

CHANGING

it_fieldcatalog = gt_fieldcatalog

it_outtab = gt_outtab. "table must be empty !

PERFORM create_hierarchy.

PERFORM register_events.

CALL METHOD g_alv_tree->column_optimize

EXPORTING

* i_start_column =

* i_end_column =

i_include_heading = 'X'

EXCEPTIONS

start_column_not_found = 1

end_column_not_found = 2

OTHERS = 3.

* Send data to frontend.

CALL METHOD g_alv_tree->frontend_update.

ENDFORM. " init_tree

*&---------------------------------------------------------------------*

*& Form build_hierarchy_header

*&---------------------------------------------------------------------*

* build hierarchy-header-information

*----------------------------------------------------------------------*

* -->P_L_HIERARCHY_HEADER strucxture for hierarchy-header

*----------------------------------------------------------------------*

FORM build_hierarchy_header CHANGING

p_hierarchy_header TYPE treev_hhdr.

p_hierarchy_header-heading = 'Stücklistenauflösung'(300).

p_hierarchy_header-width = 35.

p_hierarchy_header-width_pix = ''.

ENDFORM. " build_hierarchy_header

*&---------------------------------------------------------------------*

*& Form exit_program

*&---------------------------------------------------------------------*

* free object and leave program

*----------------------------------------------------------------------*

FORM exit_program USING toselscr TYPE c.

IF toselscr = 'X'.

LEAVE TO SCREEN 0.

ELSE.

LEAVE PROGRAM.

ENDIF.

ENDFORM. "exit_program

*--------------------------------------------------------------------

FORM build_fieldcatalog.

DATA: ls_fieldcatalog TYPE lvc_s_fcat.

CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'

EXPORTING

i_structure_name = 'ZBOMEXPLODE'

CHANGING

ct_fieldcat = gt_fieldcatalog.

LOOP AT gt_fieldcatalog INTO ls_fieldcatalog.

CASE ls_fieldcatalog-fieldname.

WHEN 'MEINS'.

ls_fieldcatalog-outputlen = 10.

WHEN 'DUMPS'.

ls_fieldcatalog-outputlen = 10.

WHEN 'DATUV'.

ls_fieldcatalog-outputlen = 10.

WHEN 'DATUB'.

ls_fieldcatalog-outputlen = 10.

WHEN 'STLNR'.

ls_fieldcatalog-outputlen = 15.

WHEN 'WERKS'.

ls_fieldcatalog-outputlen = 10.

WHEN 'STLAN'.

ls_fieldcatalog-outputlen = 5.

WHEN 'STLAL'.

ls_fieldcatalog-outputlen = 5.

ENDCASE.

MODIFY gt_fieldcatalog FROM ls_fieldcatalog.

ENDLOOP.

ENDFORM. " build_fieldcatalog

*-----------------------------------------------------------------------

FORM register_events.

*§4. Event registration: tell ALV Tree which events shall be passed

* from frontend to backend.

DATA: lt_events TYPE cntl_simple_events,

l_event TYPE cntl_simple_event,

l_event_receiver TYPE REF TO lcl_tree_event_receiver.

*§4a. Frontend registration(i): get already registered tree events.

*................................................................

* The following four tree events registers ALV Tree in the constructor

* method itself.

* - cl_gui_column_tree=>eventid_expand_no_children

* (needed to load data to frontend when a user expands a node)

* - cl_gui_column_tree=>eventid_header_context_men_req

* (needed for header context menu)

* - cl_gui_column_tree=>eventid_header_click

* (allows selection of columns (only when item selection activated))

* - cl_gui_column_tree=>eventid_item_keypress

* (needed for F1-Help (only when item selection activated))

*

* Nevertheless you have to provide their IDs again if you register

* additional events with SET_REGISTERED_EVENTS (see below).

* To do so, call first method GET_REGISTERED_EVENTS (this way,

* all already registered events remain registered, even your own):

CALL METHOD g_alv_tree->get_registered_events

IMPORTING

events = lt_events.

* (If you do not these events will be deregistered!!!).

* You do not have to register events of the toolbar again.

*§4b. Frontend registration(ii): add additional event ids

l_event-eventid = cl_gui_column_tree=>eventid_node_double_click.

APPEND l_event TO lt_events.

l_event-eventid = cl_gui_column_tree=>eventid_item_double_click.

APPEND l_event TO lt_events.

*§4c. Frontend registration(iii):provide new event table to alv tree

CALL METHOD g_alv_tree->set_registered_events

EXPORTING

events = lt_events

EXCEPTIONS

cntl_error = 1

cntl_system_error = 2

illegal_event_combination = 3.

IF sy-subrc <> 0.

MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT

ENDIF.

*--------------------

*§4d. Register events on backend (ABAP Objects event handling)

CREATE OBJECT l_event_receiver.

SET HANDLER l_event_receiver->handle_node_double_click FOR g_alv_tree.

SET HANDLER l_event_receiver->handle_item_double_click FOR g_alv_tree.

ENDFORM. " register_events

*&---------------------------------------------------------------------*

*& Form create_hierarchy

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* --> p1 text

* <-- p2 text

*----------------------------------------------------------------------*

FORM create_hierarchy.

DATA: ls_stb LIKE LINE OF gt_stb,

ls_line TYPE zbomexplode,

lv_txt TYPE lvc_value,

lv_key TYPE lvc_nkey.

* WEGXX = Node Number

* TTIDX = Index in Table (gt_matcat-index <--> gt_stb-ttidx)

* VWEGX = Parent Node Number (regarding to stufe)

"Add Root-Node

MOVE-CORRESPONDING gs_topmat TO ls_line.

ls_line-ojtxp = gs_topmat-maktx.

ls_line-idnrk = gs_topmat-matnr.

lv_txt = gs_topmat-matnr.

SHIFT lv_txt LEFT DELETING LEADING '0'.

CALL METHOD g_alv_tree->add_node

EXPORTING

i_relat_node_key = ''

i_relationship = cl_gui_column_tree=>relat_last_child

is_outtab_line = ls_line

i_node_text = lv_txt

IMPORTING

e_new_node_key = lv_key.

"Create Hierarchy Recursive - Add Child Nodes

CLEAR ls_stb.

ls_stb-stufe = 0. "Parent

ls_stb-wegxx = 0. "Parent

PERFORM add_line USING ls_stb lv_key.

ENDFORM. " create_hierarchy

*&---------------------------------------------------------------------*

*& Form add_line

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* -->IS_STB text

* -->IV_KEY text

*----------------------------------------------------------------------*

FORM add_line USING is_stb TYPE stpox iv_key TYPE lvc_nkey.

DATA: ls_line TYPE stpox,

lv_next TYPE histu,

lv_key TYPE lvc_nkey,

lv_txt TYPE lvc_value,

ls_lin TYPE zbomexplode,

ls_matcat1 LIKE LINE OF gt_matcat,

ls_stb1 TYPE stpox.

lv_next = is_stb-stufe + 1.

LOOP AT gt_stb INTO ls_line WHERE stufe = lv_next

AND vwegx = is_stb-wegxx. "Parent

MOVE-CORRESPONDING ls_line TO ls_lin.

lv_txt = ls_line-idnrk.

"We want to display the BOM-Number (STLNR) of each Material (if it is itself also a BOM)

"Actually gt_stb STLNR shows the BOM of the parent of which the component is part of

READ TABLE gt_matcat INTO ls_matcat1 WITH KEY matnr = ls_line-idnrk.

IF sy-subrc = 0. "Material is also a BOM

READ TABLE gt_stb INTO ls_stb1 WITH KEY ttidx = ls_matcat1-index.

ls_lin-stlan = ls_stb1-stlan.

ls_lin-stlal = ls_stb1-stlal.

ls_lin-stlnr = ls_stb1-stlnr.

ELSE. "Material is no BOM - its the last level

CLEAR: ls_lin-stlan, ls_lin-stlal, ls_lin-stlnr.

ENDIF.

CALL METHOD g_alv_tree->add_node

EXPORTING

i_relat_node_key = iv_key

i_relationship = cl_gui_column_tree=>relat_last_child

is_outtab_line = ls_lin

i_node_text = lv_txt

IMPORTING

e_new_node_key = lv_key.

PERFORM add_line USING ls_line lv_key.

ENDLOOP.

ENDFORM. "add_line

*&---------------------------------------------------------------------*

*& Form get_bom_data

*&---------------------------------------------------------------------*

* text

*----------------------------------------------------------------------*

* -->IV_RET text

*----------------------------------------------------------------------*

FORM get_bom_data CHANGING iv_ret.

DATA: lv_mktls TYPE c VALUE 'X'.

CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'

EXPORTING

capid = 'PP01' "App ID

datuv = pa_datum

mktls = 'X' "Materialkurztext

mehrs = 'X' "Multi-level

mtnrv = pa_matnr

stlal = pa_stlal

stlan = pa_stlan

werks = pa_werks

IMPORTING

topmat = gs_topmat

TABLES

stb = gt_stb

matcat = gt_matcat

EXCEPTIONS

alt_not_found = 1

call_invalid = 2

material_not_found = 3

missing_authorization = 4

no_bom_found = 5

no_plant_data = 6

no_suitable_bom_found = 7

OTHERS = 8.

iv_ret = sy-subrc.

IF sy-subrc <> 0.

MESSAGE 'Stückliste konnte nicht gelesen werden!'(805) TYPE 'I' DISPLAY LIKE 'E'.

ELSE.

FIELD-SYMBOLS: <stb> TYPE stpox,

<mat> TYPE cscmat.

LOOP AT gt_stb ASSIGNING <stb>.

SHIFT <stb>-idnrk LEFT DELETING LEADING '0'.

ENDLOOP.

LOOP AT gt_matcat ASSIGNING <mat>.

SHIFT <mat>-matnr LEFT DELETING LEADING '0'.

ENDLOOP.

ENDIF.

ENDFORM. "get_bom_data

Structure zbomexplode