Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
ChrisSolomon
Active Contributor

This is the continuation of the previous blog (part 4) where we covered using Search Helps in our forms.

 

-Part 1: Intro to OADP and Organization Structure Views

-Part 2: OADP continued (Object Provider...the "O" of OADP)

-Part 3: OADP wrap up (Data Provider....the "D" of OADP)

-Part 4: Search Help WebDynpro ABAP components and usage in HCM P&F forms

-Part 5: The OADP WebDynpro ABAP component

-Part 6: Summary

 

OADP "engine" Component

So we covered how the pop-up window is triggered and how the selected values return to the form, but how does all the "magic" in the middle happen....the display of our data based on our searches?

The "Search Help" WDA component actually contains another WDA component called OBJECTDATAPROVIDER. This is the actual "workhorse" of the Search Help.

(*note, you can test this component using SE80 and running the WDA examples OADP_EXAMPLE and OADP_TEST. You may need to refer to SAP note 1109215 if these do not exist in your SICF.)

Our Search Help WDA calls this component first in it's method CALL_POPUP.

  CALL METHOD lr_oadp->init_data_from_orgviewgroup(
  
EXPORTING
   cache_maxage                   
= 1                       "update data once a day
   data_begda                     
= sy-datum
   data_dest                      
= 'NONE'                  "read the data from own system
   data_endda                     
= sy-datum
   hide_dropdown_for_single_views 
= abap_true
   initial_ui_settings            
= lr_ui_settings
   instance_id                    
= 'SEARCH_ORGUNIT'
   objects_begda                  
= sy-datum
   objects_endda                  
= sy-datum
   orgviewgroup                   
= l_orgviewgroup
   user                           
= sy-uname ).

This is where it tells the OADP component which OADP "Structural Org Group View" from configuration that we wish to use. For our example, this is l_orgviewgroup value is "ASR_ORG_SEARCH".

Once the window is up and the user makes selections (which again, came from our HR_SELECTIONS "sel_id" value), the user clicks"start" to execute their search. This fires the method  ONACTIONSTART_SEARCH in view NAVIGATIONVIEW which in turn calls the Component Controller's method EXECUTE_OBJECT_SEARCH. This method inspects our search fields and their values. It also calculates the number of "hits" (l_total_hits), the starting point in our paging (l_start_index) and the numberof hits shown at once in the ALV table(l_package_size). From this is constructs our results message (for example, " 1116 Hits Found Hits 1 to 10 Are Displayed ")

Then, this code executes the actual "search":

 

* execute search
 
call method wd_this->model->execute_object_search
   
exporting paging_direction = paging_direction
   
importing error_msg = l_error_msg.

 

Executing the Search

This calls the class CL_OADP_MODEL  method EXECUTE_OBJECT_SEARCH which fires:

* execute the search
  update_objects
( importing error_msg = error_msg ).

This in turn calls function hrwpc_rfc_oadp_exec_objsearch of function group HRWPC_OADP_UI.

      CALL FUNCTION 'HRWPC_RFC_OADP_EXEC_OBJSEARCH' destination m_data_dest
       
EXPORTING
          OBJSEL                       
= m_objsel
          XADVANCEDSEARCH              
= m_adv_search_on
          BEGDA                        
= m_objects_begda
          ENDDA                        
= m_objects_endda
          USER                         
= m_user
*         LANGU                         = SY-LANGU
          CACHEMAXAGE                  
= m_cache_maxage
          HITPACKAGESIZE               
= m_search_package_size
          HITPACKAGESTARTINDEX         
= m_search_start_index
       
IMPORTING
          TOTALHITS                    
= m_search_total_hits
*         READDATE                      =
*         READTIME                      =
       
TABLES
          T_PARAMVALUES                
= mt_application_params
          T_SEARCHVALUES               
= mt_search_values
          T_SEARCHOBJECTS              
= mt_objects
      
EXCEPTIONS
         OBJSEL_NOT_FOUND             
= 1
         OBJECTSELECTION_INVALID      
= 2
        
OTHERS                        = 3

 

This function finds our "Search Class" based on the "OADP Structural View Group" ID we passed (ie. ASR_ORG_SEARCH).  It also reads our application parameters and checks to see if we are doing the same search as a previous one (checks cache) to avoid doing it again. If the search is not cached, it fires our search.

So this function knows our search class and what application parameters we want to use but how does the ACTUAL search happen?

Calling our Search Class

Keep in mind, because our "Search Class" CL_HRWPC_SEARCH_VIA_SELID  implements the interface IF_HRWPC_OADP_OBJECTSEARCH , this code simply calls the method which in turn calls the method IF_HRWPC_OADP_OBJECTSEARCH~EXECUTE_SIMPLE_SEARCH as implemented in our class.

Remember, we passed it a parameter called "SIMPLE_SEARCH_SELID" with a value "ASR_ORG_SEARCH". Inside that class, it takes this value as a "selection ID" (ie. SEL_ID).

METHOD if_hrwpc_oadp_objectsearch~get_fields_for_simple_search.
 
DATA: l_selid       TYPE hr_selid.
 
DATA: ls_paramvalue TYPE hrwpc_s_oadp_paramvalue.
* clear result
 
CLEAR t_searchfields[].
* get sel_id from search params
 
READ TABLE t_paramvalues INTO ls_paramvalue
                          
WITH KEY paramname = 'SIMPLE_SEARCH_SELID'.
 
IF sy-subrc <> 0.
   
RETURN.
 
ENDIF.

  l_selid
= ls_paramvalue-paramvalue.

 
CALL METHOD cl_hrwpc_search_via_selid=>get_searchfields_from_selid
   
EXPORTING
      sel_id        
= l_selid
      langu         
= langu
   
IMPORTING
      t_searchfields
= t_searchfields[].
ENDMETHOD.

 

Remember that the "Selection ID" is used not only to tell our "OADP" WDA component how to build our "search options" in the NAVIGATIONVIEW but it also is used here in order to determine our "search fields" and values as well.

Selection ID

We can see this SELECTION ID (aka. SIMPLE_SEARCH_SELID, aka. SEL_ID) in action as configured.  Go to transaction SM34 and enter "HR_SELECTIONS".

Click "display".

We can see what fields are selected under "Table":

...more...

This is what lays out our "Search Field" in the "OADP" OBJECTDATAPROVIDER WDA component's NAVIGATIONVIEW view. As we see...

After the user clicks the "Start" button, this executes the search in the Search Class' method IF_HRWPC_OADP_OBJECTSEARCH~EXECUTE_SIMPLE_SEARCH as mentioned above. This then calls method EXECUTE_SELID which calls function HR_COMBINED_SELECTION that does the work of looking it up in HRP1000:

CALL FUNCTION 'HR_COMBINED_SELECTION'

The results are just our OBJIDs that match the selection:

The data is looped and "enriched" into table T_RESULT_OBJECTS. This appears as:

Some code is in place to check if the "user" is to be excluded from the result set (in the case of a manger for instance).

The "results" are then run through another function to generate "object keys" (ie. give each row a unique "index" number". This is the first column shown as "OBJ_KEY".

As explained earlier, after the "search" is handled and model is set (class CL_OADP_MODEL), control returns to the OBJECTDATAPROVIDER WDA component's Component Controller method EXECUTE_OBJECT_SEARCH. Here, some other bits of code follow to calculate "hits" and number of results to display per "package size" (ie. 10 rows in table at a time). Lastly, the timestamp is calculated. This is all passed back to the "wrapper"/engine WebDynpro ABAP.

But how is the results table display determined? How does it know what data to show in what column and how to name them?

Merging the Data with our OADP Columns

Look at WDA component  OBJECTDATAPROVIDER. In controller method EXECUTE_OBJECT_SEARCH, look at call to method change_dataview. It builds our columns and fills them with data:

 

* create the new column context
  wd_this
->create_dataview_context( ).

* fill new data in column context
  wd_this
->fill_dataview_context( ).

 

First, it sets our "model" (class CL_OADP_MODEL) with the call to method UPDATE_DATAVIEW. This calls function HRWPC_RFC_OADP_EVAL_DATAVIEW which calls function HRWPC_OADP_CHECK_DATAVWCACHE to determine our column metadata and contents.What happens in here is a LOT of write/reads/extracts from memory.....not for the timid (and actually not really much we need to be concerned with).

This looks at:

...and the content for each "column"...

But how does it know of all this data WHAT to put into each column shown?

FM for Column Contents

Remember our column configuration.....

 

If you look, you can see that we defined our content for the column to be determined by function HRWPC_FILL_STANDARD_COLUMNS(FM for Column Contents).  

 

From SAP documentation:

  "If the column content is to be determined in the backend system, enter a function module that is to get the column content. To create a function
module of your own, use the function module HRWPC_CB_CONTENT in the standard system as a template. You must use this as a template since your function module must have the same interface as the function module in the standard system."

The function HRWPC_FILL_STANDARD_COLUMNSlooks at our "column name" and then determines what field this maps to in our data.


For example, our column name "ORG_STEXT_JS" maps over to STEXT. Actually, it looks to see if STEXT is empty or not and will try to map it to SHORT if STEXT is not available.


if KEY_OBJECTS-STEXT is initial.

          column_content
-content = KEY_OBJECTS-SHORT.
else.

          column_content
-content = KEY_OBJECTS-STEXT.
endif.


Likewise, our other column name, "ORG_OBJID_2" similarly maps to field REALO.


With our columns defined ("how" to display to users) and the content for those columns defined ("what" to display for users), we finally get:

In Part 6, we wrap this all up....this series comes to an end!...

Labels in this area