cancel
Showing results for 
Search instead for 
Did you mean: 

Doubt for optimize abap code in BADI

PTecnico
Explorer
0 Kudos
162

Hello Experts,

I need implement the BAdI, that allow create reate object relation for adapting employee organizational assignment

https://help.sap.com/docs/SAP_SUCCESSFACTORS_EMPLOYEE_CENTRAL_INTEGRATION_TO_SAP_BUSINESS_SUITE/a7f1...


I need create a relationship between the object S and Custom

The BADI have a method IF_SFIOM_ADAPT_EE_ORG_ASSGNMNT~CREATE_OBJECT_RELATION for Create object relation

The information organizational comes as a parameter in the internal table is_ee_org_ass_repl_req-org_assignment

For each employee who goes through this BADI, and processes their organizational assignment as appear in the following image:

PTecnico_0-1737024469720.png

I had this code  and generate issue of performance:

    LOOP AT is_ee_org_ass_repl_req-org_assignment INTO DATA(ls_org_assignment).
	lv_fecha_inicial = ls_org_assignment-start_date.
        lv_fecha_final = ls_org_assignment-end_date.
	lv_posicion	ls_org_assignment-position_id

      SELECT SINGLE sobid  FROM hrp1013 CLIENT SPECIFIED  
        INTO (@DATA(lv_sobid) )
        WHERE  mandt = @SY-mandt and plvar =  '01' and
        objid = @LV_posicion AND ( begda <= lv_fecha_final AND endda >= lv_fecha_final ) 

    ENDLOOP.

I need read the infotype hrp1013 for get the employee type where when the employee type = 1

I have done the following change:

DATA(lv_cont) = lines( is_ee_org_ass_repl_req-org_assignment ). 
IF lv_cont >= 2.
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont - 1 ] TO lt_fin. 
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont ] TO lt_fin.     
ELSEIF lv_cont = 1.
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont ] TO lt_fin.     
ENDIF.

DATA: lt_sobid TYPE TABLE OF hrp1001-sobid, lt_posids TYPE TABLE OF hrp1001-objid. 



  IF lt_fin IS NOT INITIAL.
   SELECT sobid FROM hrp1013 CLIENT SPECIFIED 
      INTO TABLE lt_sobid FOR ALL ENTRIES IN lt_fin
       WHERE mandt = @SY-mandt  AND 
             plvar = '01'       AND 
             objid = @LT_posids AND 
             begda <= lv_fecha_final AND
             endda >= lv_fecha_final
   ENDIF. 

   " Processing the results as needed 
   LOOP AT lt_sobid INTO DATA(ls_sobid). 
   " My logic here using ls_sobid 
   ENDLOOP.

 My Question :

What other changes can do? or Using the new ABAP how can change this code ?

View Entire Topic
radinator
Participant
0 Kudos

Your code is a bit confusing.

  • Comparing the first code snippet to the second one:
    In the first snippet you loop over the incoming table and etract start and end date as well as the id and then select on HRP1013 with mandant, planvariant, id and the date range
  • The second snippet does some sort of weird entry swapping. If there are more than or exactly 2 entries it swaps the last 2 entries and puts only those two entries in the lt_fin table. If there is only one entry it just takes that one entry. In the part below that you check if lt_fin is not empty and if this is the case you perform the select

Can you explain what the swapping is used for?

To me there is little change in general, just some re-formating going on. In order to give an answer to your question on what you can do better I’d say

  • In the SQL statement use the BETWEEN keyword when comparing date values so you don’t need to use brackets and comparsion operators and it’s more type safe (assuming the DB field and the comparing values are of type D)
  • In the second code snippet, you check if lt_fin is not empty and regardless of it being empty or not you use the result oft he following SQL statement for processing the data. Here you should either include the data processing in the IF context or you do a return code check if the SQL statement actually returns any value. If you don’t do this you could get into the situation where the query returns no values, setting sy-subrc to 4 and you work with the data from the previous iteration. You should also CLEAR the tables before

 

PTecnico
Explorer
0 Kudos

Hi

The is triger by each employee and when is called the BADI the table is_ee_org_ass_repl_req-org_assignment, have all the organizational assignment only for this employee:

I need pass only the two last records to a internal table that I am named as lt_fin

 

DATA :lt_fin  TYPE TABLE OF SFIOM_S_REPL_REQ_ORG_ASS_EXTND .
  DATA(lv_cont) = lines( is_ee_org_ass_repl_req-org_assignment ).
  IF lv_cont >= 2.
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont - 1 ] TO lt_fin .
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont ] TO lt_fin.
ELSEIF lv_cont = 1.
  APPEND is_ee_org_ass_repl_req-org_assignment[ lv_cont ] TO lt_fin.
ENDIF.

 

And then I need do a loop to the table lt_fin, but an SELECT in LOOP generate issue of performance

 

LOOP AT lt_fin INTO DATA(ls_fin).
SELECT SINGLE persg FROM hrp1013 INTO @DATA(lv_empsgrp)
WHERE plvar = '01'
AND otype = 'S'
AND objid = @LS_fin-position_id
AND istat = '1'
AND begda LE @LSfin-end_date
AND endda GE @Fin-end_date.
IF SY-SUBRC = 0.
" Apply my logic here
ENDIF.
ENDLOOP.

 

I have checked the option of SELECT FOR ALL ENTRIES , and with this should be two loop?

Regards

 

radinator
Participant
0 Kudos
Hello again 🙂 Ok now I see the reason for the array index access to the iTab. About the performance issue of the for LOOP, I am pretty sure it's because of how you compare the data values. As I said in my last post you can use BETWEEN instead of < and > operators. Try this and see if the speed increases or not. The FOR ALL ENTRIES option is not advised because (and this is more from memory rather than actual knowledge) can't be optimized on the database making it a very slow operation. Or try to load the DB with all data regarding this empl entry into a iTab and then access it via the [] operator. This works the same as the [ index ] version, you just need to use fields as your selection like iTab[ field1 = 'value1' field2 = value2 ]. Make sure to use the VALUE #() operator with the OPTIONAL keyword to avoid runtime errors if there is no entry found. Like line = value #( iTab[ field1 = 'value1' field2 = value2 ] optional ).
radinator
Participant
0 Kudos
Usually performance issues aren't there where you expect them, but where you expect them the least 🙂