第 31 页 / 共 275 页
Use of New BAdIs (Enhancement Spots) 2.3
3. You can then display the documentation for this BAdI via the non-labeled icon
on the right-hand side from the name of the BAdI definition.
4. You can view the available methods by double-clicking the name of the inter-
face on the right-hand side (IF_EX_ME_POHIST_DISP_CUST) or by expanding the
definition on the left-hand side and then double-clicking Interface.
To view the parameters, double-click the method, and then click the Parame-
ters button.
2.3.3 Creating Enhancement Implementations
You also create an enhancement implementation in Transaction SE19.
1. Choose the New BAdI option in the Create Implementation area. Enter the
name of the enhancement spot, that is, ES_BADI_ME_POHIST, and click Create
Implementation.
2. In the dialog window that appears (see Figure 2.11), you must specify a name
for the enhancement implementation, for example, Z_BADI_ME_POHIST. Enter a
short text as a description for this enhancement. You can leave the Composite
Enhancement Implementation field empty (see the following box). Confirm
the dialog to create the enhancement implementation.
Figure 2.11 Creating an Enhancement Implementation
31
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 32 页 / 共 275 页
2 General Information on User Exits and BAdIs
Composite Enhancement Implementations
You can optionally assign one or several simple enhancement implementations of
a composite enhancement implementation. The advantage of this is that several
enhancements, which may jointly map a process, are also logically combined in the
system. You subsequently have a better overview of the relationships between indi-
vidual enhancements.
To use a composite enhancement implementation, you enter a name from the cus-
tomer namespace for the composite enhancement implementation when you create
an enhancement implementation (see Figure 2.11). If there still isn’t any composite
implementation, you can create this directly from this dialog via the icon on the
right-hand side of the field.
3. In the dialog window that appears, you can select the implementing BAdIs.
Because no input help ([F4]) is provided here, you can simply close the window
via Cancel ([F12]).
4. You can select the BAdIs a lot more conveniently in the next dynpro (see Fig-
ure 2.12). Here you can see a list of the BAdI implementations on the left-hand
side, which is currently still empty. Click the Create BAdI Implementation
icon, which can be found directly above this area. The dialog window then
appears, as shown in Figure 2.12.
5. In this window, you can select the BAdI definition via the input help. Select ME_
POHIST_DISP_CUST here. To implement the BAdI, you must still enter the name
for the implementation (e.g., ZME_POHIST_DISP_CUST) and for the implementing
class (e.g., ZCL_POHIST_DISP_CUST). Enter a short text, and confirm the window
by clicking the green checkmark.
6. Confirm the next question on whether the include is supposed to be created by
choosing Yes.
7. Click Activate ([Ctrl] + [F3]), and call the implementation and the class gener-
ated in the background. This still has nothing to do with the activation of the
BAdI (see Section 2.3.5, Activating and Deactivating BAdIs).
32
© 2013 by Galileo Press Inc., Boston (MA)
| Composite Enhancement Implementations |
|---|
| You can optionally assign one or several simple enhancement implementations of a composite enhancement implementation. The advantage of this is that several enhancements, which may jointly map a process, are also logically combined in the system. You subsequently have a better overview of the relationships between indi- vidual enhancements. To use a composite enhancement implementation, you enter a name from the cus- tomer namespace for the composite enhancement implementation when you create an enhancement implementation (see Figure 2.11). If there still isn’t any composite implementation, you can create this directly from this dialog via the icon on the right-hand side of the field. |
第 33 页 / 共 275 页
Use of New BAdIs (Enhancement Spots) 2.3
Figure 2.12 Creating a BAdI Implementation
2.3.4 Working with Methods
This path so far has been significantly more time-consuming than with classic
BAdIs. However, we can now focus again on the methods and the actual function
of the BAdIs.
1. Expand the BAdI implementation on the left-hand side. Double-click the Imple-
menting Class entry that appears. The list of the existing methods in the BAdI
now appears on the right-hand side (see Figure 2.13).
2. To directly edit a method, double-click the method. You can double-click the
implementing class to use the enhanced options of the class. The use of meth-
ods is identical to the classic BAdIs, so no further explanation is given here.
33
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 34 页 / 共 275 页
2 General Information on User Exits and BAdIs
Figure 2.13 Overview of Methods
3. Insert the coding from Listing 2.3 into the method FIELDCAT_CHANGE, save, and
activate the method. The currency fields are hidden by this coding in the Pur-
chase Order History tab on the item level of the purchase order so that the
user isn’t able to see any amounts.
METHOD if_ex_me_pohist_disp_cust~fieldcat_change.
* Hide amount and currency key
DELETE ct_fieldcat WHERE fieldname = ‘DMBTR’ OR
fieldname = ‘HSWAE’ OR
fieldname = ‘WRBTR’ OR
fieldname = ‘WAERS’.
ENDMETHOD.
Listing 2.3 Example — Changing the Field Catalogue
2.3.5 Activating and Deactivating BAdIs
You can activate and deactivate BAdIs in enhancement implementations by fol-
lowing these steps:
1. Select the respective BAdI in the initial screen of the enhancement implementa-
tion, and activate or deactivate the implementation by setting or deleting the
checkmark for Implementation is active in the Runtime Behavior area (see
Figure 2.14).
34
© 2013 by Galileo Press Inc., Boston (MA)
第 35 页 / 共 275 页
Use of New BAdIs (Enhancement Spots) 2.3
Figure 2.14 Activating or Deactivating the BAdI Implementation
2. If you change the activation status of a BAdI implementation, you must also
save and activate the enhancement implementation again (in the example
already given, Z_BADI_ME_POHIST).
35
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 36 页 / 共 275 页
© 2013 by Galileo Press Inc., Boston (MA)
第 37 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
Hardly any area of Materials Management (MM) provides as many options to
enhance standards as in Purchasing. Deciding which enhancements to present in
detail in this chapter wasn’t easy. Among the most frequently required and most
useful functions are the two enhancements presented in this chapter. Implement-
ing customized fields in the purchase order is a complex topic that leads to many
questions, so a large part of this chapter is devoted to exploring these customiza-
tions. You can also find an overview of all enhancement options in Appendix A.
3.1 Customized Fields in Purchase Orders
To store custom data together with a purchase order, you must provide the user
with the respective input fields. There are various alternatives. The enhancement
MM06E005 is provided if you intend to only use a few individual fields at a header
or item level. This is relatively simple to implement, and you can directly attach
your fields as an append structure to Table EKKO or to Table EKPO. Furthermore,
this enhancement is also used in other purchasing documents, for example, in the
request for quotation (RFQ), as well as in the classic purchase order transactions.
However, the new method for using customized fields via the BAdIs ME_GUI_PO_
CUST and ME_PROCESS_PO_CUST is described over the next few pages. This method
was introduced for Release 4.7. These BAdIs enhance the Enjoy purchase orders;
however, the single-screen Transactions ME21N, ME22N, and ME23N provide
some benefits here. The BAdIs are more flexible and can also insert more complex
requirements seamlessly into the purchase order, and use several custom tabs at
the header and item level.
Customized Fields in Purchase Requisitions
For purchase requisitions, the options for implementing custom fields can be compared
with those of purchase orders. You can use enhancement MEREQ001 for simple situations
and attach the required fields, for example, as an append structure to Table EBAN.
37
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
| Customized Fields in Purchase Requisitions |
|---|
| For purchase requisitions, the options for implementing custom fields can be compared with those of purchase orders. You can use enhancement MEREQ001 for simple situations and attach the required fields, for example, as an append structure to Table EBAN. |
第 38 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
If you require more flexibility, the BAdI ME_PROCESS_REQ_CUST is provided, which is
similar to the solution presented in this chapter. Therefore, you can transfer the example
easily in purchase requisitions
3.1.1 Overview of the Implementation
The implementation of customized fields can be structured essentially into three
components. Before going into detail, you should first get an overview of these
components.
Part 1 — Encapsulation of Custom Data in a Function Group
A custom function is initially required to include the internal data retention of
custom fields, the dynpros in the form of subscreens, and function modules to
access the dynpros and the data externally. The integration into the purchase order
is executed by calling these function modules from the respective methods of the
BAdIs. The necessary function modules are listed in Table 3.1.
Time (Function Module) Use
Initialize Deleting the global data, for example, to
(Z_ME_CUST_INIT) generate a new document
Open Reading the custom data on an already
(Z_ME_CUST_OPEN) existing purchase order from the database
and providing the data in the global data
of the function group
Read data Reading the global data for the header
(Z_ME_CUST_DATA_GET) or item and transferring to the calling
program
Write data Writing changed or newly transferred
(Z_ME_CUST_DATA_SET) data to global data
Post Calling an update module when the
(Z_ME_CUST_POST) purchase order is saved
Set dynpro Transferring the data to a dynpro
(Z_ME_CUST_DYN_SET)
Table 3.1 Overview of Necessary Function Modules
38
© 2013 by Galileo Press Inc., Boston (MA)
| Time (Function Module) | Use |
|---|---|
| Initialize (Z_ME_CUST_INIT) | Deleting the global data, for example, to generate a new document |
| Open (Z_ME_CUST_OPEN) | Reading the custom data on an already existing purchase order from the database and providing the data in the global data of the function group |
| Read data (Z_ME_CUST_DATA_GET) | Reading the global data for the header or item and transferring to the calling program |
| Write data (Z_ME_CUST_DATA_SET) | Writing changed or newly transferred data to global data |
| Post (Z_ME_CUST_POST) | Calling an update module when the purchase order is saved |
| Set dynpro (Z_ME_CUST_DYN_SET) | Transferring the data to a dynpro |
第 39 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
Time (Function Module) Use
Read dynpro Copying the data from a dynpro
(Z_ME_CUST_DYN_GET)
Update (Properties: Process type update module):
(Z_ME_CUST_UPDATE) Writing the custom data to the database,
the call is executed from the “Post”
function module
Table 3.1 Overview of Necessary Function Modules (Cont.)
Part 2 — BAdI MEPO_GUI_PO_CUST
The BAdI MEPO_GUI_PO_CUST includes all methods to insert custom tabs at a header
or item level into the purchase order, and to execute the data transport between
the function group and the dynpros displayed in the tabstrips. An overview of all
the methods is provided in Table 3.2.
Method Use
SUBSCRIBE You create new tabstrips (header or item) and
assign these to a dynpro of your function group.
MAP_DYNPRO_FIELDS You map your dynpro fields in a metafield.
Metafields describe the content of a dynpro field
using various characteristics and are important
when notifications are assigned to a specific field,
particularly with regard to the display of error
messages.
TRANSPORT_FROM_MODEL This method will run depending on the registered
subscreen and its type (header or item). Here
you essentially call the Read Data module from
your function group. You store the result in a
suitable structure in the attributes of your BAdI
implementation. You need this data again in the
method TRANSPORT_FROM_DYNPRO.
TRANSPORT_TO_DYNPRO The previously read data is now copied by the
call of the Set Dynpro function module to the
function group and is then displayed in the
dynpro.
Table 3.2 Methods of the BAdI MEPO_GUI_PO_CUST
39
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
| Time (Function Module) | Use |
|---|---|
| Read dynpro (Z_ME_CUST_DYN_GET) | Copying the data from a dynpro |
| Update (Z_ME_CUST_UPDATE) | (Properties: Process type update module): Writing the custom data to the database, the call is executed from the “Post” function module |
| Method | Use |
|---|---|
| SUBSCRIBE | You create new tabstrips (header or item) and assign these to a dynpro of your function group. |
| MAP_DYNPRO_FIELDS | You map your dynpro fields in a metafield. Metafields describe the content of a dynpro field using various characteristics and are important when notifications are assigned to a specific field, particularly with regard to the display of error messages. |
| TRANSPORT_FROM_MODEL | This method will run depending on the registered subscreen and its type (header or item). Here you essentially call the Read Data module from your function group. You store the result in a suitable structure in the attributes of your BAdI implementation. You need this data again in the method TRANSPORT_FROM_DYNPRO. |
| TRANSPORT_TO_DYNPRO | The previously read data is now copied by the call of the Set Dynpro function module to the function group and is then displayed in the dynpro. |
第 40 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
Method Use
TRANSPORT_FROM_DYNPRO After a user has made an entry, you retrieve the
data of the dynpro in the BAdI by calling the
Read Dynpro function module. Compare the data
with the previous status (see TRANSPORT_FROM_
MODEL). If the content has changed, you must
pass this information to the data model.
TRANSPORT_TO_MODEL If changes have occurred, you transfer the new
data again to your function group by calling the
Write Data function module.
EXECUTE You can use this method optionally to handle
custom function codes if you have positioned the
respective buttons in a custom dynpro.
Table 3.2 Methods of the BAdI MEPO_GUI_PO_CUST (Cont.)
Part 3 — BAdI MEPO_PROCESS_PO_CUST
The BAdI MEPO_PROCESS_PO_CUST is ultimately used to integrate your custom data
into the process flow of the purchase order to execute, for example, input checks
and to integrate other function modules from your function group. An overview
of these relevant methods is given in Table 3.3
Methods Use
INITIALIZE From this method, you call the Initialize function module
of your function group when you start your transaction.
OPEN This method runs as soon as a purchase order is opened.
Then you call the Open function module to make custom
data available.
PROCESS_ITEM You can check inputs at item level.
PROCESS_HEADER You can check inputs at header level.
PROCESS_SCHEDULE You can check inputs on schedules.
PROCESS_ACCOUNT You can check inputs for account assignments.
CHECK This method allows you to check the document
completely.
Table 3.3 Methods of the BAdI ME_PROCESS_PO_CUST
40
© 2013 by Galileo Press Inc., Boston (MA)
| Method | Use |
|---|---|
| TRANSPORT_FROM_DYNPRO | After a user has made an entry, you retrieve the data of the dynpro in the BAdI by calling the Read Dynpro function module. Compare the data with the previous status (see TRANSPORT_FROM_ MODEL). If the content has changed, you must pass this information to the data model. |
| TRANSPORT_TO_MODEL | If changes have occurred, you transfer the new data again to your function group by calling the Write Data function module. |
| EXECUTE | You can use this method optionally to handle custom function codes if you have positioned the respective buttons in a custom dynpro. |
| Methods | Use |
|---|---|
| INITIALIZE | From this method, you call the Initialize function module of your function group when you start your transaction. |
| OPEN | This method runs as soon as a purchase order is opened. Then you call the Open function module to make custom data available. |
| PROCESS_ITEM | You can check inputs at item level. |
| PROCESS_HEADER | You can check inputs at header level. |
| PROCESS_SCHEDULE | You can check inputs on schedules. |
| PROCESS_ACCOUNT | You can check inputs for account assignments. |
| CHECK | This method allows you to check the document completely. |
第 41 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
Methods Use
POST When the purchase order is saved, you must also save your
own data by calling the Post function module.
CLOSE You also call the Initialize function module before a new
document is started.
FIELDSELECTION_* Depending on the context, you can set the field status
of your custom fields in various methods for the field
selection.
Table 3.3 Methods of the BAdI ME_PROCESS_PO_CUST (Cont.)
Figure 3.1 shows an overview of all the BAdI methods used in the example, as
well as their interaction with the custom function group. The SUBSCRIBE, MAP_DYN-
PRO_FIELDS, and FIELDSELECT_ITEM methods are necessary to activate the custom
fields. However, they don’t communicate with your function group.
BAdIME_GUI_PO_CUST Function Group ZME_CUST
SUBSCRIBE Read Data
Z_ME_CUST_DATA_GET
MAP_DYNPRO_FIELDS
Set Dynpro
TRANSPORT_FROM_MODEL Z_ME_CUST_DYN_SET
TRANSPORT_TO_DYNPRO Read Dynpro
Z_ME_CUST_DYN_GET
TRANSPORT_FROM_DYNPRO
Write Data
TRANSPORT_TO_MODEL Z_ME_CUST_DATA_SET
Initialization
Z_ME_CUST_INIT
BAdIME_PROCESS_PO_CUST
Open
FIELDSELECTION_ITEM Z_ME_CUST_OPEN
PROCESS_ITEM Post
Z_ME_CUST_POST
INITIALIZE
Update
CLOSE Z_ME_CUST_UPDATE
OPEN
POST
Figure 3.1 BAdI Methods Used and Their Integration with the Function Group
41
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
| Methods | Use |
|---|---|
| POST | When the purchase order is saved, you must also save your own data by calling the Post function module. |
| CLOSE | You also call the Initialize function module before a new document is started. |
| FIELDSELECTION_* | Depending on the context, you can set the field status of your custom fields in various methods for the field selection. |
| BAdIME_GUI_PO_CUST |
|---|
| SUBSCRIBE |
| MAP_DYNPRO_FIELDS |
| TRANSPORT_FROM_MODEL |
| TRANSPORT_TO_DYNPRO |
| TRANSPORT_FROM_DYNPRO |
| TRANSPORT_TO_MODEL |
| Function Group ZME_CUST |
|---|
| Read Data Z_ME_CUST_DATA_GET |
| Set Dynpro Z_ME_CUST_DYN_SET |
| Read Dynpro Z_ME_CUST_DYN_GET |
| Write Data Z_ME_CUST_DATA_SET |
| Initialization Z_ME_CUST_INIT |
| Open Z_ME_CUST_OPEN |
| Post Z_ME_CUST_POST |
| Update Z_ME_CUST_UPDATE |
| BAdIME_PROCESS_PO_CUST |
|---|
| FIELDSELECTION_ITEM |
| PROCESS_ITEM |
| INITIALIZE |
| CLOSE |
| OPEN |
| POST |
第 42 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
3.1.2 Implementation of Custom Purchase Order Data and Function
Group
After you get a general overview of the work involved, the first step is defining
custom data and creating the function group. Additional tabs at the header and
item levels are integrated with the purchase order so you can enter custom data
and save it.
To present the following example in a simpler way, the example only includes the
creation of three text fields, respectively, at the header and item level. The data is
stored in separate tables. When you understand the principle of BAdIs, you can
easily use and store any complex data quantities.
1. Start with the definition of your custom fields in the ABAP Dictionary. Start
Transaction SE11, and create a table to store the custom header data (sugges-
tion: ZME_POHEAD). The fields from Table 3.4 are used in the example.
2. Create another table to store the custom item data (suggestion: ZME_POITEM).
The fields from Table 3.5 are used in the example.
3. You still require work structures for the dynpros that should also be created in
the ABAP Dictionary. Create a structure for the header data (suggestion: ZME_
POHEAD_DS) and for the item data, respectively, (suggestion: ZME_POITEM_DS)
with the fields from Table 3.6 and Table 3.7.
Field Name Key Field Data Element
MANDT Yes MANDT
EBELN Yes EBELN
ZK_FELD1 CHAR32
ZK_FELD2 CHAR32
ZK_FELD3 CHAR32
Table 3.4 Fields of the Table ZME_POHEAD
Field Name Key Field Data Element
MANDT Yes MANDT
EBELN Yes EBELN
Table 3.5 Fields of the Table ZME_POITEM
42
© 2013 by Galileo Press Inc., Boston (MA)
| Field Name | Key Field | Data Element |
|---|---|---|
| MANDT | Yes | MANDT |
| EBELN | Yes | EBELN |
| ZK_FELD1 | CHAR32 | |
| ZK_FELD2 | CHAR32 | |
| ZK_FELD3 | CHAR32 |
| Field Name | Key Field | Data Element |
|---|---|---|
| MANDT | Yes | MANDT |
| EBELN | Yes | EBELN |
第 43 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
Field Name Key Field Data Element
EBELP Yes EBELP
ZP_FELD1 CHAR32
ZP_FELD2 CHAR32
ZP_FELD3 CHAR32
Table 3.5 Fields of the Table ZME_POITEM (Cont.)
Component Component Type
ZK_FELD1 CHAR32
ZK_FELD2 CHAR32
ZK_FELD3 CHAR32
Table 3.6 Structure ZME_POHEAD_DS
Component Component Type
ZP_FELD1 CHAR32
ZP_FELD2 CHAR32
ZP_FELD3 CHAR32
Table 3.7 Structure ZME_POITEM_DS
You’ve now created the prerequisites necessary in the ABAP Dictionary. The func-
tion group can then be created and the dynpros required can be generated.
1. Go to Transaction SE80, and change the object type on the left-hand side in
Function Group (see Figure 3.2). Then specify the name of a function group
(suggestion: ZME_CUST), and confirm the name by pressing the [Enter] key and
confirming the dialog window that appears to create the new function group.
2. Navigate to the include LZME_CUSTTOP to create the global data. Create two
structures for the header data and two internal tables with an additional work
structure for the item data. Duplicate implementation is used so that an object
can always maintain the status of the database, while the other object stores
the current content revised by the user. Moreover, you require both ABAP Dic-
tionary structures ZME_POHEAD_DS and ZME_POITEM_DS for the dynpros that you
provide with the key term, TABLES.
43
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
| Field Name | Key Field | Data Element |
|---|---|---|
| EBELP | Yes | EBELP |
| ZP_FELD1 | CHAR32 | |
| ZP_FELD2 | CHAR32 | |
| ZP_FELD3 | CHAR32 |
| Component | Component Type |
|---|---|
| ZK_FELD1 | CHAR32 |
| ZK_FELD2 | CHAR32 |
| ZK_FELD3 | CHAR32 |
| Component | Component Type |
|---|---|
| ZP_FELD1 | CHAR32 |
| ZP_FELD2 | CHAR32 |
| ZP_FELD3 | CHAR32 |
第 44 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
Figure 3.2 Completed Function Group ZME_CUST
3. For the subsequent integration with the purchase order, various standard form
routines are called in your program that need to be available. You also inte-
grate the include LMEVIEWSF01. This still requires a global data field OK-CODE to
include possible custom function codes. Use Listing 3.1 as a sample.
FUNCTION-POOL ZME_CUST. “MESSAGE-ID ..
* Dynpro structures
TABLES: zme_pohead_ds,
zme_poitem_ds.
* Structures for header data
* (_db contains the status of the database)
DATA: gs_pohead_db TYPE zme_pohead,
gs_pohead TYPE zme_pohead.
* Table and work structure for the item data
* (_db contains the status of the database)
DATA: gt_poitem_db TYPE SORTED TABLE OF zme_poitem
44
© 2013 by Galileo Press Inc., Boston (MA)
第 45 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
WITH UNIQUE KEY mandt ebeln ebelp,
gt_poitem LIKE gt_poitem_db,
gs_poitem_db TYPE zme_poitem,
gs_poitem TYPE zme_poitem.
* Form routines for dynpro calls. Always necessary!
DATA ok-code TYPE sy-ucomm.
INCLUDE lmeviewsf01.
Listing 3.1 Global Data (Include LZME_CUSTTOP)
4. Create a dynpro for the header data in the function group (suggestion: 0100),
and insert the three fields from the ABAP Dictionary structure ZME_POHEAD_DS
as an input field. Choose the dynpro type in the Subscreen properties.
5. The field properties are controlled via the BAdIs. To interact your dynpro with
the BAdIs, you must integrate the modules EVENT_PBO and EVENT_PAI in the
flow logic. These modules are also included in the include LMEVIEWSF01 and are
already known (see Listing 3.2). Save and activate the dynpro.
PROCESS BEFORE OUTPUT.
MODULE EVENT_PBO.
PROCESS AFTER INPUT.
MODULE EVENT_PAI.
Listing 3.2 Flow Logic for the Dynpros 0100 and 0200
6. Create another dynpro (suggestion: 0200) for the item data. Use the structure
ZME_POITEM as a reference here. Proceed as before.
In the next work step, the necessary function modules are created according to
Table 3.1.
1. Start with the function module ZME_CUST_INIT to initialize the global data. The
module doesn’t require any parameters. You can find the coding for this in
Listing 3.3.
FUNCTION Z_ME_CUST_INIT.
*”------------------------------------------------------------
*”*”Local interface:
*”------------------------------------------------------------
* Initialization of the global data.
45
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 46 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
REFRESH: gt_poitem_db, gt_poitem.
ClEAR: gs_pohead_db, gs_pohead,
gs_poitem_db, gs_poitem,
zme_pohead_ds, zme_poitem_ds.
ENDFUNCTION.
Listing 3.3 Function Module Z_ME_CUST_INIT
2. Create the function module Z_ME_CUST_OPEN to “open” a purchase order. The
data is read from the custom database tables and provided in the global data.
Only the purchase order number is required as an import parameter. Use List-
ing 3.4 as a sample.
FUNCTION Z_ME_CUST_OPEN.
*”------------------------------------------------------------
*”*”Local interface:
*” IMPORTING
*” REFERENCE(I_EBELN) TYPE EBELN
*”------------------------------------------------------------
* Read purchase order header
SELECT SINGLE * FROM zme_pohead INTO gs_pohead_db
WHERE ebeln = i_ebeln.
* Read purchase order items
SELECT * FROM zme_poitem INTO TABLE gt_poitem_db
WHERE ebeln = i_ebeln.
* Copying the database version to the current version
gs_pohead = gs_pohead_db.
gt_poitem = gt_poitem_db.
ENDFUNCTION.
Listing 3.4 Function Module Z_ME_CUST_OPEN
3. Implement the function module “Read Data”. Use Z_ME_CUST_DATA_GET as the
name. An import parameter controls whether header data or item data is pro-
cessed. Two other import parameters specify the document number and the
document item. Because the document item is only transferred if necessary,
set the Optional flag for this parameter. You also need the structures of your
header and item data as export parameters.
46
© 2013 by Galileo Press Inc., Boston (MA)
第 47 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
The function module now reads the data from the global area and returns the
data via export parameters to the calling program. You can find the respective
sample in Listing 3.5.
FUNCTION z_me_cust_data_get.
*“------------------------------------------------------------
*“*“Local interface:
*“ IMPORTING
*“ REFERENCE(I_TYPE) TYPE STRING
*“ REFERENCE(I_EBELN) TYPE EBELN
*“ REFERENCE(I_EBELP) TYPE EBELP OPTIONAL
*“ EXPORTING
*“ REFERENCE(E_HEADER) TYPE ZME_POHEAD
*“ REFERENCE(E_ITEM) TYPE ZME_POITEM
*“------------------------------------------------------------
* I_TYPE: HEADER = header data
* ITEM = item data
CASE i_type.
WHEN ‘HEADER‘.
e_header = gs_pohead.
WHEN ‘ITEM‘.
READ TABLE gt_poitem INTO e_item
WITH TABLE KEY mandt = sy-mandt
ebeln = i_ebeln
ebelp = i_ebelp.
IF sy-subrc NE 0.
* Item doesn‘t exist yet, initial data
CLEAR e_item.
e_item-mandt = sy-mandt.
e_item-ebeln = i_ebeln.
e_item-ebelp = i_ebelp.
ENDIF.
ENDCASE.
ENDFUNCTION.
Listing 3.5 Function Module Z_ME_CUST_DATA_GET
4. The next step concerns the function module “Write Data”. Use the name Z_ME_
CUST_DATA_SET. An import parameter controls whether header data or item data
is processed. Define the header and item data also as optional import parame-
ters. Because the structure already contains the purchase order number and the
47
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 48 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
purchase order item for items, these don’t need to be specially transferred. You
also need an indicator to define whether an item is to be deleted.
The header data is only overwritten when this function module is called. With
regard to the item data, first check whether this item already exists in the inter-
nal table to overwrite the line if required or to insert a new line in the table. If
the deletion indicator is set, remove the line from the internal table. You can
view the sample in Listing 3.6.
FUNCTION z_me_cust_data_set.
*“------------------------------------------------------------
*“*“Local interface:
*“ IMPORTING
*“ REFERENCE(I_TYPE) TYPE STRING
*“ REFERENCE(I_HEADER) TYPE ZME_POHEAD OPTIONAL
*“ REFERENCE(I_ITEM) TYPE ZME_POITEM OPTIONAL
*“ REFERENCE(I_DELKZ) TYPE XFELD OPTIONAL
*“------------------------------------------------------------
* I_TYPE: HEADER = Header data
* ITEM = Item data
CASE i_type.
WHEN ‘HEADER‘.
gs_pohead = i_header.
WHEN ‘ITEM‘.
* Delete item?
IF i_delkz IS NOT INITIAL.
DELETE TABLE gt_poitem
WITH TABLE KEY mandt = sy-mandt
ebeln = i_item-ebeln
ebelp = i_item-ebelp.
ELSE.
CLEAR gs_poitem.
* Item already available?
READ TABLE gt_poitem INTO gs_poitem
WITH TABLE KEY mandt = sy-mandt
ebeln = i_item-ebeln
ebelp = i_item-ebelp.
IF sy-subrc = 0.
* Update line
gs_poitem = i_item.
48
© 2013 by Galileo Press Inc., Boston (MA)
第 49 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
gs_poitem-mandt = sy-mandt.
MODIFY gt_poitem FROM gs_poitem INDEX sy-tabix.
ELSE.
* Insert line
gs_poitem = i_item.
gs_poitem-mandt = sy-mandt.
INSERT gs_poitem INTO TABLE gt_poitem.
ENDIF.
ENDIF.
ENDCASE.
ENDFUNCTION.
Listing 3.6 Function Module Z_ME_CUST_DATA_SET
5. You also need two other function modules for the communication with the
dynpros: Z_ME_CUST_DYN_SET and Z_ME_CUST_DYN_GET. A respective import
parameter is again required to distinguish between header and item data.
EE For Z_ME_CUST_DYN_SET, create two structures for the header or item data
(type ZME_POHEAD_DS and ZME_POITEM_DS) as further import parameters. Set
the Optional flag again because only header or item data are transferred.
EE To retrieve data via the function module Z_ME_CUST_DYN_GET, set up the
respective export parameters for the associated data ZME_POHEAD_DS and
ZME_POITEM_DS.
You can view the coding for both modules in Listing 3.7 and Listing 3.8.
FUNCTION z_me_cust_dyn_get.
*“------------------------------------------------------------
*“*“Local interface:
*“ IMPORTING
*“ REFERENCE(I_TYPE) TYPE STRING
*“ EXPORTING
*“ REFERENCE(E_POHEAD) TYPE ZME_POHEAD_DS
*“ REFERENCE(E_POITEM) TYPE ZME_POITEM_DS
*“------------------------------------------------------------
* I_TYPE: HEADER = header data
* ITEM = Item data
CASE i_type.
WHEN ‘HEADER‘.
e_pohead = zme_pohead_ds.
WHEN ‘ITEM‘.
e_poitem = zme_poitem_ds.
49
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 50 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
ENDCASE.
ENDFUNCTION.
Listing 3.7 Function Module Z_ME_CUST_DYN_GET
FUNCTION z_me_cust_dyn_set.
*”------------------------------------------------------------
*”*”Local interface:
*” IMPORTING
*” REFERENCE(I_TYPE) TYPE STRING
*” REFERENCE(I_POHEAD) TYPE ZME_POHEAD_DS OPTIONAL
*” REFERENCE(I_POITEM) TYPE ZME_POITEM_DS OPTIONAL
*”------------------------------------------------------------
* I_TYPE: HEADER = Header data
* ITEM = Item data
CASE i_type.
WHEN ‘HEADER’.
zme_pohead_ds = i_pohead.
WHEN ‘ITEM’.
zme_poitem_ds = i_poitem.
ENDCASE.
ENDFUNCTION.
Listing 3.8 Function Module Z_ME_CUST_DYN_SET
Both modules are ultimately required for updating. A module formats the data and
then transfers it to the second module, which is an update module.
1. Create the module Z_ME_CUST_UPDATE and activate the option Update Module
for this in the properties in the Processing Type section. To avoid any unnec-
essary accesses to the database, the header and item data are transferred twice
to this module: Once in the status on how it is found in the database (that you
have parked, refer to Listings 3.1 and 3.4) and once in the current status revised
by the user.
2. The internal tables with the items are transferred in the example as table param-
eters. When the tables are to be transferred as CHANGING parameters, you must
first create another table type in the ABAP Dictionary. Because it’s an update
module, you must set the Pass Value flag for the import parameters.
3. The two statuses must be compared, and only when a difference exists must the
line be inserted into, or be updated in, the database tables. Listing 3.9 includes
the example for this module.
50
© 2013 by Galileo Press Inc., Boston (MA)
第 51 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
FUNCTION z_me_cust_update.
*”------------------------------------------------------------
*”*”Local interface:
*” IMPORTING
*” REFERENCE(I_POHEAD_DB) TYPE ZME_POHEAD
*” REFERENCE(I_POHEAD) TYPE ZME_POHEAD
*” TABLES
*” T_POITEM_DB STRUCTURE ZME_POITEM
*” T_POITEM STRUCTURE ZME_POITEM
*”------------------------------------------------------------
DATA: lt_item_new TYPE TABLE OF zme_poitem,
lt_item_chg TYPE TABLE OF zme_poitem.
* Update of the header data.
IF i_pohead_db IS INITIAL.
* Header data aren’t yet in the DB
INSERT zme_pohead FROM i_pohead.
ELSE.
IF i_pohead_db <> i_pohead.
* Data have been changed
UPDATE zme_pohead FROM i_pohead.
ENDIF.
ENDIF.
* Preparing the item data
LOOP AT t_poitem INTO gs_poitem.
* Was this line there previously?
READ TABLE t_poitem_db INTO gs_poitem_db
WITH KEY mandt = sy-mandt
ebeln = gs_poitem-ebeln
ebelp = gs_poitem-ebelp.
IF sy-subrc = 0.
* Item was already in DB, delete and
* note if applicable
DELETE t_poitem_db INDEX sy-tabix.
IF gs_poitem_db <> gs_poitem.
* Content changed, note for UPDATE
APPEND gs_poitem TO lt_item_chg.
ENDIF.
ELSE.
* Item is new, note for Insert
51
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 52 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
APPEND gs_poitem TO lt_item_new.
ENDIF.
ENDLOOP.
* Updating the item data
* 1. New lines
IF lt_item_new IS NOT INITIAL.
INSERT zme_poitem FROM TABLE lt_item_new.
ENDIF.
* 2. Changed lines
IF lt_item_chg IS NOT INITIAL.
UPDATE zme_poitem FROM TABLE lt_item_chg.
ENDIF.
* 3. Lines that are now still in t_poitem_db
* can still be found in the database , haven’t however
* been retransferred -> conclusion: The lines
* have been deleted by the user ...
IF t_poitem_db[] IS NOT INITIAL.
DELETE zme_poitem FROM TABLE t_poitem_db.
ENDIF.
ENDFUNCTION.
Listing 3.9 Function Module Z_ME_CUST_UPDATE
4. Create the module Z_ME_CUST_POST, which prepares the data for updating and
calls the previously created function module Z_ME_CUST_UPDATE with the addi-
tion IN UPDATE TASK.
5. You need an import parameter with the document number. This document
number is only provided with new documents during the posting and is then
transferred to the function module via this parameter. You must also enhance
the client in the update data or the comparison to changes will fail. Copy the
document number in the structure with the header data and in the internal
table with the items. Then transfer the formatted data to the update module.
Caution
Under no circumstances should you trigger (as well as in any other position within the
entire enhancement) a COMMIT WORK — this is only performed by the SAP standard
coding!
52
© 2013 by Galileo Press Inc., Boston (MA)
| Caution |
|---|
| Under no circumstances should you trigger (as well as in any other position within the entire enhancement) a COMMIT WORK — this is only performed by the SAP standard coding! |
第 53 页 / 共 275 页
Customized Fields in Purchase Orders 3.1
You can find the sample in Listing 3.10.
FUNCTION z_me_cust_post.
*”------------------------------------------------------------
*”*”Local interface:
*” IMPORTING
*” REFERENCE(I_EBELN) TYPE EKKO-EBELN
*”------------------------------------------------------------
FIELD-SYMBOLS <fs_item> TYPE zme_poitem.
DATA: ls_pohead_db TYPE zme_pohead,
ls_pohead TYPE zme_pohead,
lt_poitem_db TYPE TABLE OF zme_poitem,
lt_poitem TYPE TABLE OF zme_poitem.
* No update without document number!
CHECK i_ebeln IS NOT INITIAL.
* Create and change local copy
ls_pohead_db = gs_pohead_db.
ls_pohead = gs_pohead.
lt_poitem_db = gt_poitem_db.
lt_poitem = gt_poitem.
* Enhance new header data
ls_pohead-mandt = sy-mandt.
ls_pohead-ebeln = i_ebeln.
* Enhance new item data
LOOP AT lt_poitem ASSIGNING <fs_item>.
<fs_item>-mandt = sy-mandt.
<fs_item>-ebeln = i_ebeln.
ENDLOOP.
* Calling the update module
CALL FUNCTION ‘Z_ME_CUST_UPDATE’
IN UPDATE TASK
EXPORTING
i_pohead_db = ls_pohead_db
i_pohead = ls_pohead
TABLES
t_poitem_db = lt_poitem_db
t_poitem = lt_poitem.
ENDFUNCTION.
Listing 3.10 Function Module Z_ME_CUST_POST
53
Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618
第 54 页 / 共 275 页
3 User Exits and BAdIs in Purchasing
3.1.3 Integration of Custom Fields into the BAdIs
Now the entire data administration of your custom fields is complete. However,
these fields still need to be integrated with the Enjoy transactions for the purchase
order (ME21N, ME22N, and ME23N). This is relatively simple for the header data.
Some methods are additionally required for the item data to send a message to
your function group if the user has navigated between the items.
The next milestone is to integrate your new dynpros in custom tabstrips with the
purchase order even if they still don’t have any function. Three prerequisites must
be fulfilled for this.
EE The tabstrips must be specified via the method SUBSCRIBE of the BAdI
ME_GUI_PO_CUST.
EE The fields that can be found in your previously defined dynpros must be linked
to a metafield via the MAP_DYNPRO_FIELDS method of the same BAdI.
EE At least one field in the dynpros must be displayed. Without any further action,
your fields will only appear in the display transaction ME23N. These fields are
hidden when they are created or changed. You also won’t see any tabstrip in
this case. To prevent this, you must additionally use the FIELDSELECTION_HEADER
and FIELDSELECTION_ITEM methods of the BAdI ME_PROCESS_PO_CUST and fun-
damentally display your fields.
Using these methods isn’t as complex as it may look. Follow these steps to
proceed:
1. Create an implementation for the BAdI ME_GUI_PO_CUST as well as for the BAdI
ME_PROCESS_PO_CUST. Methods from both BAdI implementations will now be
required repeatedly.
2. The method SUBSCRIBE is important. All custom tabstrips are specified in it and
linked with a custom dynpro. The method has three parameters:
EE The IM_APPLICATION parameter displays from which application the BAdI has
been called. This is currently always filled with PO because the BAdI is only
integrated into the purchase order. To be on the safe side, however, you can
implement a query in this value.
54
© 2013 by Galileo Press Inc., Boston (MA)