Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

In my last Blog ( Create your own BOL Object ) I showed how you can create your own custom BOL object
 that meet your personal requirements.
 Now that we have our BOL Object we might want to use it for our purposes. 
Let's say that we want to add several fields to assignment block and
display them on the screen,  for instance we take the fields from our Z table
that we use in the creation of our BOL Object.
We also want to keep the connection for the original transaction context .
The steps for doing that are :
1) We need to add a field to our Z table BP_GUID which will keep us connected
    to the main transaction context .
2) Perform the adjustment for the Z Table.
3) Search for the right BP_GUID that fit to our user account.
4) create new record that contain the details that we want to display for the specific
See the following screen shot.

Now we need to perform some adjustment for our table .

choose the Database Utility from the menu .
See the following screen shot.

once you choose this option you'll get the next screen :

In our case we will choose the Delete data option becuse we want to create a new record, you also have to know that if you choose the Save data option there's no 100  percent guarantee that your data in the table will be saved , so you should consider the use of Database Utility very careful. 

After we perform the adjustment and activated the table we can step forward to the next step which is the creation of a new record with the details that we want to display on the screen .  

First to the record creation we should find the key which is the BP_GUID that will connect us to the account context . 

To find the right BP_GUID enter transaction GENIL_BOL_BROWSER and insert the BP_APPL_COND  in the component set field.

See the following screen shot.

when you enter to the component set choose the predefined search
named BuilEmpSearch  
 See the following screen shot.

Now we can look for any partner , in my case i'll choose to search  my user and i'll get the compatible  BP_GUID which is : DF21EBC73A26F8F1A2B0001F29644FC0
See the following screen shot.

Now let's create a new record in the DataBase table ZUSR_BOL_TB with user name, BP_GUID , First and last names.
See the following screen shot.

For now we finish with the database side and we wiil go to perform some improvement in our BOL object to support the different searching options.

So let's go to transaction SE24 and put ZCL_OWN_BOL in the input filed.
click on Local Types button and put the lines inside :


TYPES: BEGIN OF ty_general_rng ,

sign TYPE bapisign,

option TYPE bapioption,

low TYPE string ,

high TYPE string ,

END OF ty_general_rng .

tt_general_rng TYPE STANDARD TABLE OF ty_general_rng .

See the following screen shot:

Now go back to the method list and edit the

replace the exisiting code with the bellow lines:
METHOD if_genil_appl_intlay~get_dynamic_query_result.
DATA: lr_object TYPE REF TO if_genil_cont_root_object,
lt_result TYPE TABLE OF zusr_bol_st,
lv_dyn_where TYPE string,
lv_len TYPE i ,
ls_range TYPE ty_general_rng.

DATA: lt_bp_guid TYPE tt_general_rng,
lt_bname_range TYPE tt_general_rng,
lt_name_first TYPE tt_general_rng,
lt_name_last TYPE tt_general_rng.

FIELD-SYMBOLS: <lfs_result> TYPE zusr_bol_st,
<lfs_selection_range> TYPE genilt_selection_parameter.

  • decomposition of selection parameters and build a dynamic where condition

LOOP AT it_selection_parameters[] ASSIGNING <lfs_selection_range>.
MOVE: <lfs_selection_range>-sign TO ls_range-sign ,
<lfs_selection_range>-option TO ls_range-option ,
<lfs_selection_range>-low TO ls_range-low ,
<lfs_selection_range>-high TO ls_range-high.
CASE <lfs_selection_range>-attr_name.
APPEND ls_range TO lt_bname_range[].
CONCATENATE lv_dyn_where 'bname in lt_bname_range[] and' INTO lv_dyn_where SEPARATED BY space .

APPEND ls_range TO lt_bp_guid[].
CONCATENATE lv_dyn_where 'bp_guid in lt_bp_guid[] and' INTO lv_dyn_where SEPARATED BY space .

APPEND ls_range TO lt_name_first[].
CONCATENATE lv_dyn_where 'name_first in lt_name_first[] and' INTO lv_dyn_where SEPARATED BY space .

APPEND ls_range TO lt_name_last[].
CONCATENATE lv_dyn_where 'name_last in lt_name_last[] and' INTO lv_dyn_where SEPARATED BY space .

lv_len = STRLEN( lv_dyn_where ) - 4 . "remove the last 'AND' in the condition
lv_dyn_where = lv_dyn_where(lv_len) .
CHECK STRLEN( lv_dyn_where ) > 0.
SELECT * FROM zusr_bol_tb INTO TABLE lt_result[] WHERE (lv_dyn_where).
CHECK LINES( lt_result[] ) > 0.
LOOP AT lt_result[] ASSIGNING <lfs_result>.
lr_object = iv_root_list->add_object( iv_object_name = 'Root'
is_object_key = <lfs_result>-bname ).
CHECK lr_object IS BOUND.
lr_object->set_query_root( abap_true ).


Save and activate your code.

We might want to add the BNAME ,NAME_LAST,NAME_FIRST fields to a view that we will create

Personally I choose the BP_HEAD component but you can choose any component that you may use.

OK. So let's get in and execute transaction BSP_WD_CMPWB_NEW and choose BP_HEAD component with our enhancement set which is specifically in my case called ZENH_CRM and hit the display button and go to Runtime Repository Editor, open the MODELS folder to see with which BOL component set the BP_HEAD component use.

See the following screen shot.

We can see now that the component BP_HEAD use the Model BP_APPL_COND and we want that our BOL object will appear in the repository of the BP_HEAD component so that we can use it for our purpose.

To do that we need to go to the component set definition.

See the following screen shot.

Now choose the appropriate component set which is in our case BP_APPL_COND.

See the following screen shot.

Now click on component assignment make new entry and add our BOL object named ZBOLOB.

See the following screen shot.

Don't forget to save the new entry.

After you saved it successfully enter again to BSP_WD_CMPWB_NEW transaction with BP_HEAD component and click on the BOL Model Browser tab, we want to check here that we can see our BOL entity ready for use.

See the following screen shot.

Now we can see that our BOL entity Root that we created is ready for use in the enhancement of BP_HEAD component. We will go to Component Structure Browser tab and create our view.

See the following screen shot.

We'll choose a name for our view.

See the following screen shot.

After we named the view we need to add 2 model nodes, one for BuilHeader and
one For our Root BOL object.

The first one is for getting the relevant BP_GUID from the custom controller and get the appropriate first name last name and user name according to our table .

See the following screen shot.

The next step is to add the fields that we might use in our view to context which we working on.

We start with the BuilHeader fields.

See the following screen shot.

We use also attributes from the Root BOL object .
See the following screen shot.

We got the whole attributes as shown bellow.
See the following screen shot.

We move to the next step.

Here we need to define the view type and its properties.

The view type we choose form view without buttons and in the properties we make it configurable and that for keep to our self the option to Add/Remove

Attributes from the view.

See the following screen shot.

Now we finish the view addition with the wizard we will see that our view is listed with the other views in the component.

See the following screen shot.

After we added the view we should create a binding to the custom controller context node BUILHEADER.

So we put the mouse curser on the context node BUILHEADER pressing the right mouse

Click and create the binding.

See the following screen shot.

We will create the binding for our context node to the same context node in the custom controller.

See the following screen shot.

After we create the appropriate binding we need to add the attributes to the view.

So we move to the configuration tab when we working on the view and then we switch to edit mode.

We see that we have the 2 BOL objects that we added when we working with the wizard in time of the view creation.

In our case we will add the attributes from the Root BOL object.

See the following screen shot.

After we add the attributes to our view we need to add our view as an assignment block.

First we need to add our view to the BPHEADOverview viewset , to do this we will go to the

Runtime Repository Editor and we will add our view to the OverviewPage of BPHEADOverview viewset .

See the following screen shot.

After we added the view to the BPHEADOverview viewset we will go to the configuration tab of BPHEADOverview viewset and switch to edit mode and add our view TestBOLroot to the list of views that appears as an assignment
blocks in the BPHEADOverview viewset by click on the arrow button and moving it from the left side to the right side .

See the following screen shot.

After we handle the addition of adding our view as an assignment block we need to handle some code addtions for the right treatment in the attributes in our view .

First we will go to the ROOT context node within our view and redefine
the method IF_BSP_MODEL~INIT.

See the following screen shot.

Put the next ilnes into the method save and aactivate the method.

TYPES: BEGIN OF ltype_attr_struct,
mandt TYPE mandt,
bp_guid TYPE bu_partner_guid,
bname TYPE xubname,
name_last TYPE bu_namep_l,
name_first TYPE bu_namep_f,
END OF ltype_attr_struct.

DATA: lrf_data_struct TYPE REF TO ltype_attr_struct,
lrf_value_node TYPE REF TO cl_bsp_wd_value_node,
lrf_bol_collection TYPE REF TO if_bol_bo_col.

super->if_bsp_model~init( id = id owner = owner ).

CREATE DATA lrf_data_struct.

CREATE OBJECT lrf_value_node
iv_data_ref = lrf_data_struct.

CREATE OBJECT lrf_bol_collection TYPE cl_crm_bol_bo_col.
lrf_bol_collection->add( lrf_value_node ).
me->set_collection( lrf_bol_collection ).
After we add the above lines to the method we will go to the implementation class of our view, which is in our case is ZL_ZBP_HEAD_TESTBOLROOT_IMPL.

we will double click on the class name and we will move to display mode of the class in a way that all the method could be shown.

The first thing to do is to write our own method for performing the right query when we need to display the attributes on the screen .

After that we will redefine the method DO_PREPARE_OUTPUT.

so let's create a new method named root_query which is an Instance Method , and the visibility of it is Private.

put the next lines to the method .

METHOD root_query.

DATA: lrf_advanced_query TYPE REF TO cl_crm_bol_dquery_service,
lrf_root_result_collection TYPE REF TO if_bol_entity_col,
lrf_root_result_bol_entity TYPE REF TO cl_crm_bol_entity,
lrf_current_root TYPE REF TO if_bol_bo_property_access,
lrf_current_builheader TYPE REF TO if_bol_bo_property_access,
lt_params TYPE crmt_name_value_pair_tab,
ls_params TYPE crmt_name_value_pair,
ls_builheader_properties TYPE crmst_header_object_buil,
lv_low_value TYPE string ,
ls_root_properties TYPE zusr_bol_st.

ls_params-name = 'MAX_HITS' .
ls_params-value = '1'. "we don't need in this case more the single record for result
APPEND ls_params TO lt_params.

lrf_current_root ?= me->typed_context->root->collection_wrapper->get_current( ).
CHECK lrf_current_root IS BOUND .

lrf_current_root->get_properties( IMPORTING es_attributes = ls_root_properties ).

CHECK ls_root_properties IS INITIAL .
" means that we don't have any values in our
"fields and therfore wi'll excute the query
lrf_current_builheader ?=
me->typed_context->builheader->collection_wrapper->get_current( ).

CHECK lrf_current_builheader IS BOUND .

lrf_current_builheader->get_properties( IMPORTING es_attributes = ls_builheader_properties ).

CHECK ls_builheader_properties-bp_guid IS NOT INITIAL .

lv_low_value = ls_builheader_properties-bp_guid.
lrf_advanced_query = cl_crm_bol_dquery_service=>get_instance( 'Search' ).
lrf_advanced_query->set_query_parameters( it_parameters = lt_params ).
lrf_advanced_query->add_selection_param( iv_attr_name = 'BP_GUID'
iv_sign = 'I'
iv_option = 'EQ'
iv_low = lv_low_value
iv_high = '' ).

lrf_root_result_collection = lrf_advanced_query->get_query_result( ).

IF lrf_root_result_collection IS BOUND . "if we found something that match our selection

lrf_root_result_bol_entity = lrf_root_result_collection->get_first( ).
lrf_root_result_bol_entity->get_properties( IMPORTING es_attributes = ls_root_properties ).
lrf_current_root->set_properties( is_attributes = ls_root_properties ).

Save and activate your code .
the next step is to redefine the method DO_PREPARE_OUTPUT.

put the next lines into the method .



iv_first_time = iv_first_time.

me->ROOT_QUERY( ).



save and activate your code .

Now all job is done our BOL object is wroking like a Rolls-Royce and it's time to derive pleasure from .
We will go to the webclient , choose our account and display it .

we can see that we have our attributes shown on the screen .

See the following screen shot.

Good Luck. -(smile)

1 Comment

  1. Guest

    Hello Harel!

    When I open Configuration tab for new created view TestBOLRoot, I cache what error:

    Error Processing Navigation Entries
    An exception has occurred
    Exception Class    CX_BSP_WD_INCORRECT_IMPLEMENT - Define NavigationalLink for source view BSP_DLC_CONF/ConfigVS.
    Program:               SAPMHTTP
    Source Text Row:  0

    Can you tell me how can I resolve this problem?

    With best regards, Marat.