2025년 3월 4일 화요일

[ABAP]_BOM 역전개 프로그램

 

*&---------------------------------------------------------------------*
*& Report  INVERSE_BOM_EXPLOSION
*& Inverse BOM Explosion
*&---------------------------------------------------------------------*
*&
*& BOM 역전개  : 긁어서 테스트 해 보시기바랍니다.
*&---------------------------------------------------------------------*

REPORT  y_inverse_bom_explosion.


TABLES    :stas, mara, makt, marc, t179t.

TYPE-POOLS: slis.

TYPES: BEGIN OF ty_1,
         vwalt(2)     TYPE c,
         matnr        TYPE marc-matnr,
         menge        TYPE p DECIMALS 0,
       END   OF ty_1,

       BEGIN OF ty_2,
         matnr        TYPE stpov-matnr,
         vwalt(2)     TYPE c,
         pmatnr       TYPE stpov-matnr,
         maktx        TYPE stpov-ojtxb,
         maktx1       TYPE stpov-ojtxb,
         menge        TYPE p DECIMALS 0,
         vtext        TYPE t179t-vtext,
       END   OF ty_2.

DATA : wa_store       TYPE ty_2,
       wa_gather      TYPE  ty_1,
       wa_stpov       TYPE stpov,
       wa_gather2     TYPE ty_1.


DATA : it_store       TYPE TABLE OF ty_2,
       it_gather      TYPE TABLE OF ty_1,
       it_gather2     TYPE TABLE OF ty_1,
       it_list        TYPE TABLE OF stpov,
       it_equicat     TYPE TABLE OF cscequi,
       it_kndcat      TYPE TABLE OF cscknd,
       it_matcat      TYPE TABLE OF cscmat,
       it_stdcat      TYPE TABLE OF cscstd,
       it_tplcat      TYPE TABLE OF csctpl.

DATA : g_partno       TYPE marc-matnr.
DATA : g_valdat       TYPE sy-datum.
DATA : g_lang         TYPE sy-langu.
DATA : g_index        TYPE sy-tabix.
DATA : g_cnt          TYPE sy-tfill.
DATA : g_repid        TYPE sy-repid.
DATA : g_initmenge(1) TYPE p DECIMALS 0 VALUE 1.
DATA : g_altbom(2)    TYPE c VALUE '01'.
DATA : g_abaptrue(1)  TYPE c VALUE 'X'.


DATA : wk_layout      TYPE slis_layout_alv,
       alvfld         TYPE slis_fieldcat_alv,
       fieldcat       TYPE TABLE OF slis_fieldcat_alv,
       i_sort         TYPE slis_t_sortinfo_alv,
       w_sort         LIKE LINE OF i_sort.


SELECT-OPTIONS:
       so_matnr     FOR  marc-matnr NO INTERVALS OBLIGATORY.
PARAMETERS:
       p_werks      TYPE marc-werks OBLIGATORY.

DEFINE alv_spec.

  alvfld-fieldname = &1.
  alvfld-seltext_m = &2.
  alvfld-tabname   = 'IT_STORE'.

  case &1.
    when 'VWALT'.
      alvfld-no_zero     = g_abaptrue.
    when 'MATNR'.
      w_sort-fieldname   = &1.
      w_sort-up          = g_abaptrue.
      w_sort-subtot      = g_abaptrue.
      append w_sort     to i_sort.
      clear w_sort.
    when 'MAKTX'.
      w_sort-fieldname   = &1.
      w_sort-down        = g_abaptrue.
      append w_sort     to i_sort.
      clear w_sort.
    when 'MENGE'.
      alvfld-emphasize   = 'C310'.
  endcase.

  append alvfld to fieldcat.
  clear  alvfld.

END-OF-DEFINITION.

*

INITIALIZATION.

  g_valdat = sy-datum.
  g_lang = sy-langu.
  g_repid = sy-repid.

  alv_spec 'VWALT' 'Alternative BOM'.
  alv_spec 'MATNR' 'Child_Partno'.
  alv_spec 'MAKTX' 'Child_Text'.
  alv_spec 'MENGE' 'Qty Required'.
  alv_spec 'PMATNR' 'Parent_Partno'.
  alv_spec 'MAKTX1' 'Parent_Text'.

  wk_layout-colwidth_optimize = g_abaptrue.
  wk_layout-zebra             = g_abaptrue.
  wk_layout-no_vline          = g_abaptrue.
  wk_layout-no_hline          = g_abaptrue.
  wk_layout-window_titlebar   =
           'INVERSE BILL OF MATERIAL MATRIX EXPLOSION' .

*

START-OF-SELECTION.

  LOOP AT so_matnr.
    CLEAR: g_index, g_cnt, wa_stpov, wa_gather, wa_store, g_partno.
    REFRESH: it_gather[],it_gather2[],it_equicat[],it_kndcat[].
    REFRESH: it_stdcat[],it_tplcat[],it_list[],it_matcat[].
    g_partno          = so_matnr-low.
    wa_gather-matnr   = so_matnr-low.
    wa_gather-menge   = g_initmenge.
    wa_gather-vwalt   = g_altbom.
    APPEND wa_gather TO it_gather[].
    CLEAR  wa_gather.
    PERFORM get_parts.
  ENDLOOP.

  CHECK it_store[] IS NOT INITIAL.
  PERFORM get_model_child_texts.
  SORT it_store[] BY vwalt matnr ASCENDING.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = g_repid
      is_layout          = wk_layout
      it_fieldcat        = fieldcat[]
      it_sort            = i_sort[]
    TABLES
      t_outtab           = it_store[].


*&---------------------------------------------------------------------*
*&      Form  GET_PARTS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_parts .

  CLEAR g_cnt.
  DESCRIBE TABLE it_gather LINES g_cnt.
  IF g_cnt = 0.
    EXIT.
  ENDIF.

  LOOP AT it_gather INTO wa_gather.

    CALL FUNCTION 'CS_WHERE_USED_MAT'
      EXPORTING
        datub                      = g_valdat
        datuv                      = g_valdat
        matnr                      = wa_gather-matnr
        werks                      = p_werks
      TABLES
        wultb                      = it_list[]
        equicat                    = it_equicat[]
        kndcat                     = it_kndcat[]
        matcat                     = it_matcat[]
        stdcat                     = it_stdcat[]
        tplcat                     = it_tplcat[]
      EXCEPTIONS
        call_invalid               = 1
        material_not_found         = 2
        no_where_used_rec_found    = 3
        no_where_used_rec_selected = 4
        no_where_used_rec_valid    = 5
        OTHERS                     = 6.
    CLEAR  g_cnt.
*Move to final itab
    DESCRIBE TABLE it_list[] LINES g_cnt.
    IF g_cnt = 0.
      wa_store-matnr = g_partno.
      MOVE wa_gather-matnr TO wa_store-pmatnr.
      MOVE wa_gather-vwalt TO wa_store-vwalt.
      wa_store-menge = wa_gather-menge.
      COLLECT wa_store   INTO it_store .
      CLEAR wa_store.
      CLEAR wa_gather.
    ELSE.
*Assign Alternative BOM if any ( VWALT )
      LOOP AT it_list INTO wa_stpov
              WHERE postp NE 'F' AND ( sumfg = space OR sumfg = 'x' ).
        g_index = sy-tabix.
        CHECK ( wa_stpov-vwalt = space ).
        MOVE wa_gather-vwalt TO wa_stpov-vwalt.
        MODIFY it_list INDEX g_index FROM wa_stpov TRANSPORTING vwalt.
      ENDLOOP.
      g_index = 0.
*Check if deleted from BOM Hierarchy
      LOOP AT it_list INTO wa_stpov
              WHERE postp NE 'F' AND ( sumfg = space OR sumfg = 'x' ).
        SELECT lkenz INTO (stas-lkenz)
               FROM  stas
               WHERE ( stlnr = wa_stpov-stlnr ) AND
                     ( stlkn = wa_stpov-stlkn ) AND
                     ( lkenz = g_abaptrue ).
          EXIT.
        ENDSELECT.

        IF sy-subrc NE 0.
*Material Master Deletion indicator check
          SELECT matnr INTO (mara-matnr)
                 FROM  mara
                 WHERE ( matnr EQ wa_stpov-matnr ) AND
                       ( lvorm EQ space ).
            EXIT.
          ENDSELECT.

          IF sy-subrc EQ 0.
*Prepare it_list for next level
            MOVE wa_stpov-matnr  TO wa_gather2-matnr.
            MOVE wa_stpov-vwalt  TO wa_gather2-vwalt.
            wa_gather2-menge = wa_stpov-menge * wa_gather-menge.
            COLLECT wa_gather2 INTO it_gather2.
            CLEAR   wa_gather2.
          ENDIF.

        ENDIF.

      ENDLOOP.

    ENDIF.
    REFRESH it_list[].
  ENDLOOP.

  it_gather[] = it_gather2[].
  REFRESH it_gather2[].
*Recursive process for exploding next level values
  PERFORM get_parts.

ENDFORM.                    "get_parts

*&---------------------------------------------------------------------*
*&      Form  VALIDATE_ENTRIES
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM validate_entries .

  DESCRIBE TABLE so_matnr[] LINES g_cnt.

  DO g_cnt TIMES.
    g_index = sy-index.
    READ TABLE so_matnr INDEX g_index.
    CHECK ( sy-subrc EQ 0 ).
    MOVE so_matnr-low TO g_partno.
    SELECT mara~matnr INTO (mara-matnr)
           FROM  mara INNER JOIN marc ON ( mara~matnr = marc~matnr )
           WHERE ( mara~matnr EQ g_partno ) AND
                 ( mara~mtart EQ 'HALB' )   AND
                 ( mara~lvorm EQ space )    AND
                 ( marc~werks EQ p_werks )  AND
                 ( marc~lvorm EQ space ).
      EXIT.
    ENDSELECT.
    CHECK ( sy-subrc NE 0 ).
    MESSAGE e983(zpp) WITH g_partno.
    EXIT.
  ENDDO.

ENDFORM.                    " VALIDATE_ENTRIES

*&---------------------------------------------------------------------*
*&      Form  GET_CHILD_TEXTS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_model_child_texts .

  TYPES:  BEGIN OF ty_makt,
            matnr        TYPE makt-matnr,
            maktx        TYPE makt-maktx,
          END   OF ty_makt.

  DATA : wa_makt         TYPE ty_makt,
         it_makt         TYPE TABLE OF ty_makt.

  SELECT matnr maktx
         FROM  makt  INTO TABLE it_makt
         FOR ALL ENTRIES IN it_store
         WHERE matnr = it_store-matnr
         AND   spras = g_lang.
  SELECT matnr maktx
         FROM  makt  APPENDING TABLE it_makt
         FOR ALL ENTRIES IN it_store
         WHERE matnr = it_store-pmatnr
         AND   spras = g_lang.

  CHECK   it_makt[] IS NOT INITIAL.

  SORT it_store BY matnr pmatnr ASCENDING.

  LOOP AT it_store INTO wa_store.

    g_index = sy-tabix.
    AT NEW matnr.
      READ TABLE it_makt[] INTO wa_makt WITH KEY matnr = wa_store-matnr
                           TRANSPORTING maktx.
      CHECK ( sy-subrc EQ 0 ).
      READ TABLE it_store INTO wa_store INDEX g_index.
      IF ( sy-subrc EQ 0 ).
        MOVE wa_makt-maktx TO wa_store-maktx.
        MODIFY it_store FROM wa_store TRANSPORTING maktx
                        WHERE ( matnr = wa_store-matnr ).
      ENDIF.
    ENDAT.
    READ TABLE it_makt[] INTO wa_makt WITH KEY matnr = wa_store-pmatnr
                         TRANSPORTING maktx.
    CHECK ( sy-subrc EQ 0 ).
    MOVE wa_makt-maktx TO wa_store-maktx1.
    MODIFY it_store INDEX g_index FROM wa_store TRANSPORTING maktx1.

  ENDLOOP.

ENDFORM.                    " GET_CHILD_TEXTS

댓글 없음:

댓글 쓰기