第 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