SAP and the Thinking Process Part 2
Building stronger Current Reality Trees Part 2
In this article, I´m going to continue on the topic started in part one. As mentioned in the previous text, SAP can support you very well in constructing Current Reality Tree. Now we will continue with the next two examples.
to remember, we are talking about the same tree as in part one.

Entity nr. 124 says: “We have an unnecessary inventory”. There are many ways to mininge the data from SAP to support this claim. You can gain the sum of the value kept in your inventory and WIP (work in progress). For these purposes, SAP provides its own standard transactions. But there can be another point of view. If one of your problems, whilst you are constructing a current reality tree, is lack of capacity, then it is useful to examine how much capacity ( or time ) is held in your inventory. Of course, there could be other reasons for doing it in this way. This approach is not difficult. The first step is building an interval table with materials and their current inventories. The next step is delivering all needed times for producing these from their working plans. The last step is calculating the desired result.
Here is my coding example:
*&---------------------------------------------------------------------* *& Report zminutes_in_cz *& *&---------------------------------------------------------------------* *& *& made by Hrbacek Jaroslav Januar 2016 *&---------------------------------------------------------------------* ***db-tab na ukladani ma nazev ZMINUTESCZ REPORT zminutes. CLASS lcl_events DEFINITION DEFERRED. TYPES: BEGIN OF radka_typ, matnr TYPE matnr, labst TYPE mard-labst, minut TYPE mng02, aufnr TYPE aufnr, END OF radka_typ. TYPES: BEGIN OF feau_typ, aufnr TYPE aufnr, matnr TYPE afko-plnbez, minut TYPE mng02, END OF feau_typ. DATA: lt_vysledek TYPE TABLE OF radka_typ, ls_vysledek LIKE LINE OF lt_vysledek, lt_stueli TYPE TABLE OF zcl_dlz_product=>t_stueli_mehrfach, lo_material TYPE REF TO zcl_dlz_product, lt_aufnr TYPE TABLE OF feau_typ, ls_aufnr LIKE LINE OF lt_aufnr. DATA: wa_matnr TYPE matnr, wa_steus TYPE steus, wa_date TYPE sy-datum, wa_fevor TYPE fevor, lv_objnr TYPE jest-objnr, ls_jest TYPE jest. DATA: gv_vysledek TYPE mng02. SELECT-OPTIONS selmtnr FOR wa_matnr. PARAMETERS: p_lgort TYPE lgort-lgort DEFAULT 'CE01', p_werks TYPE werks-werks DEFAULT '013'. PARAMETERS: p_bst RADIOBUTTON GROUP rad1, p_klakul RADIOBUTTON GROUP rad1 DEFAULT 'X', p_setind RADIOBUTTON GROUP rad1, "in DB schreiben p_rmind RADIOBUTTON GROUP rad1, " from DB löschen p_stueli RADIOBUTTON GROUP rad1. " kompletni_stueli_pro_selection of matnr SELECT-OPTIONS: selfevor FOR wa_fevor, selsteus FOR wa_steus DEFAULT 'PP96'. PARAMETERS: p_mng TYPE mng02 DEFAULT 100. PARAMETERS: p_people TYPE int2 DEFAULT 62. SELECT-OPTIONS seldate FOR wa_date. " date for db remove PARAMETERS: p_stand TYPE crhd-stand. ***************************************************** START-OF-SELECTION. IF p_bst IS NOT INITIAL OR p_setind IS NOT INITIAL. SELECT a~matnr a~labst INTO CORRESPONDING FIELDS OF TABLE lt_vysledek FROM ( mard AS a INNER JOIN marc AS b ON a~matnr = b~matnr AND a~werks = b~werks ) WHERE a~matnr IN selmtnr AND a~lgort = p_lgort AND a~werks = p_werks AND b~beskz = 'E' AND labst > 0. LOOP AT lt_vysledek INTO ls_vysledek. CREATE OBJECT lo_material EXPORTING i_matnr = ls_vysledek-matnr i_werk = p_werks i_basis_menge = ls_vysledek-labst. ls_vysledek-minut = lo_material->get_minutes( EXPORTING i_stand = p_stand i_with_endproduct = 'X' i_steus = selsteus[] ). IF ls_vysledek-minut > 0. MODIFY lt_vysledek FROM ls_vysledek. ELSE. DELETE TABLE lt_vysledek FROM ls_vysledek. ENDIF. gv_vysledek = gv_vysledek + ls_vysledek-minut. CLEAR: ls_vysledek, lo_material. ENDLOOP. SELECT a~aufnr INTO CORRESPONDING FIELDS OF TABLE lt_aufnr FROM ( caufv AS a INNER JOIN jest AS b ON a~objnr = b~objnr INNER JOIN afko AS c ON c~aufnr = a~aufnr INNER JOIN afpo AS d ON d~aufnr = a~aufnr ) WHERE b~stat = 'I0002' AND a~werks = p_werks AND c~plnbez IN selmtnr AND c~dispo IN selfevor AND d~lgort = p_lgort. LOOP AT lt_aufnr INTO ls_aufnr . CONCATENATE 'OR' ls_aufnr-aufnr INTO lv_objnr. SELECT SINGLE * FROM jest INTO ls_jest WHERE objnr = lv_objnr AND ( stat = 'I0045' OR stat = 'I0012' ). IF sy-subrc = 0. DELETE lt_aufnr WHERE aufnr = ls_aufnr-aufnr . ENDIF. CLEAR ls_aufnr. ENDLOOP. LOOP AT lt_aufnr INTO ls_aufnr . CREATE OBJECT lo_material EXPORTING i_aufnr = ls_aufnr-aufnr i _werk = p_werks. ls_vysledek-aufnr = ls_aufnr. ls_vysledek-minut = lo_material->get_minutes_feau( i_stand = p_stand i_steus = selsteus[] ). ls_vysledek-matnr = lo_material->matnr. ls_vysledek-labst = lo_material->basis_menge. IF ls_vysledek-minut > 0. gv_vysledek = gv_vysledek + ls_vysledek-minut. APPEND ls_vysledek TO lt_vysledek. ENDIF. CLEAR: ls_aufnr, ls_vysledek, lo_material. ENDLOOP. IF p_setind IS NOT INITIAL. DATA: ls_zminutescz TYPE zminutescz. ls_zminutescz-people = p_people. ls_zminutescz-datum = sy-datum. ls_zminutescz-minutesbestand = gv_vysledek. INSERT zminutescz FROM ls_zminutescz. CLEAR: ls_zminutescz. ENDIF. ELSEIF p_klakul IS NOT INITIAL. SELECT a~matnr a~labst INTO CORRESPONDING FIELDS OF TABLE lt_vysledek FROM ( mard AS a INNER JOIN marc AS b ON a~matnr = b~matnr AND a~werks = b~werks ) WHERE a~matnr IN selmtnr AND a~lgort = p_lgort AND a~werks = p_werks AND b~dismm <> 'ND' AND b~beskz = 'E'. LOOP AT lt_vysledek INTO ls_vysledek. CREATE OBJECT lo_material EXPORTING i_matnr = ls_vysledek-matnr i_werk = p_werks i_basis_menge = p_mng. ls_vysledek-minut = lo_material->get_minutes( EXPORTING i_stand = p_stand i_with_endproduct = 'X' i_steus = selsteus[] ). ls_vysledek-labst = p_mng. MODIFY lt_vysledek FROM ls_vysledek. CLEAR: ls_vysledek, lo_material. ENDLOOP. ELSEIF p_rmind IS NOT INITIAL. DATA: lt_remove TYPE TABLE OF zminutescz. SELECT * FROM zminutescz INTO TABLE lt_remove WHERE datum IN seldate. DELETE zminutescz FROM TABLE lt_remove. CLEAR lt_remove. ELSEIF p_stueli IS NOT INITIAL. zcl_dlz_product=>get_mehrfach_stueli( EXPORTING i_endmatnr = selmtnr[] IMPORTING e_itab_stueli = lt_stueli ). ENDIF. CLASS ZCL_DLZ_PRODUCT IMPLEMENTATION. METHOD get_minutes. DATA: ls_help TYPE t_line_of_path, ls_plan LIKE LINE OF plan_po, lv_vykon_pracoviste TYPE crhd-zgr03, lv_suma TYPE p LENGTH 6 DECIMALS 2. gs_range_steues = i_steus. me->lv_with_endproduct = i_with_endproduct. get_bom( ). get_all_a_plans( ). """!!!get minuty!!!! LOOP AT me->plan_po_all INTO ls_plan. SELECT SINGLE zgr03 FROM crhd INTO lv_vykon_pracoviste WHERE objid = ls_plan-arbid AND stand = i_stand AND werks = me->werk. IF sy-subrc <> 0. CONTINUE. ENDIF. lv_suma = lv_suma + ( ( me->basis_menge / ls_plan-bmsch ) * ( ls_plan-vgw03 / ( lv_vykon_pracoviste / 100 ) ) ). CLEAR: ls_plan. ENDLOOP. r_minutes = lv_suma. ENDMETHOD. METHOD get_minutes_feau. DATA: lv_aufpl TYPE afko-aufpl, lv_pomocna TYPE afru-budat, lv_matnr TYPE matnr. gs_range_steues = i_steus. SELECT SINGLE aufpl plnbez FROM afko INTO (lv_aufpl,lv_matnr) WHERE aufnr = me->gv_aufnr. me->matnr = lv_matnr. me->gv_stand = i_stand. SELECT SINGLE budat FROM afru INTO lv_pomocna WHERE aufpl = lv_aufpl. IF sy-subrc <> 0. r_minutes = 0. ELSE. r_minutes = minutes_feau( ). ENDIF. ENDMETHOD.
Entity nr. 124 says: “We are measured according to local optimum” This is, unfortunately, the most common way how companies evaluate their productivity for a plant. From my point of view, the reason is “ it has always been done this way” and it is easy to understand and calculate. But in fact, almost nobody cares, that this approach is flawed. An explanation of my statement is not the aim of this article, but you can find it in The Theory Of Constraint. The old way for the productivity evaluation goes like this, but it can differ from plant to plant: In my example, each worker is assessed in a particular period of time. Its productive times are gathered from the DB-table AFRU and then compared against its attendance.
Here is the ABAP class for this action :
class ZCL_HR_PERSONAL definition public final create public . public section. types: ty_r_pernr TYPE RANGE OF pernr-pernr . types: BEGIN OF t_rueckmeldung, pernr TYPE afru-pernr, budat TYPE afru-budat, "rüzkgemeldete datum ism03 TYPE afru-ism03, "rückgemeldete zeit ile03 TYPE afru-ile03, " min? hodiny? lmnga TYPE afru-lmnga, "rückgemeldete menge plnbez TYPE afko-plnbez, "materialnr des Auftrags vgw03 TYPE afvv-vgw03, "vorgabe wert ltxa1 TYPE afvc-ltxa1, "text des Vorgangs vornr TYPE afvc-vornr, "vorgangsnr arbpl TYPE crhd-arbpl, sollzet_personal TYPE vgwrt, vykon TYPE p LENGTH 5 DECIMALS 2, END OF t_rueckmeldung . types: z_tab_rueckmeldung TYPE TABLE OF t_rueckmeldung . types: t_tab_arbpl TYPE TABLE OF arbpl . types: t_tab_pool TYPE TABLE OF object_person_assignment . types: BEGIN OF t_efektivitaet, pernr TYPE pernr-pernr , pr_data TYPE person , present TYPE i , ausfall_time TYPE i , should_time_own TYPE i , is_time_own TYPE i , should_time_voreign TYPE i , is_time_voreign TYPE i , fevor TYPE zdbrsettings-fevor , efektivita TYPE p LENGTH 5 DECIMALS 2, END OF t_efektivitaet . types: t_tab_efektivitaet TYPE TABLE OF t_efektivitaet . types: BEGIN OF gt_months , month TYPE spmon, start TYPE sy-datum, end TYPE sy-datum, END OF gt_months . data GS_EFEKTIVITAET type T_EFEKTIVITAET . data GT_POOL_KAPA type T_TAB_POOL . class-data GT_ARBPL type T_TAB_ARBPL . data GT_RUECKMELDUNGEN type Z_TAB_RUECKMELDUNG . data GV_MATNR type MATNR . data GV_VORNR type VORNR . data GV_PERNR type PERNR-PERNR . data GS_PERSONAL_DATA type PERSON . methods CONSTRUCTOR importing value(I_PERNR) type PERNR-PERNR optional value(I_START) type SY-DATUM optional value(I_END) type SY-DATUM optional value(I_MATNR) type MATNR optional value(I_VORNR) type VORNR optional value(I_ARBPL) type ARBPL optional . methods GET_PRESENT . methods GET_TIMES . class-methods GET_EFECTIVITY_TABLE importing !I_START type DATUM !I_END type DATUM !I_PEOPLE type ANY exporting !E_TABLE_EFEKTIVITY type T_TAB_EFEKTIVITAET . class-methods GET_LEISTUNG_SUM_TABLES importing !I_START type DATUM !I_END type DATUM !I_PEOPLE type ANY !I_MATNR type MATNR optional !I_VORNR type VORNR optional value(I_ARBPL) type ARBPL optional exporting !E_TABLE_RUECKMELDUNG type Z_TAB_RUECKMELDUNG . class-methods GET_EFECTIVITY_TABLE_DYNAMIC importing !I_START type DATUM !I_END type DATUM !I_PEOPLE type ANY !I_MOUNTHLY type CHAR1 . "if not initial=> mounthly, else yeraly methods GET_PRESENT_NO_AUTHORITY . methods GET_ABSENC_PRESENT exporting value(ET_AB) type STANDARD TABLE value(ET_SALDO) type STANDARD TABLE value(EV_SUM_PRESENTS) type MBNUM . protected section. class-data: ******dynamic table****** w_tab TYPE STANDARD TABLE OF abap_compdescr . class-data W_TAB_WA type ABAP_COMPDESCR . class-data W_TYP type ref to CL_ABAP_ELEMDESCR . class-data LT_TOT_COMP type CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE . class-data LT_COMP type CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE . class-data: la_comp LIKE LINE OF lt_comp . class-data LO_NEW_TYPE type ref to CL_ABAP_STRUCTDESCR . class-data LO_TABLE_TYPE type ref to CL_ABAP_TABLEDESCR . class-data W_TREF type ref to DATA . class-data W_DY_LINE type ref to DATA . ************************* " class-data:gt_itab type standard table. class-data START type SY-DATUM . class-data END type SY-DATUM . class-data: gt_mounths TYPE TABLE OF gt_months . class-data: gt_yeras TYPE TABLE OF gjahr . class-data GO_OUTPUT_TABLE type ref to CL_SALV_TABLE . class-data GV_ARBPL type ARBPL . methods GET_FEVOR . methods GET_RUECKMELDUNGEN . methods GET_ARBPL_TABLE . methods GET_PERSONAL_DATA . methods GET_LEISTUNG . methods GET_EFECTIVITY . methods GET_TAB_MOUNT . methods GET_TAB_YEAR . methods GET_FIELDS_TAB . methods GET_DYNAMIC_LINE exporting !E_STRUCTURE type ANY . class-methods GET_TABLE_HEADER . P RIVATE SECTION. ENDCLASS. CLASS ZCL_HR_PERSONAL IMPLEMENTATION. METHOD constructor. gs_efektivitaet-pernr = i_pernr. gv_pernr = i_pernr. start = i_start. end = i_end. get_personal_data( ). gv_matnr = i_matnr . gv_vornr = i_vornr . ENDMETHOD. METHOD get_absenc_present. DATA: lt_periods TYPE TABLE OF t549q, ls_periods TYPE t549q, lt_ab TYPE TABLE OF pc20i, lt_saldo TYPE TABLE OF pc2b5, ls_saldo TYPE pc2b5. CALL FUNCTION 'HR_PAYROLL_PERIODS_GET' EXPORTING get_begda = start get_endda = end TABLES get_periods = lt_periods . IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. LOOP AT lt_periods INTO ls_periods. CALL FUNCTION 'HR_TIME_RESULTS_GET' EXPORTING get_pernr = gv_pernr get_pabrj = ls_periods-pabrj get_pabrp = ls_periods-pabrp TABLES get_ab = lt_ab get_saldo = lt_saldo . IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. APPEND LINES OF lt_ab TO et_ab. APPEND LINES OF lt_saldo TO et_saldo. READ TABLE lt_saldo INTO ls_saldo WITH KEY ztart = '0050'. ev_sum_presents = ev_sum_presents + ls_saldo-anzhl. CLEAR: lt_ab, ls_periods, lt_saldo, ls_saldo. ENDLOOP. ENDMETHOD. METHOD get_arbpl_table. SELECT arbpl FROM zdbrsettings2 INTO TABLE gt_arbpl WHERE fevor = me->gs_efektivitaet-fevor. ENDMETHOD. METHOD get_dynamic_line. DATA: ls_monts TYPE gt_months, ls_year LIKE LINE OF gt_yeras, lo_clovek TYPE REF TO zcl_hr_personal, lv_pocitadlo TYPE i, lv_start_y TYPE c LENGTH 8 , lv_start_y_s TYPE sy-datum, lv_end_y TYPE c LENGTH 8 , lv_end_y_s TYPE sy-datum. lv_pocitadlo = 1. FIELD-SYMBOLS: TYPE any, TYPE any. ASSIGN zcl_hr_personal=>w_dy_line->* TO . ***************************!!!!!!!!!!!!!!!!!!! ASSIGN COMPONENT 1 OF STRUCTURE TO . = gv_pernr. IF gt_mounths IS NOT INITIAL. "pokud mesicne LOOP AT gt_mounths INTO ls_monts. lv_pocitadlo = lv_pocitadlo + 1. CREATE OBJECT lo_clovek EXPORTING i_pernr = me->gv_pernr i_start = ls_monts-start i_end = ls_monts-end . lo_clovek->get_times( ). ASSIGN COMPONENT lv_pocitadlo OF STRUCTURE TO . = lo_clovek->gs_efektivitaet-efektivita. CLEAR: lo_clovek, ls_monts. ENDLOOP. ELSE. " pokud rocne LOOP AT gt_yeras INTO ls_year. CONCATENATE ls_year '01' '01' INTO lv_start_y. lv_start_y_s = lv_start_y. CONCATENATE ls_year '12' '31' INTO lv_end_y. lv_end_y_s = lv_end_y. lv_pocitadlo = lv_pocitadlo + 1. CREATE OBJECT lo_clovek EXPORTING i_pernr = me->gv_pernr i_start = lv_start_y_s i_end = lv_end_y_s . lo_clovek->get_times( ). ASSIGN COMPONENT lv_pocitadlo OF STRUCTURE TO . = lo_clovek->gs_efektivitaet-efektivita. CLEAR: lo_clovek, lv_start_y_s, lv_start_y, lv_end_y_s, lv_end_y, ls_year. ENDLOOP. ENDIF. e_structure = . ENDMETHOD. METHOD get_efectivity. IF gs_efektivitaet-present = 0. gs_efektivitaet-present = 1. ENDIF. gs_efektivitaet-ausfall_time = gs_efektivitaet-present - ( gs_efektivitaet-is_time_own + gs_efektivitaet-is_time_voreign ). gs_efektivitaet-efektivita = ( ( gs_efektivitaet-should_time_own + gs_efektivitaet-should_time_voreign ) / gs_efektivitaet-present ) * 100 . ENDMETHOD. METHOD get_efectivity_table. DATA: lt_pernr TYPE TABLE OF pernr-pernr, lv_pernr TYPE pernr-pernr, lv_pernr_kontrola TYPE pernr-pernr, ls_range TYPE RANGE OF pernr-pernr, lo_clovek TYPE REF TO zcl_hr_personal. ls_range = i_people. SELECT pernr FROM pa0001 INTO TABLE lt_pernr WHERE endda >= i_start AND pernr IN ls_range. LOOP AT lt_pernr INTO lv_pernr. SELECT SINGLE pernr FROM afru INTO lv_pernr_kontrola WHERE pernr EQ lv_pernr. IF sy-subrc <> 0. CONTINUE. ENDIF. CREATE OBJECT lo_clovek EXPORTING i_pernr = lv_pernr * i_matnr = i_start = i_start i_end = i_end . lo_clovek->get_times( ). IF lo_clovek->gs_efektivitaet IS NOT INITIAL. APPEND lo_clovek->gs_efektivitaet TO e_table_efektivity. ENDIF. CLEAR: lo_clovek, lv_pernr. ENDLOOP. ENDMETHOD. METHOD get_efectivity_table_dynamic. FIELD-SYMBOLS: TYPE STANDARD TABLE, TYPE any, TYPE any. DATA: lt_pernr TYPE TABLE OF pernr-pernr, lv_pernr TYPE pernr-pernr, lv_pernr_kontrola TYPE pernr-pernr, ls_range TYPE RANGE OF pernr-pernr, lo_clovek TYPE REF TO zcl_hr_personal, lo_priprava TYPE REF TO zcl_hr_personal. ls_range = i_people. CREATE OBJECT lo_priprava EXPORTING i_start = i_start i_end = i_end . IF i_mounthly IS NOT INITIAL. lo_priprava->get_tab_mount( ). ELSE. lo_priprava->get_tab_year( ). ENDIF. lo_priprava->get_fields_tab( ). * Create new type from component table lo_new_type = cl_abap_structdescr=>create( lt_tot_comp ). * Create new table type lo_table_type = cl_abap_tabledescr=>create( lo_new_type ). * Create dynamic internal table and assign to Field Symbol CREATE DATA w_tref TYPE HANDLE lo_table_type. ASSIGN w_tref->* TO . * Create dynamic work area and assign to Field Symbol CREATE DATA w_dy_line LIKE LINE OF . ASSIGN w_dy_line->* TO . SELECT pernr FROM pa0001 INTO TABLE lt_pernr WHERE endda >= i_start AND pernr IN ls_range. LOOP AT lt_pernr INTO lv_pernr. *!!!pozor - az bude dane pernr dej select single afru - jestli je neco vubec na to pernr SELECT SINGLE pernr FROM afru INTO lv_pernr_kontrola WHERE pernr EQ lv_pernr AND budat BETWEEN i_start AND i_end. IF sy-subrc <> 0. CONTINUE. ENDIF. CREATE OBJECT lo_clovek EXPORTING i_pernr = lv_pernr . lo_clovek->get_dynamic_line( IMPORTING e_structure = ). APPEND TO . CLEAR: lo_clovek, , lv_pernr. ENDLOOP. TRY. cl_salv_table=>factory( * EXPORTING * list_display = IF_SALV_C_BOOL_SAP=>FALSE * r_container = * container_name = IMPORTING r_salv_table = go_output_table CHANGING t_table = ). CATCH cx_salv_msg . ENDTRY. zcl_hr_personal=>get_table_header( ). go_output_table->display( ). ENDMETHOD. METHOD get_fevor. DATA: ls_object TYPE rcrid, lt_object LIKE TABLE OF ls_object, ls_out_object TYPE object_person_assignment. ls_object-objty = 'P'. ls_object-objid = me->gs_efektivitaet-pernr. APPEND ls_object TO lt_object. "ziskat resource v jap - fevor prez kapaid - viz jap CALL FUNCTION 'Z_HR_COI2_WORKCENTER_OF_PERSON' EXPORTING begda = sy-datlo endda = sy-datlo * IN_PLVAR = TABLES in_object = lt_object out_object = gt_pool_kapa "lt_out_object *EXCEPTIONS *no_in_objects = 1 READ TABLE me->gt_pool_kapa INTO ls_out_object INDEX 1. SELECT SINGLE fevor FROM zdbrsettings INTO me->gs_efektivitaet-fevor WHERE kapname = ls_out_object-short AND pull > 0. ENDMETHOD. METHOD get_fields_tab. DATA: lv_radku TYPE i, lv_flname(6) TYPE c, lv_colno(2) TYPE n. * Add entries to w_fields_tab CLEAR w_tab_wa. w_tab_wa-name = 'PERNR'. w_tab_wa-type_kind = 'N'. w_tab_wa-length = '8'. APPEND w_tab_wa TO w_tab. IF gt_mounths IS NOT INITIAL. DESCRIBE TABLE gt_mounths LINES lv_radku. ELSE. DESCRIBE TABLE gt_yeras LINES lv_radku. ENDIF. DO lv_radku TIMES. CLEAR w_tab_wa. lv_colno = sy-index. CONCATENATE 'POLE' lv_colno INTO lv_flname. w_tab_wa-name = lv_flname. w_tab_wa-type_kind = 'P'. w_tab_wa-length = '10'. w_tab_wa-decimals = '2'. APPEND w_tab_wa TO w_tab. CLEAR: lv_flname. ENDDO. LOOP AT w_tab INTO w_tab_wa. CASE w_tab_wa-type_kind. WHEN 'STRING'. w_typ = cl_abap_elemdescr=>get_string( ). WHEN 'XSTRING'. w_typ = cl_abap_elemdescr=>get_xstring( ). WHEN 'I'. w_typ = cl_abap_elemdescr=>get_i( ). WHEN 'F'. w_typ = cl_abap_elemdescr=>get_f( ). WHEN 'D'. w_typ = cl_abap_elemdescr=>get_d( ). WHEN 'T'. w_typ = cl_abap_elemdescr=>get_t( ). WHEN 'C'. w_typ = cl_abap_elemdescr=>get_c( p_length = w_tab_wa-length ). WHEN 'N'. w_typ = cl_abap_elemdescr=>get_n( p_length = w_tab_wa-length ). WHEN 'X'. w_typ = cl_abap_elemdescr=>get_x( p_length = w_tab_wa-length ). WHEN 'P'. w_typ = cl_abap_elemdescr=>get_p( p_length = w_tab_wa-length p_decimals = w_tab_wa-decimals ). ENDCASE. CLEAR la_comp. la_comp-type = w_typ. "Field type la_comp-name = w_tab_wa-name. "Field name ex: FIELD1 APPEND la_comp TO lt_tot_comp. "Add entry to component table ENDLOOP. ENDMETHOD. METHOD get_leistung. DATA:ls_line TYPE t_rueckmeldung, lt_new_table LIKE TABLE OF ls_line, lv_arbpl TYPE arbpl. CLEAR: gs_efektivitaet-should_time_own, gs_efektivitaet-should_time_voreign, gs_efektivitaet-is_time_own, gs_efektivitaet-is_time_voreign. LOOP AT gt_rueckmeldungen INTO ls_line. ls_line-sollzet_personal = ( ls_line-vgw03 / 100 ) * ls_line-lmnga. IF ls_line-ism03 > 0 AND ls_line-ile03 = 'MIN' AND ls_line-lmnga > 0. ls_line-vykon = ( ( ls_line-vgw03 / 100 ) / ( ls_line-ism03 / ls_line-lmnga ) ) * 100 . ELSEIF ls_line-ism03 > 0 AND ls_line-ile03 = 'H' AND ls_line-lmnga > 0 . ls_line-vykon = ( ( ls_line-vgw03 / 100 ) / ( ( ls_line-ism03 * 60 ) / ls_line-lmnga ) ) * 100 . ENDIF. APPEND ls_line TO lt_new_table. gs_efektivitaet-should_time_own = gs_efektivitaet-should_time_own + ls_line-sollzet_personal. gs_efektivitaet-is_time_own = gs_efektivitaet-is_time_own + ls_line-ism03. CLEAR: lv_arbpl, ls_line. ENDLOOP. CLEAR: gt_rueckmeldungen. gt_rueckmeldungen = lt_new_table. CLEAR: lt_new_table. ENDMETHOD. METHOD get_leistung_sum_tables. DATA: lt_pernr TYPE TABLE OF pernr-pernr, lv_pernr TYPE pernr-pernr, ls_range TYPE RANGE OF pernr-pernr, lo_clovek TYPE REF TO zcl_hr_personal, ls_line TYPE t_rueckmeldung, lt_new_table LIKE TABLE OF ls_line. ls_range = i_people. gv_arbpl = i_arbpl. SELECT pernr FROM afru INTO TABLE lt_pernr WHERE budat >= i_start AND pernr IN ls_range. SORT lt_pernr STABLE . DELETE ADJACENT DUPLICATES FROM lt_pernr COMPARING ALL FIELDS. LOOP AT lt_pernr INTO lv_pernr. CREATE OBJECT lo_clovek EXPORTING i_pernr = lv_pernr i_matnr = i_matnr i_vornr = i_vornr i_start = i_start i_end = i_end . lo_clovek->get_times( ). APPEND LINES OF lo_clovek->gt_rueckmeldungen TO e_table_rueckmeldung. CLEAR: lo_clovek, lv_pernr. ENDLOOP. ENDMETHOD. METHOD get_personal_data. CALL FUNCTION 'HR_GET_EMPLOYEE_DATA' EXPORTING erson_id = me->gs_efektivitaet-pernr selection_begin = sy-datum selection_end = sy-datum IMPORTING personal_data = gs_efektivitaet-pr_data EXCEPTIONS person_not_found = 1 no_active_integration = 2 OTHERS = 3 . IF sy-subrc <> 0. * Implement suitable error handling here ENDIF. gs_personal_data = gs_efektivitaet-pr_data. ENDMETHOD. METHOD get_present. DATA: time_results TYPE STANDARD TABLE OF ptm_time_results, time_results_wa LIKE LINE OF time_results, lt_zes TYPE TABLE OF pc2b6,"zes. ls_zes LIKE LINE OF lt_zes, lv_pritomnost TYPE i. CALL FUNCTION 'HR_TIME_RESULTS_IN_INTERVAL' EXPORTING int_pernr = me->gs_efektivitaet-pernr int_begda = me->start int_endda = me->end TABLES int_time_results = time_results EXCEPTIONS wrong_cluster_version = 1 no_read_authority = 2 cluster_archived = 3 technical_error = 4 OTHERS = 5. LOOP AT time_results INTO time_results_wa. APPEND LINES OF time_results_wa-zes TO lt_zes. ENDLOOP. LOOP AT lt_zes INTO ls_zes WHERE ztart = '0050'. lv_pritomnost = lv_pritomnost + ( ls_zes-anzhl * 60 ). ENDLOOP. *present in min me->gs_efektivitaet-present = lv_pritomnost. ENDMETHOD. METHOD get_present_no_authority. DATA: lt_zes TYPE TABLE OF pc2b6,"zes. lt_zes_2 TYPE TABLE OF pc2b6,"zes. ls_zes LIKE LINE OF lt_zes, lv_pritomnost TYPE i, lv_mesic TYPE n LENGTH 2 , lv_rok TYPE n LENGTH 4, lv_stopka TYPE sy-datum. DATA: b2_key TYPE pc2b0. lv_mesic = 01. IF gt_mounths IS NOT INITIAL. b2_key-pernr = me->gv_pernr. b2_key-pabrj = start+0(4). b2_key-pabrp = start+4(2). b2_key-cltyp = 1. IMPORT zes TO lt_zes FROM DATABASE pcl2(b2) ID b2_key. CLEAR: b2_key. ELSEIF gt_yeras IS NOT INITIAL. DO 12 TIMES. b2_key-pernr = me->gv_pernr. b2_key-pabrj = start+0(4). b2_key-pabrp = lv_mesic. b2_key-cltyp = 1. IMPORT zes TO lt_zes_2 FROM DATABASE pcl2(b2) ID b2_key. APPEND LINES OF lt_zes_2 TO lt_zes. lv_mesic = lv_mesic + 1. CLEAR: b2_key, lt_zes_2. ENDDO. ELSE. ***************************************************** lv_rok = start+0(4). lv_mesic = start+4(2). WHILE lv_stopka+0(6) <= end+0(6). b2_key-pernr = me->gv_pernr. b2_key-pabrj = lv_rok. b2_key-pabrp = lv_mesic. b2_key-cltyp = 1. IMPORT zes TO lt_zes_2 FROM DATABASE pcl2(b2) ID b2_key. IF end+0(4) = lv_rok AND end+4(2) = lv_mesic AND start+0(4) = lv_rok AND start+4(2) = lv_mesic. DELETE lt_zes_2 WHERE reday NOT BETWEEN start+6(2) AND end+6(2). ELSEIF start+0(4) = lv_rok AND start+4(2) = lv_mesic. DELETE lt_zes_2 WHERE reday < start+6(2). ELSEIF end+0(4) = lv_rok AND end+4(2) = lv_mesic. DELETE lt_zes_2 WHERE reday > end+6(2). ENDIF. APPEND LINES OF lt_zes_2 TO lt_zes. lv_mesic = lv_mesic + 1. IF lv_mesic > 12. lv_mesic = 1. lv_rok = lv_rok + 1. ENDIF. CLEAR: b2_key, lt_zes_2. lv_stopka+0(4) = lv_rok. lv_stopka+4(2) = lv_mesic. ENDWHILE. ENDIF. LOOP AT lt_zes INTO ls_zes WHERE ztart = '0050'. lv_pritomnost = lv_pritomnost + ( ls_zes-anzhl * 60 ). ENDLOOP. *present in min me->gs_efektivitaet-present = lv_pritomnost. ENDMETHOD. METHOD get_rueckmeldungen. IF me->gs_efektivitaet-pernr IS NOT INITIAL. SELECT a~pernr a~budat a~lmnga a~ism03 a~ile03 b~plnbez c~vgw03 d~ltxa1 d~vornr e~arbpl INTO CORRESPONDING FIELDS OF TABLE gt_rueckmeldungen FROM ( afru AS a INNER JOIN afko AS b ON a~aufnr = b~aufnr INNER JOIN afvv AS c ON c~aplzl = a~aplzl AND c~aufpl = a~aufpl INNER JOIN afvc AS d ON c~aufpl = d~aufpl AND c~aplzl = d~aplzl INNER JOIN crhd AS e ON e~objid = d~arbid ) WHERE a~pernr = me->gs_efektivitaet-pernr AND a~budat BETWEEN me->start AND me->end AND a~stokz = ' ' AND a~stzhl = '00000000'. ELSEIF me->gv_matnr IS NOT INITIAL. SELECT a~pernr a~budat a~lmnga a~ism03 a~ile03 b~plnbez c~vgw03 d~ltxa1 d~vornr e~arbpl INTO CORRESPONDING FIELDS OF TABLE gt_rueckmeldungen FROM ( afru AS a INNER JOIN afko AS b ON a~aufnr = b~aufnr INNER JOIN afvv AS c ON c~aplzl = a~aplzl AND c~aufpl = a~aufpl INNER JOIN afvc AS d ON c~aufpl = d~aufpl AND c~aplzl = d~aplzl INNER JOIN crhd AS e ON e~objid = d~arbid ) WHERE b~plnbez = me->gv_matnr AND a~budat BETWEEN me->start AND me->end AND a~stokz = ' ' AND a~stzhl = '00000000'. ENDIF. IF gv_matnr IS NOT INITIAL AND gv_vornr IS NOT INITIAL. DELETE gt_rueckmeldungen WHERE plnbez <> gv_matnr. DELETE gt_rueckmeldungen WHERE vornr <> gv_vornr. ELSEIF gv_matnr IS NOT INITIAL AND gv_vornr IS INITIAL. DELETE gt_rueckmeldungen WHERE plnbez <> gv_matnr. ELSE. ENDIF. IF gv_arbpl IS NOT INITIAL. DELETE gt_rueckmeldungen WHERE arbpl <> gv_arbpl. ENDIF. ENDMETHOD. METHOD get_table_header. ------- ENDMETHOD. METHOD get_tab_mount. DATA: lv_mesicu TYPE i, lv_radka TYPE spmon, lv_mesic TYPE gmonat, lv_rok TYPE gjahr, ls_months TYPE gt_months. CONCATENATE start+04(02) start+00(04) INTO lv_radka. lv_mesic = start+04(02). lv_rok = start+00(04). ls_months-month = lv_radka. CALL FUNCTION 'MONTHS_BETWEEN_TWO_DATES' EXPORTING i_datum_von = start i_datum_bis = end IMPORTING e_monate = lv_mesicu . CALL FUNCTION 'CACS_CALC_END_DATE_OF_MONTH' EXPORTING iv_month = start+04(02) iv_year = start+00(04) IMPORTING et_end_dateof_month = ls_months-end. CONCATENATE ls_months-end+00(06) '01' INTO ls_months-start. APPEND ls_months TO gt_mounths. CLEAR ls_months. DO lv_mesicu TIMES. IF lv_mesic < 12. lv_mesic = lv_mesic + 1. ELSE. lv_mesic = 1. lv_rok = lv_rok + 1. ENDIF. CONCATENATE lv_mesic lv_rok INTO lv_radka. ls_months-month = lv_radka. CALL FUNCTION 'CACS_CALC_END_DATE_OF_MONTH' EXPORTING iv_month = lv_mesic iv_year = lv_rok IMPORTING et_end_dateof_month = ls_months-end. CONCATENATE ls_months-end+00(06) '01' INTO ls_months-start. APPEND ls_months TO gt_mounths. CLEAR: lv_radka, ls_months. ENDDO. ENDMETHOD. METHOD get_tab_year. DATA: lv_roku TYPE i, _yeras. ENDDO. ENDMETHOD. METHOD get_times. get_present_no_authority( ). get_rueckmeldungen( ). get_leistung( ). IF me->gv_matnr IS INITIAL. get_efectivity( ). ENDIF. ENDMETHOD. ENDCLASS.
As you can see, there are plenty of ways how to mine data from SAP for supporting facts not only for the use in current reality trees but for other processes which need some facts for decision making. In this two-part article, I have shown options and approaches how you can do it and I hope SAP will help you in your own quests.