SAP BOM批量反查报表(横向动态展示)

BOM示例:

BOM层级
1A
2123
3QW
4RT
5Q
BOM层级
1B
2456
3UY
4Q


效果展示:

物料上层组件1上层组件2上层组件3上层组件4
Q1A
QRW1A
QU6B

代码执行:

*&---------------------------------------------------------------------*
*& Report
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*& Responsibility
*&---------------------------------------------------------------------*
* Program Name:  ZPPR003
* T-Code:        ZPPR003
* Date written:  2023/11/15
* Author's name: Tony Tian
* Last update:   2023/11/15
* Program title: BOM物料反查报表
* Project Name:
* Version:       v1.0

*&---------------------------------------------------------------------*
* Description: BOM物料反查报表
*&---------------------------------------------------------------------*
*

*&---------------------------------------------------------------------*
* Change History
*&---------------------------------------------------------------------*
*     Date   |   Programmer   |   Corr. #   |   Description
*            |                |             |
*            |                |             |
*&---------------------------------------------------------------------*

REPORT zppr003.

TYPE-POOLS: slis.
TABLES:
  mast,
  stko.

*&---------------------------------------------------------------------*
* TYPES
*&---------------------------------------------------------------------*
TYPES:
  BEGIN OF ty_list,
    matnr   TYPE matnr,
    matnr1  TYPE matnr,
    matnr2  TYPE matnr,
    matnr3  TYPE matnr,
    matnr4  TYPE matnr,
    matnr5  TYPE matnr,
    matnr6  TYPE matnr,
    matnr7  TYPE matnr,
    matnr8  TYPE matnr,
    matnr9  TYPE matnr,
    matnr10 TYPE matnr,
    matnr11 TYPE matnr,
    matnr12 TYPE matnr,
    matnr13 TYPE matnr,
    matnr14 TYPE matnr,
    matnr15 TYPE matnr,
    maktx   TYPE maktx,
    maktx1  TYPE maktx,
    maktx2  TYPE maktx,
    maktx3  TYPE maktx,
    maktx4  TYPE maktx,
    maktx5  TYPE maktx,
    maktx6  TYPE maktx,
    maktx7  TYPE maktx,
    maktx8  TYPE maktx,
    maktx9  TYPE maktx,
    maktx10 TYPE maktx,
    maktx11 TYPE maktx,
    maktx12 TYPE maktx,
    maktx13 TYPE maktx,
    maktx14 TYPE maktx,
    maktx15 TYPE maktx,
  END OF ty_list.

*&---------------------------------------------------------------------*
* GLOBAL DATA
*&---------------------------------------------------------------------*
DATA: lv_fieldname TYPE char30,
      lv_matnr     TYPE matnr,
      lv_count     TYPE i,
      lv_count2    TYPE i,
      lv_null      TYPE i,
      lv_stop.

DATA:t1  TYPE timestampl, "开始时时戳
     t2  TYPE timestampl, "结束时间戳
     tc1 TYPE c LENGTH 22, "开始时间戳文本
     tc2 TYPE c LENGTH 22, "结束时间戳文本
     td1 TYPE d, "开始时间:日期
     td2 TYPE d, "结束时间:日期
     th1 TYPE i, "开始时间:时
     th2 TYPE i, "结束时间:时
     tm1 TYPE i, "开始时间:分
     tm2 TYPE i, "结束时间:分
     ts1 TYPE p DECIMALS 7, "开始时间:秒(含小数部分)
     ts2 TYPE p DECIMALS 7, "结束时间:秒(含小数部分)
     tmd TYPE p DECIMALS 4. "时间差异,取6位小数

*&---------------------------------------------------------------------*
* GLOBAL INTERNAL TABLES
*&---------------------------------------------------------------------*
DATA: gt_list1 TYPE TABLE OF ty_list,
      gt_list2 TYPE TABLE OF ty_list,
      equicat  TYPE TABLE OF cscequi,
      kndcat   TYPE TABLE OF cscknd,
      matcat   TYPE TABLE OF cscmat,
      stdcat   TYPE TABLE OF cscstd,
      tplcat   TYPE TABLE OF csctpl,
      wultb    TYPE TABLE OF stpov.

DATA: dy_table TYPE REF TO data,
      gs_line  TYPE REF TO data.

FIELD-SYMBOLS: <dyn_alv>   TYPE STANDARD TABLE,
               <dyn_wa>,
               <dyn_field>.

DATA: gt_fieldcat TYPE lvc_t_fcat,
      gs_fieldcat TYPE lvc_s_fcat.
DATA: gs_layout   TYPE lvc_s_layo.

*&---------------------------------------------------------------------*
* SELECTION-SCREEN
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK bk1 WITH FRAME TITLE TEXT-001.
  PARAMETERS: p_werks TYPE mast-werks OBLIGATORY DEFAULT '2011'.
  SELECT-OPTIONS: s_matnr FOR mast-matnr OBLIGATORY.
  PARAMETERS: p_datuv TYPE stko-datuv DEFAULT sy-datum OBLIGATORY.
  PARAMETERS:r_sig TYPE char01 RADIOBUTTON GROUP g1,
             r_mut TYPE char01 RADIOBUTTON GROUP g1 DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK bk1.

*&---------------------------------------------------------------------*
*
*        MAIN PROGRAM
*
*----------------------------------------------------------------------*
START-OF-SELECTION.

  PERFORM time_calculate USING 'INIT'.

  PERFORM get_data.

  PERFORM set_fieldcat.

  PERFORM set_layout.

  PERFORM create_table.

  PERFORM display_alv.

*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
FORM get_data .

  SELECT matnr INTO TABLE gt_list1 FROM mara WHERE matnr IN s_matnr.

  SORT gt_list1 BY matnr.
  DELETE ADJACENT DUPLICATES FROM gt_list1 COMPARING matnr.

  WHILE lv_stop = abap_false.

    PERFORM time_calculate USING 'CACL'.

    lv_count = lv_count + 1. "用来动态填充 MATNR(1~15)

    IF r_sig = abap_true AND lv_count = 2.
      EXIT.
    ENDIF.

    PERFORM single_layer_up_search.

    CLEAR gt_list1.
    MOVE-CORRESPONDING gt_list2 TO gt_list1.
    CLEAR gt_list2.

  ENDWHILE.

  PERFORM get_other_data.

ENDFORM.                    " GET_DATA

*&---------------------------------------------------------------------*
*& Form single_layer_up_search
*&---------------------------------------------------------------------*
FORM single_layer_up_search .

  LOOP AT gt_list1 ASSIGNING FIELD-SYMBOL(<lfs>).

    CLEAR: lv_matnr,lv_count2,lv_fieldname,matcat.

*--> 获取上一个 MATNR
    IF lv_count = 1.
      lv_matnr = <lfs>-matnr.
    ELSE.
      lv_count2 = lv_count - 1.
      lv_fieldname = 'MATNR' && lv_count2.
      CONDENSE lv_fieldname NO-GAPS.
      ASSIGN COMPONENT lv_fieldname OF STRUCTURE <lfs> TO <dyn_field>.
      IF sy-subrc EQ 0.
        lv_matnr = <dyn_field>.
      ENDIF.
    ENDIF.

*--> 根据上一个 MATNR,进行向上展BOM
    CALL FUNCTION 'CS_WHERE_USED_MAT'
      EXPORTING
        datub                      = p_datuv
        datuv                      = p_datuv
        matnr                      = lv_matnr
        werks                      = p_werks
      TABLES
        wultb                      = wultb
        equicat                    = equicat
        kndcat                     = kndcat
        matcat                     = matcat
        stdcat                     = stdcat
        tplcat                     = 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.

*--> 如果向上展BOM失败,即停止循环
    IF matcat IS INITIAL.
      APPEND <lfs> TO gt_list2.
      lv_null = lv_null + 1.
      CONTINUE.
    ENDIF.

*--> 如果向上展BOM成功,将结果填入下一个 MATNR
    LOOP AT matcat ASSIGNING FIELD-SYMBOL(<matcat>).

      CLEAR:lv_fieldname.
      lv_fieldname = 'MATNR' && lv_count.
      CONDENSE lv_fieldname NO-GAPS.
      ASSIGN COMPONENT lv_fieldname OF STRUCTURE <lfs> TO <dyn_field>.
      IF sy-subrc EQ 0.
        <dyn_field> = <matcat>-matnr.
      ENDIF.

      APPEND <lfs> TO gt_list2.

    ENDLOOP.

  ENDLOOP.

*--> 判断所有行是否向上展失败,失败停止全局循环,成功继续下一个循环
  DATA(lv_line) = lines( gt_list2 ).

  IF lv_line = lv_null.
    lv_stop = abap_true.
    EXIT.
  ENDIF.

  CLEAR: gt_list1,lv_null.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form get_other_data
*&---------------------------------------------------------------------*
FORM get_other_data .

  DATA: lv_value(20),
        lv_filed1(70),
        lv_filed2(70),
        lv_where(100),
        lv_count TYPE i.

  DEFINE %%select_maktx.

    SELECT SINGLE maktx INTO (&1) FROM makt WHERE (&2).

  END-OF-DEFINITION.

  LOOP AT gt_list1 ASSIGNING FIELD-SYMBOL(<lfs>).

    CLEAR lv_count.

    DO 16 TIMES.

      IF sy-index = '1'.
        lv_value  = '<lfs>-maktx'.
        lv_filed2 = 'maktx'.
        lv_where  = 'matnr = <lfs>-matnr AND spras = ''1'''.
      ELSE.
        lv_count  = lv_count + 1.
        lv_value  = '<lfs>-maktx' && lv_count.
        lv_filed1 = '<lfs>-matnr' && lv_count.
        lv_filed2 = 'maktx' && lv_count.
        CONCATENATE 'matnr' '=' lv_filed1 'AND' 'spras' '=' '1' INTO lv_where SEPARATED BY ' '.
      ENDIF.

      %%select_maktx: lv_value lv_where.

      ASSIGN COMPONENT lv_filed2 OF STRUCTURE <lfs> TO <dyn_field>.
      IF sy-subrc EQ 0.
        <dyn_field> = lv_value.
      ENDIF.

      CLEAR: lv_value,lv_where,lv_filed1,lv_filed2.

    ENDDO.

  ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form set_fieldcat
*&---------------------------------------------------------------------*
FORM set_fieldcat .

  DATA: lv_index TYPE i.

  PERFORM get_max_column CHANGING lv_index.

  REFRESH gt_fieldcat.
  DEFINE  init_fill_fcat.
    CLEAR gs_fieldcat.
    gs_fieldcat-fieldname  = &1.
    gs_fieldcat-coltext    = &2.
    gs_fieldcat-scrtext_l  = &2.
    gs_fieldcat-scrtext_m  = &2.
    gs_fieldcat-scrtext_s  = &2.
    gs_fieldcat-reptext    = &2.
    gs_fieldcat-ref_table  = &3.
    gs_fieldcat-ref_field = &4.
    gs_fieldcat-f4availabl = &5.
    gs_fieldcat-icon   = &6.
    gs_fieldcat-edit = &7.
    gs_fieldcat-no_zero  = &8.
    gs_fieldcat-inttype  = &9.
    APPEND gs_fieldcat TO gt_fieldcat.
  END-OF-DEFINITION.

  DATA:lv_fieldname1 TYPE char30.
  DATA:lv_fieldname2 TYPE char30.

  init_fill_fcat 'MATNR' '物料' 'MARA' 'MATNR' '' '' '' 'X' ''.
  init_fill_fcat 'MAKTX' '物料描述' 'MAKT' 'MAKTX' '' '' '' 'X' ''.
  "循环最多行项目的行数
  DO lv_index TIMES.
    CLEAR:lv_fieldname.
    lv_fieldname1 = 'MATNR' && sy-index.
    lv_fieldname2 = '上层组件' && sy-index.
    init_fill_fcat lv_fieldname1 lv_fieldname2 'MARA' 'MATNR' '' '' '' 'X' ''.

    CLEAR:lv_fieldname.
    lv_fieldname1 = 'MAKTX' && sy-index.
    lv_fieldname2 = '上层组件' && sy-index && '描述'.
    init_fill_fcat lv_fieldname1 lv_fieldname2 'MAKT' 'MAKTX' '' '' '' 'X' ''.
  ENDDO.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form set_layout
*&---------------------------------------------------------------------*
FORM set_layout .

  CLEAR gs_layout.
  gs_layout-sel_mode   = 'A'.     "选择行模式
  gs_layout-cwidth_opt = 'A'.     "优化列宽设置
  gs_layout-zebra      = 'X'.     "设置斑马线

ENDFORM.

*&---------------------------------------------------------------------*
*& Form create_table
*&---------------------------------------------------------------------*
FORM create_table .

  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = gt_fieldcat
    IMPORTING
      ep_table        = dy_table.
  ASSIGN dy_table->* TO <dyn_alv>.    " 用表类型指针 <dyn_table> 指向 数据对象的内容.

  CREATE DATA gs_line LIKE LINE OF <dyn_alv>.  " 建立一个与动态内表结构相同的数据对象,且数据对象为是一个结构
  ASSIGN gs_line->* TO <dyn_wa>. " 用<dyn_wa>指针指向该结构

  MOVE-CORRESPONDING gt_list1 TO <dyn_alv>.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form display_alv
*&---------------------------------------------------------------------*
FORM display_alv .

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program = sy-repid
      is_layout_lvc      = gs_layout
*     i_callback_pf_status_set = 'FRM_SET_STATUS'
*     i_callback_user_command  = 'FRM_USER_COMMAND'
      it_fieldcat_lvc    = gt_fieldcat
      i_save             = 'A'
    TABLES
      t_outtab           = <dyn_alv>
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form get_max_column
*&---------------------------------------------------------------------*
FORM get_max_column  CHANGING lv_index TYPE i.

  DATA: lv_filed(7),
        lv_filed_count TYPE i,
        lv_where(250).

  DATA: lt_list TYPE TABLE OF ty_list.

  DEFINE %%select_max.

    SELECT (&1) FROM @gt_list1 AS t WHERE (&2) INTO TABLE @lt_list.

  END-OF-DEFINITION.

  WHILE lt_list IS INITIAL.

    lv_filed_count = lv_filed_count + 1.
    lv_filed = 'MATNR' && lv_filed_count.
    CONDENSE lv_filed.
    CONCATENATE lv_filed 'IS' 'NOT' 'INITIAL' INTO lv_where SEPARATED BY ' '.

    %%select_max: lv_filed lv_where.

    IF lt_list IS INITIAL.
      EXIT.
    ENDIF.
    lv_index = lv_index + 1.
    CLEAR lt_list.

  ENDWHILE.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form time_calculate
*&---------------------------------------------------------------------*
FORM time_calculate  USING p_value.

  CASE p_value.

    WHEN 'INIT'.

      GET TIME STAMP FIELD t1.
      tc1 = t1.
      td1 = tc1+0(8).
      th1 = tc1+8(2).
      tm1 = tc1+10(2).
      ts1 = tc1+12(10).

    WHEN 'CACL'.

      GET TIME STAMP FIELD t2.
      tc2 = t2.
      td2 = tc2+0(8).
      th2 = tc2+8(2).
      tm2 = tc2+10(2).
      ts2 = tc2+12(10).

      tmd = ( td2 - td1 ) * 24 * 3600 + ( th2 - th1 ) * 3600 + ( tm2 - tm1 ) * 60 + ( ts2 - ts1 ).

      IF tmd > '1800'.
        MESSAGE '报表运行时间超过30分钟,程序自动停止!请减少料号输入量!' TYPE 'E'.
      ENDIF.

  ENDCASE.

ENDFORM.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值