实战BADI程序-MD_EXPORT_TREE
摘自:http://www.itpub.net/thread-1202518-1-2.html
BADI: (Business Add-Ins) SAP新的系统增强技术. 
为了更深入的学习SAP程序设计, 共享编程经验. 现将实际工作中的程序做成教程发布出来,与大家共同探讨实际工作遇到的问题以及好的解决方案.
以下程序为MRP库存需求列表的BADI增强(MD_EXPORT_TREE): 启用此增强后,在MD04,MD05展开工单时会出现一个按钮可以导出工单报告:
事务码SE18:创建BADI实现:
<ignore_js_op> 
 
点击Display:
<ignore_js_op> 
 
点击 <ignore_js_op> 创建BADI实现:
 创建BADI实现:
<ignore_js_op> 
 
命名一个实现类并指定一个要实现的BADI(MD_EXPORT_TREE):
<ignore_js_op> 
 
执行后出现:
<ignore_js_op> 
 
因为我们并没有创建模板实现类,所以要选择Empty Class定义一个新的实现, 在IDES中默认有一个实现类,可以选择它并执行Copy sample class 并按照我们自己的需要创建一个实现
执行后保存到系统
<ignore_js_op> 
 
展开ZMD_EXPORT_TREE并双击Implementing Class以修改创建的实现类:
<ignore_js_op> 
 
双击方法IF_EX_MD_EXPORT_TREE~EXPORT_TREE或点击更改按钮实现此方法:
以下程序就是这篇文档中要用到的程序, 在这里我是调用另外一个程序显示工单报告:
method IF_EX_MD_EXPORT_TREE~EXPORT_TREE.
  DATA: lt_fieldcat    TYPE lvc_t_fcat,
        lt_tree_lines  TYPE md_t_tree_struc.
  lt_fieldcat[]   = it_fieldcat[].
  lt_tree_lines[] = it_tree_lines[].
  EXPORT p_fieldcat FROM lt_fieldcat TO MEMORY ID 'lt_fieldcat'. "通过指针导出参数
  EXPORT p_tree_lines FROM lt_tree_lines TO MEMORY ID 'lt_tree_lines'. "通过指针导出参数
  SUBMIT ZSCR_EXPORT_TREE AND RETURN.
endmethod.
如果你想更快的看到这个BADI的实现那么以下程序可以实现,拷贝自SAP系统自带实例:
METHOD IF_EX_MD_EXPORT_TREE~EXPORT_TREE.
* This example implementation creates a small ALV table based on
* the content of the order report tree. This table is printed using the
* print object of the ALV table.
* type including fields to be printed
  TYPES: BEGIN OF table_type,
           node        TYPE lvc_nkey,
           parent_node TYPE lvc_nkey,
           matnr       TYPE matnr,
           berid       TYPE berid,
           werks       TYPE werks_d,
           bbdat       TYPE dat00,
           delb0       TYPE delb0,
           delnr       TYPE del12,
           delps       TYPE delps,
           rcdat       TYPE dat00,
           rceb0       TYPE delb0,
           rcenr       TYPE del12,
           rceps       TYPE delps,
           err01       TYPE aussl,
           msgxx       TYPE msgxx,
         END OF table_type.
* table type including fields to be printed
  TYPES: t_table_type TYPE STANDARD TABLE OF table_type.
* local references to objects
  DATA: lr_table       TYPE REF TO cl_salv_table,
        lr_columns     TYPE REF TO cl_salv_columns,
        lr_print_obj   TYPE REF TO cl_salv_print.
* local internal tables
  DATA: lt_fieldcat    TYPE lvc_t_fcat,
        lt_tree_lines  TYPE md_t_tree_struc,
        lt_tree_small  TYPE t_table_type.
* local structures
  DATA: ls_tree_lines  TYPE mdtreestruc,
        ls_tree_small  TYPE table_type.
* transfer imported tables into local tables
  lt_fieldcat[]   = it_fieldcat[].
  lt_tree_lines[] = it_tree_lines[].
* don't print all columns of the tree; create smaller table
  LOOP AT lt_tree_lines INTO ls_tree_lines.
    MOVE-CORRESPONDING ls_tree_lines TO ls_tree_small.
    APPEND ls_tree_small TO lt_tree_small.
  ENDLOOP.
* create ALV table
  TRY.
      cl_salv_table=>factory(
        EXPORTING
          list_display = abap_true
        IMPORTING
          r_salv_table = lr_table
        CHANGING
          t_table      = lt_tree_small ).
    CATCH cx_salv_msg.                                  "#EC NO_HANDLER
  ENDTRY.
* optimize column width
  lr_columns = lr_table->get_columns( ).
  lr_columns->set_optimize( abap_true ).
* get print object of table
  lr_print_obj = lr_table->get_print( ).
* ALV should be printed only but not displayed on the screen
  CALL METHOD lr_print_obj->set_print_only
    EXPORTING
      value = abap_true.
* print the table
  lr_table->display( ).
ENDMETHOD.
如果你不是拷贝以上实例程序那么请继续:
创建BADI调用的显示报告的程序ZSCR_EXPORT_TREE:
事务码SE38:
<ignore_js_op> 
 
保存好程序后为它创建一个SCREEN, 报告将被显示在此Screen上:
事务码SE51:
<ignore_js_op> 
 
<ignore_js_op> 
 
执行 <ignore_js_op> 创建显示报告的控件:
 创建显示报告的控件:
起动Screen Painter后选择自定义组件 <ignore_js_op> 将它拖动到Screen:
 将它拖动到Screen:
<ignore_js_op> 
 
设定它的大小并命名为ALV_GRID, 这个自定义组件用于显示一个ALV MRP报告.
返回到Screen Painter属性设定:
<ignore_js_op> 
 
为OK功能代码设定一个名称OK_CODE
点击Flow logic:
<ignore_js_op> 
 
取消注释并创建模块程序
双击模块名称创建程序模块:
<ignore_js_op> 
 
<ignore_js_op> 
 
系统会首选创建一个Include 程序, 这样便于程序模块化. 在这里我将所有模块程序都放入主程序中:
执行后系统自动跳到先前创建的程序:
修改STATUS_1000为以下程序:
MODULE STATUS_1000 OUTPUT.
  SET PF-STATUS 'ZMD01'.
*  SET TITLEBAR 'xxx'.
ENDMODULE.                 " STATUS_1000  OUTPUT
因为GUI 状态ZMD01并不存在所以双击它新建一个:
<ignore_js_op> 
 
<ignore_js_op> 
 
展开Function Keys为返回按钮设定一个功能码:
在这个程序中当显示完报告后会让用户退回到原调用程序
执行 <ignore_js_op> 激活它
 激活它
返回到Screen Paint用相同的方法在主程序中创建:
MODULE USER_COMMAND_1000 INPUT.
ENDMODULE.                 " USER_COMMAND_1000  INPUT
创建一个OUTPUT MODULE: CREATE_ALV_GRID 此模块用于创建真正的报告:
<ignore_js_op> 
 
以下为完整的程序:
REPORT  ZSCR_EXPORT_TREE.
DATA:
      ok_code TYPE sy-ucomm,
      ok_save TYPE sy-ucomm.
DATA: lt_fieldcat    TYPE lvc_t_fcat,
      lt_tree_lines  TYPE md_t_tree_struc.
DATA:
      alv_grid        TYPE REF TO cl_gui_alv_grid,
      container       TYPE REF TO cl_gui_custom_container,
      i_save          TYPE c,
      gs_variant      TYPE disvariant,
      gs_layout       TYPE lvc_s_layo.   " Alv grid layout
IMPORT p_fieldcat TO lt_fieldcat FROM MEMORY ID 'lt_fieldcat'.
IMPORT p_tree_lines TO lt_tree_lines FROM MEMORY ID 'lt_tree_lines'.
CALL SCREEN 1000.
*&---------------------------------------------------------------------*
*&      Module  STATUS_1000  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE STATUS_1000 OUTPUT.
  SET PF-STATUS 'ZMD01'.
ENDMODULE.                 " STATUS_1000  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_1000  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_1000 INPUT.
  ok_save = ok_code.
  CLEAR ok_code.
  CASE ok_save.
    WHEN 'BACK'.
      FREE MEMORY ID 'lt_fieldcat'.
      FREE MEMORY ID 'lt_tree_lines'.
      LEAVE PROGRAM.
    WHEN OTHERS.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_1000  INPUT
*&---------------------------------------------------------------------*
*&      Module  CREATE_ALV_GRID  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE CREATE_ALV_GRID OUTPUT.
  IF container IS INITIAL.
    CREATE OBJECT container
      EXPORTING
        CONTAINER_NAME = 'ALV_GRID'.
    CREATE OBJECT alv_grid
      EXPORTING
        i_parent = container.
  ENDIF.
  PERFORM C_ALV_GRID_LAYOUT.
  PERFORM C_ALV_GRID_VARIANT.
  CALL METHOD alv_grid->set_table_for_first_display
    EXPORTING
      I_STRUCTURE_NAME = 'md_t_tree_struc'
      I_SAVE           = i_save
      IS_VARIANT       = gs_variant
      IS_LAYOUT        = gs_layout
      "IT_TOOLBAR_EXCLUDING = lt_functions
      "I_DEFAULT       = ''
    CHANGING
      IT_FIELDCATALOG  = lt_fieldcat
      IT_OUTTAB = lt_tree_lines.
ENDMODULE.                 " CREATE_ALV_GRID  OUTPUT
*修改ALV_GRID以让它可以被多列多行选择
FORM C_ALV_GRID_LAYOUT.
  gs_layout-sel_mode = 'A'.   " Multiple columns selection
ENDFORM.
*修改ALV_GRID以让用户可以修改布局并保存
FORM C_ALV_GRID_VARIANT.
  i_save = 'A'.
  gs_variant-report = sy-repid.
ENDFORM.
激活程序
激活Screen
激活BADI
执行MD04测试BADI:
<ignore_js_op> 
 
点击 <ignore_js_op> 展开概览:
 展开概览:
<ignore_js_op> 
 
默认导出报告的按钮不可见,执行 <ignore_js_op> 展开工单报告后便可见:
 展开工单报告后便可见:
<ignore_js_op> 
 
执行导出 <ignore_js_op> , 它会调用BADI增强呼叫先前被创建的程序来显示报告:
 , 它会调用BADI增强呼叫先前被创建的程序来显示报告:
<ignore_js_op> 
 
完成
此程序涉及到ABAP ALV GRID, BADI, SCREEN的使用
参考资料:
BC425  Enhancements and Modifications
摘自:http://www.itpub.net/thread-1202518-1-1.html
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号