Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

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.

The output table structure will be defined as

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

  FIELD-SYMBOLS:<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_period-perkz = lc_perkztag.
    ls_period-perid = 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 sy-subrc IS INITIAL.
    MESSAGE e089(zmop) WITH 'MC_ADD_ERTAG_AND_ATAGE' sy-subrc
       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_period-atage = 1.
* Date must be working
    CHECK ls_period-perid = ls_period-ertag.
* Daily Value Park
    ls_calendar-sptag = ls_period-ertag.
* Monthly Value Park
    ls_calendar-spmon = ls_period-ertag+0(6).
* Annual value of stop
    ls_calendar-spjah = ls_period-ertag+0(4).

* Weekly values ​​stop
    CALL FUNCTION 'DATE_GET_WEEK'
      EXPORTING
        date         = ls_calendar-sptag
      IMPORTING
        week         = ls_calendar-spwoc
      EXCEPTIONS
        date_invalid = 1
        OTHERS       = 2.
    IF NOT sy-subrc IS INITIAL.
      MESSAGE e012(zmop) WITH 'DATE_GET_WEEK' sy-subrc
         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 sy-tabix = 1.
* Periodenraster als Merker für Arbeitstage
* Period as a marker for scanning business days
      REFRESH lt_period[].
      CLEAR   ls_period.

      lw_spwoc = ls_calendar-spwoc.
      lw_spmon = ls_calendar-spmon.
      lw_spjah = ls_calendar-spjah.
      CLEAR lw_atwoc.
      CLEAR lw_atmon.
      CLEAR lw_atjah.
    ENDIF.

* Working days of the week conserve
    IF NOT ls_calendar-spwoc = lw_spwoc.
      ls_period-perkz = lc_perkzwoche.
      ls_period-perid = lw_spwoc.
      ls_period-atage = lw_atwoc.
      APPEND ls_period TO lt_period.
      CLEAR lw_atwoc.
      lw_spwoc = ls_calendar-spwoc.
    ENDIF.

* Preserve working day of the month
    IF NOT ls_calendar-spmon = lw_spmon.
      ls_period-perkz = lc_perkzmonat.
      ls_period-perid = lw_spmon.
      ls_period-atage = lw_atmon.
      APPEND ls_period TO lt_period.
      CLEAR lw_atmon.
      lw_spmon = ls_calendar-spmon.
    ENDIF.

* Working days of the year, preserving
    IF NOT ls_calendar-spjah = lw_spjah.
      ls_period-perkz = lc_perkzjahr.
      ls_period-perid = lw_spjah.
      ls_period-atage = lw_atjah.
      APPEND ls_period TO lt_period.
      CLEAR lw_atjah.
      lw_spjah = ls_calendar-spjah.
    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_period-perkz = lc_perkzwoche.
  ls_period-perid = lw_spwoc.
  ls_period-atage = lw_atwoc.
  APPEND ls_period TO lt_period.

* Preserve working day of the month
  ls_period-perkz = lc_perkzmonat.
  ls_period-perid = lw_spmon.
  ls_period-atage = lw_atmon.
  APPEND ls_period TO lt_period.

* Arbeitstage des Jahres konservieren
* Working days of the year, preserving
  ls_period-perkz = lc_perkzjahr.
  ls_period-perid = lw_spjah.
  ls_period-atage = 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 sy-subrc EQ 0.
      <lfs_calendar>-atwoc = ls_period-atage.
    ENDIF.
* Working day month
    READ TABLE lt_period INTO ls_period WITH KEY perkz = lc_perkzmonat
                                  perid = <lfs_calendar>-spmon.
    IF sy-subrc EQ 0.
      <lfs_calendar>-atmon = ls_period-atage.
    ENDIF.
* Working days a year
    READ TABLE lt_period INTO ls_period WITH KEY perkz = lc_perkzjahr
                                                 perid = <lfs_calendar>-spjah.
    IF sy-subrc EQ 0.
      <lfs_calendar>-atjah = ls_period-atage.
    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 sy-subrc EQ 0.
      <lfs_calendar>-wdatf = ls_temp-sptag.
    ENDIF.
    LOOP AT lt_dades TRANSPORTING NO FIELDS WHERE wdate = <lfs_calendar>-wdate.
      lw_tabix = sy-tabix.
      EXIT.
    ENDLOOP.
    CLEAR ls_temp.
    READ TABLE lt_dades INTO ls_temp INDEX lw_tabix.
    IF sy-subrc EQ 0.
      <lfs_calendar>-wdatt = ls_temp-sptag.
    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 sy-subrc IS INITIAL.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
         WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    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_attri-weekday.
      <lfs_calendar>-wtagt = ls_attri-weekday_s.
      <lfs_calendar>-wfrei = ls_attri-freeday.
    ENDLOOP.
  ENDIF.
  IF lt_calendar IS NOT INITIAL.
    ct_calendar[] = lt_calendar[].
  ENDIF.
ENDMETHOD.