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.
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.