Once I had to face the following problem, how to programmatically pack all the goods of some delivery including creation of handling units. I have spent quite considerable time finding working solution. You know there is a certain set of various function modules which leads to the solution, but there is big number of blind ways. Even when you pick up proper FMs, you have to use them in correct order and provide correct input parameters. Finally we have decided to pack every delivery item/position into each new HU, not to pack them all into one HU. Below there is offered a solution working in our case. I hope it could save time to someone else. If you would give me your feedback, it would be very nice.
I already tested following FMs as BAPI_HU_CREATE, BAPI_HU_CHANGE_HEADER, BAPI_HU_PACK, SD_DELIVERY_UPDATE_PACKING, WS_DELIVERY_UPDATE, HU_PACKING_AND_UNPACKING.
I discovered that even the transaction VL02N internally calls FM HU_PACKING_AND_UNPACKING. Usage of BAPI_HU_CREATE and BAPI_HU_PACK with itempropsal is Ok unless you do not need to act with delivery. In such case you need to involve some of those FMs as SD_DELIVERY_UPDATE_PACKING or WS_DELIVERY_UPDATE or HU_PACKING_AND_UNPACKING. But HU with already filled item proposals causes doubled items inside the every HU after usage FMs working with the delivery. Later on I came to the folowing solution, ommit every item proposals and let the job on FM WS_DELIVERY_UPDATE with suitable VERPO (VEPO) itab given as parameter.
The following code should be commented enough to follow the main idea.
Some data of top include
TYPES:
abap_bool TYPE c LENGTH 1,
gtty_result TYPE STANDARD TABLE OF bapiret2.
* constants for abap_bool
CONSTANTS:
abap_true TYPE abap_bool VALUE 'X',
abap_false TYPE abap_bool VALUE ' ',
abap_undefined TYPE abap_bool VALUE '-'.
CONSTANTS: cv_vbtyp_notification LIKE likp-vbtyp VALUE '7',
cv_in_delivery LIKE verko-object VALUE '03', " inbound
cv_out_delivery LIKE verko-object VALUE '01', " outbound
cv_velin LIKE vepo-velin VALUE '1',
cv_pksta_packed TYPE pksta VALUE 'C'.
DATA: gv_vbuk TYPE vbuk, " vbuk-pkstk = Overall packing status of all items
gs_likp TYPE likp,
gv_shipment_already_created TYPE abap_bool VALUE abap_false,
gv_pack_mat TYPE mara-matnr.
The main routine
*&---------------------------------------------------------------------*
*& Form pack_delivery
*&---------------------------------------------------------------------*
* Pack whole delivery = all positions
*----------------------------------------------------------------------*
* -->PS_LIKP contains vbeln, vbtyp
* -->PV_PACK_MAT packaging material
*----------------------------------------------------------------------*
FORM pack_delivery
USING ps_likp TYPE likp " contains vbeln, vbtyp
pv_pack_mat TYPE mara-matnr.
DATA: lt_lips TYPE STANDARD TABLE OF lips.
" add leading zeros
UNPACK ps_likp-vbeln TO ps_likp-vbeln.
IF ps_likp-vbeln IS NOT INITIAL.
SELECT * " posnr werks lgort meins lfimg matnr charg ...
FROM lips
INTO CORRESPONDING FIELDS OF TABLE lt_lips
WHERE vbeln = ps_likp-vbeln.
ENDIF.
IF lt_lips IS INITIAL.
MESSAGE e000 WITH text-017.
ENDIF.
DATA: lt_hu LIKE STANDARD TABLE OF hum_rehang_hu,
ls_hu LIKE LINE OF lt_hu,
lv_pksta TYPE vbup-pksta.
DATA: lt_vekp TYPE STANDARD TABLE OF vekp,
lt_vepo TYPE STANDARD TABLE OF vepo,
lv_exidv TYPE exidv.
DATA: ls_vbkok LIKE vbkok,
lt_hus LIKE STANDARD TABLE OF vekpvb,
ls_hus LIKE LINE OF lt_hus.
" Handling-Unit Confirmation: Header Data
DATA: lt_verko LIKE STANDARD TABLE OF verko,
ls_verko TYPE verko,
" Handling Unit Confirmation: Content Data
lt_verpo LIKE STANDARD TABLE OF verpo,
ls_verpo TYPE verpo,
lt_prot LIKE STANDARD TABLE OF prott,
ls_prot TYPE prott.
FIELD-SYMBOLS: <fs_vekp> LIKE vekp,
<fs_vepo> LIKE vepo,
<fs_lips> LIKE lips.
" Pack each non empty delivery position into its own new HU
LOOP AT lt_lips ASSIGNING <fs_lips>.
IF ( <fs_lips>-lfimg IS NOT INITIAL ) AND ( <fs_lips>-lfimg > 0 ).
" Filter already packed items
CLEAR lv_pksta.
SELECT SINGLE pksta
FROM vbup
INTO lv_pksta
WHERE vbeln = <fs_lips>-vbeln
AND
posnr = <fs_lips>-posnr.
IF NOT ( ( sy-subrc EQ 0 ) AND ( lv_pksta NE cv_pksta_packed ) ).
CONTINUE.
ENDIF.
" Create HU and assign it to the delivery (no items are yet created)
CLEAR ls_hu.
PERFORM get_assigned_hu
USING <fs_lips>
pv_pack_mat
ps_likp-vbtyp
CHANGING ls_hu.
" Get data needed for delivery packing
IF ls_hu IS NOT INITIAL.
APPEND ls_hu TO lt_hu.
" FM HU_CREATE alredy made record in VEKP table
SELECT * FROM vekp
INTO TABLE lt_vekp
WHERE venum = ls_hu-venum.
LOOP AT lt_vekp ASSIGNING <fs_vekp>.
CLEAR ls_verko.
MOVE-CORRESPONDING <fs_vekp> TO ls_verko.
ls_verko-ernam = sy-uname.
ls_verko-object = cv_out_delivery. " Outbound Delivery
ls_verko-objkey = ps_likp-vbeln. " Object to Which the HU is Assigned
ls_verko-exidv = <fs_vekp>-exidv.
APPEND ls_verko TO lt_verko.
ENDLOOP.
" Prepare item row (later stored in VEPO)
" in our case 1x HU = 1 x item row = no loop needed
" new HU
ls_verpo-exidv_ob = ls_hu-top_hu_external.
ls_verpo-venum = ls_hu-venum.
" other lips fields
MOVE-CORRESPONDING <fs_lips> TO ls_verpo.
" quantity + units
ls_verpo-tmeng = <fs_lips>-lfimg.
ls_verpo-vrkme = <fs_lips>-meins.
APPEND ls_verpo TO lt_verpo.
ENDIF.
ENDIF.
ENDLOOP.
IF ( lt_verko IS NOT INITIAL ) AND ( lt_verpo IS NOT INITIAL ).
ls_vbkok-vbeln = <fs_lips>-vbeln.
ls_vbkok-vbeln_vl = <fs_lips>-vbeln.
ls_vbkok-vbtyp_vl = ps_likp-vbtyp.
" Save Handling unit data, pack, update delivery
CALL FUNCTION 'WS_DELIVERY_UPDATE'
EXPORTING
vbkok_wa = ls_vbkok
synchron = abap_true
commit = abap_true
delivery = <fs_lips>-vbeln
nicht_sperren = space
TABLES
verko_tab = lt_verko
verpo_tab = lt_verpo
prot = lt_prot.
IF NOT lt_prot[] IS INITIAL.
CLEAR: ls_prot.
READ TABLE lt_prot INDEX 1 INTO ls_prot.
MESSAGE ID ls_prot-msgid
TYPE ls_prot-msgty
NUMBER ls_prot-msgno
WITH ls_prot-msgv1 ls_prot-msgv2
ls_prot-msgv3 ls_prot-msgv4.
ENDIF.
ENDIF.
ENDFORM. " PACK_DELIVERY
*&---------------------------------------------------------------------*
*& Form GET_ASSIGNED_HU
*&---------------------------------------------------------------------*
* Create empty HU and assign it to the delivery
*----------------------------------------------------------------------*
* -->PV_VBELN text
* -->PV_PACK_MAT text
* -->PV_VBTYP text
*----------------------------------------------------------------------*
FORM get_assigned_hu
USING ps_lips TYPE lips " delivery position data
pv_pack_mat TYPE mara-matnr
pv_vbtyp TYPE vbtyp
CHANGING ps_hu TYPE hum_rehang_hu.
DATA: lt_return LIKE STANDARD TABLE OF bapiret2,
ls_return LIKE LINE OF lt_return,
lv_hukey TYPE bapihukey-hu_exid,
ls_huheader TYPE bapihuheader,
ls_headerproposal TYPE bapihuhdrproposal,
lt_itemproposal TYPE STANDARD TABLE OF bapihuitmproposal,
ls_itemproposal LIKE LINE OF lt_itemproposal.
" Subprocess 1: Create HU
" HU header proposal
ls_headerproposal-plant = ps_lips-werks.
MOVE ps_lips-lgort TO ls_headerproposal-stge_loc. " storage location
UNPACK pv_pack_mat TO pv_pack_mat.
ls_headerproposal-pack_mat = pv_pack_mat.
" creates record in VEKP (with item proposal given also in VEPO)
CALL FUNCTION 'BAPI_HU_CREATE'
EXPORTING
headerproposal = ls_headerproposal
IMPORTING
huheader = ls_huheader
hukey = lv_hukey
TABLES
itemsproposal = lt_itemproposal
return = lt_return.
IF lt_return[] IS INITIAL.
CLEAR ls_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = ls_return.
ELSE.
PERFORM get_bapi_error USING lt_return.
ENDIF.
" Wait to avoid lock in production environment
WAIT UP TO 1 SECONDS.
" Set connection to the outbound delivery type (pack_mat_object)
MOVE cv_out_delivery TO ls_huheader-pack_mat_object.
MOVE ps_lips-vbeln TO ls_huheader-pack_mat_obj_key.
REFRESH lt_return.
CALL FUNCTION 'BAPI_HU_CHANGE_HEADER'
EXPORTING
hukey = ls_huheader-hu_exid
huchanged = ls_huheader
IMPORTING
huheader = ls_huheader
TABLES
return = lt_return.
IF lt_return[] IS INITIAL.
CLEAR ls_return.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = ls_return.
ELSE.
PERFORM get_bapi_error USING lt_return.
ENDIF.
CLEAR ps_hu.
" note: hu_exid + hu_id are stored in VEKP - Handling Unit - Header Table
ps_hu-top_hu_external = ls_huheader-hu_exid. " External Handling Unit Identification of new HU
ps_hu-top_hu_internal = ls_huheader-hu_id. " Internal Handling Unit Number of new HU
ps_hu-venum = ls_huheader-hu_id. " Internal Handling Unit Number of new HU
ps_hu-rfbel = ps_lips-vbeln.
ps_hu-rfpos = ps_lips-posnr.
ENDFORM. " GET_ASSIGNED_HU
*&---------------------------------------------------------------------*
*& Form GET_BAPI_ERROR
*&---------------------------------------------------------------------*
* Checks errors in result table
*----------------------------------------------------------------------*
* -->P_LT_RETURN text
*----------------------------------------------------------------------*
FORM get_bapi_error
USING pt_return TYPE gtty_result.
FIELD-SYMBOLS: <fs_return> LIKE bapiret2.
LOOP AT pt_return ASSIGNING <fs_return>.
IF <fs_return>-type = 'E' OR <fs_return>-type = 'A'.
MESSAGE ID <fs_return>-id
TYPE <fs_return>-type
NUMBER <fs_return>-number
WITH <fs_return>-message_v1 <fs_return>-message_v2
<fs_return>-message_v3 <fs_return>-message_v4.
LEAVE SCREEN.
ENDIF.
ENDLOOP.
ENDFORM. " GET_BAPI_ERROR
Wednesday, March 19, 2014
Tuesday, March 4, 2014
Vendor filtering - The Collective search help exit for KRED
Intro
This article describes one really common task, how to filter vendors of too much generous search help based on authorization object. The solution is search help exit. Ok, here we focus on the solution for SAP collective search help the name KRED, which is widely used in many transactions e.g. FK03, XK03, MK03 and so on. The main idea for below solution is catched from Brad Bohn suggestion, see SAP forum at http://scn.sap.com/thread/1831345.Filtered LIFNR and it's search help exit
The collective search help KRED
contains quite a lot of elementary search helps. We can assign to every sub search help it is own search help exit. Ok, it would work, but lose central management point and it brings furthermore some more work.The nice way seems to be usage of search help exit directly on the KRED search help itself.
When you try to establish your own function module for search help exit, you will be asked for Access key for your installation. Here ask your BC team.
The elementary search help exit injection
If you do that you will discover one unpleasant thing. The return data are not processed through your custom search help exit on collective level. So, what to do? Fortunately we are given the list of elementary search helps inside the collective one. See internal table SHLP_TAB[]. Each search help contains structure intdescr and it has the field selmexit, what is the name of the search help exit. We can programmatically inject our own search help exit for each one search help in a loop.See the code below:
constants: cv_root_shlp_name type shlpname value 'KRED',
cv_shlp_exit_name type string value '/YourNamespace/H_FI_F4UT_KRED'.
field-symbols: <fs_shlp> type line of shlp_desct.
if ( shlp-shlpname eq cv_root_shlp_name ) and ( shlp_tab[] is not initial ).
loop at shlp_tab[] assigning <fs_shlp>.
if not <fs_shlp>-intdescr is initial.
<fs_shlp>-intdescr-selmexit = cv_shlp_exit_name.
endif.
endloop.
endif.
field-symbols: <fs_shlp> type line of shlp_desct.
if ( shlp-shlpname eq cv_root_shlp_name ) and ( shlp_tab[] is not initial ).
loop at shlp_tab[] assigning <fs_shlp>.
if not <fs_shlp>-intdescr is initial.
<fs_shlp>-intdescr-selmexit = cv_shlp_exit_name.
endif.
endloop.
endif.
The post selection filtering
Now comes the task of filtering the data. We used here the same func. module for collective search help and it is elementary search helps. So filtering has to be active just for elementary helps.There is more events triggering our search help exit. We need to focus on just one, the POSTSEL. The post selection is the right place to filter data returned to user before displaying.
Here is just worthy to mention that looping over authorization object check is quite slow solution. The better and faster way is to load all fields of authorization object into internal table and process it by yourself.
Authorization object
Just action number 3 the displaying is what we are looking for.
Classic slow/simple code example
DATA: i TYPE i.
LOOP AT results_tab.
i = sy-tabix.
AUTHORITY-CHECK OBJECT 'F_LFA1_GRP'
ID 'KTOKK' FIELD results_tab-ktokk
ID 'ACTVT' FIELD '03'. "For Display
IF sy-subrc <> 0.
* Delete the corresponding entry in RECORD_TAB.
DELETE record_tab INDEX i.
* Keep SY-TABIX of record_tab and results_tab synchronous
DELETE results_tab.
ENDIF.
ENDLOOP.
Here we need to find a bit faster solution over classic check above.
Read authorization object at once
CONSTANTS cv_auth_object TYPE ust12-objct VALUE 'F_LFA1_GRP'.
FIELD-SYMBOLS <fs_usvalues> TYPE usvalues.
DATA: lt_usvalues TYPE STANDARD TABLE OF usvalues.
CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
EXPORTING
user_name = sy-uname
sel_object = cv_auth_object
TABLES
values = lt_usvalues.
FIELD-SYMBOLS <fs_usvalues> TYPE usvalues.
DATA: lt_usvalues TYPE STANDARD TABLE OF usvalues.
CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
EXPORTING
user_name = sy-uname
sel_object = cv_auth_object
TABLES
values = lt_usvalues.
constants cv_allowed_actvt type i value 3.
loop at lt_usvalues assigning <fs_usvalues>.
" Check ACTVT ( later filter KTOKK by ACTVT)
if <fs_usvalues>-field eq 'ACTVT'.
if <fs_usvalues>-von eq '*'.
lv_actvt_ok = abap_true.
exit.
elseif ( <fs_usvalues>-von is not initial ) and ( <fs_usvalues>-bis is not initial ).
move <fs_usvalues>-von to lv_actvt.
if cv_allowed_actvt eq lv_actvt.
lv_actvt_ok = abap_true.
exit.
elseif cv_allowed_actvt ge lv_actvt.
move <fs_usvalues>-bis to lv_actvt.
if cv_allowed_actvt le lv_actvt.
lv_actvt_ok = abap_true.
exit.
endif.
endif.
elseif ( <fs_usvalues>-von is not initial ).
move <fs_usvalues>-von to lv_actvt.
if cv_allowed_actvt eq lv_actvt.
lv_actvt_ok = abap_true.
exit.
endif.
endif.
endif.
endloop.
Next step is to fill out custom select option table and used it in further SQL selection with table LFA1.
Selection of allowed vendors as the second step
The result itab lt_usvalues is later converted into select-option based itab for SQL select.
ls_ktokk_selopt LIKE LINE OF lt_ktokk_selopt.
IF lv_actvt_ok EQ abap_true.
LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
" Pickup KTOKK patterns in case of positive ACTVT
" Prepare select option intab for SQL query
IF <fs_usvalues>-field EQ 'KTOKK'.
CLEAR ls_ktokk_selopt.
ls_ktokk_selopt-sign = 'I'.
ls_ktokk_selopt-low = <fs_usvalues>-von.
IF <fs_usvalues>-bis IS NOT INITIAL.
ls_ktokk_selopt-high = <fs_usvalues>-bis.
ls_ktokk_selopt-option = 'BT'.
ELSEIF ( <fs_usvalues>-von CS '*' ) OR ( <fs_usvalues>-von CS '?' ).
ls_ktokk_selopt-option = 'CP'.
ELSE.
ls_ktokk_selopt-option = 'EQ'.
ENDIF.
APPEND ls_ktokk_selopt TO lt_ktokk_selopt.
ENDIF.
ENDLOOP.
ENDIF.
The data of select-option table would look like
" Get allowed LIFNR based on KTOKK patterns
data lt_lifnr_ok type standard table of lfa1-lifnr.
if lt_ktokk_selopt is not initial.
select lifnr from lfa1
into table lt_lifnr_ok
where ktokk in lt_ktokk_selopt
order by ktokk.
endif.
Now we have all possible LIFNRs which can be offered to user based on authorization object. The last point is just to exclude all unauthorized vendors before displaying.
Exclude unallowed LIFNRs from result
data: lv_i type i,
ls_lifnr_ok like line of lt_lifnr_ok.
loop at results_tab.
lv_i = sy-tabix.
read table lt_lifnr_ok into ls_lifnr_ok with key results_tab-lifnr.
if sy-subrc <> 0.
* Delete the corresponding entry in RECORD_TAB.
delete record_tab index lv_i.
* Keep SY-TABIX of record_tab and results_tab synchronous
delete results_tab.
endif.
endloop.
Now all vendors of any sub-elementary search help are going to be filtered via our exit function module.
See the whole FM's code for convenience
FUNCTION /YourNameSpace/h_fi_f4ut_kred.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" TABLES
*" SHLP_TAB TYPE SHLP_DESCT
*" RECORD_TAB STRUCTURE SEAHLPRES
*" CHANGING
*" VALUE(SHLP) TYPE SHLP_DESCR
*" VALUE(CALLCONTROL) LIKE DDSHF4CTRL STRUCTURE DDSHF4CTRL
*"----------------------------------------------------------------------
TYPES:
abap_bool TYPE c LENGTH 1.
* constants for abap_bool
CONSTANTS:
abap_true TYPE abap_bool VALUE 'X',
abap_false TYPE abap_bool VALUE ' ',
abap_undefined TYPE abap_bool VALUE '-'.
DATA: BEGIN OF results_tab OCCURS 0,
lifnr TYPE lifnr,
END OF results_tab.
* Enable the postprocessing of selected values
CALL FUNCTION 'F4UT_POST_SELECTION_PROCESSING'
TABLES
shlp_tab = shlp_tab
record_tab = record_tab
CHANGING
shlp = shlp
callcontrol = callcontrol.
* Assign search help exit func. module injection to every child
* elementary sub search helps of main collective search help the name KRED
CONSTANTS: cv_root_shlp_name TYPE shlpname VALUE 'KRED',
cv_shlp_exit_name TYPE string VALUE '/YourNameSpace/H_FI_F4UT_KRED'.
FIELD-SYMBOLS: <fs_shlp> TYPE LINE OF shlp_desct.
IF ( shlp-shlpname EQ cv_root_shlp_name ) AND ( shlp_tab[] IS NOT INITIAL ).
LOOP AT shlp_tab[] ASSIGNING <fs_shlp>.
IF NOT <fs_shlp>-intdescr IS INITIAL.
<fs_shlp>-intdescr-selmexit = cv_shlp_exit_name.
ENDIF.
ENDLOOP.
ENDIF.
* Do selection before displaying the results to user
* (It is triggered on elementary child search helps)
IF callcontrol-step = 'POSTSEL'.
" Get result data to be filtered
CALL FUNCTION 'F4UT_PARAMETER_VALUE_GET'
EXPORTING
parameter = 'LIFNR' "Searchhelp-Parameter
fieldname = 'LIFNR' "Fieldname in RESULTS_TAB
TABLES
shlp_tab = shlp_tab
record_tab = record_tab
results_tab = results_tab
CHANGING
shlp = shlp
callcontrol = callcontrol.
IF results_tab[] IS NOT INITIAL.
" We have some data to be filtered
CONSTANTS cv_auth_object TYPE ust12-objct VALUE 'F_LFA1_GRP'.
FIELD-SYMBOLS <fs_usvalues> TYPE usvalues.
DATA: lt_usvalues TYPE STANDARD TABLE OF usvalues.
CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
EXPORTING
user_name = sy-uname
sel_object = cv_auth_object
TABLES
values = lt_usvalues.
IF lt_usvalues IS INITIAL.
" 1) No auth object at all --> no result
REFRESH results_tab[].
ELSE.
" 2) Filtering part
DATA: lv_actvt TYPE i,
lv_actvt_ok TYPE abap_bool VALUE abap_false.
CONSTANTS cv_allowed_actvt TYPE i VALUE 3.
LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
" 2 A) Check ACTVT ( later filter KTOKK by ACTVT)
IF <fs_usvalues>-field EQ 'ACTVT'.
IF <fs_usvalues>-von EQ '*'.
lv_actvt_ok = abap_true.
EXIT.
ELSEIF ( <fs_usvalues>-von IS NOT INITIAL ) AND ( <fs_usvalues>-bis IS NOT INITIAL ).
MOVE <fs_usvalues>-von TO lv_actvt.
IF cv_allowed_actvt EQ lv_actvt.
lv_actvt_ok = abap_true.
EXIT.
ELSEIF cv_allowed_actvt GE lv_actvt.
MOVE <fs_usvalues>-bis TO lv_actvt.
IF cv_allowed_actvt LE lv_actvt.
lv_actvt_ok = abap_true.
EXIT.
ENDIF.
ENDIF.
ELSEIF ( <fs_usvalues>-von IS NOT INITIAL ).
MOVE <fs_usvalues>-von TO lv_actvt.
IF cv_allowed_actvt EQ lv_actvt.
lv_actvt_ok = abap_true.
EXIT.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
DATA: lt_ktokk_selopt TYPE STANDARD TABLE OF ers_range_option,
ls_ktokk_selopt LIKE LINE OF lt_ktokk_selopt.
IF lv_actvt_ok EQ abap_true.
LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
" Pickup KTOKK patterns in case of positive ACTVT
" Prepare select option intab for SQL query
IF <fs_usvalues>-field EQ 'KTOKK'.
CLEAR ls_ktokk_selopt.
ls_ktokk_selopt-sign = 'I'.
ls_ktokk_selopt-low = <fs_usvalues>-von.
IF <fs_usvalues>-bis IS NOT INITIAL.
ls_ktokk_selopt-high = <fs_usvalues>-bis.
ls_ktokk_selopt-option = 'BT'.
ELSEIF ( <fs_usvalues>-von CS '*' ) OR ( <fs_usvalues>-von CS '?' ).
ls_ktokk_selopt-option = 'CP'.
ELSE.
ls_ktokk_selopt-option = 'EQ'.
ENDIF.
APPEND ls_ktokk_selopt TO lt_ktokk_selopt.
ENDIF.
ENDLOOP.
ENDIF.
" 2 B) Get allowed LIFNR based on KTOKK patterns
DATA lt_lifnr_ok TYPE STANDARD TABLE OF lfa1-lifnr.
IF lt_ktokk_selopt IS NOT INITIAL.
SELECT lifnr FROM lfa1
INTO TABLE lt_lifnr_ok
WHERE ktokk IN lt_ktokk_selopt
ORDER BY ktokk.
ENDIF.
ENDIF.
ENDIF.
" 3) Exclude unallowed LIFNRs from result
DATA: lv_i TYPE i,
ls_lifnr_ok LIKE LINE OF lt_lifnr_ok.
LOOP AT results_tab.
lv_i = sy-tabix.
READ TABLE lt_lifnr_ok INTO ls_lifnr_ok WITH KEY results_tab-lifnr.
IF sy-subrc <> 0.
* Delete the corresponding entry in RECORD_TAB.
DELETE record_tab INDEX lv_i.
* Keep SY-TABIX of record_tab and results_tab synchronous
DELETE results_tab.
ENDIF.
ENDLOOP.
ENDIF.
ENDFUNCTION.
Subscribe to:
Posts (Atom)