Hello folks,
We all are familiar with the CRM Web UI search screens. When we choose
the search parameters and hit the search button, internally what happens
is that, an instance of that particular application is created and a
query is fired to fetch the results.
All of this is usually taken care by the Web UI Framework.
But most of the time we might have the need to fetch the result in a
function module or a method. One way to approach this problem is to make
a direct select query to the DB, but this would be very expensive. So
the other alternate and better solution is to use the BOL Search Object.
This technique is normally used to create RFCs to export the data in CRM system to other systems.
I've tried to explain this approach in this thread. Hope I've done justice.
Prerequisites
1) Need to know the BOL application name. For eg: the application name for Business Transactions is 'BT'.
(these values are stored in Table CRMC_GIL_APPCOMP. This is also
accessible from SPRO, through the node CRM->CRM Cross App
Comps->GENIL->Basic Settings)
2) The name of the Query Object. For eg: The query object name for Opportunities is 'BTQOpp'
(You can find your query object name from transaction genil_bol_browser.
Enter your component set name and it will list the available query
objects)
3) Technical names of the search parameter.
(In transaction genil_bol_browser, double click your query object and
hit the F4 button in the Parameter field. This will give a list of
available parameters)
4) Your search filters. For eg: Opportunity Id = 555.
Steps for calling the Query Object
1) Get an instance of the BOL Core
We would need a BOL Core instance to call the call the methods of the framework.
DATA: lr_core TYPE REF TO cl_crm_bol_core.
lr_core = cl_crm_bol_core=>get_instance( ).
2) Start up the Component
lr_core->start_up( LV_APPLICATION_NAME ).
3) Get the Object model and find the result object structure
Data: lv_obj_model TYPE REF TO if_genil_obj_model,
lv_obj_model TYPE REF TO if_genil_obj_model,
lv_struc_name TYPE strukname.
TRY.
lv_obj_model = cl_crm_genil_model_service=>get_runtime_model( iv_application = is_query-application ).
CATCH cx_crm_genil_general_error.
ENDTRY.
CALL METHOD lv_obj_model->get_result_type_of_query
EXPORTING
iv_query_object_name = LV_QUERY_OBJECT_NAME
RECEIVING
rv_result = lv_result_object.
lv_struc_name = lv_obj_model->get_attr_struct_name( lv_result_object ).
4) Declare a field symbol. (Now this step is required because we are
writing a generic FM and we don't know the type of the result structure.
Hence we need to declare it at run time.)
FIELD-SYMBOLS : <fs_result_attr> TYPE ANY.
CREATE DATA lv_struc_ref TYPE (lv_struc_name).
ASSIGN lv_struc_ref->* TO <fs_result_attr>.
This way, we ensure that the field symbol can handle any type of result structure.
5) Initiate the dynamic query service.
Data: lr_adv_query TYPE REF TO cl_crm_bol_dquery_service.
lr_adv_query = cl_crm_bol_dquery_service=>get_instance( LV_QUERY_OBJECT_NAME ).
6) OPTIONAL: Set query parameters. (maximum hits)
DATA: lt_params TYPE crmt_name_value_pair_tab,
ls_params TYPE crmt_name_value_pair.
ls_params-name = 'MAX_HITS' .
ls_params-value = iv_maxhits.
APPEND ls_params TO lt_params.
lr_adv_query->set_query_parameters( it_parameters = lt_params ).
7) Fill the selection parameters
lr_adv_query->add_selection_param( iv_attr_name = 'OBJECT_ID'
iv_sign = 'I' "Inclusive or Exclusive
iv_option = 'EQ' "Equal, not equal, contains. But make sure the option is supported.
iv_low = '555'
iv_high = '' ).
Similarly multiple parameter search filters can be added.
😎 Execute the query
Data: lr_coll TYPE REF TO if_bol_entity_col.
lr_coll = lr_adv_query->get_query_result( ).
This step will give us the results as a collection of entities.
9) The next step is to loop into this collection of entity and to read the attributes of each entity.
This is pretty standard stuff.
IF lr_coll IS BOUND.
lr_entity ?= lr_coll->get_first( ).
WHILE lr_entity IS BOUND.
CALL METHOD lr_entity->if_bol_bo_property_access~get_properties
IMPORTING
es_attributes = <fs_result_attr>.
Here you can manipulate the result to fill it into a export parameter
lr_entity ?= lr_coll->get_next( ).
CLEAR: <fs_result_attr>.
EndWhile.Endif.
Hope it helps.
If you guys have any further questions, please post them.
thanks,
Madan