Skip to Content

Finding the Constraint

Capacity evaluation in PP

Introduction:

The topic of this blog post is to show you how can SAP PP help you to find the constraint on the shop floor.

If you use ToC (Theory of Constraint) in your plant or you would like to or you are at least aware of ToC and its principles then you know that its keystone is knowing your constraint. How to find a constraint in your production using SAP, that is the topic of my post.

 

How you can do it?

In SAP PP there are standard transactions for capacity evaluation and planning like CM01 and other CMXX transactions using actual data and CM38 for Planning Scenarios. Working with these TAs to get the overall picture about the distribution of capacity loads and overloads across the entire plant is quite challenging. That was the reason I decided to build my own tool which I could customize to my own requirements. From the beginning of my journey, I was trying to use SAP function module CY_FILL_KUBEL. Without having the right documentation, it was hard and almost impossible to get what I wanted. Eventually, I decided to take another approach.

In the coding below you can see my way through with all needed notes. The function of the code is very simple and straightforward. Through parameters you can select capacity IDs and the time area (from, to) you are focusing on. Then it provides the basic tables for each selected ID with available capacity for time period chosen above and with a time grid selected by the parameter p_peart ( Methode get_available => FM  ‘CR_CAPACITY_PERIODS’ and ‘CR_CAPACITY_AVAILABLE_PERIODS’ ). You can choose whether to go on with a sum from the table (as in my case) or to use load_tab for details according to your preferences and time grid.  The next method provides a sum of all capacity requirements for the capacity ID and time area (expanded by backlog, which is set by the parameter p_back) using the internal table lt_kbeds. The function module ‘CY_AMOUNT_KBED_COMPUTE’ provides the exact amount of the duration for each working step according to settings in work-centre master data. In the last step, the sum of capacity requirements and available capacity are divided to get the percentage of the capacity load.

Here is my coding….

 

*&---------------------------------------------------------------------*
*& Report  zcapaload
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zcapaload.
DATA: wa_kapid TYPE kapid.
SELECT-OPTIONS:sl_kapid FOR wa_kapid."range for kapid
PARAMETERS: p_werk TYPE werks-werks DEFAULT '013'. " your plant

PARAMETERS: p_from TYPE sy-datum DEFAULT sy-datum,  "parameters for time area to evaluate
            p_to TYPE sy-datum .

PARAMETERS:            p_plscn TYPE plscn, " for Planning Scenario
            p_peart TYPE daper DEFAULT 'C', " for Entry type "A = day; C = week; D = month
            p_back TYPE i DEFAULT 30. " for backlog -> how far in the history / how many days back

CLASS lcl_kapid DEFINITION CREATE PRIVATE.

  PUBLIC SECTION.
       TYPES:     " for main itab 
       BEGIN OF t_loads,
               kapid  TYPE kapid, "capacity id
               arbpl TYPE arbpl, "if capacity id goes with work-center, you can mine the number
               name TYPE kako-name, "if capacity id goes with (Pool) capacity, you can mine the name
               sum_load TYPE kbed-kruerest, " the sum of capacity requirements
               sum_avail TYPE kbed-kruerest, " the sum of capacity available
               load_prct TYPE p LENGTH 5 DECIMALS 2, "load in % 
             END OF t_loads.
       TYPES: tt_loads TYPE STANDARD TABLE OF t_loads WITH DEFAULT KEY.
      TYPES BEGIN OF t_kbeds.  " for capacity requirements evaluation
        INCLUDE  TYPE kbed .
        TYPES:   duration TYPE kbed-kruerest, "for duration of the capacity requirements in second
              END OF t_kbeds.

    CLASS-DATA: lt_loads TYPE tt_loads,
                lt_kbeds TYPE HASHED TABLE OF t_kbeds WITH UNIQUE KEY kapid bedid bedzl canum.
    CLASS-METHODS class_constructor.

    CLASS-METHODS get_table.
    METHODS constructor IMPORTING is_loads TYPE t_loads.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-METHODS get_loads.
    DATA: loads TYPE t_loads.
    METHODS: get_data RETURNING VALUE(rs_loads) TYPE t_loads,
             get_available,
             get_requirements.
ENDCLASS.


CLASS lcl_kapid IMPLEMENTATION.

  METHOD constructor.
   loads = is_loads.
  ENDMETHOD.

  METHOD class_constructor.
      SELECT * FROM kako INTO CORRESPONDING FIELDS OF TABLE lt_loads WHERE kapid IN sl_kapid AND werks = p_werk.
  ENDMETHOD.


  METHOD get_table.
    get_loads( ). " at first we mine all requirements for time area and plant and for Planning Scenario if selected
    LOOP AT lt_loads ASSIGNING FIELD-SYMBOL(<fs_loads>). " the next step is getting capacity requirements and available for specifically capacity id
     DATA(lo) = NEW lcl_kapid( <fs_loads> ).
     <fs_loads> = lo->get_data( ).
    ENDLOOP.
  ENDMETHOD.


  METHOD get_loads.
          SELECT * FROM kbed APPENDING TABLE lt_kbeds
               FOR ALL ENTRIES IN lt_loads
               WHERE kapid = lt_loads-kapid
                 AND sstad <= p_to
                 AND sendd >= p_from
                 AND plscn = p_plscn
                 AND NOT keinh IS NULL
                 AND ( canumf = '0000' OR
                       canumf IS NULL ).
            SORT lt_kbeds BY kapid.
  ENDMETHOD.

  METHOD get_data.
    get_available( ).
    get_requirements( ).
    loads-load_prct = ( loads-sum_load / loads-sum_avail ) * 100. "get load in %
    rs_loads = loads.
  ENDMETHOD.


  METHOD get_available.
        DATA:  load_tab TYPE TABLE OF rc65k.
* Create period for each day (shifts can be different by day):
  CALL FUNCTION 'CR_CAPACITY_PERIODS'
    EXPORTING
      datub         = p_to
      datuv         = p_from
*       KAPEL         = ' '
      kapid         = loads-kapid
*       MRPCAL        = ' '
*       PEANZ         = '000'
      peart         = p_peart  "A = day; C = week; D = month
*       PEBEG         = ' '
*       PEDAU         = '000'
*       VERSN         =
*       ZRAST         = ' '
    TABLES
      t_per         = load_tab.

* Get available capacity for each day by shift:
  CALL FUNCTION 'CR_CAPACITY_AVAILABLE_PERIODS'
    EXPORTING
      exact_breaks              = 'X'
      shifts                    = 'X'
      unit_si                   = 'X'      "in seconds
    TABLES
      t_avail                   = load_tab
    EXCEPTIONS
      hierarchy_not_found       = 1
      object_not_in_hierarchy   = 2
      version_without_hierarchy = 3
      parameter_not_with_time   = 4
      OTHERS                    = 5.
**get sum
  LOOP AT load_tab ASSIGNING FIELD-SYMBOL(<fs_load>).
   loads-sum_avail = loads-sum_avail + <fs_load>-angeb.
   ENDLOOP.
  ENDMETHOD.


  METHOD get_requirements.
  DATA:    ls_prevod TYPE kbedd,
           ls_duration TYPE cx_duration_sec,
           backlog TYPE sy-datum.
  backlog = p_from - p_back. "date for backlog withdraw


      LOOP AT lt_kbeds ASSIGNING FIELD-SYMBOL(<fs_kbeds>) WHERE kapid = loads-kapid.
        MOVE-CORRESPONDING <fs_kbeds> TO ls_prevod.
     CALL FUNCTION 'CY_AMOUNT_KBED_COMPUTE'
  EXPORTING
    in_kbed                      = ls_prevod
 IMPORTING
   ex_requirement_sec           = ls_duration
 EXCEPTIONS
   duration_initial             = 1
   unit_conversion_error        = 2
   schedule_error               = 3
   OTHERS                       = 4  .
        IF sy-subrc <> 0.
          ls_duration  = 1.
        ENDIF.
        loads-sum_load = loads-sum_load + ls_duration.
        CLEAR: ls_prevod,ls_duration.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_kapid=>get_table( ).

Conclusion:

If it is run through all your capacity IDs you can get the ID with the highest load for the time interval which shall be than your constraint you are looking for.  With this constraint, according to ToC, you can proceed to 5 focusing steps where SAP can help you too. But this topic is for another blog post.  🙂

Regards

Jarda

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. ANAND SHUKLA

    Hi Jaroslav Hrbacek,

    Thank you for sharing such article with code.

    But it will great help from your side if you can also attach output screen after this enhancement, so it may get very picture for us.

     

     

    (0) 
  2. Jaroslav Hrbacek Post author

    Hi Anand Shukla,

    this is great with SAP. Once you have the data (as in our case the itab lt_load), you can use them everywhere. (graphic classes- alv, hierarchical table, graph etc)

    In our company, we have various ways for evaluating these data. see pictures:

    (0) 

Leave a Reply