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.

...

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

ABAP Cheat Sheet 补充内容

以下内容整理自 SAP 官方 ABAP 速查表(主题:SAP LUW),作为本文的扩展补充资料。

SAP LUW

Introduction

[!NOTE] The concept is relevant to both ABAP Cloud and classic ABAP, but some of the statements covered in the cheat sheet and the executable example are only relevant to classic ABAP.

This cheat sheet provides a high-level overview of the SAP LUW concept that deals with data consistency with a focus on SAP LUW-related statements, supported by an executable example to check the syntax in action.

When you run an application, you typically change data in a transaction, which may be temporarily stored in transactional buffers. This data may be temporarily inconsistent in the buffers, but it is important that the data be in a consistent state at the end of the transaction so that it can be saved to the database.

Consider the following example of transactional consistency:

[!NOTE] - This cheat sheet focuses on classic ABAP and the unrestricted ABAP language version Standard ABAP. Hence, the links in this cheat sheet open topics in the ABAP Keyword Documentation for Standard ABAP. - The SAP LUW concept is also relevant to ABAP Cloud. The ABAP RESTful Application Programming Model (RAP) is the transactional programming model for ABAP Cloud. It comes with a well-defined transactional model and follows the rules of the SAP LUW. Find out more in this blog.

Terms

The following terms are related to the concept of the SAP LUW and try to give you some context about it:

⬆️ back to top

SAP LUW Overview

For an SAP LUW, the following aspects come into play:

Using the above bank transfer as an example:

⬆️ back to top

Bundling Techniques

The following bundling techniques are available in Standard ABAP. This means that programming units are registered in different work processes, but are executed by a single work process. All database changes are put into one database LUW, and all changes are committed in one final database commit.

Using update function modules

  FUNCTION zsome_update_fu_mod
    IMPORTING
      VALUE(values) TYPE some_dbtab.

    MODIFY some_dbtab FROM @values.

  ENDFUNCTION.
    "--------------------- Synchronous update ---------------------
    DATA(st_a) = VALUE some_type( ... ).

    ... 

    "Registering the update function module specified in uppercase letters
    CALL FUNCTION 'ZSOME_UPDATE_FU_MOD' IN UPDATE TASK 
        EXPORTING values = st_a.

    ...

    "Triggering the synchronous update
    COMMIT WORK AND WAIT.                              

    "--------------------- Asynchronous update ---------------------
    DATA(st_b) = VALUE some_type( ... ).

    ... 

    CALL FUNCTION 'ZSOME_UPDATE_FU_MOD' IN UPDATE TASK 
        EXPORTING values = st_b.

    ...

    "Triggering the asynchronous update
    COMMIT WORK.

    "--------------------- Local update ---------------------
    
    "Before update function modules are registered.
    SET UPDATE TASK LOCAL.

    DATA(st_c) = VALUE some_type( ... ).

    ... 

    CALL FUNCTION 'ZSOME_UPDATE_FU_MOD' IN UPDATE TASK 
        EXPORTING values = st_c.

    ...

    "The update will be synchronous no matter if you use the COMMIT WORK 
    "statement with or without the addition AND WAIT.
    COMMIT WORK.
    "COMMIT WORK AND WAIT.
[!NOTE] If a runtime error occurs during the update, the update work process executes a database rollback, and notifies the user whose program created the entries.

Using remote-enabled function modules

Using subroutines

⬆️ back to top

Related ABAP Statements

An SAP LUW is usually started by opening a new internal session. The statements to end an SAP LUW have already been mentioned above: [COMMIT WORK [AND WAIT]](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapcommit.htm) and ROLLBACK WORK.

COMMIT WORK [AND WAIT]

ROLLBACK WORK

[!NOTE] - COMMIT WORK vs. COMMIT WORK AND WAIT in ABAP Cloud - Both COMMIT WORK and COMMIT WORK AND WAIT are valid syntax options in ABAP for Cloud Development. - However, the functionality of COMMIT WORK and COMMIT WORK AND WAIT - and also SET UPDATE TASK LOCAL - is primarily applicable in classic ABAP, where update function modules, among others, are available. These function modules are not applicable in ABAP Cloud. - In ABAP Cloud, local updates are always enforced implicitly and automatically, meaning that updates occur in the same work process and are always synchronous. - Consequently, in ABAP Cloud, COMMIT WORK and COMMIT WORK AND WAIT behave identically, rendering the choice between the two irrelevant. - Typically, COMMIT WORK in ABAP Cloud returns a value of 0 for sy-subrc, while other values would result in a runtime error. - In the context of RAP, when committing in a RAP transaction, refer to the notes about COMMIT ENTITIES here. - Notes on database connections: - The database interface uses the standard connection of the current work process to access the standard database by default. - Optionally, database accesses can also be made by using secondary connections to secondary databases or by using service connections to the standard database. The secondary connections are usually used by technical components. For example, they are used for caches, traces, logs, and so on. - The implicit database rollback is performed on all database connections that are currently open. - Within the SAP LUW, database changes and commits are allowed on service connections or through secondary database connections.

⬆️ back to top

Concepts Related to the SAP LUW

The following concepts are related to the SAP LUW to ensure transactional consistency. They are not discussed in detail here. For more information, see the links.

Authorization concept

Lock concept

[!NOTE] For more information about related topics in RAP, see the sections Authorization Control and Concurrency Control in the Development guide for the ABAP RESTful Application Programming Model.

⬆️ back to top

The SAP LUW in ABAP Cloud and RAP

A limited set of ABAP language features is available in ABAP for Cloud Development (restricted ABAP language version). The limitations include the fact that the above bundling techniques are not available. Note that the local update is enabled by default in ABAP Cloud.

In fact, RAP is the transactional programming model for ABAP Cloud. And RAP comes with a well-defined transactional model and follows the rules of the SAP LUW. At the end of an SAP LUW in RAP, database modification operations should be performed in a final step in the RAP late save phase by persisting the consistent data in the RAP transactional buffer to the database.

There are RAP-specific ABAP EML statements for commit and rollback:

⬆️ back to top

Controlled SAP LUW

Example using CL_ABAP_TX:

...

*&---------------------------------------------------------------------*
*& Activating the modify transactional phase
*&---------------------------------------------------------------------*

cl_abap_tx=>modify( ).

"The following database modification statement is not allowed in the
"modify transactional phase. In certain contexts, e.g. in ABAP Cloud,
"the runtime error BEHAVIOR_ILLEGAL_STMT_IN_CALL occurs.
MODIFY zdemo_abap_carr FROM TABLE @( VALUE #(
    ( carrid = 'XY'
      carrname = 'XY Airlines'
      currcode = 'EUR'
      url =  'some_url' ) ) ).

...

*&---------------------------------------------------------------------*
*& Activating the save transactional phase
*&---------------------------------------------------------------------*

cl_abap_tx=>save( ).

"In this phase, database modifications are allowed.
MODIFY zdemo_abap_carr FROM TABLE @( VALUE #(
    ( carrid = 'XY'
      carrname = 'XY Airlines'
      currcode = 'EUR'
      url =  'some_url' ) ) ).
...

⬆️ back to top

More Information

⬆️ back to top

Executable Example

After the import of the repository, proceed as follows:

[!NOTE] - The examples in the main branch of the ABAP cheat sheet repository are designed to be imported into the SAP BTP ABAP Environment. For Standard ABAP, you can find examples (such as zdemo_abap_sap_luw) in the other branches of the repository. - The executable example ... - demonstrates the SAP LUW using classic dynpros to provide a self-contained and simple example that highlights the considerations regarding implicit database commits, without putting the spotlight on dynpros. Note that classic dynpros are outdated for application programs. New developments should use web-based UIs, such as SAP Fiori UIs. - covers the following topics in simple contexts: - Demonstrating synchronous update, asynchronous update, and local update triggered by COMMIT WORK, COMMIT WORK AND WAIT, and SET UPDATE TASK LOCAL using update function modules. - Demonstrating the statements PERFORM ... ON COMMIT and PERFORM ... ON ROLLBACK using subroutines. - does not claim to include meaningful dynpros with meaningful dynpro sequences and is not intended to be a role model for proper dynpro design. - is not intended to solve concrete programming tasks. You should always work out your own solution for each individual case. - is only intended to demonstrate a selection of keywords and visualize SAP LUW-related syntax in action on a high level. - is explained in more detail in the expandable section below. Click to view the details. - Dynpros cannot be created in ABAP Cloud. As mentioned earlier, RAP is the transactional programming model for ABAP Cloud. It comes with a well-defined transactional model and follows the rules of the SAP LUW. See the links in the More Information section. - The steps to import and run the code are outlined here. - Disclaimer


🟢 Click to expand for more information
The example demonstrates the SAP LUW using dynpros and bundling techniques with update function modules and subroutines. In the dynpros, you can select various options that determine how the program runs. It covers the following aspects:

The selection options follow this pattern:

First dynpro:

Second dynpro:

Third dynpro:

During program execution, logs are collected and eventually written to a database table (also using an update function module or subroutine). These logs document the progress of the transaction with various pieces of information. These include work process information, SAP LUW key retrieval, and transaction state retrieval (using methods of the CL_SYSTEM_TRANSACTION_STATE class).

If the program is not terminated immediately and the SAP LUW has ended, another program is called that displays a dynpro.

Fourth dynpro (part of a new program that is started):

Notes on the various options for checking out the SAP LUW:

The log shows the value 1 for the transaction state after the update task is executed and the update function modules are called.

来源说明:本节内容来源:SAP-samples/abap-cheat-sheets (GitHub),原作者 SAP。原 Markdown 文件:17_SAP_LUW.md。版权归原作者所有。