Tuesday, October 17, 2023

Workflow: Developments at a glance!

1. Create a new workflow step by step: LINK

2. Assign Agent: LINK

3. Create Workflow Class: LINK

4. Create Workflow BOR: LINK

5. Workflow Decision (Binary):

6. Workflow Fork:

Courtesy/ Reference/ Support: blogs.sap.com

ABAP 7.5 Coding Standards in General

 ABAP 7.4/7.5: SELECT Queries and LOOP

-------------------------------------------------------------------------------------

CASE 1:

SELECT SINGLE VORNA as First_Name,

                               NACHN as Last_Name

FROM PA0002      

INTO TABLE @DATA(LS_EE_NAME).

This will create a structure with columns with field description as FIRST_NAME and LAST_NAME

-------------------------------------------------------------------------------------

CASE 2:

SELECT VORNA as First_Name,

                NACHN as Last_Name

FROM PA0002      

INTO TABLE @DATA(LT_EE_NAME).

This will create an internal table with single column with field description as FIRST_NAME and LAST_NAME

-------------------------------------------------------------------------------------

CASE 3: WHERE

PARAMETERS: P_PERNR TYPE PERSNO.

SELECT SINGLE PERNR as Employee,

                               VORNA as First_Name,

                               NACHN as Last_Name

FROM PA0002      

INTO TABLE @DATA(LS_EE_NAME)

WHERE Employee EQ @P_PERNR.

// One can use Internal table as well without using SINGLE

-------------------------------------------------------------------------------------

CASE 4: JOIN // WHERE  // FOR ALL ENTRIES IN

PARAMETERS: P_PERNR TYPE PERSNO.

CONSTANTS: LC_SUBTY TYPE SUBTY VALUE '0001'.

IF LT_EE_MAIN[] IS NOT INITIAL.

    SELECT A~VORNA, A~NACHAN

                   B~SUBTY, B~REGIO, B~STATE, B~PSTLZ

    FROM PA0002 AS A

    INNER JOIN PA0006 

    ON PA0006-PERNR EQ PA0002-PERNR

    INTO TABLE @DATA(LT_EE_NAME)

    FOR ALL ENTRIES IN @LT_EE_MAIN[]

    WHERE A~PERNR EQ @LT_EE_MAIN[]-PERNR

          AND A~PERNR EQ @P_PERNR         

         AND B~SUBTY EQ @LC_SUBTY.

-------------------------------------------------------------------------------------

CASE 5: General Declarations

DATA: lv_rows  TYPE i. lv_rows  = 0.

lv_rows = NEW i(  0  ).


DATA(lv_vehicle) = 'Mercedes'.

DATA(lv_rows) = LINES( itab ).

lo_human = NEW class_human( name = ‘TONY’ ).


INSERT Values in an Internal Table:

DATA(LT_TAB) = VALUE((10)( 20 )(30).


-------------------------------------------------------------------------------------

CASE 6: LOOP & APPEND

TYPES: BEGIN OF LTY_CITY_1,

                  CITY TYPE CHAR10,

                  STATE TYPE CHAR10,

                  PST_CD TYPE CHAR10,

               END OF LTY_CITY_1,

               BEGIN OF LTY_CITY_2,

                  CITY TYPE CHAR10,

              END OF LTY_CITY_2.

DATA: LIT_CITIES TYPE TABLE OF LTY_CITY_1,

             GT_CITY TYPE  TABLE OF LTY_CITY_2

DATA(GT_CITY) = VALUE LTY_CITY_1( FOR LS_CITY IN LIT_CITIES 

                                  ( LS_CITY-CITY )

                                   WHERE ( LS_CITY-CITY )(STATE = 'NY') ).

Store value from one table to another by filtering conditions in loop (avoiding append a different table in loop)

-------------------------------------------------------------------------------------

CASE 7: FILTER

EXAMPLE 1:

DATA(extract) =  FILTER #( spfli_tab USING KEY carr_city

                                   WHERE carrid  = CONV #( to_upper( carrid ) ) AND

                                                  cityfrom = CONV #( to_upper( cityfrom ) ) 

                                              ).

EXAMPLE 2:

TYPES: BEGIN OF filter,

         cityfrom TYPE spfli-cityfrom,

         cityto   TYPE spfli-cityto,

       END OF filter,

       filter_tab TYPE HASHED TABLE OF filter

                  WITH UNIQUE KEY cityfrom cityto.

DATA(filter_tab) = …        

DATA(extract) = FILTER #( spfli_tab IN filter_tab WHERE cityfrom = cityfrom  AND cityto = cityto ).

EXAMPLE 3:

TYPES: BEGIN OF line,

    id    TYPE i,

    value TYPE string,

  END OF line,

  itab TYPE SORTED TABLE OF line WITH UNIQUE KEY id.

DATA(def) = VALUE line( id = 0 value = `not found` ).

DATA(result) = VALUE #( itab[ id = … ] DEFAULT def ).


Workflow: Transactions at a glance!

 Workflow Troubleshooting

SWU_OBUF --> Manual buffer refresh

SWPC --> continue WF after a system crash

SWI6 --> show all WF instances, work item IDs by BOR/CL name & Object Key (optional)

SWI5 --> work item per work center, job, organizational unit, position, user

SWIA --> work item administration (WI)

SWI2_DIAG --> error diagnosis

SWWL --> delete work item

SWI2_DEAD --> deadline monitor

SWWL_TOPLEVEL --> delete a parent workflow with all of its child work items

SWI2_DURA --> process duration

SWUD --> WF diagnosis

SWI2_ADM1 --> find orphaned work item

SWELS --> event trace

SM12 --> lock, unlock the object

SWEL --> display event trace SARA archiving

Workflow Development (For Daily Usage)

SWDD --> WF builder (Create and view new or existing Workflow)

SBWP --> WF inbox

SWI1 --> selection report for work item

SWNADMIN --> Workflow notification management

SWO1 --> business object builder (BOR)

PFTC --> template, task management (WS, TS)

SM37 --> view scheduled and processed jobs

Others

PFTC_DIS --> assigning possible agent

PFAC --> rule creation, editing, testing

SWU0 --> simulate the event linkage

SWEQADM --> event queue, preventing RFC-problem

SWUS --> test, execute WF

SWB_COND --> all start conditions

SWEINST --> all terminating events linkage

SWU9 --> WF trace for the session

SWUI_VERIFY --> WF verification

Related to basis and Workflow config

SOST --> SAP connect transmission request

SWPA --> customizing WF runtime system

SWNCONFIG --> notification configuration

SWEQBROWSER --> event waiting in the event queue

PPOME organizational management, structure & staff assignment, user mapping

SM52 --> view tRFC

SWI2_FREQ --> opened task statistic


ABAP Supports - Transactions/ Table handling

 Debug a table entry (single entry, one at a time)

Go to SE11 --> provide table name  --> go to content --> get the entry in detail view --> in the address bar type /HA and hit ENTER button twice --> it will take you to debug screen of a SWITCH CASE, provide the value as INST (Inserting a new entry), DELE (for delete the entry), MODY (to modify the existing one). Next it will take you to screen with respective button in edit mode and you are good to modify as per need. SAVE it and come back, else debugger screen will continue.

 Debug multiple table entry (delete a set of entries in table)

Go to SE38 --> Provide the Include program LSE16NF10  --> Go to function Module SE16_INTERFACE at line 619 --> Set debugger.

Then go to SE16N --> open the table content with table name provided --> get the detail view by executing --> this will take to debugger session that will be appearing next, when the debugger stops at Function Module SE16_INTERFACE at line 619 --> Edit the entry of the field/parameter GD_SAPEDIT and GD-EDIT  and set X as value for both  --> then next screen will appear with delete button --> next you choose, the entries (multiple) and keep delete and SAVE.

SM12 -> to unlock the table if it is locked by others

SM59 -> to check if any session debugger is stuck or awaiting 

SE36 -> Logical Database (LDB) 

SE21 - > Package

SE09/SE10 -> Transports

SE01/ SE01D --> SAP user profile

SE24 --> Class

SE11 --> DDIC

SE37 --> function modules

ST22 --> Dumps/ Runtime Errors

STMS --> change requests transferring


Wednesday, August 16, 2023

ABAP 7.5 Coding Standards in OOPS

ABAP 7.4/7.5 in OOPS:

--------------------------------------------------------------------------------------

1 Upcasting/Downcasting with CAST

Before:

DATA lo_structure TYPE REF TO CL_ABAP_STRUCTDESCR. "Structure_description

DATA lo_components TYPE ABAP_COMPDESCR_TAB.

lo_structure ?= cl_abap_typedescr=>describe_by_name( 'ZSC_MONSTER_HEADER' ).

lo_components = structure_description->components.

After:

DATA(lo_components) = CAST cl_abap_structdescr(

cl_abap_typedescr=>describe_by_name( 'ZSC_MONSTER_HEADER' ) )->components.

--------------------------------------------------------------------------------------

2 Finding the Subclass of an Object Instance

DATA: full_screen_adapter TYPE REF TO cl_salv_fullscreen_adapter,

container_adapter TYPE REF TO cl_salv_grid_adapter.

TRY.

"Presume full screen mode (No Container)

"Fullscreen Adapter (Down Casting)

"Target FULL_SCREEN_ADAPTER = CL_SALV_FULLSCREEN_ADAPTER

"CL_SALV_FULLSCREEN is a subclass of CL_SALV_ADAPTER 

full_screen_adapter ?= io_salv_adapter.

"Get the Grid

ro_alv_grid = full_screen_adapter->get_grid( ).

CATCH cx_sy_move_cast_error.

"We must be in container mode

"CL_SALV_GRID_ADAPTER is a subclass of CL_SALV_ADAPTER

container_adapter ?= io_salv_adapter.

ro_alv_grid = container_adapter->get_grid( ).

ENDTRY.

After:

IF io_salv_adapter IS INSTANCE OF cl_salv_fullscreen_adapter.

    full_screen_adapter ?= io_salv_adapter.

    ro_alv_grid = full_screen_adapter->get_grid( ).

ELSEIF io_salv_adapter IS INSTANCE OF cl_salv_grid_adapter.

    container_adapter ?= io_salv_adapter.

    ro_alv_grid = container_adapter->get_grid( ).

ENDIF.

-------------------------------------------------------------

CASE TYPE OF io_salv_adapter.

WHEN TYPE cl_salv_fullscreen_adapter INTO DATA(full_screen_adapter2).

ro_alv_grid = full_screen_adapter2->get_grid( ).

WHEN TYPE cl_salv_grid_adapter INTO DATA(container_adapter2).

ro_alv_grid = container_adapter2->get_grid( ).

WHEN OTHERS.

RETURN.

ENDCASE.

--------------------------------------------------------------------------------------

3 CHANGING and EXPORTING Parameters

DATA: monster_number TYPE zde_monster_number VALUE '0000000001',

something_spurious TYPE string,

something_unrelated TYPE string.

DATA(monster_header_record) = lcl_monster=>get_details(

EXPORTING id_monster_number = monster_number

IMPORTING ed_something_spurious = something_spurious

CHANGING cd_something_unrelated = something_unrelated ).

--------------------------------------------------------------------------------------

4 Changes to Interfaces

INTERFACE scary_behavior.

METHODS: scare_small_children,

sells_mortgages DEFAULT FAIL,

hide_under_bed DEFAULT IGNORE,

is_fire_breather

DEFAULT IGNORE

RETURNING rf_yes_it_is TYPE abap_bool.

ENDINTERFACE. "Scary Behavior

--------------------------------------------------------------------------------------



Thursday, June 08, 2023

OOPS ABAP HR Classes

 List of Classes:

CL_HRPY_MASTER_INFOTYPE_READER

Replace with HR_READ_INFOTYPE, HR_INTOYPE_OPERATIONS

Wednesday, May 24, 2023

OOPS ABAP HR Decouple Framework

 How to Read Infotype (in oops)

DATA: lo_infotype TYPE REF TO cl_hrpa_read_infotype,

       li_infotype TYPE REF TO if_hrpa_read_infotype,

       lt_pri_infty TYPE pnnnn, "primary infotype

       lt_sec_infty TYPE pnnnn, "secoundary infotype

       lv_has_data TYPE boole_d,

       lv_has_auth TYPE boole_d.

 

// Initialization of the object

 TRY.

 CALL METHOD cl_hrpa_read_infotype=>get_instance

 *  EXPORTING

 *    masterdata_buffer =

   IMPORTING

     infotype_reader   = li_infotype.

  CATCH cx_hrpa_violated_assertion.

 ENDTRY.

 // Read method to get infotype data - METHOD: READ_SINGLE

 TRY.

 CALL METHOD li_infotype->read_single

   EXPORTING

     tclas         = 'A' "employee

     pernr         = '00012345'

     infty         = '0001'

     subty         = space

     objps         = space

     sprps         = ''

     begda         = '19000101'

     endda         = sy-datum

     mode          = '3'

     no_auth_check = space

   IMPORTING

     pnnnn         = lt_pri_infty

     pnnnn2        = lt_sec_infty

 *    pref          =

     data_exists   = lv_has_data

     missing_auth  = lv_has_auth.

  CATCH cx_hrpa_violated_assertion .

 ENDTRY.

 // Read method to get infotype data - METHOD: READ

 // Manipulate Data as needed

   CLEAR lt_infotype.

   CALL METHOD lr_infotype_reader->read

     EXPORTING

       tclas         = 'A'

       pernr         = lv_pernr

       infty         =  '0001'

       begda         = iv_begda

       endda         = iv_endda

       no_auth_check = abap_true

     IMPORTING

       infotype_tab  = lt_infotype

       data_exists   = lv_data_exists

       missing_auth  = lv_missing_auth.

 // Manipulate data

   LOOP AT lt_infotype INTO ls_infotype.

     CALL METHOD cl_hr_pnnnn_type_cast=>prelp_to_pnnnn

       EXPORTING

         prelp = ls_infotype

       IMPORTING

         pnnnn = ls_p0001.

        APPEND ls_p0001 TO lt_p0001.

   ENDLOOP. 

Wednesday, May 10, 2023

OOPS ABAP HR: Pay Result (US)

Get Data from Payroll (US Payroll)

Step 1: Data declaration 

data: ls_rgdir type pc261

(lo_payresult_access) = NEW cl_hr_pay_access( ),

lo_emp_pay_result type ref to cl_hr_pay_result,

lo_emp_pay_result_us type ref to cl_hr_pay_result_us.


Step 2. Get data from table HRPY_RGDIR

Get the records from table HRPY_RGDIR and store the data in an internal table lt_rgdir[]

with needful where clause(s).


Step 3: Use class CL_HR_PAY_ACCESS and CL_HR_PAY_RESULT

LOOP the internal table lt_regdir[] to assigned fields symbol <fs_rgdir>

ls_rgdir = <fs_rgdir>.

call method lo_payresult_access->read_pay_result (by paasing ls_rgdir)

Get the result in object lo_emp_pay_result.

Use the object lo_emp_pay_result for RT/TCRT/CRT table to read or loop.


RT Result will be found (for all countries):

lo_emp_pay_result->inter-rt[].

Wide cast to US data (as needed only for MOLGA US

lo_emp_pay_result_us ?= lo_emp_pay_result.


US Garnishment result will be found in:

lo_emp_pay_result_us->natio-grdoc[] and lo_emp_pay_result->natio-grrec[]

ENDLOOP.

Thursday, March 23, 2023

ABAP CODE 1: Dynamic Table and STructure

 Inserting:

INSERT LINES OF <itab1> INTO <itab2> INDEX <idx>.

INSERT LINES OF <itab1>  FROM <n1>  TO <n 2> INTO <itab2> INDEX <idx>.

INSERT LINES OF ITAB INTO JTAB INDEX 1.

Dynamic:

DATA: lo_dynamic_table_1 TYPE REF TO DATA,

            lo_dynamic_workarea_1 TYPE REF TO DATA,

            lv_table_name TYPE STRING.

FIELD-SYMBOLS: <lt_table_structure> TYPE TABLE,

                                  <ls_table_structure> TYPE ANY.

lv_table_name = 'PA0002'.

"This will create a table of same fields as of SFLIGHT

CREATE DATA lo_dynamic_table_1 TYPE TABLE OF (lv_table_name).

ASSIGN lo_dynamic_table_1->* TO <lt_table_structure>. 


"This will workarea of same fields as of SFLIGHT

CREATE DATA lo_dynamic_workarea_1 LIKE LINE OF (lv_table_name).

ASSIGN lo_dynamic_workarea_1->* TO <ls_table_structure>.



Assign Components

CASE 1: 

LOOP AT ITAB ASSIGNING <fs-structure>.

"determination of field name logic goes here let's say you have 

"field name is in variable lv_field

    ASSIGN COMPONENT (lv_field) of STRUCTURE <fs-structure> to <fs-field>.

    IF <fs-field> IS ASSIGNED.

      <fs-field> = 'the value you want to assign'.

    ENDIF.

ENDLOOP.

CASE 2:
LOOP AT ITAB ASSIGNING <fs-structure>.

*-- determination of field name logic goes here let's say you have 
*-- field name is in variable lv_field1 and other is lv_field2

    ASSIGN COMPONENT (lv_field1) of STRUCTURE <fs-structure> to <fs-field1>.

    ASSIGN COMPONENT (lv_field2) of STRUCTURE <fs-structure> to <fs-field2>.

    IF <fs-field1> IS ASSIGNED ANDV<fs-field2> IS ASSIGNED .
      <fs-field1> = <fs-field1> + <fs-field1>.
    ENDIF.

ENDLOOP.
CASE 3:
TYPES: BEGIN OF ts_basic_line,
     matnr TYPE mara-matnr,
     lifnr TYPE lfa1-lifnr,
   END OF ts_basic_line,
   ty_basic_line TYPE TABLE OF ts_basic_line.

DATA: lt_basic_data TYPE ty_basic_line,
      lo_structure  TYPE REF TO cl_abap_structdescr,
      lt_components TYPE abap_component_tab.

lt_basic_data = VALUE #( ( matnr = '111' lifnr = '333' ) ). " data for test
READ TABLE lt_basic_data ASSIGNING FIELD-SYMBOL(<fs_line>) INDEX 1.
IF sy-subrc EQ 0.
  lo_structure ?= cl_abap_typedescr=>describe_by_data( <fs_line> ).
  lt_components = lo_structure->get_components( ).

  LOOP AT lt_components ASSIGNING FIELD-SYMBOL(<fs_strucutre_fields>).
    LOOP AT lt_basic_data ASSIGNING FIELD-SYMBOL(<fs_data>).
      ASSIGN COMPONENT <fs_strucutre_fields>-name OF STRUCTURE <fs_data> 
                                               TO FIELD-SYMBOL(<fs_value>).
      IF sy-subrc EQ 0.
        " here your code, e.x. data conversion
        <fs_value> = |{ <fs_value> ALPHA = IN }|.
      ENDIF.
    ENDLOOP.
  ENDLOOP.
ENDIF.

CASE 4: Multiple Dynamic Tables in a single table
DATA: lt_dynamic_tables TYPE TABLE OF REF TO DATA.
            ls_dynamic_table  TYPE REF TO DATA.
FIELD-SYMBOLS: <fs_dynamic_table>  TYPE ANY TABLE.

" Store the lists of Dynamic Table
DO 10 TIMES.  "(as required)
  CREATE DATA ls_dynamic_table TYPE TABLE OF PA0002. 
  APPEND ls_dynamic_table TO lt_dynamic_table. 
ENDDO.

" Read the list of dynamic tables
LOOP AT lt_dynamic_table INTO ls_dynamic_table.
  ASSIGN ls_dynamic_table->* TO <fs_dynamic_table>.
" This will aloo to reach each table data
ENDLOOP.