ABAP | Advanced Business Application Programming | Dynamic Programming

Bringing Dynamism to ABAP : A New Paradigm for Agile Coding !

            Dynamic programming in ABAP empowers developers to build logic that adapts at runtime deciding not just the structure of the data, but also the behavior of the code on the fly. By leveraging concepts like dynamic field symbols, data references and runtime type resolution, ABAP developers can achieve true agile coding. 

            This approach brings flexibility, scalability and efficiency into modern ABAP applications, where execution flow and data types are determined dynamically based on real-time conditions rather than static design.



Use Cases :

  • Processing dynamic structures or tables (e.g. generic data uploads).
  • Building frameworks or re-usable utilities.
  • Working with metadata or generic APIs (like FPM, BRF+, BOPF).

Agile Coding in Practice :

  • Dynamic field technology aligns beautifully with agile principles.
  • Reusability : Write once, apply to any structure.
  • Adaptability : Code reacts to runtime needs.
  • Maintainability : Centralized generic logic for multiple scenarios.

Requirement :

  • To track daily attendance and manage resource planning effectively.
  • The report should fetch and display the daily attendance status of employees.
  • The statuses should include: Present, WFH, CL Applied, PL Applied respectively.
  • The report should highlight employees who have applied for 3 or more consecutive days of CL or PL.
  • Users should be able to filter data by date range or employee ID.
  • The report should fetch data from relevant attendance and leave tables in real-time.

Implementation :

*&---------------------------------------------------------------------*
*& Report YHR_PUNCH_MUSTER
*&---------------------------------------------------------------------*
REPORT YHR_PUNCH_MUSTER.

CLASS YCL_MUSTER DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS :

      VALIDATION       ,     "Validation
      FETCH_DATA       ,     "Fetch PERNRs & TEVEN
      PROCESS_DATA     ,     "Process Data
      GET_HEADING      ,     "Get Heading E.g. 01-JUN_Mon, 02-JUN_Tue
      DISPLAY_ALV      ,     "Display ALV
      GET_PUNCH_STATUS ,     "Get Punch E.g. P, AA, CL, PL, WFH
      FIELDCATALOG     ,     "Create Field Catelog

      CREATE_COLUMN IMPORTING
                      FIELDNAME  TYPE SLIS_FIELDCAT_ALV-FIELDNAME     "Create Column for Catelog
                      SELTEXT    TYPE SLIS_FIELDCAT_ALV-SELTEXT_M
                      COL_POS    TYPE SLIS_FIELDCAT_ALV-COL_POS
                      FIX_COLUMN TYPE SLIS_FIELDCAT_ALV-FIX_COLUMN
                      OUTPUTLEN  TYPE SLIS_FIELDCAT_ALV-OUTPUTLEN
                      NO_OUT     TYPE SLIS_FIELDCAT_ALV-NO_OUT.

ENDCLASS.
DATA:LV_OBJ TYPE REF TO YCL_MUSTER.
DATA: P_BEGN         TYPE D,
      P_END          TYPE D,
      P_DAYS1        TYPE SCAL-INDICATOR,
      P_T247         TYPE T247,
      L_DAY(5)       TYPE C,
      L_TYPE         TYPE CHAR30,
      L_COUNT2       TYPE I,
      LV_LEAVE_COUNT TYPE I,
      LV_STATUS      TYPE CHAR10,
      TEMP_DATE      TYPE SY-DATUM.

TYPES: BEGIN OF TY_TEVEN,
         PERNR TYPE TEVEN-PERNR,
         LDATE TYPE TEVEN-LDATE,
         LTIME TYPE TEVEN-LTIME,
         SATZA TYPE TEVEN-SATZA,
       END OF TY_TEVEN,

       BEGIN OF TY_PA0001,
         PERNR TYPE PA0001-PERNR,
         ENAME TYPE PA0001-ENAME,
         ENDDA TYPE PA0001-ENDDA,
         BEGDA TYPE PA0001-BEGDA,
         WERKS TYPE PA0001-WERKS,
         PERSG TYPE PA0001-PERSG,
         PERSK TYPE PA0001-PERSK,
         BTRTL TYPE PA0001-BTRTL,
       END OF TY_PA0001.

DATA:
  T_ABSENCE1 TYPE TABLE OF BAPIP2001L,
  P_RETURN   TYPE BAPIRETURN1,
  T_TEVEN    TYPE STANDARD TABLE OF TY_TEVEN,
  T_PA0001   TYPE STANDARD TABLE OF TY_PA0001,
  W_PA0001   TYPE TY_PA0001,
  T_FLDCAT   TYPE LVC_T_FCAT,    "SLIS_T_FIELDCAT_ALV
  WA_FLDCAT  TYPE LVC_S_FCAT,    "SLIS_FIELDCAT_ALV
  W_LAYOUT   TYPE LVC_S_LAYO,
  T_ALVTABLE TYPE REF TO DATA,
  T_ALVLINE  TYPE REF TO DATA.

FIELD-SYMBOLS:<TA_FINAL>     TYPE STANDARD TABLE,
              <WA_FINAL>     TYPE ANY,
              <WA_FIELDNAME>.

TABLES: PA0001.
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-T01.
  SELECTION-SCREEN SKIP 1.
  SELECT-OPTIONS: S_PERNR FOR PA0001-PERNR.
  SELECTION-SCREEN SKIP 1.
  SELECT-OPTIONS: S_DATE FOR SY-DATUM NO-EXTENSION OBLIGATORY.
  SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN END OF BLOCK B1.

INITIALIZATION.
  LV_OBJ = NEW YCL_MUSTER( ).

START-OF-SELECTION.

*Basic Validation
  CALL METHOD LV_OBJ->VALIDATION.

*Fetch PERNR Data
  CALL METHOD LV_OBJ->FETCH_DATA.

*Field Catalog
  CALL METHOD LV_OBJ->FIELDCATALOG.

*Process Data
  CALL METHOD LV_OBJ->PROCESS_DATA.

*Display ALV
  CALL METHOD LV_OBJ->DISPLAY_ALV.

*Implementation
CLASS YCL_MUSTER IMPLEMENTATION.

  METHOD VALIDATION.

    CLEAR : P_BEGN, P_END.
    CALL FUNCTION 'HR_JP_MONTH_BEGIN_END_DATE'
      EXPORTING
        IV_DATE             = S_DATE-LOW
      IMPORTING
        EV_MONTH_BEGIN_DATE = P_BEGN
        EV_MONTH_END_DATE   = P_END.

    IF S_DATE-HIGH GT P_END.
      MESSAGE 'Max Date Can Be Upto End-Date Of The Current Month !' TYPE 'S' DISPLAY LIKE 'E'.
      LEAVE LIST-PROCESSING.
    ENDIF.

  ENDMETHOD.

  METHOD FETCH_DATA.

*Fetch Employee, Week Off, Substitution Logic : PA0001, PA0007, TEVEN, PA2003
*Active Employee, Week Off, Night Shift & Substitution Code is suppressed for simplicity

    IF S_PERNR IS INITIAL.
      APPEND VALUE #( SIGN = 'I' OPTION = 'BT' LOW = 00000000 HIGH = 99999999 ) TO S_PERNR.
    ENDIF.
    IF S_DATE-HIGH IS INITIAL.
      S_DATE-HIGH = S_DATE-LOW.
    ENDIF.

    SELECT PERNR
     ENAME
     ENDDA
     BEGDA
     WERKS
     PERSG
     PERSK
     BTRTL
     FROM PA0001
     INTO TABLE T_PA0001
     WHERE
     PERNR IN S_PERNR
     AND  BEGDA LE S_DATE-HIGH
     AND  ENDDA GE S_DATE-HIGH.

    IF T_PA0001[] IS NOT INITIAL.
      SELECT PERNR
          LDATE
          LTIME
          SATZA
          INTO TABLE T_TEVEN
          FROM TEVEN
          FOR ALL ENTRIES IN T_PA0001
          WHERE PERNR = T_PA0001-PERNR
          AND   LDATE BETWEEN S_DATE-LOW AND S_DATE-HIGH.
      SORT T_PA0001 ASCENDING BY PERNR.
    ELSE.
      MESSAGE 'No Records Found' TYPE 'S' DISPLAY LIKE 'E'.
      LEAVE LIST-PROCESSING.
    ENDIF.
  ENDMETHOD.

  METHOD FIELDCATALOG.

    LV_OBJ->CREATE_COLUMN( EXPORTING FIELDNAME = 'PERNR' SELTEXT = 'P No.' COL_POS = 1 FIX_COLUMN = 'X' OUTPUTLEN = '10' NO_OUT = '' ).
    LV_OBJ->CREATE_COLUMN( EXPORTING FIELDNAME = 'NAME' SELTEXT = 'Name' COL_POS = 2 FIX_COLUMN = 'X' OUTPUTLEN = '20' NO_OUT = '' ).
    LV_OBJ->CREATE_COLUMN( EXPORTING FIELDNAME = 'LINECOLOR' SELTEXT = '' COL_POS = 3 FIX_COLUMN = 'X' OUTPUTLEN = '10' NO_OUT = 'X' ).

    TEMP_DATE = S_DATE-LOW.
    WHILE TEMP_DATE <= S_DATE-HIGH.

      CALL METHOD LV_OBJ->GET_HEADING.

      LV_OBJ->CREATE_COLUMN( EXPORTING FIELDNAME = L_TYPE SELTEXT = L_TYPE+0(20) COL_POS = L_COUNT2 + 1 FIX_COLUMN = '' OUTPUTLEN = '11' NO_OUT = '' ).

      "Increment TEMP_DATE
      CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
        EXPORTING
          DATE      = TEMP_DATE
          DAYS      = 01
          MONTHS    = 00
          SIGNUM    = '+'
          YEARS     = 00
        IMPORTING
          CALC_DATE = TEMP_DATE.
    ENDWHILE.

* Create Dynamic-Table
    CALL METHOD CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE
      EXPORTING
        IT_FIELDCATALOG = T_FLDCAT
      IMPORTING
        EP_TABLE        = T_ALVTABLE.

    ASSIGN T_ALVTABLE->* TO <TA_FINAL>.

    CREATE DATA T_ALVLINE LIKE LINE OF <TA_FINAL>.
    ASSIGN T_ALVLINE->* TO <WA_FINAL>.
    REFRESH :<TA_FINAL>.

  ENDMETHOD.

  METHOD CREATE_COLUMN.

    WA_FLDCAT-FIELDNAME = FIELDNAME.
    WA_FLDCAT-SCRTEXT_M = SELTEXT.
    WA_FLDCAT-COL_POS = COL_POS.
    WA_FLDCAT-FIX_COLUMN = FIX_COLUMN.
    WA_FLDCAT-OUTPUTLEN = OUTPUTLEN.
    WA_FLDCAT-NO_OUT = NO_OUT.

    APPEND WA_FLDCAT TO T_FLDCAT.
    CLEAR  WA_FLDCAT.

  ENDMETHOD.

  METHOD PROCESS_DATA.

    LOOP AT T_PA0001 INTO W_PA0001.   "PERNR Wise

      CLEAR: TEMP_DATE, LV_LEAVE_COUNT, P_RETURN, T_ABSENCE1[].
      TEMP_DATE = S_DATE-LOW.

      ASSIGN COMPONENT 'PERNR' OF STRUCTURE <WA_FINAL> TO <WA_FIELDNAME>.
      <WA_FIELDNAME> = W_PA0001-PERNR.

      ASSIGN COMPONENT 'NAME' OF STRUCTURE <WA_FINAL> TO <WA_FIELDNAME>.
      <WA_FIELDNAME> = W_PA0001-ENAME.

      CALL FUNCTION 'BAPI_ABSENCE_GETDETAILEDLIST'
        EXPORTING
          EMPLOYEENUMBER   = W_PA0001-PERNR
          TIMEINTERVALLOW  = S_DATE-LOW
          TIMEINTERVALHIGH = S_DATE-HIGH
        IMPORTING
          RETURN           = P_RETURN
        TABLES
          ABSENCE          = T_ABSENCE1.

      WHILE TEMP_DATE <= S_DATE-HIGH.

        CALL METHOD LV_OBJ->GET_HEADING.

        CALL METHOD LV_OBJ->GET_PUNCH_STATUS.

        ASSIGN COMPONENT L_TYPE OF STRUCTURE <WA_FINAL> TO  <WA_FIELDNAME>.
        <WA_FIELDNAME> = LV_STATUS.

        IF LV_LEAVE_COUNT GE 3. "Set Line Color If PERNR has 3 consecutive PL/CL
          ASSIGN COMPONENT 'LINECOLOR' OF STRUCTURE <WA_FINAL> TO <WA_FIELDNAME>.
          <WA_FIELDNAME> = 'C710'.
        ENDIF.

        "Increment TEMP_DATE
        CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
          EXPORTING
            DATE      = TEMP_DATE
            DAYS      = 01
            MONTHS    = 00
            SIGNUM    = '+'
            YEARS     = 00
          IMPORTING
            CALC_DATE = TEMP_DATE.
      ENDWHILE.

      APPEND <WA_FINAL> TO <TA_FINAL>.
      CLEAR <WA_FINAL>.
    ENDLOOP.

  ENDMETHOD.

  METHOD GET_HEADING. "MON(01)

    CLEAR: P_DAYS1,P_T247,L_TYPE.
    CALL FUNCTION 'DATE_COMPUTE_DAY'
      EXPORTING
        DATE = TEMP_DATE
      IMPORTING
        DAY  = P_DAYS1.

    "P_DAYS1 return data > if TEMP_DATE is on mon = 1, tue = 2, wed = 3, thus = 4, fri = 5, sat = 6, sun = 7
    IF P_DAYS1 IS NOT INITIAL.
      CLEAR: L_DAY, L_TYPE.
      IF P_DAYS1 = 1.
        L_DAY = 'Mon'.
      ELSEIF  P_DAYS1 = 2.
        L_DAY = 'Tue'.
      ELSEIF P_DAYS1 = 3.
        L_DAY = 'Wed'.
      ELSEIF P_DAYS1 = 4.
        L_DAY = 'Thus'.
      ELSEIF P_DAYS1 = 5.
        L_DAY = 'Fri'.
      ELSEIF P_DAYS1 = 6.
        L_DAY = 'Sat'.
      ELSEIF P_DAYS1 = 7.
        L_DAY = 'Sun'.
      ENDIF.

      CALL FUNCTION 'IDWT_READ_MONTH_TEXT'
        EXPORTING
          LANGU = 'E'
          MONTH = TEMP_DATE+4(2)
        IMPORTING
          T247  = P_T247.

*      CONCATENATE TEMP_DATE+6(2) '-' P_T247-KTX '_' L_DAY '' INTO L_TYPE. " eg-> 01-JUN_Mon, 02-JUN_Tue
      L_TYPE = |{ TEMP_DATE+6(2) }-{ P_T247-KTX }_{ L_DAY }|. "eg-> 01-JUN_Mon, 02-JUN_Tue
      DESCRIBE TABLE T_FLDCAT LINES L_COUNT2.
    ENDIF.
  ENDMETHOD.

  METHOD DISPLAY_ALV.
    IF <TA_FINAL> IS NOT INITIAL.

      W_LAYOUT-ZEBRA = 'X'.
      W_LAYOUT-INFO_FNAME = 'LINECOLOR'.

      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
        EXPORTING
          I_CALLBACK_PROGRAM = SY-REPID
          IS_LAYOUT_LVC      = W_LAYOUT
          IT_FIELDCAT_LVC    = T_FLDCAT[]
          I_SAVE             = 'X'
        TABLES
          T_OUTTAB           = <TA_FINAL>
        EXCEPTIONS
          PROGRAM_ERROR      = 1
          OTHERS             = 2.
      IF SY-SUBRC <> 0.
* Implement suitable error handling here
      ENDIF.

    ELSE.
      MESSAGE 'No Records Found' TYPE 'S' DISPLAY LIKE 'E'.
    ENDIF.
  ENDMETHOD.

  METHOD GET_PUNCH_STATUS.

    CLEAR LV_STATUS.

    TRY.
        DATA(WA_TEVEN) =  T_TEVEN[ PERNR = W_PA0001-PERNR SATZA = 'P10' LDATE = TEMP_DATE ].
        LV_STATUS = 'P'. "Present
        CLEAR LV_LEAVE_COUNT.

      CATCH CX_SY_ITAB_LINE_NOT_FOUND .

        LOOP AT T_ABSENCE1 INTO DATA(WA_ABSENCE1) WHERE EMPLOYEENO EQ W_PA0001-PERNR.

          IF TEMP_DATE BETWEEN WA_ABSENCE1-VALIDBEGIN AND WA_ABSENCE1-VALIDEND.

            IF WA_ABSENCE1-SUBTYPE = '0003'.
              LV_STATUS = 'CL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0001'.
              LV_STATUS = 'PL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0027'.
              LV_STATUS = 'SSL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0013'.
              LV_STATUS = 'LWOP'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0017'.
              LV_STATUS = 'MTL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0009' OR  WA_ABSENCE1-SUBTYPE  = '0006'.
              LV_STATUS = 'SL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0015'.
              LV_STATUS = 'SPL'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0031'.
              LV_STATUS = 'CB'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0064'.
              LV_STATUS = 'WFH'.
            ELSEIF WA_ABSENCE1-SUBTYPE = '0008'.
              LV_STATUS = 'IOD'.
            ENDIF.
            IF LV_STATUS EQ 'CL' OR LV_STATUS EQ 'PL'.
              LV_LEAVE_COUNT = LV_LEAVE_COUNT + 1.
            ENDIF.
            EXIT.
          ENDIF.
        ENDLOOP.

        IF LV_STATUS IS INITIAL."Status If No Data found in TEVEN & PA2001
          LV_STATUS = 'AA'.
          CLEAR : LV_LEAVE_COUNT.
        ENDIF.

    ENDTRY.
    CLEAR WA_TEVEN.
  ENDMETHOD.
ENDCLASS.

Output :



Conclusion :

            Dynamic field symbols and data references push ABAP beyond its traditional boundaries making it capable of runtime decision-making, flexible data handling, and adaptive logic flows. This opens the door to more agile, scalable and modern ABAP development.

- Published By Nimi Soni



        

Note: All visuals and content are protected and not to be copied, reproduced, or distributed without prior consent.
Copyright © Nimi Soni, 2022














Popular posts from this blog

The Perspective !

True Education Through My Lens !