I hate "Get Pernr" and "Get Peras" for many reasons:
- When I'm debugging, stepping through my code, I can't F5 (step into) the 'Get Pernr' loop. Only if a break point is set within the loop will it jump in
- It can't be instantiated, which means it can't be put in a class and modularized/reused.
- SAP magic occurs where the variable pernr comes out of no where without being declared.
- It's a loop that can't have conditions on it except from the selection screen.
So I came up with another option:
Here is a typical program screen screen block:
DATA: pa0001 TYPE p0001.
SELECTION-SCREEN BEGIN OF BLOCK b_selection WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_pernr FOR pa0001-pernr NO INTERVALS.
SELECTION-SCREEN END OF BLOCK b_selection.
The add selection method is a class used to store the values taken from the screen:
lo_selection->add_selection( iv_fieldname = 'PERNR'
iv_tclas = 'A'
iv_infotype = '0001'
it_conditions = s_pernr[] ).
Add selection is an instance method in my selection class that formats the input parameters into an appropriate selection search structure
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZJV_PA_SELECTION->ADD_SELECTION
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_FIELDNAME TYPE CHAR30
* | [--->] IV_TCLAS TYPE TCLAS
* | [--->] IV_INFOTYPE TYPE INFTY
* | [--->] IT_CONDITIONS TYPE TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD ADD_SELECTION.
DATA: ls_search_selection TYPE hrasr00_search_selection.
FIELD-SYMBOLS: <fs_selection> TYPE any,
<fs_field> TYPE any.
LOOP AT it_conditions ASSIGNING <fs_selection>.
ls_search_selection-fieldname = iv_fieldname.
ls_search_selection-tclas = iv_tclas.
ls_search_selection-infty = iv_infotype.
ASSIGN COMPONENT 1 OF STRUCTURE <fs_selection> TO <fs_field>.
ls_search_selection-sign = <fs_field>.
ASSIGN COMPONENT 2 OF STRUCTURE <fs_selection> TO <fs_field>.
ls_search_selection-opti = <fs_field>.
ASSIGN COMPONENT 3 OF STRUCTURE <fs_selection> TO <fs_field>.
ls_search_selection-low = <fs_field>.
ASSIGN COMPONENT 4 OF STRUCTURE <fs_selection> TO <fs_field>.
ls_search_selection-high = <fs_field>.
APPEND ls_search_selection TO gt_search_selections.
CLEAR ls_search_selection.
ENDLOOP.
ENDMETHOD.
The get employees method is a static method in my main that takes in the search selection table built and returns a table to which the employee's pernr's are a column in the table
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZJV_PA_MAIN=>GET_EMPLOYEES
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_SEARCH_SELECTION TYPE HRASR00_SEARCH_SELECTION_TAB
* | [--->] IV_BEGIN_DATE TYPE DATS
* | [--->] IV_END_DATE TYPE DATS
* | [<-()] R_PERNR_TABLE TYPE OBJEC_T
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_employees.
DATA: lt_objects TYPE objec_t.
CALL METHOD cl_hrasr00_employee_search=>search_employee
EXPORTING
search_selections = it_search_selection
begda = iv_begin_date
endda = iv_end_date
IMPORTING
employees = lt_objects.
r_pernr_table = lt_objects.
ENDMETHOD.
Here is a crude implementation of both solutions so that the runtime of each can be compared:
GET PERAS
REPORT zjv_program_testing.
NODES: peras.
TABLES: pernr.
get peras.
Alternative Solution
DATA: lo_selection TYPE REF TO zjv_pa_selection.
DATA: pa0001 TYPE p0001.
SELECTION-SCREEN BEGIN OF BLOCK b_selection WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_pernr FOR pa0001-pernr NO INTERVALS.
SELECTION-SCREEN END OF BLOCK b_selection.
CREATE OBJECT lo_selection.
lo_selection->add_selection( iv_fieldname = 'PERNR'
iv_tclas = 'A'
iv_infotype = '0001'
it_conditions = s_pernr[] ).
DATA lt_selection TYPE hrasr00_search_selection_tab.
DATA: lt_objects TYPE objec_t.
lt_selection = lo_selection->get_search_selection( ).
CALL METHOD cl_hrasr00_employee_search=>search_employee
EXPORTING
search_selections = lt_selection
begda = '18000101'
endda = '99991231'
IMPORTING
employees = lt_objects.
Using the T-code "SAT" we can capture the run time performance of both options to retrieve over 5000 personnel numbers on a single core processor/ Development environment.
Runtime in Microseconds:
GET PERAS: 2,483,603 ( ~2.48 seconds )
Alternative: 5,970,883 ( ~5.97 seconds )
GET PERAS is ~2.4 times faster than the alternative
In my opinion these are the :
Advantages
- It utilizes object oriented programming ( cl_hrasr00_employee_search=>search_employee )
- I can take in any selection options at runtime.
- I have a list of the personnel numbers for my selection criteria
- Allows abap program to integrate elegantly with object oriented programming
- Is modular/reusable
Disadvantages
- More complex to implement
- Is slower than the LDB
Potential
- Might be able to work with Web Dynpro
This is not the perfect solution nor the perfect implementation but it is an alternative for the object oriented ABAP developer.
I welcome all comments, concerns, questions, and changes. If any one can think of a better solution or improve on my own please let me know :smile: