导读:最近和BOM物料干上了,记录一下我的开发过程和学到的东西。

顺查BOM物料下的所有层级物料

方法一:通过函数“CS_BOM_EXPL_MAT_V2”;

代码例子如下:(有效期可以通过MAST表去STKO表去获取)

"函数递归 获取BOM物料组件
  CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
    EXPORTING
      capid                 = 'PP01' "bom类型
      datuv                 = datua "有效期
      mdmps                 = ''  " 限制字段:限制BOM只展1层,但下层是虚拟件的则再往下展开一层,默认为空不限制
      mehrs                 = 'X'  " 重要字段:BOM多级展开,默认为空,只展开一层 多阶展开 'X'-多阶; ''-单阶
      mtnrv                 = s_matnr " 必须字段:物料号
      werks                 = s_werks " 必须字段:工厂号
      stpst                 = 0
    TABLES
      stb                   = gt_stb    " 必须接收的表:BOM展开明细
      matcat                = gt_matcat    " 父级物料清单:参与BOM展开的父级物料清单,即含有组件的物料
    EXCEPTIONS
      alt_not_found         = 1
      call_invalid          = 2
      material_not_found    = 3
      missing_authorization = 4
      no_bom_found          = 5
      no_plant_data         = 6
      no_suitable_bom_found = 7
      conversion_error      = 8
      OTHERS                = 9.

值得注意的是gt_matcat-index = gt_stb-ttidx.(根据这个关系可以获取到某个物料的组件)

方法二:直接联表查询(一般不用这个方法,麻烦且需要标记物料层级)

由于不常用,这里只是简单过一下。

1、从MAST表获取BOM的物料清单,根据物料清单去查询STPO表从而获取1层的物料组件,(订单数量在STKO表),

2、利用递归的方法,对第一层的子组件逐一遍历,类似的再去查询MAST表和STPO表,获取2层的物料组件

3、以此类推。。。。

4、直至所有层数遍历完成即可。

OO TREE ALV展示BOM物料层级步骤说明

全局变量定义如下:

DATA: tree1 TYPE REF TO cl_gui_alv_tree.      "树控件
DATA: l_custom_container TYPE REF TO cl_gui_custom_container. "自定义容器

DATA:ok_code TYPE sy-ucomm,
     my_code TYPE sy-ucomm.

DATA: gt_fieldcat TYPE TABLE OF lvc_s_fcat,
      gs_fieldcat TYPE lvc_s_fcat.

DATA:gt_stpo_alv  TYPE TABLE OF STPOX.


字段设置宏定义代码
 

*定义宏
DEFINE fieldcat.
  CLEAR:gs_fieldcat.
      gs_fieldcat-just = 'C'.               "C居中对齐、L左边对齐、R右边对齐
      gs_fieldcat-fieldname = &1.      "标识对应的字段名
      gs_fieldcat-coltext   = &2.       "列标题
      gs_fieldcat-seltext   = &2.       "对话功能的列标识符,影响的是点击筛选按钮时,弹出的选择屏幕中的字段描述
      gs_fieldcat-ref_table = &3.   "内部表字段的参考表名称
      gs_fieldcat-ref_field = &4.   "内部表字段的参考字段名称
      gs_fieldcat-edit = &5.       "列是否可编辑
      gs_fieldcat-col_opt = &6.     "字段级优化列宽
      gs_fieldcat-key = &7.         "固定列
      gs_fieldcat-emphasize = &8.         "列颜色
      gs_fieldcat-outputlen = &9.         "指定列宽度
      APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.

新建屏幕9000

创建自定义容器 TREE1

在PBO模块初始化容器以及控件

MODULE status_9000 OUTPUT.
  IF tree1 IS INITIAL.
    PERFORM frm_init_alv_tree.
  ENDIF.
  CALL METHOD cl_gui_cfw=>flush.
ENDMODULE.

*--------------------------------------------------------------------*
* form : 初始化树
*--------------------------------------------------------------------*
FORM frm_init_alv_tree.
  CREATE OBJECT l_custom_container
    EXPORTING
      container_name = 'TREE1'.

  CREATE OBJECT tree1
    EXPORTING
      parent              = l_custom_container
      node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
      item_selection      = 'X'
      no_html_header      = 'X'
      no_toolbar          = ' '.

  "获取BOM 物料信息
  "函数递归 获取BOM物料组件
  CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
    EXPORTING
      capid                 = 'PP01' "bom类型
      datuv                 = datua "有效期
      mdmps                 = ''  " 限制字段:限制BOM只展1层,但下层是虚拟件的则再往下展开一层,默认为空不限制
      mehrs                 = 'X'  " 重要字段:BOM多级展开,默认为空,只展开一层 多阶展开 'X'-多阶; ''-单阶
      mtnrv                 = s_matnr " 必须字段:物料号
      werks                 = s_werks " 必须字段:工厂号
      stpst                 = 0
    TABLES
      stb                   = gt_stb    " 必须接收的表:BOM展开明细
      matcat                = gt_matcat    " 父级物料清单:参与BOM展开的父级物料清单,即含有组件的物料
    EXCEPTIONS
      alt_not_found         = 1
      call_invalid          = 2
      material_not_found    = 3
      missing_authorization = 4
      no_bom_found          = 5
      no_plant_data         = 6
      no_suitable_bom_found = 7
      conversion_error      = 8
      OTHERS                = 9.

  DATA l_hierarchy_header TYPE treev_hhdr.
  PERFORM build_hierarchy_header CHANGING l_hierarchy_header.
  PERFORM build_fieldcatalog.
  DATA: ls_variant TYPE disvariant.
  ls_variant-report = sy-repid.

  CALL METHOD tree1->set_table_for_first_display
    EXPORTING
      is_hierarchy_header = l_hierarchy_header
      i_background_id     = 'ALV_BACKGROUND'
      i_save              = 'A'
      is_variant          = ls_variant
    CHANGING
      it_outtab           = gt_stpo_alv
      it_fieldcatalog     = gt_fieldcat.

  DATA: l1         TYPE lvc_nkey,l2 TYPE lvc_nkey,l3 TYPE lvc_nkey,l4 TYPE lvc_nkey,
        l5         TYPE lvc_nkey,l6 TYPE lvc_nkey,l7 TYPE lvc_nkey,l8 TYPE lvc_nkey,l9 TYPE lvc_nkey,l10 TYPE lvc_nkey,
        l_key      TYPE lvc_nkey,
        l_last_key TYPE lvc_nkey,
        added .
  "遍历组件、向TREE1控件填充叶子节点
  LOOP AT gt_stb INTO gs_stb.
    CASE gs_stb-stufe .
      WHEN '0'.
        l_key = ''.
      WHEN '1'.
        l_key = l1.
      WHEN '2'.
        l_key = l2.
      WHEN '3'.
        l_key = l3.
      WHEN '4'.
        l_key = l4.
      WHEN '5'.
        l_key = l5.
      WHEN '6'.
        l_key = l6.
      WHEN '7'.
        l_key = l7.
      WHEN '8'.
        l_key = l8.
      WHEN '9'.
        l_key = l9.
      WHEN '10'.
        l_key = l10.
    ENDCASE.
    PERFORM add_complete_line USING  l_key
                            CHANGING l_last_key gs_stb .
    CASE gs_stb-stufe .
      WHEN '0'.
        l1 = l_last_key.
      WHEN '1'.
        l2 = l_last_key.
      WHEN '2'.
        l3 = l_last_key.
      WHEN '3'.
        l4 = l_last_key.
      WHEN '4'.
        l5 = l_last_key.
      WHEN '5'.
        l6 = l_last_key.
      WHEN '6'.
        l7 = l_last_key.
      WHEN '7'.
        l8 = l_last_key.
      WHEN '8'.
        l9 = l_last_key.
      WHEN '9'.
        l10 = l_last_key.
    ENDCASE.
    MODIFY gt_stb FROM gs_stb .
  ENDLOOP.
  CALL METHOD tree1->update_calculations.
  CALL METHOD tree1->frontend_update.
ENDFORM.

*--------------------------------------------------------------------*
* form : 表头设置
*--------------------------------------------------------------------*
FORM build_hierarchy_header CHANGING
                             p_hierarchy_header TYPE treev_hhdr.
  p_hierarchy_header-heading = 'BOM层次'.
  p_hierarchy_header-tooltip = 'ToolTip'.
  p_hierarchy_header-width = 40.
  p_hierarchy_header-width_pix = 'X'.
ENDFORM.

*--------------------------------------------------------------------*
* form : 字段设置
*--------------------------------------------------------------------*
FORM build_fieldcatalog.
  fieldcat 'IDNRK' '物料编号' 'MARC' 'MATNR' '' 'X' '' '' '40'.
  fieldcat 'OJTXP' '物料描述' 'MAKT' 'MAKTX' '' 'X' '' '' '65'.
ENDFORM.

*--------------------------------------------------------------------*
* form : 向子节点追加数据
*--------------------------------------------------------------------*
FORM add_complete_line USING
                               p_relat_key TYPE lvc_nkey
                     CHANGING  p_node_key TYPE lvc_nkey ps_stpox TYPE STPOX.
  DATA: l_node_text TYPE lvc_value.
  DATA: lt_item_layout TYPE lvc_t_layi,
        ls_item_layout TYPE lvc_s_layi.
  ls_item_layout-fieldname = tree1->c_hierarchy_column_name.
  ls_item_layout-class     = cl_gui_column_tree=>item_class_text.
  APPEND ls_item_layout TO lt_item_layout.
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
    EXPORTING
      input  = ps_stpox-IDNRK
    IMPORTING
      output = ps_stpox-IDNRK.

  l_node_text =  ps_stpox-IDNRK.
  CALL METHOD tree1->add_node
    EXPORTING
      i_relat_node_key = p_relat_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      is_outtab_line   = ps_stpox
      i_node_text      = l_node_text
      it_item_layout   = lt_item_layout
    IMPORTING
      e_new_node_key   = p_node_key.
ENDFORM.

注意:gt_stpo_alv这个表必须是空的,否则显示的数据会出错,至于表结构跟随STPOX表即可

还有别漏了后面刷新的两行代码,不要问我为啥知道,都是泪。

 做完这里后来到屏幕的PAI模块

MODULE user_command_9000 INPUT.
  my_code = ok_code.
  CLEAR ok_code.

  CASE my_code.
    WHEN 'E' OR 'ENDE' OR 'ECAN'.
      "释放容器,退出程序
      CALL METHOD l_custom_container->free.
      CLEAR l_custom_container.
      CLEAR tree1.


      LEAVE TO SCREEN 0.
    WHEN OTHERS.
      "为正确调用工具栏按钮功能,必须调用该方法
      CALL METHOD cl_gui_cfw=>dispatch.
  ENDCASE.
  CALL METHOD cl_gui_cfw=>flush.
ENDMODULE.

请注意,此处必须释放容器,不然TREE ALV只会渲染一次,下一次调用还是上一次的数据。

至此,完毕!已经尽可能的简化步骤了,网上的资料都是步骤很繁琐的。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐