Skip to Content

Retrieving the dates for different periods based on Plant and factory Calendar

The following example provides an idea of how to see the factory calendar dates based on the plant , Factory calendar and different combination of Period indicators.

The different Period indicators

P             Period according to fiscal year variant

M            Monthly

W            Weekly

T              Daily

                Initial value

K             Period according to planning calendar

A new class is defined.

Method details.PNG

The output table structure will be defined as

output table structure.PNG

The code in the method is.

   METHOD get_factory_data.

  DATA:lw_fabkl TYPE fabkl, “Factory Calendar
       lw_datum TYPE sydatum,
       lw_enddate TYPE sydatum,
       lt_period TYPE STANDARD TABLE OF periotab,
       ls_period TYPE periotab,
       ls_calendar TYPE zmop_periods,
       lt_calendar TYPE STANDARD TABLE OF zmop_periods,
       lw_spjah    TYPE mcjahr, “Periode Jahr, Period of years
       lw_spmon    TYPE spmon, “Periode Monat,Period of months
       lw_spwoc    TYPE spwoc, “Periode Woche,Period of weeks
       lw_atjah    TYPE atage, “Working days a year
       lw_atmon    TYPE atage, “Working day a month
       lw_atwoc    TYPE atage, “Labor Day weekend
       lt_daasc  TYPE STANDARD TABLE OF zmop_periods,
       lt_dades  TYPE STANDARD TABLE OF zmop_periods,
       lw_tabix TYPE sytabix,
       ls_temp TYPE zmop_periods,
       lt_attri  TYPE STANDARD TABLE OF casdayattr,
       ls_attri  TYPE casdayattr.

  CONSTANTS: lc_perkzjahr  VALUE ‘J’,                        “Jahr, Year
             lc_perkzmonat VALUE ‘M’,                        “Monat, Month
             lc_perkztag   VALUE ‘T’,                        “Tag, Day
             lc_perkzwoche VALUE ‘W’.                        “Woche, Week

  FIELDSYMBOLS:<lfs_calendar> TYPE zmop_periods.

*Get Fctory calendar.
  IF im_fabkl IS NOT INITIAL.
    lw_fabkl im_fabkl.
  ELSE.
    SELECT SINGLE fabkl
      FROM t001w INTO lw_fabkl
      WHERE  werks = im_werks.
  ENDIF.

* Predefining to-date is not there, then From Date
  IF im_enddate IS INITIAL.
    lw_enddate = im_startdate.
  ELSE.
    lw_enddate = im_enddate.
  ENDIF.

* Every day for the period prescribed form
  lw_datum = im_startdate.
  WHILE NOT lw_datum > lw_enddate.
    ls_periodperkz = lc_perkztag.
    ls_periodperid = lw_datum.
    APPEND ls_period TO lt_period.
    lw_datum = lw_datum + 1.
  ENDWHILE.

* FM-default periods + period Date
* FM provides first Working day period and the number of working days back
  CALL FUNCTION ‘MC_ADD_ERTAG_AND_ATAGE’
    EXPORTING
      ifabkl                        = lw_fabkl
    TABLES
      iptab                         = lt_period
    EXCEPTIONS
      factory_cal_read_not_possible = 1
      perid_invalid                 = 2
      OTHERS                        = 3.
  IF NOT sysubrc IS INITIAL.
    MESSAGE e089(zmop) WITH ‘MC_ADD_ERTAG_AND_ATAGE’ sysubrc
       RAISING error.
  ENDIF.

* STEP 2: Schedule for each day

* Period to build grid
  LOOP AT lt_period INTO ls_period.

* Date must have proper continuity
    CHECK ls_periodatage = 1.
* Date must be working
    CHECK ls_periodperid = ls_periodertag.
* Daily Value Park
    ls_calendarsptag = ls_periodertag.
* Monthly Value Park
    ls_calendarspmon = ls_periodertag+0(6).
* Annual value of stop
    ls_calendarspjah = ls_periodertag+0(4).

* Weekly values ​​stop
    CALL FUNCTION ‘DATE_GET_WEEK’
      EXPORTING
        date         = ls_calendarsptag
      IMPORTING
        week         = ls_calendarspwoc
      EXCEPTIONS
        date_invalid = 1
        OTHERS       = 2.
    IF NOT sysubrc IS INITIAL.
      MESSAGE e012(zmop) WITH ‘DATE_GET_WEEK’ sysubrc
         RAISING error.
* Funktionsbaustein & mit Fehlercode & abgebrochen
* Function module & terminated with error code &
    ENDIF.

    APPEND ls_calendar TO lt_calendar.
  ENDLOOP.

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* STEP 3: Days for each periodicity
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Screen multiplex period
  LOOP AT lt_calendar INTO ls_calendar.

* Initialization sequence
    IF sytabix = 1.
* Periodenraster als Merker für Arbeitstage
* Period as a marker for scanning business days
      REFRESH lt_period[].
      CLEAR   ls_period.

      lw_spwoc = ls_calendarspwoc.
      lw_spmon = ls_calendarspmon.
      lw_spjah = ls_calendarspjah.
      CLEAR lw_atwoc.
      CLEAR lw_atmon.
      CLEAR lw_atjah.
    ENDIF.

* Working days of the week conserve
    IF NOT ls_calendarspwoc = lw_spwoc.
      ls_periodperkz = lc_perkzwoche.
      ls_periodperid = lw_spwoc.
      ls_periodatage = lw_atwoc.
      APPEND ls_period TO lt_period.
      CLEAR lw_atwoc.
      lw_spwoc = ls_calendarspwoc.
    ENDIF.

* Preserve working day of the month
    IF NOT ls_calendarspmon = lw_spmon.
      ls_periodperkz = lc_perkzmonat.
      ls_periodperid = lw_spmon.
      ls_periodatage = lw_atmon.
      APPEND ls_period TO lt_period.
      CLEAR lw_atmon.
      lw_spmon = ls_calendarspmon.
    ENDIF.

* Working days of the year, preserving
    IF NOT ls_calendarspjah = lw_spjah.
      ls_periodperkz = lc_perkzjahr.
      ls_periodperid = lw_spjah.
      ls_periodatage = lw_atjah.
      APPEND ls_period TO lt_period.
      CLEAR lw_atjah.
      lw_spjah = ls_calendarspjah.
    ENDIF.

* Arbeitstage der Periode
* Working days of the period
    lw_atjah = lw_atjah + 1.
    lw_atmon = lw_atmon + 1.
    lw_atwoc = lw_atwoc + 1.

  ENDLOOP.

* Working days of the week conserve
  ls_periodperkz = lc_perkzwoche.
  ls_periodperid = lw_spwoc.
  ls_periodatage = lw_atwoc.
  APPEND ls_period TO lt_period.

* Preserve working day of the month
  ls_periodperkz = lc_perkzmonat.
  ls_periodperid = lw_spmon.
  ls_periodatage = lw_atmon.
  APPEND ls_period TO lt_period.

* Arbeitstage des Jahres konservieren
* Working days of the year, preserving
  ls_periodperkz = lc_perkzjahr.
  ls_periodperid = lw_spjah.
  ls_periodatage = lw_atjah.
  APPEND ls_period TO lt_period.

* STEP 4: Working days to weeks and months to assign the days
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Screen multiplex period
  LOOP AT lt_calendar ASSIGNING <lfs_calendar>.

* Arbeitstage Woche
* Labor Day weekend
    READ TABLE lt_period INTO ls_period WITH KEY perkz = lc_perkzwoche
                                  perid = <lfs_calendar>spwoc.
    IF sysubrc EQ 0.
      <lfs_calendar>atwoc = ls_periodatage.
    ENDIF.
* Working day month
    READ TABLE lt_period INTO ls_period WITH KEY perkz = lc_perkzmonat
                                  perid = <lfs_calendar>spmon.
    IF sysubrc EQ 0.
      <lfs_calendar>atmon = ls_periodatage.
    ENDIF.
* Working days a year
    READ TABLE lt_period INTO ls_period WITH KEY perkz = lc_perkzjahr
                                                 perid = <lfs_calendar>spjah.
    IF sysubrc EQ 0.
      <lfs_calendar>atjah = ls_periodatage.
    ENDIF.

* Abhängig von gewünschter Periode Datum und Arbeitstage vereinfachen
* Depending on the desired period date and simplify working days
    CASE im_perkz.
      WHEN lc_perkztag.
        <lfs_calendar>wdate = <lfs_calendar>sptag.
        <lfs_calendar>wtage = 1.
      WHEN lc_perkzwoche.
        <lfs_calendar>wdate = <lfs_calendar>spwoc.
        <lfs_calendar>wtage = <lfs_calendar>atwoc.
      WHEN lc_perkzmonat.
        <lfs_calendar>wdate = <lfs_calendar>spmon.
        <lfs_calendar>wtage = <lfs_calendar>atmon.
      WHEN lc_perkzjahr.
        <lfs_calendar>wdate = <lfs_calendar>spjah.
        <lfs_calendar>wtage = <lfs_calendar>atjah.
    ENDCASE.

  ENDLOOP.

  lt_daasc[] = lt_calendar[].
  lt_dades[] = lt_calendar[].
  SORT lt_dades BY sptag DESCENDING.

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* STEP 5: Eliminate Duplicates
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  CASE im_perkz.
    WHEN lc_perkzwoche.
      DELETE ADJACENT DUPLICATES FROM lt_calendar COMPARING spwoc.
    WHEN lc_perkzmonat.
      DELETE ADJACENT DUPLICATES FROM lt_calendar COMPARING spmon.
    WHEN lc_perkzjahr.
      DELETE ADJACENT DUPLICATES FROM lt_calendar COMPARING spjah.
  ENDCASE.

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* STEP 6: Start and end date of the period occupied
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Screen multiplex period
  LOOP AT lt_calendar ASSIGNING <lfs_calendar>.

* Start and end date of the period occupied
    READ TABLE lt_daasc INTO ls_temp WITH KEY wdate = <lfs_calendar>wdate BINARY SEARCH TRANSPORTING sptag.
    IF sysubrc EQ 0.
      <lfs_calendar>wdatf = ls_tempsptag.
    ENDIF.
    LOOP AT lt_dades TRANSPORTING NO FIELDS WHERE wdate = <lfs_calendar>wdate.
      lw_tabix = sytabix.
      EXIT.
    ENDLOOP.
    CLEAR ls_temp.
    READ TABLE lt_dades INTO ls_temp INDEX lw_tabix.
    IF sysubrc EQ 0.
      <lfs_calendar>wdatt = ls_tempsptag.
    ENDIF.
  ENDLOOP.

*~~~~~~~~~~~~~~~~~~~~~~~~
* STEP 8: Attributes days
*~~~~~~~~~~~~~~~~~~~~~~~~

  IF im_perkz = lc_perkztag.
    REFRESH lt_attri[].

    CALL FUNCTION ‘DAY_ATTRIBUTES_GET’
      EXPORTING
        factory_calendar           = lw_fabkl
        date_from                  = im_startdate
        date_to                    = lw_enddate
      TABLES
        day_attributes             = lt_attri
      EXCEPTIONS
        factory_calendar_not_found = 1
        holiday_calendar_not_found = 2
        date_has_invalid_format    = 3
        date_inconsistency         = 4
        OTHERS                     = 5.
    IF NOT sysubrc IS INITIAL.
      MESSAGE ID symsgid TYPE symsgty NUMBER symsgno
         WITH symsgv1 symsgv2 symsgv3 symsgv4.
    ENDIF.

    LOOP AT lt_calendar ASSIGNING <lfs_calendar>.
      READ TABLE lt_attri INTO ls_attri WITH KEY date = <lfs_calendar>wdate BINARY SEARCH.
      <lfs_calendar>wtagn = ls_attriweekday.
      <lfs_calendar>wtagt = ls_attriweekday_s.
      <lfs_calendar>wfrei = ls_attrifreeday.
    ENDLOOP.
  ENDIF.
  IF lt_calendar IS NOT INITIAL.
    ct_calendar[] = lt_calendar[].
  ENDIF.
ENDMETHOD.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.