Adding multiple messages in MIGO transaction via MB_CHECK_LINE_BADI

作者:郑德鼎 约 6 分钟阅读 更新日期:2024-02-22 2 年前更新 标签:ABAP, MM, 开发, 物料管理

Ankit Maskara

November 21, 2018 3 minute read

Adding multiple messages in MIGO transaction via MB_CHECK_LINE_BADI

524,852

Dear Community,

In this blog I would like to share an innovative approach to a very common problem of displaying multiple messages on line item checks in MIGO transaction.

The solutions explored included implementation of BADI’s – MB_MIGO_BADI and MB_CHECK_LINE_BADI. Details are below –

MB_MIGO_BADI – As most of us would know that this BADI is provided for the sole purpose of addition of custom sub screens to MIGO Transaction. Even though this BADI has a CHECK_ITEM method to return multiple messages (to ET_BAPIRET2) but it has a limitation that only five active implementations of this BADI can be there in any system. So, this is not a foolproof solution. So, I needed to look at alternate ways.

MB_CHECK_LINE_BADI – I explored this and implemented CHECK_LINE method. Then it was observed that this BADI is generally only used to display a single message to application log that too is issued via the MESSAGE statement.

But the requirement was of mutliple messages so, there was trouble.

Further debugging of standard code for SAPLMIGO, I realized that we have the application log handler in a private variable P_LOG_HANDLE of local class – LCL_MIGO_LOG but unfortunately this was not accessible in the CHECK_LINE method of MB_CHECK_LINE_BADI. One way could have been to use ABAP Memory and Export the log handler’s value to CHECK_LINE method’s implementation and then add messages to application log. This needed implicit enhancement and ABAP Memory (which is OBSOLETE). So, this was not a preferable solution.

Now, comes the innovative solution. On analysis of standard code, I observed that we have internal table EMSEG of program SAPLMBWL accessible in CHECK_LINE method. Standard uses the same table to fill messages in the application log. So, I filled this table with our validation messages and then standard code did the trick of adding them to application log and it got rendered suitably on MIGO screen.

I felt this was a hack but still a preferred solution as it did not warrant any kind of project approvals or usage of OBSOLETE techniques.

Code snippet –

" Local data

DATA:

lt_message TYPE bapiret2_t,

lt_emseg TYPE STANDARD TABLE OF emseg.

APPEND VALUE #( type = 'E' id = 'SY' number = 614 ) to lt_message.
APPEND VALUE #( type = 'E' id = 'SY' number = 615 ) to lt_message.
APPEND VALUE #( type = 'E' id = 'SY' number = 616 ) to lt_message.
LOOP AT lt_message ASSIGNING FIELD-SYMBOL(<fs_msg>).
APPEND INITIAL LINE TO lt_emseg ASSIGNING FIELD-SYMBOL(<fs_mseg>).

<fs_mseg>-msgid = <fs_msg>-id.

<fs_mseg>-msgno = <fs_msg>-number.

<fs_mseg>-msgty = <fs_msg>-type.

<fs_mseg>-msgv1 = <fs_msg>-message_v1.

<fs_mseg>-msgv2 = <fs_msg>-message_v2.

<fs_mseg>-msgv3 = <fs_msg>-message_v3.

<fs_mseg>-msgv4 = <fs_msg>-message_v4.

<fs_mseg>-line_id = is_mseg-line_id.

<fs_mseg>-global_counter = is_vm07m-global_counter.

ENDLOOP.

FIELD-SYMBOLS : <ft_emseg> TYPE ty_t_emseg.

ASSIGN ('(SAPLMBWL)EMSEG[]') TO <ft_emseg>.

IF <ft_emseg> IS ASSIGNED.
APPEND LINES OF lt_emseg TO <ft_emseg>.
ENDIF.

Sample Output –

Update: 19th June 2020 – I found another FM whihc offers an elegant way of getting all the BAL log handlers in memory.

FM is – BAL_GLB_SEARCH_LOG

Sample code snippet is below which will give a list of all log handlers in memory for a particular filter.

DATA: ls_log_filter TYPE bal_s_lfil,

ls_message TYPE bal_s_msg,

lt_log_handle TYPE bal_t_logh.

APPEND INITIAL LINE TO ls_log_filter-object ASSIGNING FIELD-SYMBOL(<ls_log_search_object>).
<ls_log_search_object> = VALUE #( sign = if_slad_select_options=>C_SIGNs-including

option = if_slad_select_options=>c_options-eq

low = CONV balobj_d( '<SLG1 log object name>' ) ).

CALL FUNCTION 'BAL_GLB_SEARCH_LOG'

EXPORTING

i_s_log_filter = ls_log_filter

IMPORTING

e_t_log_handle = lt_log_handle

EXCEPTIONS

log_not_found = 1

OTHERS = 2.

Sincerely appreicate any feedback/comments/questions.

FollowLikeRSS Feed

Michelle Crapo

November 27, 2018 at 3:12 pm

Nice blog.

Like 1

Reply

Alert Moderator

Share

Jelena Perfiljeva

November 27, 2018 at 4:38 pm

Please see the moderator note on this blog: https://blogs.sap.com/2014/09/30/assign-life-made-easy/

Like 1

Reply

Alert Moderator

Share

Ankit Maskara

Blog Post Author

November 28, 2018 at 1:25 am

Hi Jelena,

Thanks for educating me.

But I could not find any other suitable way apart from above barring the ABAP Memory & Implicit enhancmenet technique.

If you have any other experience please suggest.

Best Regards.

Like 0

Reply

Alert Moderator

Share

Jelena Perfiljeva

November 28, 2018 at 3:30 pm

This is kind of a lose-lose situation. Personally, most likely I wouldn't pursue either option and just declare it not feasible. Stuff like this can't go to S/4HANA and it's something that the customers need to start considering.

If you're saying that BADI can return multiple messages but there is no way to display them then this would seem like an overlook to me that SAP should fix. With the SAP logo next to your name it seems you'd be in a good position to suggest that internally.

Like 1

Reply

Alert Moderator

Share

Ankit Maskara

Blog Post Author

November 28, 2018 at 5:00 pm

Hi Jelena,

BADI cannot return multiple messages and all demo implementations of the BADI also are built to return a single message by issuing a Message statement but since the customer requirement needs multiple messages so, I proposed above approach.

Best Regards.

Like 0

Reply

Alert Moderator

Share

Former Member

June 14, 2013 6 minute read

How to create a custom TAB for MIGO Item Details

71153,081

Dear all, I have implemented a custom tab in MIGO, you can follow the steps.

My requirement was to add a new tab named “Warranty” in MIGO.

Step1 : Create a custom table to store the data of  “Warranty”  tab

The first four fields should be the key fields, and the rest fields are your required custom fields.

Step 2: create a structure with the custom field you require on the MIGO.

Step 3: open structure GOITEM and append the same custom structure into it as shown below.

Step 4: Create another structure and append the table created in Step-1.

Step 5:  Create a Table type of the structure created in step-4 as shown below.

Step 6: go to SE80 and create a program as shown below. This screen must contain two screen.

Step 7: SE19 -> Badi Name: MB_MIGO_BADI

Press Create Impl. Button and create Implementation: ZMIGO_WARRENTY as shown below.

Step 8: Create a Class : ZCLASS_MIGO_WARRENTY as shown below.

Step 9: Maintain the following attributes in your Class Interface as shown below.

Step 10: Write the following codes for the methods shown below.

(a) for    IF_EX_MB_MIGO_BADI~INIT

METHOD if_ex_mb_migo_badi~init. APPEND gf_class_id TO ct_init.ENDMETHOD.

(b) for   IF_EX_MB_MIGO_BADI~PBO_DETAIL

METHOD if_ex_mb_migo_badi~pbo_detail. DATA: wa_extdata  TYPE zst_warrenty.

DATA :gf_class_id TYPE migo_class_id.

gf_class_id = ‘ZCLASS_MIGO_WARRENTY’.

CHECK i_class_id = gf_class_id.

IF g_no_input IS INITIAL.

e_cprog   = ‘ZSAPMZMM_MIGO_WARENTY’.

e_dynnr   = ‘9001’.                     “External fields: Input

e_heading = ‘Warranty’(001).

ELSE.

e_cprog   = ‘ZSAPMZMM_MIGO_WARENTY’.

e_dynnr   = ‘9002’.                     “External fields: Display

e_heading = ‘Warranty’(001).

ENDIF.

g_line_id = i_line_id.

READ TABLE gt_extdata INTO wa_extdata WITH KEY line_id = g_line_id. IF sy–subrc = 0 AND wa_extdata–mblnr IS NOT INITIAL AND wa_extdata–mjahr IS NOT INITIAL AND wa_extdata–zeile IS NOT INITIAL. SELECT SINGLE * FROM ztb_warrenty

CLIENT SPECIFIED INTO CORRESPONDING FIELDS OF wa_extdata

WHERE mandt = sy–mandt

AND   mblnr = wa_extdata–mblnr AND   mjahr = wa_extdata–mjahr AND   zeile = wa_extdata–zeile.

SET PARAMETER ID: ‘ZWARANTY’ FIELD wa_extdata–zzwarnt,

‘ZWARBEGD’ FIELD wa_extdata–zzwbegd,

‘ZWARENDD’ FIELD wa_extdata–zzwendd.

ELSE.

SET PARAMETER ID: ‘ZWARANTY’ FIELD space,

‘ZWARBEGD’ FIELD space,

‘ZWARENDD’ FIELD space.

ENDIF.ENDMETHOD.

(c) for    IF_EX_MB_MIGO_BADI~PAI_DETAIL

METHOD if_ex_mb_migo_badi~pai_detail.

e_force_change = ‘X’.ENDMETHOD.

(d) for    IF_EX_MB_MIGO_BADI~LINE_MODIFY

METHOD if_ex_mb_migo_badi~line_modify. DATA: ls_extdata  TYPE zst_warrenty.

IF cs_goitem–mblnr IS NOT INITIAL AND cs_goitem–mjahr IS NOT INITIAL AND cs_goitem–zeile IS NOT INITIAL.

ls_extdata–line_id  = i_line_id. ls_extdata–mblnr    = cs_goitem–mblnr. ls_extdata–mjahr    = cs_goitem–mjahr. ls_extdata–zeile    = cs_goitem–zeile. ls_extdata–zzwarnt  = cs_goitem–zzwarnt. ls_extdata–zzwbegd  = cs_goitem–zzwbegd. ls_extdata–zzwendd  = cs_goitem–zzwendd. DELETE gt_extdata WHERE line_id = ls_extdata–line_id.

INSERT ls_extdata INTO TABLE gt_extdata.

ELSE.

ls_extdata–line_id  = i_line_id. ls_extdata–zzwarnt  = cs_goitem–zzwarnt. ls_extdata–zzwbegd  = cs_goitem–zzwbegd. ls_extdata–zzwendd  = cs_goitem–zzwendd. DELETE gt_extdata WHERE line_id = ls_extdata–line_id.

INSERT ls_extdata INTO TABLE gt_extdata.

ENDIF.ENDMETHOD.

(e) for    IF_EX_MB_MIGO_BADI~RESET

METHOD if_ex_mb_migo_badi~reset.

CLEAR: gt_extdata,

g_no_input,

gs_exdata_header,

g_cancel,

g_line_id.ENDMETHOD.

(f) for    IF_EX_MB_MIGO_BADI~POST_DOCUMENT

METHOD if_ex_mb_migo_badi~post_document. DATA: wa_warrenty TYPE ztb_warrenty,

it_warrenty TYPE TABLE OF ztb_warrenty,

wa_mseg     TYPE mseg,

wa_extdata  TYPE zst_warrenty.

...

郑德鼎

关于作者:郑德鼎

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「Adding multiple messages in MIGO transaction via MB_CHECK_LINE_BADI.docx」整理生成,仅用于内部技术分享与学习交流。