How to create customer screen on ME21N/ME22N/ME23N Item Level using BadI
This is a manual how to use the BadIs ME_GUI_PO_CUST and ME_PROCESS_PO_CUST to create a customer screen on item level in ME21/22/23n and how to fill this screen with a customer field (and a selected value).
- ME_GUI_PO_CUST (classical)
- ME_PROCESS_PO_CUST (enhancement spot)
Helpful information and sample code in example implementation class CL_EXM_IM_ME_GUI_PO_CUST and CL_EXM_IM_ME_PROCESS_PO_CUST. In both examples all needed information is mentioned, but not always easy to find!
SAP Notes: 1910516
Step by step:
1. Append CI_EKPODB with your customer field
2. Create with SE11 a table with the following fields
d. Your customer field:
3. Create with SE11 a structure with the following fields
a. Your customer field
4. Create with screen painter (SE51) a screen with the new field
a. Program should be either your already existing function pool for MM exits or create a copy of the SAP example SAPLMEPOBADIEX
c. Element List (referring to your structure fields)!
d. Flow Logic
i. Important to add the two modules event_pbo and module_pai!
5. Change the function pool for global data in the top include
a. Tables: your structure of step 3 (line 52)
b. Internal tables both referring to your table of step 2 (line 54 – 59)
c. Include lmeviewsf01 (otherwise you will get a dump!!) (line 62)
6. Create the following function modules in the same function pool you used in the layout!
a. Y_MM_MEPOBADI_GET_DATA as copy of example code MEPOBADIEX_GET_DATA
i. Import Parameter
1. IM_EBELN type EBELN
2. IM_EBELP type EBELP
ii. Export parameter
1. EX_DATA type your table of step 2
iii. Source code completely identically to MEPOBADIEX_GET_DATA
b. Function module Y_MM_MEPOBADI_PUSH as copy of MEPOBADIEX_PUSH
i. Import Parameter
1. IM_DYNP_DATA type your structure of step 3
ii. Source code: fill your structure with the import parameter (line 18)
c. Function module Y_MM_MEPOBADI_POP as copy of MEPOBADIEX_POP
i. Export Parameter
1. EX_DYNP_DATA type your structure of step 3
ii. Source code: fill export parameter with your structure (line 18)
d. Y_MM_MEPOBADI_SET_DATA as copy of example code MEPOBADIEX_SET_DATA
i. Import Parameter:
1. IM_DATA type your table of step 2
2. IM_PHYSICAL_DELETE_REQUEST type MMPUR_BOOL
ii. Source code (copy of example source code of MEPOBADIEX_SET_DATA)
1. Important to change the code in line 38 to your customer field:
* update existing data
<data>-yyrevisionstand = im_data-yyrevisionstand. (line 38)
7. BADI (SE18)
i. Go to Menu –> Implementation –> Overview –> and choose your implementation
ii. If there is no implementation you have to create one (search in scn how to do)
b. Change Class Interface YCL_IM_MM_ME_GUI_PO_CUST
1. SUBSCREEN1 / Level: Constant / Visibility: Public / Type: MEPO_NAME / Initial Value ‘ITEMSCREEN1’
2. DYNP_DATA_PBO / Level Instance Attribute / Visibility Private / Associated Type your structure of step 3
3. DYNP_DATA_PAI / Level Instance Attribute / Visibility Private / Associated Type your structure of step 3
i. SUBSCRIBER: enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~SUBSCRIBE
1. Method SUBSCRIBE is mandatory to show your own tab.
2. According to Note 1910516 it is not possible to show more than one customer tab (one in header, one in position).
I did not test if this is still valid
ls_subscriber-name = defined attribute
ls_subscriber-dynpro = dynpro number of your SE51 screen of step 4
ls_subscriber-program = function pool of your SE51 screen of step 4
ls_subscriber-struct_name = your structure of step 3
ls_subscriber-label = either direct text of via text definition of your class
ls_subscriber-position = position of the tab in the position details.
According to Note 1910516 it should be between 30 and 50 to avoid problems with existing screens.
ii. MAP_DYNPRO_FIELDS: : enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~MAP_DYNPRO_FIELDS
1. Change source code by entering your field in the when case in line 56
2. Important: mapping one of the following customer fields in Line 58
iii. TRANSPORT_FROM_MODEL enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~TRANSPORT_FROM_MODEL
1. Important: Change function module to your module of step 6a
iv. TRANSPORT_TO_DYNP enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~TRANSPORT_TO_DYNP
1. Change function module to your module of step 6b
v. TRANSPORT_FROM_DYNP enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~TRANSPORT_FROM_DYNP
1. Change function module with your module of step 6c
vi. TRANSPORT_TO_MODEL enter copy of source code of CL_EXM_IM_ME_GUI_PO_CUST~TRANSPORT_TO_MODEL
1. Delete lines for standard fields (line20 – 32 of the example coding are not necessary for custom fields)
2. Change “if case” of line 64 to your own field
3. Change function module of line 66 to your module of step 6a
4. Change line 73 to your own field
5. Change function module of line 74 to your module of step 6d
6. Enter line 78 (move changed value to local structure)
7. Enter call of method set_data
8. BADI Enhancement Spot ME_PROCESS_PO_CUST
Have a look into CL_EXM_IM_ME_PROCESS_PO_CUST to get sample coding
Important: you can call only one “Enhancement Implementation”, if there is already an active implementation you have to either use this or deactivate it!
a. Method IF_EX_ME_PROCESS_PO_CUST~FIELDSELECTION_ITEM
i. Necessary to display your customer field (compare to Note 1910516)
1. Enter the following coding:
Important: Change to your customer field used in Method MAP_DYNPRO_FIELDS
DATA: l_changeable TYPE mmpur_bool.
FIELD-SYMBOLS: <fs> LIKE LINE OF ch_fieldselection.
* Is PO changeable?
l_changeable = im_header->is_changeable( ).
READ TABLE ch_fieldselection ASSIGNING <fs>
WITH TABLE KEY metafield = mmmfd_cust_10.
IF sy–subrc = 0.
IF l_changeable = ‘X’.
<fs>–fieldstatus = ‘.’. ” READY FOR INPUT
<fs>–fieldstatus = ‘*’. ” view
b. Method IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM
i. Necessary to pre-fill you customer field with e.g values from material master
ii. Enter e.g. some lines like below:
iii. Important is to use the following highlighted lines to get the entered data
data: lwa_mepoitem type mepoitem,
lwa_po_lgfsb type ymm_po_lgfsb.
data ls_ekpo type uekpo.
data ls_eban type eban.
data lt_eban type table of eban.
data: gv_objid type toav0–object_id,
gt_conn type table of toav0,
gt_conn_av type table of toav0,
gs_conn type toav0,
gs_toa01 type toa01,
lw_banfn type banfn.
call method im_item->get_data
re_data = lwa_mepoitem.
iv. And after your select you have to use the following highlighted lines to set your selected data
select single yyrevisionstand from marc
where matnr = lwa_mepoitem–matnr
and werks = lwa_mepoitem–werks.
if sy–subrc eq 0 and lwa_mepoitem–yyrevisionstand is not initial.
call method im_item->set_data
im_data = lwa_mepoitem.
If you just followed all steps and also put all function modules into the same function pool you should see now your custom tab and field in the item details:
- Own tab not displayed in ME21N and ME22N but displayed in ME23N
o You forget or did not entered the code in IF_EX_ME_PROCESS_PO_CUST~FIELDSELECTION_ITEM of ME_PROCESS_PO_CUST
o Compare to Note 1910516, if there are only “display” fields on your customer screen you will not see the whole tab in creation and change mode!
- Own field changeable in ME23N
o Mistake in declaration of screen and/or method SUBSCRIBE of ME_GUI_PO_CUST
- Refer in created screen/dynpro to your defined structure
- Refer in method SUBSCRIBE in line “ls_subscriber-struct_name” to the same structure like you used for the dynpro
- Methods of ME_GUI_PO_CUST not proceeded
o Check your screen definition
- You need to use both modules (event_pbo and event_pai) to get the method run, they are mandatory
- Dump (PERFORM_NOT_FOUND CX_SY_DYN_CALL_ILLEGAL_FORM ) when choosing the new tab
o You forgot to add the include lmeviewsf01 in the top include of your function module
- Still no display of the new tab but you already marked your field correct in IF_EX_ME_PROCESS_PO_CUST~FIELDSELECTION
- Check BADI Enhancement Spot ME_PROCESS_PO_CUST
- Important: you can call only one “Enhancement Implementation”, if there is already an active implementation you have to either use this and add your code there or deactivate it and create your own (always considering side effects of already existing coding)!
- System does not react like you expect
- Ensure that all your function modules are in the same function pool
- Set break point in both BaDIs to check if they are proceeded. If not you will find the reason above described!