最近在群里看到小伙伴谈到migo的收货的增强,如图所示:
如何做到呢,首先我们做下准备工作:
1.我们需要创建2个表分别作为抬头和行项目的数据存储
2.创建函数组和函数模块做数据传输和更新以及子屏幕的创建
3.将相关代码写到对应的BADI增强的方法中
*********************************************************************************************************************************************************
在这里,找到的对应的badi是MB_MIGO_BADI ,tcode: se19创建实施 如下并且激活,留作后面备用
1.创建需要的表 tcode :se11 创建抬头数据表和屏幕结构
创建结构欧,点击编辑 -》包含—》include
行项目的数据存储表
到此,所需的结构及表创建结束
2.创建所需的函数和子屏幕 tcode:se80 创建function group
接下来,创建抬头数据和行项目数据获取传输的函数:
创建抬头数据输入和输出的函数
*在函数组的top中输入如下
FUNCTION-POOL zqmigo. "MESSAGE-ID ..
* INCLUDE LZQMIGOD... " Local class definition
TABLES:zqmkpf_badi,zqmesg_badi,zqmkpf,zqmseg.
DATA:g_goaction TYPE goaction.
DATA:g_refdoc TYPE refdoc.
DATA:g_action TYPE action.
自建表的数据的更新要使用update function
创建行项目的数据输出输入的函数
创建获取 取得MIGO操作码及事务码的函数,这里是控制 A04的时候显示,不能修改自屏幕页签的数据
最后,函数创建完,该创建子屏幕了,不然你为了什么呢,是不?
我这里创建了2个屏幕,分别为 抬头和行项目的
9001 抬头
9002 行项目
自此,函数和屏幕就创建完了
3.增强已经找到了,那么就要开始写入代码了
badi的属性里加上如下属性参数
数据的传入表和结构,以及控制输出的参数
GF_CLASS_ID Instance Attribute Private Type MIGO_CLASS_ID MIGO 组件的类标识 (外部细节屏幕) 'MIGO_BADI_IMPLEMENTATION1'
IT_MSEG_BADI Instance Attribute Private Type ZQMESG_BADI_TAB 行项目增强结构
IS_MKPF_BADI Instance Attribute Private Type ZQMKPF_BADI 抬头数据增强结构
G_NO_INPUT Instance Attribute Private Type XFELD 复选框
G_CANCEL Instance Attribute Private Type XFELD 复选框
IF_EX_MB_MIGO_BADI~PBO_DETAIL
DATA: ls_zqmesg_badi TYPE zqmesg_badi.
* This check is obligatory, otherwise the program flow is incorrect
* (If there would be more than one implementation of BAdI MB_MIGO_BADI,
* only one subscreen would be displayed).
CHECK gf_class_id = i_class_id.
* Show screen only if there is an item
CHECK i_line_id IS NOT INITIAL.
* External subscreen:
* The content of global field G_NO_INPUT (set in method MODE_SET) will
* influence the number of external subsreen:
* if g_no_input is initial.
* IF g_no_input IS INITIAL.
e_cprog = 'SAPLZQMIGO'(006).
e_dynnr = '9002'.
e_heading = 'MIGO 行项目自定义屏幕增强'.
* ENDIF.
* Read data
READ TABLE it_mseg_badi INTO ls_zqmesg_badi WITH KEY global_counter = i_line_id.
IF sy-subrc = 0.
* Export data to function group (for display on subscreen)
CALL FUNCTION 'ZQMIGO_ITEM_BADI_SET_DATA'
EXPORTING
i_input = ls_zqmesg_badi.
ENDIF.
IF_EX_MB_MIGO_BADI~PAI_DETAIL
*-----------------------------------------------------------------------
* Changing parameter E_FORCE_CHANGE can be set to 'X'. In this case
* method LINE_MODIFY is called.
* ATTENTION:
* DO NOT SET parameter E_FORCE_CHANGE = ' '. In this case you might
* overwrite parameter E_FORCE_CHANGE of another BAdI implementation.
*-----------------------------------------------------------------------
DATA: ls_zqmseg_badi TYPE zqmesg_badi.
DATA: ls_zqmseg_badi_screen TYPE zqmesg_badi,
mblnr TYPE mblnr.
* Only if a line exists
CHECK i_line_id <> 0.
* Get data from external screen
CALL FUNCTION 'ZQMIGO_ITEM_BADI_GET_DATA'
IMPORTING
e_output = ls_zqmseg_badi_screen.
* Compare new data with old data
READ TABLE it_mseg_badi INTO ls_zqmseg_badi WITH KEY global_counter = i_line_id.
IF sy-subrc = 0.
ls_zqmseg_badi_screen-global_counter = i_line_id.
IF ls_zqmseg_badi <> ls_zqmseg_badi_screen.
* If there were any changes, it's obligatory to force MIGO to trigger
* method LINE_MODIFY.
e_force_change = 'X'.
ENDIF.
ENDIF.
IF_EX_MB_MIGO_BADI~LINE_MODIFY
DATA: ls_zqmseg TYPE zqmseg.
DATA: ls_zqmesg_badi TYPE zqmesg_badi.
DATA: ls_zqmesg_badi_screen TYPE zqmesg_badi.
FIELD-SYMBOLS: <fs_mseg_badi> LIKE ls_zqmesg_badi.
DATA: l_del TYPE sy-tabix.
CHECK i_line_id <> 0.
READ TABLE it_mseg_badi WITH KEY global_counter = i_line_id
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
**************取屏幕中现有数据
CLEAR: ls_zqmesg_badi_screen.
CALL FUNCTION 'ZQMIGO_ITEM_BADI_GET_DATA'
IMPORTING
e_output = ls_zqmesg_badi_screen.
IF ls_zqmesg_badi_screen-global_counter = i_line_id.
**************BADI全局变量中已存在
DELETE it_mseg_badi WHERE global_counter = i_line_id.
MOVE-CORRESPONDING cs_goitem TO ls_zqmesg_badi.
ls_zqmesg_badi-zbadi_erfme = ls_zqmesg_badi_screen-zbadi_erfme.
ls_zqmesg_badi-zbadi_erfmg = ls_zqmesg_badi_screen-zbadi_erfmg.
APPEND ls_zqmesg_badi TO it_mseg_badi.
ENDIF.
ELSE.
**************BADI全局变量中不存在
IF NOT cs_goitem-mblnr IS INITIAL
AND NOT cs_goitem-mjahr IS INITIAL
AND NOT cs_goitem-zeile IS INITIAL.
**************从自定义表中取数
CLEAR: ls_zqmseg.
SELECT SINGLE *
FROM zqmseg
INTO CORRESPONDING FIELDS OF ls_zqmseg
WHERE mblnr EQ cs_goitem-mblnr
AND mjahr EQ cs_goitem-mjahr
AND zeile EQ cs_goitem-zeile.
IF sy-subrc = 0.
MOVE-CORRESPONDING ls_zqmseg TO ls_zqmesg_badi.
ELSE.
MOVE-CORRESPONDING cs_goitem TO ls_zqmesg_badi.
ENDIF.
ELSE.
MOVE-CORRESPONDING cs_goitem TO ls_zqmesg_badi.
ENDIF.
ls_zqmesg_badi-global_counter = i_line_id.
ls_zqmesg_badi-zbadi_erfme = ls_zqmesg_badi_screen-zbadi_erfme.
ls_zqmesg_badi-zbadi_erfmg = ls_zqmesg_badi_screen-zbadi_erfmg.
APPEND ls_zqmesg_badi TO it_mseg_badi.
ENDIF.
IF_EX_MB_MIGO_BADI~LINE_DELETE
* DELETE TABLE it_mseg_badi WITH TABLE KEY global_counter = i_line_id.
* BREAK-POINT.
DELETE it_mseg_badi WHERE global_counter = i_line_id.
IF_EX_MB_MIGO_BADI~RESET
CLEAR is_mkpf_badi.
CLEAR it_mseg_badi.
CLEAR: g_no_input,
g_cancel.
DATA:ls_mseg TYPE mseg.
DATA: ls_zqmseg_badi TYPE zqmesg_badi.
is_mkpf_badi-mandt = sy-mandt.
is_mkpf_badi-mblnr = is_mkpf-mblnr.
is_mkpf_badi-mjahr = is_mkpf-mjahr.
LOOP AT it_mseg_badi INTO ls_zqmseg_badi.
ls_zqmseg_badi-mandt = sy-mandt.
ls_zqmseg_badi-mblnr = is_mkpf-mblnr.
ls_zqmseg_badi-mjahr = is_mkpf-mjahr.
modify it_mseg_badi from ls_zqmseg_badi transporting mandt mblnr mjahr.
ENDLOOP.
CALL FUNCTION 'ZQMIGO_BADI_UPDATE_DATA' IN UPDATE TASK
EXPORTING
i_zmkpf = is_mkpf_badi
TABLES
t_zmseg = it_mseg_badi.
IF_EX_MB_MIGO_BADI~MODE_SET
* ACTION and REFDOC will discribe the mode of transaction MIGO.
* ----------------------------------------------------------------------
* i_action:
* A01 = Goods receipt
* A02 = Return delivery
* A03 = Cancellation
* A04 = Display
* A05 = Release GR bl.st.
* A06 = Subsequent deliv.
* A07 = Goods issue
*
* i_refdoc:
* R01 = Purchase order
* R02 = Material document
* R03 = Delivery note
* R04 = Inbound delivery
* R05 = Outbound delivery
* R06 = Transport
* R07 = Transport ID code
* R08 = Order
* R09 = Reservation
* R10 = Other GR
*-----------------------------------------------------------------------
* In case of 'DISPLAY' the global field G_NO_INPUT will be set to 'X'.
* The result is that a different external subscreen will be choosen in
* method PBO_DETAIL.
IF i_action = 'A04' OR i_action = 'A03'.
g_no_input = 'X'.
ENDIF.
* In case of 'CANCEL' the global field G_CANCEL will be set to 'X'.
* The result is that in method POST_DOCUMENT a different handling is
* used
IF i_action = 'A03'.
g_cancel = 'X'.
ENDIF.
CALL FUNCTION 'ZMIGO_SET_GOACTION'
EXPORTING
i_goaction = i_action
i_refdoc = i_refdoc
.
IF_EX_MB_MIGO_BADI~STATUS_AND_HEADER
***********抬头数据从数据库中初始人取数
IF is_gohead-mblnr IS NOT INITIAL
AND is_gohead-mjahr IS NOT INITIAL
AND is_mkpf_badi IS INITIAL.
SELECT SINGLE *
FROM zqmkpf
INTO is_mkpf_badi
WHERE mblnr = is_gohead-mblnr
AND mjahr = is_gohead-mjahr.
ENDIF.
IF_EX_MB_MIGO_BADI~PBO_HEADER
CHECK gf_class_id = i_class_id AND i_class_id IS NOT INITIAL.
CALL FUNCTION 'ZQMIGO_BADI_SET_DATA'
EXPORTING
i_input = is_mkpf_badi.
e_cprog = 'SAPLZQMIGO'.
e_dynnr = '9001'.
e_heading = 'MIGO 抬头自定义屏幕增强'.
IF_EX_MB_MIGO_BADI~PAI_HEADER
DATA: ls_mkpf_badi TYPE zqmkpf_badi.
CALL FUNCTION 'ZQMIGO_BADI_GET_DATA'
IMPORTING
e_output = ls_mkpf_badi.
MOVE-CORRESPONDING ls_mkpf_badi TO is_mkpf_badi.
至此,完毕
这只是做个测试,有很多的不足