Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
harsha_reddy24
Explorer
602

Hi Everyone

Introduction:

The user needs an interactive Date Hierarchy display in SAP that provides a structured view of years, months, and individual dates.This helps users quickly navigate through large date ranges and select specific dates for downstream operations such as data extraction, reporting, or analysis.

Solution Overview:

 

  • The screen should display a hierarchical Tree ALV titled “DATE HIERARCHY”.

  • The top-level nodes represent Years (e.g., 2021 to 2025).

  • When the user expands a Year, the 12 months (January to December) are displayed as child nodes.

  • When the user expands a Month, all valid calendar dates for that month are dynamically generated and displayed.

  • Each date node should display the date in user’s local format (DD.MM.YYYY).

  • The user should be able to:

    • Expand/collapse nodes dynamically.

    • View all levels of hierarchy.

 

TABLES : BKPF.

"Internal table and work area for tree nodes
DATA: IT_NODE TYPE TABLE OF SNODETEXT,
      WA_NODE TYPE SNODETEXT.

"Variables for Year, Month, Date calculations
DATA: LV_YEAR  TYPE GJAHR,
      LV_MONTH TYPE NUMC2,
      LV_DATE  TYPE DATUM,
      LV_DAYS  TYPE I,
      LV_DAY   TYPE NUMC2.

"Keys for hierarchy levels
DATA: LV_YEAR_KEY  TYPE CHAR10,
      LV_MONTH_KEY TYPE CHAR15,
      LV_DATE_KEY  TYPE CHAR20.

"Selection range for fiscal year
SELECT-OPTIONS: S_GJAHR FOR BKPF-GJAHR DEFAULT '2021' TO '2025'.

START-OF-SELECTION.

  CLEAR: WA_NODE, IT_NODE.

"------------------------------------------------------------"
" Root Node Creation                                         "
"------------------------------------------------------------"
WA_NODE-TYPE    = 'T'.             "Tree title
WA_NODE-NAME    = 'DATE HIERARCHY'.
WA_NODE-TLEVEL  = '01'.
WA_NODE-NLENGTH = '18'.
WA_NODE-COLOR   = '05'.
APPEND WA_NODE TO IT_NODE.
CLEAR WA_NODE.

"------------------------------------------------------------"
" Build Year → Month → Date Hierarchy                       "
"------------------------------------------------------------"
LOOP AT S_GJAHR.
  DO.
    "Loop through each year within the selected range
    LV_YEAR = S_GJAHR-LOW + SY-INDEX - 1.
    IF LV_YEAR > S_GJAHR-HIGH.
      EXIT.
    ENDIF.

    "--------------------------------------------------------"
    " Year Node (Level 02)                                   "
    "--------------------------------------------------------"
    LV_YEAR_KEY = LV_YEAR.
    WA_NODE-TYPE    = 'P'.
    WA_NODE-ID      = LV_YEAR_KEY.
    CONCATENATE LV_YEAR ' ' INTO WA_NODE-NAME SEPARATED BY SPACE.
    WA_NODE-TLEVEL  = '02'.
    WA_NODE-NLENGTH = STRLEN( WA_NODE-NAME ).
    WA_NODE-COLOR   = '03'.
    APPEND WA_NODE TO IT_NODE.
    CLEAR WA_NODE.

    "--------------------------------------------------------"
    " 12 Months Loop (Level 03)                              "
    "--------------------------------------------------------"
    DO 12 TIMES.
      LV_MONTH = SY-INDEX.
      CONCATENATE LV_YEAR_KEY LV_MONTH INTO LV_MONTH_KEY.

      WA_NODE-TYPE = 'P'.
      WA_NODE-ID   = LV_MONTH_KEY.

      "Month Name Assignment"
      CASE LV_MONTH.
        WHEN '01'. WA_NODE-NAME = 'January'.
        WHEN '02'. WA_NODE-NAME = 'February'.
        WHEN '03'. WA_NODE-NAME = 'March'.
        WHEN '04'. WA_NODE-NAME = 'April'.
        WHEN '05'. WA_NODE-NAME = 'May'.
        WHEN '06'. WA_NODE-NAME = 'June'.
        WHEN '07'. WA_NODE-NAME = 'July'.
        WHEN '08'. WA_NODE-NAME = 'August'.
        WHEN '09'. WA_NODE-NAME = 'September'.
        WHEN '10'. WA_NODE-NAME = 'October'.
        WHEN '11'. WA_NODE-NAME = 'November'.
        WHEN '12'. WA_NODE-NAME = 'December'.
      ENDCASE.

      WA_NODE-TLEVEL  = '03'.
      WA_NODE-NLENGTH = STRLEN( WA_NODE-NAME ).
      WA_NODE-COLOR   = '04'.
      APPEND WA_NODE TO IT_NODE.
      CLEAR WA_NODE.

      "------------------------------------------------------"
      " Determine number of days in the month                "
      "------------------------------------------------------"
      CONCATENATE LV_YEAR LV_MONTH '01' INTO LV_DATE.
      CALL FUNCTION 'SLS_MISC_GET_LAST_DAY_OF_MONTH'
        EXPORTING
          DAY_IN            = LV_DATE
        IMPORTING
          LAST_DAY_OF_MONTH = LV_DATE.

      LV_DAYS = LV_DATE+6(2). "Extract day part → last day of month

      "------------------------------------------------------"
      " Date Nodes (Level 04)                                "
      "------------------------------------------------------"
      DO LV_DAYS TIMES.
        LV_DAY = SY-INDEX.
        CONCATENATE LV_YEAR LV_MONTH LV_DAY INTO LV_DATE_KEY.

        WA_NODE-TYPE    = 'P'.
        WA_NODE-ID      = LV_DATE_KEY.
        CONCATENATE LV_DAY '.' LV_MONTH '.' LV_YEAR INTO WA_NODE-NAME.
        WA_NODE-TLEVEL  = '04'.
        WA_NODE-NLENGTH = STRLEN( WA_NODE-NAME ).
        WA_NODE-COLOR   = '06'.
        APPEND WA_NODE TO IT_NODE.
        CLEAR WA_NODE.

      ENDDO.

    ENDDO.

  ENDDO.
ENDLOOP.

"------------------------------------------------------------"
" Display the Tree Output                                    "
"------------------------------------------------------------"
CALL FUNCTION 'RS_TREE_CONSTRUCT'
  TABLES
    NODETAB = IT_NODE.

CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
  EXPORTING
    CALLBACK_PROGRAM = SY-REPID.

Output:
tree.png
OOPS Approach:

TABLES: MARA, BKPF.

*---------------------------------------------------------------------*
* Data Declarations
*---------------------------------------------------------------------*
"ALV Tree objects
DATA: GO_TREE      TYPE REF TO CL_GUI_ALV_TREE,
      GO_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER.

"ALV field catalog and layout
DATA: GT_FIELDCAT TYPE LVC_T_FCAT,
      GS_FIELDCAT TYPE LVC_S_FCAT,
      GS_LAYOUT   TYPE LVC_S_LAYO.

"Output structure for tree text
TYPES: BEGIN OF TY_OUTPUT,
         COLUMN1 TYPE CHAR255,  "Single text column for tree nodes
       END OF TY_OUTPUT.

DATA: GT_OUTPUT TYPE TABLE OF TY_OUTPUT,
      GS_OUTPUT TYPE TY_OUTPUT.

"Variables used for Year → Month → Date hierarchy
DATA: LV_YEAR       TYPE GJAHR,
      LV_MONTH      TYPE NUMC2,
      LV_DATE       TYPE DATUM,
      LV_LAST_DATE  TYPE DATUM,
      LV_DAYS       TYPE I,
      LV_DAY        TYPE NUMC2,
      LV_YEAR_KEY   TYPE LVC_NKEY,
      LV_MONTH_KEY  TYPE LVC_NKEY,
      LV_DATES_LINE TYPE STRING.

"Node layout (folder / item)
DATA: LS_NODE_LAYOUT TYPE LVC_S_LAYN.

"Year range for hierarchy
SELECT-OPTIONS: S_GJAHR FOR BKPF-GJAHR DEFAULT '2021' TO '2025'.

*---------------------------------------------------------------------*
* Selection Screen Trigger
*---------------------------------------------------------------------*
START-OF-SELECTION.
  CALL SCREEN 100.  "Call main screen

*---------------------------------------------------------------------*
* PBO: Set status and create tree
*---------------------------------------------------------------------*
MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'ZSTANDARD'.

  "Create the tree only once
  IF GO_CONTAINER IS INITIAL.
    PERFORM CREATE_AND_FILL_TREE.
  ENDIF.
ENDMODULE.

*---------------------------------------------------------------------*
* PAI: Handle user commands
*---------------------------------------------------------------------*
MODULE USER_COMMAND_0100 INPUT.
  CASE SY-UCOMM.
    WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
      "Release frontend controls
      PERFORM FREE_RESOURCES.
      LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.

*---------------------------------------------------------------------*
* Create container, tree control, root node and load hierarchy
*---------------------------------------------------------------------*
FORM CREATE_AND_FILL_TREE.

  "Create custom container inside screen element 'CONTAINER'
  CREATE OBJECT GO_CONTAINER
    EXPORTING
      CONTAINER_NAME = 'CONTAINER'.

  "Build ALV field catalog
  PERFORM BUILD_FIELDCAT.

  "Create ALV tree control
  CREATE OBJECT GO_TREE
    EXPORTING
      PARENT              = GO_CONTAINER
      NODE_SELECTION_MODE = CL_GUI_COLUMN_TREE=>NODE_SEL_MODE_SINGLE
      ITEM_SELECTION      = 'X'
    EXCEPTIONS
      OTHERS              = 1.

  "Bind output table and field catalog to tree
  CALL METHOD GO_TREE->SET_TABLE_FOR_FIRST_DISPLAY
    CHANGING
      IT_OUTTAB       = GT_OUTPUT
      IT_FIELDCATALOG = GT_FIELDCAT.

  "---------------------------------------------------------------*
  " Create Root Node (DATE HIERARCHY)
  "---------------------------------------------------------------*
  CLEAR: LS_NODE_LAYOUT, GS_OUTPUT.
  LS_NODE_LAYOUT-ISFOLDER  = 'X'.
  LS_NODE_LAYOUT-N_IMAGE   = '@AV@'.
  LS_NODE_LAYOUT-EXP_IMAGE = '@AV@'.
  GS_OUTPUT-COLUMN1        = 'DATE HIERARCHY'.

  "Add root node
  CALL METHOD GO_TREE->ADD_NODE
    EXPORTING
      I_RELAT_NODE_KEY = ''  "Root level
      I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
      IS_OUTTAB_LINE   = GS_OUTPUT
      IS_NODE_LAYOUT   = LS_NODE_LAYOUT
    IMPORTING
      E_NEW_NODE_KEY   = LV_YEAR_KEY.

  "Build full tree under root node
  PERFORM BUILD_TREE_NODES USING LV_YEAR_KEY.

  "Auto-expand root node
  CALL METHOD GO_TREE->EXPAND_NODE
    EXPORTING
      I_NODE_KEY = LV_YEAR_KEY.

  CALL METHOD GO_TREE->FRONTEND_UPDATE.

ENDFORM.

*---------------------------------------------------------------------*
* Create field catalog for ALV tree
*---------------------------------------------------------------------*
FORM BUILD_FIELDCAT.
  CLEAR GS_FIELDCAT.
  GS_FIELDCAT-FIELDNAME = 'COLUMN1'.
  GS_FIELDCAT-COLTEXT   = 'Description'.
  GS_FIELDCAT-OUTPUTLEN = 255.
  APPEND GS_FIELDCAT TO GT_FIELDCAT.
ENDFORM.

*---------------------------------------------------------------------*
* Build YEAR → MONTH → DAY hierarchy inside ALV Tree
*---------------------------------------------------------------------*
FORM BUILD_TREE_NODES USING IV_ROOT_KEY TYPE LVC_NKEY.

  DATA: LV_PARENT_YEAR  TYPE LVC_NKEY,
        LV_PARENT_MONTH TYPE LVC_NKEY,
        LV_MONTH_NAME   TYPE STRING,
        LV_CHUNK        TYPE STRING,
        LV_CHUNK_COUNT  TYPE I,
        GV_GROUP_SIZE   TYPE I VALUE 10,  "Group 10 days per line
        LV_DATE_STRING  TYPE STRING.

  "Loop through selected year range
  LOOP AT S_GJAHR.
    DO.
      LV_YEAR = S_GJAHR-LOW + SY-INDEX - 1.
      IF LV_YEAR > S_GJAHR-HIGH.
        EXIT.
      ENDIF.

      "---------------------------------------------------------------*
      " Create YEAR Node
      "---------------------------------------------------------------*
      CLEAR: LS_NODE_LAYOUT, GS_OUTPUT.
      LS_NODE_LAYOUT-ISFOLDER  = 'X'.
      LS_NODE_LAYOUT-N_IMAGE   = '@AV@'.
      LS_NODE_LAYOUT-EXP_IMAGE = '@AV@'.
      GS_OUTPUT-COLUMN1        = |Year: { LV_YEAR }|.

      CALL METHOD GO_TREE->ADD_NODE
        EXPORTING
          I_RELAT_NODE_KEY = IV_ROOT_KEY      "Attach to root
          I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
          IS_OUTTAB_LINE   = GS_OUTPUT
          IS_NODE_LAYOUT   = LS_NODE_LAYOUT
        IMPORTING
          E_NEW_NODE_KEY   = LV_PARENT_YEAR.

      "---------------------------------------------------------------*
      " Create MONTH Nodes under each Year
      "---------------------------------------------------------------*
      DO 12 TIMES.
        LV_MONTH = SY-INDEX.

        "Month name mapping
        CASE LV_MONTH.
          WHEN 1.  LV_MONTH_NAME = 'January'.
          WHEN 2.  LV_MONTH_NAME = 'February'.
          WHEN 3.  LV_MONTH_NAME = 'March'.
          WHEN 4.  LV_MONTH_NAME = 'April'.
          WHEN 5.  LV_MONTH_NAME = 'May'.
          WHEN 6.  LV_MONTH_NAME = 'June'.
          WHEN 7.  LV_MONTH_NAME = 'July'.
          WHEN 8.  LV_MONTH_NAME = 'August'.
          WHEN 9.  LV_MONTH_NAME = 'September'.
          WHEN 10. LV_MONTH_NAME = 'October'.
          WHEN 11. LV_MONTH_NAME = 'November'.
          WHEN 12. LV_MONTH_NAME = 'December'.
        ENDCASE.

        CLEAR: LS_NODE_LAYOUT, GS_OUTPUT.
        LS_NODE_LAYOUT-ISFOLDER  = 'X'.
        LS_NODE_LAYOUT-N_IMAGE   = '@2L@'.
        LS_NODE_LAYOUT-EXP_IMAGE = '@2L@'.
        GS_OUTPUT-COLUMN1        = LV_MONTH_NAME.

        "Add Month node
        CALL METHOD GO_TREE->ADD_NODE
          EXPORTING
            I_RELAT_NODE_KEY = LV_PARENT_YEAR
            I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
            IS_OUTTAB_LINE   = GS_OUTPUT
            IS_NODE_LAYOUT   = LS_NODE_LAYOUT
          IMPORTING
            E_NEW_NODE_KEY   = LV_PARENT_MONTH.

        "-----------------------------------------------------------*
        " Determine last day of month
        "-----------------------------------------------------------*
        CONCATENATE LV_YEAR LV_MONTH '01' INTO LV_DATE.
        CALL FUNCTION 'LAST_DAY_OF_MONTHS'
          EXPORTING
            DAY_IN            = LV_DATE
          IMPORTING
            LAST_DAY_OF_MONTH = LV_LAST_DATE.

        LV_DAYS = LV_LAST_DATE+6(2).  "Extract number of days

        "-----------------------------------------------------------*
        " Add DAY Nodes grouped (10 days per node)
        "-----------------------------------------------------------*
        CLEAR: LV_CHUNK, LV_CHUNK_COUNT.

        DO LV_DAYS TIMES.
          LV_DAY = SY-INDEX.

          "Format date string: DD.MM.YYYY
          LV_DATE_STRING = |{ LV_DAY WIDTH = 2 }.{ LV_MONTH WIDTH = 2 }.{ LV_YEAR }|.

          "Build chunk of 10 dates
          IF LV_CHUNK IS INITIAL.
            LV_CHUNK = LV_DATE_STRING.
          ELSE.
            CONCATENATE LV_CHUNK LV_DATE_STRING INTO LV_CHUNK SEPARATED BY SPACE.
          ENDIF.

          ADD 1 TO LV_CHUNK_COUNT.

          "Add one group node after every 10 days OR last day
          IF LV_CHUNK_COUNT >= GV_GROUP_SIZE OR LV_DAY = LV_DAYS.

            CLEAR: LS_NODE_LAYOUT, GS_OUTPUT.
            LS_NODE_LAYOUT-ISFOLDER = ''.   "Leaf node
            LS_NODE_LAYOUT-N_IMAGE  = '@3C@'.
            GS_OUTPUT-COLUMN1       = LV_CHUNK.

            "Add day-chunk node
            CALL METHOD GO_TREE->ADD_NODE
              EXPORTING
                I_RELAT_NODE_KEY = LV_PARENT_MONTH
                I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
                IS_OUTTAB_LINE   = GS_OUTPUT
                IS_NODE_LAYOUT   = LS_NODE_LAYOUT.

            CLEAR: LV_CHUNK, LV_CHUNK_COUNT.
          ENDIF.
        ENDDO.

      ENDDO.  "End Month Loop

    ENDDO.
  ENDLOOP.

ENDFORM.

*---------------------------------------------------------------------*
* Release frontend controls
*---------------------------------------------------------------------*
FORM FREE_RESOURCES.
  IF GO_TREE IS BOUND.
    CALL METHOD GO_TREE->FREE.
    FREE GO_TREE.
  ENDIF.

  IF GO_CONTAINER IS BOUND.
    CALL METHOD GO_CONTAINER->FREE.
    FREE GO_CONTAINER.
  ENDIF.
ENDFORM.

date.jpg

 Conclusion:
This solution showcases a practical and user-friendly way to visualize date structures by building a dynamic Year–Month–Day hierarchy using the ALV Tree control. By grouping daily entries and leveraging container-based GUI elements, the approach delivers a clean, scalable, and intuitive navigation experience. It also demonstrates how classic ABAP techniques—selection screens, tree controls, and month/day calculations—can be combined to create interactive UI components that enhance data exploration within SAP GUI.

2 Comments
Sandra_Rossi
Active Contributor

Thanks. Don't forget that the subroutines (FORM, ENDFORM, PERFORM) are obsolete since 2009 (ABAP 7.02). ABAP Objects should now be used.

Jelena_Perfiljeva
Active Contributor
0 Likes

Absolutely awful code quality, sorry. Please see the comment in your other AI-generated post.