ABAP Development for Materials Management in SAP (第5页)

第 104 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

*” T_ITEMS STRUCTURE ZMB_MIGOITEM

*” EXCEPTIONS

*” INSERT_ERROR

*” DATA_ERROR

*”------------------------------------------------------------

* Check transferred data

IF i_head-mblnr IS INITIAL OR

i_head-mjahr IS INITIAL.

RAISE data_error.

ENDIF.

LOOP AT t_items.

IF t_items-mblnr IS INITIAL OR

t_items-mjahr IS INITIAL OR

t_items-zeile IS INITIAL.

RAISE data_error.

ENDIF.

ENDLOOP.

* Write header data

INSERT zmb_migohead FROM i_head.

IF sy-subrc <> 0.

RAISE insert_error.

ENDIF.

* Write item data

INSERT zmb_migoitem FROM TABLE t_items.

IF sy-subrc <> 0.

RAISE insert_error.

ENDIF.

ENDFUNCTION.

Listing 5.8 Coding on ZMB_MIGO_POST

8. Save all changes, and check whether all components of the function group have

been activated.

5.1.4 Preparation and Status Management in MB_MIGO_BADI

From now on, you can completely focus on the BAdI. All preparations have been

made. As described earlier, all necessary data are kept in the attributes of the class.

These are therefore created first.

104

© 2013 by Galileo Press Inc., Boston (MA)

第 105 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

1. Switch to Transaction SE19, and create a new implementation for the BAdI

MB_MIGO_BADI. Double-click the name of the implementing class ZCL_IM_MB_

MIGO_BADI, and then switch to the Attributes tabstrip.

2. Create the attributes according to Table 5.7. Consider the following notes:

EE GC_CLASS

Each implementation of the BAdI MB_MIGO_BADI must clearly be identified

toward Transaction MIGO. This happens via a constant of the type MIGO_

CLASS_ID, which you must define in the attributes because you use these in

several areas. In the example given, the constant has been specified with the

initial value ‘MIGO_OWN’. Note that the single quotation marks are necessary

here.

EE GV_LINEID

In this line number, always note the item transferred last in the dynpro.

EE GV_ACTION

This attribute contains the currently chosen action (see Table 5.8).

EE GV_REFDOC

This attribute contains the currently chosen reference document type (see

Table 5.9).

EE GS_HEADER

This structure contains the current header data on your tabstrip.

EE GT_ITEM

This internal table contains all items on the current document. You can only

define internal tables in the attributes when you refer to a table type defined

in the ABAP Dictionary or you create a local type. In the following example,

a local type (TT_MIGOITEM) has been used that is still currently unknown.

Attribute Type Visibility Reference Type

GC_CLASS Constant Private MIGO_CLASS_ID

GV_LINEID Instance Attribute Private GOITEM-GLOBAL_COUNTER

GV_ACTION Instance Attribute Private GOACTION

GV_REFDOC Instance Attribute Private REFDOC

GS_HEADER Instance Attribute Private ZMB_MIGOHEAD

GT_ITEM Instance Attribute Private TT_MIGOITEM

Table 5.7 Attributes of the Implementing Class

105

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

Attribute Type Visibility Reference Type
GC_CLASS Constant Private MIGO_CLASS_ID
GV_LINEID Instance Attribute Private GOITEM-GLOBAL_COUNTER
GV_ACTION Instance Attribute Private GOACTION
GV_REFDOC Instance Attribute Private REFDOC
GS_HEADER Instance Attribute Private ZMB_MIGOHEAD
GT_ITEM Instance Attribute Private TT_MIGOITEM

第 106 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

Action/Operation Description

A01 Goods receipt

A02 Return delivery

A03 Cancellation

A04 Display

A05 Release Goods receipt (GR) blocked

stock

A06 Subsequent delivery

A07 Goods issue

A08 Transfer posting

A09 Remove from storage

A10 Place in storage

A11 Subsequent adjustment

Table 5.8 List of Actions in Transaction MIGO

Reference Document Description

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

Table 5.9 List of the Possible Reference Documents in Transaction MIGO

3. Switch to the Types tabstrip to create the data type TT_MIGOITEM. To define a

table, you need the direct type input (see Figure 5.4).

106

© 2013 by Galileo Press Inc., Boston (MA)

Action/Operation Description
A01 Goods receipt
A02 Return delivery
A03 Cancellation
A04 Display
A05 Release Goods receipt (GR) blocked stock
A06 Subsequent delivery
A07 Goods issue
A08 Transfer posting
A09 Remove from storage
A10 Place in storage
A11 Subsequent adjustment
Reference Document Description
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

第 107 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

Figure 5.4 Enhanced Type Definition in Classes

4. Enter the name of the data type: TT_MIGOITEM.

5. Choose the Private entry in the Visibility column because this type is only used

within the class.

6. Click the yellow arrow icon on the right next to the reference type (direct type

input). You’re now in the ABAP Editor and can define the type as required.

7. Besides the actual data from table ZMB_MIGOITEM, the internal table requires

another field LINE_ID that displays the internal number during the entry. Create

a type that is made up of the field LINE_ID (type MB_LINE_ID) and ZMB_MIGOITEM.

Name this type TS_MIGOITEM.

8. Define the type TT_MIGOITEM as an internal table for TS_MIGOITEM. The complete

section should appear as follows:

PRIVATE SECTION.

TYPES BEGIN OF ts_migoitem.

TYPES line_id TYPE mb_line_id.

INCLUDE TYPE zmb_migoitem.

TYPES END OF ts_migoitem.

TYPES tt_migoitem TYPE TABLE OF ts_migoitem.

9. Save and activate your changes.

The first methods can now be programmed. Start with the method INIT. As

described earlier, this method is used to announce the implementation in Trans-

action MIGO. A maximum of five implementations may be active at the same

time.

107

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 108 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

You can now prepare the methods RESET and MODE_SET (refer to Table 5.1). You’ll

focus on the method STATUS_AND_HEADER later.

1. Switch to the Methods tabstrip of the class ZCL_IM_MB_MIGO_BADI, and then

navigate to method INIT. Here you must only transfer defined constants GC_

CLASS to the internal Table CT_INIT in the attributes. This table may already

contain other implementations. Therefore, don’t overwrite the table; instead,

attach your constant via APPEND. Because Table CT_INIT only consists of one

field, you can attach the constant directly. You don’t need a local structure (see

Listing 5.9).

METHOD if_ex_mb_migo_badi~init.

* Register implementation

APPEND gc_class TO ct_init.

ENDMETHOD.

Listing 5.9 Coding on the Method INIT

2. Edit the method RESET. This method is called when a new document is entered

or loaded. Initialize the instance attributes of your class (see Listing 5.10).

METHOD if_ex_mb_migo_badi~reset.

* Initialize instance attributes

CLEAR: gv_lineid,

gv_action,

gv_refdoc,

gs_header.

REFRESH gt_item.

ENDMETHOD.

Listing 5.10 Coding on the Method RESET

3. Switch to the method MODE_SET. In this method, you obtain the chosen action

(parameter I_ACTION; refer to Table 5.8) and the chosen reference document

type (parameter I_REFDOC; refer to Table 5.9).

Your custom fields are only integrated when this allows the current action.

You’ve already prepared the function module ZMB_MIGO_SETSTATUS, which you

now call. Set the parameter I_OUTPUTONLY when the action A04 (Display) or

A03 (Cancellation) is selected. Also note the current action in the attribute GV_

ACTION and the reference document type in the attribute GV_REFDOC to be used

later (see Listing 5.11).

108

© 2013 by Galileo Press Inc., Boston (MA)

第 109 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

METHOD if_ex_mb_migo_badi~mode_set.

* Local data declarations

DATA lv_outputonly TYPE c.

* No input for action A04 or A03

IF i_action = ‘A04‘ “ Anzeige

OR i_action = ‘A03‘. “Storno

lv_outputonly = ‘X‘.

ENDIF.

* Set current status

CALL FUNCTION ‘ZMB_MIGO_SETSTATUS‘

EXPORTING

i_outputonly = lv_outputonly.

* Hold action

gv_action = i_action.

* Hold reference document type

gv_refdoc = i_refdoc.

ENDMETHOD.

Listing 5.11 Coding on the Method MODE_SET

5.1.5 Activation of Custom Header Data

Now let’s move on to the relatively simple header data. At this point, your dyn-

pro is displayed as a tabstrip, and data is exchanged between the BAdI and your

dynpro. The reading of custom data is already implemented here when a posted

document is open. You post the header data later, together with the item data.

1. Switch to the method PBO_HEADER. Start with a mandatory check: For tech-

nical reasons, the methods from all implementations are always called in an

undefined sequence when one BAdI method is called to a method with several

active implementations. At the same time, the method PBO_HEADER is called

once for each of the five possible tabstrips. All implemented methods are there-

fore started each time. For this reason, you’re informed of the class ID in the

input parameter I_CLASS_ID (you’ve registered this in the method INIT; see

Figure 5.5) that is associated with this call. You must make sure that you check

whether the content of I_CLASS_ID corresponds to the class ID used in this

implementation from constant GC_CLASS. Otherwise, unforeseeable side effects

may arise.

109

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 110 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

2. The dynpro is registered next by transferring E_CPROG to the parameters and E_

DYNNR to the program name and the dynpro number. In the parameter E_HEAD-

ING, specify the name of the tabstrip. In the example given, the dynpro 0100 is

used in the program SAPLZMB_MIGO.

As an example, the tabstrip is only displayed when the operation refers to a

purchase order document. You can check via the attribute GV_REFDOC whether

you have filled this in method MODE_SET. The reference key for purchase orders

is R01 (refer to Table 5.9).

Figure 5.5 Interface of the Method PBO_HEADER

3. Finally, you still need to call the function module ZMB_MIGO_HEAD_SET and trans-

fer the current content of the header data to the dynpro. The current status can

always be found in the attribute GS_HEADER (see Listing 5.12).

METHOD if_ex_mb_migo_badi~pbo_header.

* Does the call refer to this implmentation?

CHECK i_class_id = gc_class.

* Register dynpro if reference to purchase order

IF gv_refdoc = ‘R01’.

e_cprog = ‘SAPLZMB_MIGO’.

110

© 2013 by Galileo Press Inc., Boston (MA)

第 111 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

e_dynnr = ‘0100’.

e_heading = ‘Eigene Daten’.

* Transfer current status of the header data to dynpro

CALL FUNCTION ‘ZMB_MIGO_HEAD_SET‘

EXPORTING

i_head = gs_header.

ENDIF.

ENDMETHOD.

Listing 5.12 Coding on the Method PBO_HEADER

4. Now process the method PAI_HEADER. You only need to write the data from the

dynpro back to the attribute GS_HEADER at this point. You do this by calling the

function module ZMB_MIGO_HEAD_GET (see Listing 5.13).

METHOD if_ex_mb_migo_badi~pai_header.

* Retrieve data from the dynpro

CALL FUNCTION ‘ZMB_MIGO_HEAD_GET’

IMPORTING

e_head = gs_header.

ENDMETHOD.

Listing 5.13 Coding on the Method PAI_HEADER

5. You must also read the custom data from the database if required, and transfer

it to the attribute GS_HEADER. You carry this out in method STATUS_AND_HEADER.

Rereading the data is only necessary when an already-posted document is dis-

played or canceled. Therefore, you can check the action (attribute GV_ACTION)

again here.

You read the data from the table ZMB_MIGOHEAD by using key fields MBLNR (mate-

rial document number) and MJAHR (posting year) that are available in the IS_

GOHEAD parameter (see Listing 5.14).

METHOD if_ex_mb_migo_badi~status_and_header.

* If an already posted document is to be displayed

* or canceled, read custom fields

* also from database.

IF gv_action = ‘A04‘ “ Anzeige

OR gv_action = ‘A03‘. “ Storno

111

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 112 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

* Read data from database

SELECT SINGLE *

FROM ZMB_MIGOHEAD

INTO gs_header

WHERE mblnr = is_gohead-mblnr

AND mjahr = is_gohead-mjahr.

ENDIF.

ENDMETHOD.

Listing 5.14 Coding on the Method STATUS_AND_HEADER

Note Data

You can also set the parameter E_HOLD_DATA_DISABLE as an option in the method STA-

TUS_AND_HEADER to prohibit the function Hold. If you continue to allow the noting of

material documents, you should program the methods HOLD_DATA_SAVE, HOLD_DATA_

LOAD, and HOLD_DATA_DELETE so that your custom data can also be noted. You can

obtain further information on this in Section 5.2.1, Noting Custom Data.

5.1.6 Activation of Custom Item Data

The actual activation of the item tabstrip works in a similar way to that of the

header tabstrip. The communication with the dynpro and the management of the

item data is slightly more time-consuming. Ultimately, there are several items in a

document that must always be correctly assigned.

1. Start with the method PBO_DETAIL to register the item tabstrip and prepare the

data. It’s also important to check the class ID just as you did before with the

header data.

2. In the parameter I_LINE_ID, you can find the line number that is being pro-

cessed. All subsequent actions are only carried out when the parameter has a

content unequal to zero.

You need to also note this line number in the attribute GV_LINEID so that you

can check later which line is actually being displayed in the dynpro.

3. There are also three parameters here, E_CPROG, E_DYNNR, and E_HEADING, to spec-

ify the program name, the dynpro number, and the caption of the tabstrip. The

item tabstrip always appears in the example regardless of the reference docu-

ment type.

112

© 2013 by Galileo Press Inc., Boston (MA)

Note Data
You can also set the parameter E_HOLD_DATA_DISABLE as an option in the method STA- TUS_AND_HEADER to prohibit the function Hold. If you continue to allow the noting of material documents, you should program the methods HOLD_DATA_SAVE, HOLD_DATA_ LOAD, and HOLD_DATA_DELETE so that your custom data can also be noted. You can obtain further information on this in Section 5.2.1, Noting Custom Data.

第 113 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

4. You must then read the current line according to parameter I_LINE_ID from

your internal table defined in the attributes GT_ITEM and transfer it to your

function group by calling the function module ZMB_MIGO_ITEM_SET. Make sure

that you copy the data via MOVECORRESPONDING into a structure suitable for the

function module because your table with additional line ID has been defined in

the attributes (see Listing 5.15).

METHOD if_ex_mb_migo_badi~pbo_detail.

* Local declarations

DATA ls_item TYPE ts_migoitem.

DATA ls_dynpro TYPE zmb_migoitem.

* Does the call refer to this implementation?

CHECK i_class_id = gc_class.

* Has a line been set?

CHECK i_line_id <> 0.

* Hold line

gv_lineid = i_line_id.

* Register dynpro

e_cprog = ‘SAPLZMB_MIGO’.

e_dynnr = ‘0200’.

e_heading = ‘Eigene Daten’.

* Read line from internal table

READ TABLE gt_item

INTO ls_item

WITH KEY line_id = i_line_id.

* Copy necessary fields

MOVE-CORRESPONDING ls_item TO ls_dynpro.

* Prepare line in dynpro

CALL FUNCTION ZMB_MIGO_ITEM_SET‘

EXPORTING

i_item = ls_dynpro.

ENDMETHOD.

Listing 5.15 Coding on the Method PBO_DETAIL

113

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 114 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

5. Switch to the method PAI_DETAIL in which you retrieve your data from the dyn-

pro, and check whether the content has changed. If it has, set the flag E_FORCE_

CHANGE through which the method LINE_MODIFY is triggered. Then carry out the

actual handling of the data. The advantage to this is that the complete item man-

agement can be found in one central position (see Listing 5.16).

METHOD if_ex_mb_migo_badi~pai_detail.

* Local declarations

DATA: ls_olddata TYPE zmb_migoitem,

ls_newdata TYPE zmb_migoitem,

ls_item TYPE ts_migoitem.

* Has a line been set?

CHECK i_line_id <> 0.

* Retrieve old status from internal table

READ TABLE gt_item

INTO ls_item

WITH KEY line_id = i_line_id.

MOVE-CORRESPONDING ls_item TO ls_olddata.

* Retrieve new status from dynpro

CALL FUNCTION ‘ZMB_MIGO_ITEM_GET’

IMPORTING

e_item = ls_newdata.

* Check whether the data has been changed

IF ls_olddata <> ls_newdata.

* Trigger execution of LINE_MODIFY

e_force_change = ‘X’.

ENDIF.

ENDMETHOD.

Listing 5.16 Coding on the Method PAI_DETAIL

6. Now it’s time for the method LINE_MODIFY. As mentioned earlier, in this method,

you manage not only possible changes to existing lines but also the insertion of

new document lines in one central position.

114

© 2013 by Galileo Press Inc., Boston (MA)

第 115 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

As a parameter, you obtain the number of the current line in I_LINE_ID. With

this line number, you must first of all check which case is actually present. Read

the table GT_ITEM using this key. If the line already exists, possible changes

must be transferred. If this line is not yet contained in GT_ITEM, you need to

initialize the line and add the table. If the document is currently being read, at

this point also read your custom data from the database.

Take a look at the case of a change. To ensure that the line being handled in the

BAdI is also the line that is currently in the dynpro, compare the parameter I_

LINE_ID with the previously noted line in the attribute GV_LINEID. You carry out

the following steps only when the comparison is successful:

1. Retrieve the data from the dynpro by calling the function module ZMB_MIGO_

ITEM_GET again. Copy the data received into a work structure that fits Table

GT_ITEM (data type TS_MIGOITEM), and enhance the line at the current LINE_ID.

Then write the changes back to Table GT_ITEM.

2. If the line doesn’t yet exist, you must first check whether it’s a line that has

already been posted. In this case, the fields CS_GOITEM-MBLNR (material docu-

ment number), CS_GOITEM-MJAHR (posting year), and CS_GOITEM-ZEILE (docu-

ment item) are filled. Read your data from Table ZMB_MIGOITEM using these

fields as a key, and copy these again into a suitable work structure for Table

GT_ITEM.

If the line doesn’t yet exist in the database, leave the work structure empty,

apart from the line LINE_ID, which you still need to enhance in both cases.

Then write the new line in Table GT_ITEM (see Listing 5.17).

METHOD if_ex_mb_migo_badi~line_modify.

* Local declarations

DATA lv_tabix TYPE sy-tabix.

DATA ls_item TYPE ts_migoitem.

DATA ls_newdata TYPE zmb_migoitem.

* Does the line already exist?

READ TABLE gt_item INTO ls_item

WITH KEY line_id = i_line_id.

lv_tabix = sy-tabix.

IF sy-subrc = 0.

* Line exists already, does change

* correspond to line in the BAdI of the dynpro line?

CHECK i_line_id = gv_lineid.

115

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 116 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

* Retrieve data from dynpro

CALL FUNCTION ‘ZMB_MIGO_ITEM_GET‘

IMPORTING

e_item = ls_newdata.

* Format changes

MOVE-CORRESPONDING ls_newdata TO ls_item.

ls_item-line_id = i_line_id.

* Write back in table gt_item

MODIFY gt_item FROM ls_item INDEX lv_tabix.

ELSE.

* Line doesn‘t yet exist, insert

IF cs_goitem-mblnr IS NOT INITIAL AND

cs_goitem-mjahr IS NOT INITIAL AND

cs_goitem-zeile IS NOT INITIAL.

* Line refers to an existing

* material document, retrieve data from database

SELECT SINGLE * FROM zmb_migoitem

INTO ls_newdata

WHERE mblnr = cs_goitem-mblnr AND

mjahr = cs_goitem-mjahr AND

zeile = cs_goitem-zeile.

IF sy-subrc = 0.

* Copy data

MOVE-CORRESPONDING ls_newdata TO ls_item.

ENDIF.

ENDIF.

* Build line with line ID and copy

* to internal table

ls_item-line_id = i_line_id.

APPEND ls_item TO gt_item.

ENDIF.

ENDMETHOD.

Listing 5.17 Coding on the Method LINE_MODIFY

3. Now you need to program the method LINE_DELETE. The method is called when

a document item is deleted. In this case, you must also delete the associated

custom data from Table GT_ITEM. Parameter I_LINE_ID is provided for you to

identify the suitable line (see Listing 5.18).

116

© 2013 by Galileo Press Inc., Boston (MA)

第 117 页 / 共 275 页

Custom Fields in Transaction MIGO 5.1

METHOD if_ex_mb_migo_badi~line_delete.

* Delete line

DELETE gt_item WHERE line_id = i_line_id.

ENDMETHOD.

Listing 5.18 Coding on the Method LINE_DELETE

5.1.7 Updating the Data

Now that you’ve fully programmed the internal handling of the data, you must

ensure that your data is also posted when the material document is updated. To

accomplish this, the method POST_DOCUMENT runs while the data is being posted.

1. Switch to the method POST_DOCUMENT. Before you can call your update modules,

you must prepare the data. The structure GS_HEADER, which has been defined

in the attributes, must still be enhanced in the document number. You obtain

this structure via the parameter IS_MKPF. You can copy the values via a simple

MOVE-CORRESPONDING.

2. Regarding item data, so far you have managed the data via the LINE_ID, that

is, the internal line number. As you know, only the items for which the user

has selected the OK field in Transaction MIGO are updated while being posted.

Therefore, the table to be updated, MSEG, which is transferred to you as the

parameter IT_MSEG, can have a different line numbering. The item number here

is specified via the field ZEILE, and you must now convert your data to this line

number. However, because Table IT_MSEG also contains the original LINE_ID

besides the line number, this isn’t a problem.

Simply process all your custom item data from the internal Table GT_ITEM in a

loop, and read the associated line from Table IT_MSEG using the field LINE_ID.

You can then fill a structure for Table ZMB_MIGOITEM from both data structures.

From the structure for Table IT_MSEG, copy the key fields, and from the struc-

ture on GT_ITEM, copy the custom fields. Add the result of a local internal table

that also uses the type ZMB_MIGOITEM.

3. You now only need to call the function module ZMB_MIGO_POST and transfer the

formatted header data and item data. Don’t forget the addition IN UPDATE TASK,

so that the function module in the updating is called (see Listing 5.19).

METHOD if_ex_mb_migo_badi~post_document.

* Local data declarations

DATA: ls_item TYPE ts_migoitem,

117

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 118 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

ls_mseg TYPE mseg,

ls_migoitem TYPE zmb_migoitem,

lt_migoitem TYPE TABLE OF zmb_migoitem.

* Prepare header data

* The key fields (material document number, posting year)

* are copied from the standard data (IS_MKPF)

MOVE-CORRESPONDING is_mkpf TO gs_header.

* Prepare item data

LOOP AT gt_item INTO ls_item.

* Determine corresponding line in IT_MSEG.

* Conversion between LINE_ID and ZEILE

* LINE_ID: internal line ID during entry

* ZEILE: Line number in table MSEG

READ TABLE it_mseg

INTO ls_mseg

WITH KEY line_id = ls_item-line_id.

IF sy-subrc = 0.

MOVE-CORRESPONDING ls_item TO ls_migoitem.

MOVE-CORRESPONDING ls_mseg TO ls_migoitem.

APPEND ls_migoitem TO lt_migoitem.

ENDIF.

ENDLOOP.

* Updating of the data

CALL FUNCTION ‘ZMB_MIGO_POST’

IN UPDATE TASK

EXPORTING

i_head = gs_header

TABLES

t_items = lt_migoitem.

ENDMETHOD.

Listing 5.19 Coding on the Method POST_DOCUMENT

5.2 Other Functions of the BAdI MB_MIGO_BADI

After you’ve implemented custom fields via the BAdI MB_MIGO_BADI in the pre-

vious chapter, you already know all the fundamentals on this BAdI. Using other

118

© 2013 by Galileo Press Inc., Boston (MA)

第 119 页 / 共 275 页

Other Functions of the BAdI MB_MIGO_BADI 5.2

methods, you can still implement additional functions, particularly to further

extend the functionality behind your custom fields.

5.2.1 Noting Custom Data

If you haven’t prohibited the function Note in the method STATUS_AND_HEADER (see

Section 5.1.5, Activation of Custom Header Data), you should ensure that your

custom fields are also noted. Because a noted document isn’t actually posted yet,

it still doesn’t have any material document number under which it can be stored.

The data are instead clearly identified by a 22-digit GUID (Global Unique Identi-

fier). Standard data are stored under this key in Table MMIM_PRED.

Three methods are available for storing your custom data: HOLD_DATA_SAVE, HOLD_

DATA_LOAD, and HOLD_DATA_DELETE. The GUID, which has also been used for the

standard fields, will transfer each of these methods as input parameters. Whether

you now store your data, that is, the header data that are in the structure GS_

HEADER and the item data in internal Table GT_ITEM, is up to you.

You have several options for storing the data:

EE You can copy Tables ZMB_MIGOHEAD and ZMB_MIGOITEM and provide them with a

GUID field as the key field. This makes saving somewhat more time-consuming,

however, and when you add another custom field later to the original tables,

you must also implement such enhancements in the Hold function.

EE One alternative allows the comfortable, dynamic storage of both objects without

any additional customization effort. You have the option in ABAP to serialize

complex variables such as structures or internal tables; that is, to convert them

into a character string. This string must have a very special data type. Use the

type XSTRINGin ABAP and type RAWSTRING in the ABAP Dictionary. You then

convert the data via the command EXPORT ... TO DATA BUFFER. You can store

the result of the conversion in a field of a database line, regardless of whether

or not this object has displayed an internal table with many lines beforehand.

If the data is subsequently retrieved, using the command IMPORT ... FROM DATA

BUFFER performs a reconversion in the actual object.

Based on the example of custom fields in Section 5.1, Custom Fields in Transac-

tion MIGO, the following example shows you how simply you can temporarily

store your data:

119

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 120 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

1. Your header and item data must be stored in a custom table. The data is saved

under a GUID, which you obtain in the methods. You also need a field of the

type RAWSTRING for the header data and the item data.

Navigate to the ABAP Dictionary (Transaction SE11), and create a new table.

Name this table ZMB_MIGOHOLD, for example.

2. Maintain the fields according to Table 5.10. The data element ZMB_RAW doesn’t

yet exist. You can create this by double-clicking. Don’t use any domains to

generate the data element, but choose the Integrated Type option in the DatA

Type tabstrip, and enter RAWSTRING here. Activate your data element, and then

navigate back to the table.

Field Name Key Field Data Element

MANDT Yes MANDT

GUID Yes GUID

HHEAD ZMB_RAW

(Definition: Integrated type RAWSTRING)

HITEMS ZMB_RAW

Table 5.10 Structure of the Table ZMB_MIGOHOLD

3. Maintain the technical settings of the table, and then activate the table.

4. Switch to your BAdI implementation, and navigate to the method HOLD_DATA_

SAVE. Create a local structure for Table ZMB_MIGOHOLD, and fill the GUID field

from the input parameter I_GUID.

5. Fill the fields HHEAD and HITEMS from your attributes S_HEADER and GT_ITEM via

the command EXPORT, which has the following structure:

EXPORT <id> FROM <variable> TO DATA BUFFER

<ziel> COMPRESSION ON.

<id> is any ID, <variable> is the source object that is to be converted, and

<target> is the target variable of the type RAWSTRING. The addition, COMPRES-

SION ON, is optional and compresses the data. This saves space in the database.

The subsequent IMPORT automatically recognizes whether the data has been

compressed, and extracts the data accordingly.

6. Finally, save your local structure via INSERT in the database (see Listing 5.20).

120

© 2013 by Galileo Press Inc., Boston (MA)

Field Name Key Field Data Element
MANDT Yes MANDT
GUID Yes GUID
HHEAD ZMB_RAW (Definition: Integrated type RAWSTRING)
HITEMS ZMB_RAW

第 121 页 / 共 275 页

Other Functions of the BAdI MB_MIGO_BADI 5.2

METHOD if_ex_mb_migo_badi~hold_data_save.

* Local work structure for ZMB_MIGOHOLD

DATA ls_migohold TYPE zmb_migohold.

* Copy GUID

ls_migohold-guid = i_guid.

* Convert header data in RAWSTRING/XSTRING

EXPORT header FROM gs_header TO DATA BUFFER

ls_migohold-hhead COMPRESSION ON.

* Convert item data in RAWSTRING/XSTRING

EXPORT item FROM gt_item TO DATA BUFFER

ls_migohold-hitems COMPRESSION ON.

* Store data in database

INSERT into zmb_migohold values ls_migohold.

ENDMETHOD.

Listing 5.20 Coding on the Method HOLD_DATA_SAVE

Now focus on the method HOLD_DATA_LOAD, which is called when a held document

is loaded back.

1. Here you must load back the data from Table ZMB_MIGOHOLD using the retrans-

ferred GUID, and fill the attributes GS_HEADER and GT_ITEM from this.

2. Create a new local work structure for Table ZB_MIGOHOLD, and read the data via

SELECT using the key in parameter I_GUID from your table.

3. You perform the reconversion from the fields HHEAD and HITEMS via the IMPORT

function with the following structure:

IMPORT <id> TO <variable> FROM DATA BUFFER <quelle>.

<id> stands for the ID that you’ve used with regard to the EXPORT; <variable>

is the target variable in which the result is to be written, that is, GS_HEADER or

GT_ITEM; and <source> is the RAWSTRING field from your work structure for

ZMB_MIGOHOLD. You can find an example on this method in Listing 5.21.

METHOD if_ex_mb_migo_badi~hold_data_load.

* Local work structure for ZMB_MIGOHOLD

DATA ls_migohold TYPE zmb_migohold.

* Read held data using I_GUID

121

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 122 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

SELECT SINGLE * FROM zmb_migohold

INTO ls_migohold

WHERE guid = i_guid.

IF sy-subrc = 0.

* Convert header data in original object

IMPORT header TO gs_header FROM DATA BUFFER

ls_migohold-hhead.

* Convert item data in original object

IMPORT item TO gt_item FROM DATA BUFFER

ls_migohold-hitems.

ENDIF.

ENDMETHOD.

Listing 5.21 Coding on the Method HOLD_DATA_LOAD

4. If you delete the marked data, you must also remove your noted data. To do

this, the method HOLD_DATA_DELETE is used. You also get the GUID as an input

parameter again. Simply delete the associated record in Table ZMB_MIGOHOLD (see

Listing 5.22).

METHOD if_ex_mb_migo_badi~hold_data_delete.

* Delete held data

DELETE FROM zmb_migohold WHERE guid = i_guid.

ENDMETHOD.

Listing 5.22 Coding on the Method HOLD_DATA_DELETE

Changes to the Data Structure

As you’ve seen, you can easily convert ABAP structures in a RAWSTRING using the com-

mands EXPORT and IMPORT, and copy these back to a structure. However, what happens

when you change such a packed structure later on?

For example, if you add another field to Table ZMB_MIGOHEAD for the header data, data

could still exist in the HHEAD field of the ZMB_MIGOHOLD table, which does not contain

this new field. However, this generally doesn’t constitute any problem. The command

IMPORT copies the suitable part back to the work structure while reading the noted data,

and the new field simply remains empty.

Vice versa is a bit more difficult. If you delete the second field again at a later stage and

still contain noted data in the RAWSTRING HHEAD of this, you obtain a short dump when

you IMPORT. You can avoid this dump by using the ACCEPTING TRUNCATION addition:

IMPORT <id> TO <variable> FROM DATA BUFFER <source> ACCEPTING TRUNCATION.

122

© 2013 by Galileo Press Inc., Boston (MA)

Changes to the Data Structure
As you’ve seen, you can easily convert ABAP structures in a RAWSTRING using the com- mands EXPORT and IMPORT, and copy these back to a structure. However, what happens when you change such a packed structure later on? For example, if you add another field to Table ZMB_MIGOHEAD for the header data, data could still exist in the HHEAD field of the ZMB_MIGOHOLD table, which does not contain this new field. However, this generally doesn’t constitute any problem. The command IMPORT copies the suitable part back to the work structure while reading the noted data, and the new field simply remains empty. Vice versa is a bit more difficult. If you delete the second field again at a later stage and still contain noted data in the RAWSTRING HHEAD of this, you obtain a short dump when you IMPORT. You can avoid this dump by using the ACCEPTING TRUNCATION addition: IMPORT <id> TO <variable> FROM DATA BUFFER <source> ACCEPTING TRUNCATION.

第 123 页 / 共 275 页

Other Functions of the BAdI MB_MIGO_BADI 5.2

For major structure changes, you should delete the content of Table ZMB_MIGOHOLD as

soon as you transport your changes to the production system.

5.2.2 Input Checks in Transaction MIGO

Two more methods are provided for checking your custom data: CHECK_HEADER and

CHECK_ITEM. These methods are only carried out when the user chooses the Check

or Post function. Follow the example below to activate the checks.

You need to carry out the checks on the attributes of your class in both cases. To

do this, you obtain the input parameter I_LINE_ID for the items. If a warning or

error message is displayed, this isn’t allowed to happen directly via the MESSAGE

command. Instead, you need to fill a return-table. You might know about this from

using the BAPI function modules. The name of this return-table is in both meth-

ods: ET_BAPIRET2. Your messages are therefore displayed in the standard error log

(see Figure 5.6) of Transaction MIGO, and the item number for item-related mes-

sages, to which the message refers, is displayed by default.

Figure 5.6 Custom Messages in the Error Log

123

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 124 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

1. Switch to the method CHECK_HEADER. For the return of messages, you must first

define a work structure for the return-table by using the type BAPIRET2. This

type is the line type that has been used to define internal Table ET_BAPIRET2.

This type therefore contains the fields required for a message (see Table 5.11).

2. Now check whether the ZK_FELD1 field is filled from the attribute GS_HEADER. If

this isn’t the case, an error message appears.

3. To display the message, fill the fields of your work structure according to Table

5.11. Then copy the structure to internal Table ET_BAPIRET2, which is defined

in the interface of the method (see Listing 5.23).

Field Description

TYPE Type of message, for example, ‘E’ for error

messages or ‘W’ for warning messages

ID Message class

NUMBER Message number

MESSAGE_V1 – MESSAGE_V4 Optional message variables 1-4 that can be

included

Table 5.11 Fields of the Return-Table

METHOD if_ex_mb_migo_badi~check_header.

* Local declaration on the return table

DATA: ls_bapiret TYPE bapiret2.

* Header field must be filled!

IF gs_header-zk_feld1 IS INITIAL.

* Configure error message

ls_bapiret-type = ‘E‘.

ls_bapiret-id = ‘ZMB‘.

ls_bapiret-number = ‘050‘.

APPEND ls_bapiret TO et_bapiret2.

ENDIF.

ENDMETHOD.

Listing 5.23 Coding on the Method CHECK_HEADER

4. Switch to the method CHECK_ITEM. You basically proceed here as you did with

checking the header data. However, you must also define a local work structure

124

© 2013 by Galileo Press Inc., Boston (MA)

Field Description
TYPE Type of message, for example, ‘E’ for error messages or ‘W’ for warning messages
ID Message class
NUMBER Message number
MESSAGE_V1 – MESSAGE_V4 Optional message variables 1-4 that can be included

第 125 页 / 共 275 页

Checking and Prepopulating Standard Fields 5.3

for your items, and read the suitable item from Table GT_ITEM using the input

parameter I_LINE_ID.

5. You can then carry out your check again. The user should also fill the field ZP_

FELD1. However, only a warning message is displayed if the field is empty (see

Listing 5.24).

METHOD if_ex_mb_migo_badi~check_item.

* Local declarations

DATA: ls_item TYPE ts_migoitem,

ls_bapiret TYPE bapiret2.

* Read item from GT_ITEM

READ TABLE gt_item INTO ls_item

WITH KEY line_id = i_line_id.

IF ls_item-zp_feld1 IS INITIAL.

* Configure warning message

ls_bapiret-type = ‘W’.

ls_bapiret-id = ‘ZMB’.

ls_bapiret-number = ‘051’.

APPEND ls_bapiret TO et_bapiret2.

ENDIF.

ENDMETHOD.

Listing 5.24 Coding on the Method CHECK_ITEM

5.3 Checking and Prepopulating Standard Fields

Standard fields aren’t provided in the check methods of the BAdI MB_MIGO_BADI.

However, you can use the BAdI MB_MIGO_ITEM_BADI to also check these fields.

Furthermore, in this BAdI, you can simply prepopulate the storage location or

the item text. If other fields are prepopulated, you can take another look at the

method LINE_MODIFY in the BAdI MB_MIGO_BADI, which provides more options in

this context.

5.3.1 Prepopulation of Storage Location and Text

The only method of the BAdI MB_MIGO_ITEM_BADI, ITEM_MODIFY is called when new

items are added or the user chooses the Check or Post function. When you fill the

125

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

第 126 页 / 共 275 页

5 User Exits and BAdIs in Inventory Management

export parameter E_STGE_LOC (storage location) or E_ITEM_TEXT (item text) in the

method, these values are set for all new additional items.

5.3.2 Checking the Standard Fields

If the user chooses the Check or Post functions, you can carry out custom checks

and prevent posting if applicable. For this, the header data in parameter IS_GOHEAD

and the item data table IS_GOITEM are provided.

If a message is displayed, you also need a work structure for a return-table with

the type BAPIRET2. Fill the work structure according to Table 5.11 in Section 5.2.2,

Input Checks in Transaction MIGO, and then append the message to internal Table

ET_RETURN, which is also defined in the interface. Because the method ITEM_MODIFY

could be called repeatedly, and Table ET_RETURN is already filled by the previous

call, you should first delete the content; otherwise, the same message could pos-

sibly appear twice in the message log (see Listing 5.25).

METHOD if_ex_mb_migo_item_badi~item_modify.

* Local work structure for the return- table

DATA: ls_bapiret TYPE bapiret2.

* For plant 1000 storage location 0001 is always

* to be suggested.

IF is_goitem-werks = ‘1000’.

e_stge_loc = ‘0001’.

ENDIF.

* Reset return table

REFRESH et_return.

* Header text must be populated

IF is_gohead-bktxt IS INITIAL.

* Configure message, warning

ls_bapiret-type = ‘W’.

ls_bapiret-id = ‘ZMB’.

ls_bapiret-number = ‘060’.

APPEND ls_bapiret TO et_return.

ENDIF.

* Item text must be filled

IF is_goitem-sgtxt IS INITIAL.

* Configure message, error

126

© 2013 by Galileo Press Inc., Boston (MA)

第 127 页 / 共 275 页

Check of the Earliest Delivery Date 5.4

ls_bapiret-type = ‘E’.

ls_bapiret-id = ‘ZMB’.

ls_bapiret-number = ‘061’.

APPEND ls_bapiret TO et_return.

ENDIF.

ENDMETHOD.

Listing 5.25 Coding on the Method ITEM_MODIFY

5.4 Check of the Earliest Delivery Date

You have the option in the purchase order to specify a delivery date. However,

vendors often don’t keep to the delivery date and deliver goods too early. When

this is better controlled, you can set the message M7 254 (“Earliest Possible Deliv-

ery Date is &” as shown in Figure 5.7) as an error message in Customizing. To do

this, choose the Materials Management • Inventory Management and Physical

Inventory • DEFINE Attributes Of System Messages • Settings for System Mes-

sages setting in Transaction SPRO, and define the message M7 254 as type ‘E’.

Figure 5.7 Error Message M7 254

As a result, all goods receipts that are supposed to be posted at an earlier date are

rejected with the error message. However, you can post the goods receipt in the

GR blocked stock (transaction type 103).

In certain circumstances, the settings for such an error message are too strict.

With the enhancement MEFLD004 (EXIT_SAPLEINR_004), you can specify the earliest

delivery date. Let’s assume you have activated the error message. Vendor 1002 is

allowed to deliver before the delivery date specified in the purchase order, but not

before the purchase order date. The following applies to all other vendors: For all

items with material group 00, a delivery of up to seven days prior to the delivery

127

Personal Copy for Yang Meteor, user id a8103f58-81fe-4f49-acf6-cfb58959c618

返回ABAP参考资料列表