Technical Articles
How to add new row / element to context node collection in SAP CRM using ABAP
Sometimes performing even basics tasks in ABAP may confuse, especially if you are a newbie in ABAP. Today I’m going to show how to add new row (line, element) to context node collection in SAP CRM using ABAP. At the end of the post you can find the final code example, implementing the discussed task. Feel free to copy, paste and run this code snippet.
Theory. In order to add new element to context node you have to:
- Define a structure line of the context node element
- Create data reference, based on the structure line, defined at the previous step
- Define the new context node object that will contain the new values, we’re going to add to the context node
- Fill the new context node object with the new values
- Add new context node object, filled with the data to the context node
Practice. The final code:
- ” define structure line of the context node
- TYPES:
- BEGIN OF line_struct_type,
- personID TYPE numc5,
- firstName TYPE char30,
- lastName TYPE char30,
- END OF line_struct_type.
- DATA:
- cn_line_struct TYPE REF TO DATA,
- cn_single_element TYPE REF TO cl_bsp_wd_value_node.
- ” create data object, based on defined structure line
- CREATE DATA cn_line_struct TYPE line_struct_type.
- ” create new data container object according to the context node structure line
- CREATE OBJECT cn_single_element
- EXPORTING
- iv_data_ref = cn_line_struct.
- ” fill the values into new data container object
- cn_single_element->set_property_as_string(
- EXPORTING
- iv_attr_name = ‘personID’
- iv_value = ‘222’
- ).
- ” push the new data container object to the existed context node collection
- comp_controller_ref->typed_context->%context_node%->collection_wrapper->ADD (
- EXPORTING
- iv_entity = cn_single_element
- ).
As you can see, even such basic stuff in ABAP SAP CRM may contain some pitfalls.
great smal solution.
Do you have more of such examples?
Could you specify what kind examples do you actually looking for?
I'm thinking about basic things e.g.
Remove entity from collection with interator:
DATA: lv_collection TYPE REF TO if_bol_bo_col,
entity TYPE REF TO cl_crm_bol_entity.
data: lv_index type i.
* In display mode only show attributes that contain a value
IF entity->is_locked( ) EQ abap_false.
lv_index = lv_collection->size( ).
WHILE lv_index GT 0.
entity ?= lv_collection->find( iv_index = lv_index ).
IF entity IS BOUND
AND entity->get_property_as_string( 'ATTR_VALUE' ) IS INITIAL.
lv_collection->remove( entity ).
ENDIF.
SUBTRACT 1 FROM lv_index.
ENDWHILE.
ENDIF.
Or working with value nodes.
br
Jürgen
Ok, I'll tink about it.
BTW, if I remember right, entity->is_locked( ) indicates if the current entity is locked only by user, who calls is_locked( ). Am I right?
If I'm right, the delete process can cause the problem, it may not delete the element, may cause the dump or other side-effects.
So, be careful with this scenario.
HI Mike,
it is just an example from my z_component nothing from production.
Just an example.
Remove entity from collection with interator:
DATA: lv_collection TYPE REF TO if_bol_bo_col,
entity TYPE REF TO cl_crm_bol_entity,
lv_index TYPE i.
lv_index = lv_collection->size( ).
WHILE lv_index GT 0.
entity ?= lv_collection->find( iv_index = lv_index ).
IF entity IS BOUND
AND entity->get_property_as_string( 'ATTR_VALUE' ) IS INITIAL.
lv_collection->remove( entity ).
ENDIF.
SUBTRACT 1 FROM lv_index.
ENDWHILE.
So, now it is more general.
br
Jürgen
That is great! How do you find out? 😕
By trial and error method 😉
Good one!!
Cheers,
Leon
nice doc..
but i have one doubt regarding the display of new added attribute, will it be display in configuration of view or not if we want to display it in UI. or any other way to display..?
Best regards,
Harish kumar.
In my post I related to the question of adding new row to existed context node with already defined structure, not to the question of adding a new attribute to the context node. Thus, if you have defined displaying of this attribute in UI via configuration or via BSP, and you retrieve this new added line from context node correctly, so I don't see any reason to have an issue.
If you mentioned some other doubt, please, let me know.
Very informative. Thanks 🙂
Hi Mike,
Good One.
I need some clarification.
In this case you considered the context node holds only a value node ( value attributes ) right?
If the context node holds a model node then this thing will not work.
In this case we need to get it's parent and use the create_related_entity method and then we need to add it to the collection of the context node.
Is it correct???
Regards,
DP.
Unfortunately, I can't check it right now, but it looks like a right direction.
Try to implement and let us know if it works.
I tried this before..
If it is a context node with model attributes we cannot add the cl_bsp_wd_value_node to the collection of context node as it refers to cl_crm_bol_entity.
I think what ever the example code that you wrote is for a context node with value attributes.
Regards,
DP.
Yeap, code, I posted, is specified for value node case.
Basically, I don't see a reason why we can't add new element to model context node, so tomorrow I'll try to play with the case of model node and hope, will can suggest the way to solve the issue.
There is no issue in doing that for a model node.. We just need to use the method create_related_entity and add it to the collection. I did it once earlier
I my code btpartnerset is the parent object and its child Btpartner is a table view, so i used the following code :
data : lr_curr_partset type ref to cl_crm_bol_entity.
lr_curr_partset ?= me->typed_context->btpartnerset->collection_wrapper->get_current( ).
CALL METHOD LR_CURR_PARTSET->CREATE_RELATED_ENTITY
EXPORTING
IV_RELATION_NAME = 'BTPartnerOpportunity'
RECEIVING
RV_RESULT = lr_partneroppt.
check lr_partneroppt is bound.
me->typed_context->btpartner->collection_wrapper->add( lr_partneroppt ).
Let me understand, earlier you wrote: «If it is a context node with model attributes we cannot add», now you are writing: «There is no issue in doing that for a model node».
So, what's the problem? Do you succeed to implement the task or not?
Do you succeed to add a new element to context node of model node type or not?
Please, clarify the situation, I want to know if «to play with the case» or you are already OK with the case.
I am already ok with this case. I just tried your code for adding a row to model node but it did not worked for me. So I am asking you for a clarification that your code is only for Value node and for adding a row to a model node we need to follow the code which i posted in the previous comment.
Actually, at the end we're using the same code except one thing.
In my code I'm showing how to build new element, fill it with data and only after that to add it to collection wrapper.
In contrast, in your case, there is no such step, since you are working with model node, so, you don't have to execute all this dances with defining structure, creating element and filling it with data. You just need to create related entity, to get the reference to created relation and if it's bounded, add it to collection wrapper.
That's all.
Hi,
Technically looks like you can, but I don't really see the benefit of it. Diferent kinds of entities inside a context node can lead to confusion or errors,
Example 1: The context node is pointed to a table view element, each row should have the same structure so all entities inside the context node should be equall.
Example 2: Someone fresh just started in the project, he/she will need some time to understand what the hell is happening, "why in this context node which I use the method get_curren give me an entity BuilHeader(for example) and in other scenarios is a "Blahblahblah" ?
I hope you don't take it to the wrong way, I'm just trying to contribute.
Cheers!
Luis
100% agree.