*递归的方式实现
FUNCTION zbomexplode .
*"--------------------------------------------------------- *"
*"Local Interface:
*"IMPORTING
*"REFERENCE(MATNR) TYPE MATNR
*"REFERENCE(WERKS) TYPE WERKS_D
*"TABLES
*"PARENT STRUCTURE SBOM
*"CHILDREN STRUCTURE SBOM
*"EXCEPTIONS
*" NO_BOM_FOUND *"----------------------------------------------------------
DATA : it_a TYPE TABLE OF sbom .
DATA : it_b TYPE TABLE OF sbom .
IF parent[] IS INITIAL .
* first time that call to the FM
SELECT stpo ~idnrk INTO TABLE it_a
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
IF it_a[] IS INITIAL .
RAISE no_bom_found .
ENDIF .
ELSE .
SELECT stpo ~idnrk INTO TABLE it_a
FROM mast
INNER JOIN stpo ON mast ~stlnr = stpo ~stlnr
FOR ALL ENTRIES IN parent
WHERE mast ~matnr = parent -matnr
AND mast ~werks = werks .
* if there is no any sub item, then stop the recursion IF it_a[] IS INITIAL.
EXIT .
ENDIF .
ENDIF .
APPEND LINES OF it_a TO children .
* get sub items recursively
CALL FUNCTION 'Z_BOM_EXPLODE'
EXPORTING
matnr = ''
werks = werks
TABLES
parent = it_a
children = it_b .
APPEND LINES OF it_b TO children .
* delete duplicate sub items at the end
IF parent[] IS INITIAL .
SORT children BY matnr .
DELETE ADJACENT DUPLICATES FROM children .
ENDIF .
ENDFUNCTION .
*使用循环代替递归的一种做法1,更便于做异常处理,程序运行时系统也不要维护递归堆栈。这个程序不好的地方在于要用两个itab频繁copy数据。
FUNCTION zbomexplode1 .
*"--------------------------------------------------------- *"
*"Local Interface:
*" IMPORTING
*" VALUE(MATNR) TYPE MATNR
*" VALUE(WERKS) TYPE WERKS_D *" TABLES
*" CHILDREN STRUCTURE SBOM *" EXCEPTIONS
*" NO_BOM_FOUND *"---------------------------------------------------------
DATA : it_a TYPE TABLE OF sbom ,
it_b TYPE TABLE OF sbom ,
it_result TYPE TABLE OF sbom .
SELECT stpo ~idnrk
INTO TABLE it_a
FROM mast
INNER JOIN stpo ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
APPEND LINES OF it_a TO it_result .
WHILE NOT it_a[] IS INITIAL .
SELECT stpo ~idnrk
INTO TABLE it_b
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
FOR ALL ENTRIES IN it_a
WHERE mast ~matnr = it_a -matnr
AND mast ~werks = werks .
APPEND LINES OF it_b TO it_result .
it_a[] = it_b[] .
ENDWHILE .
* delete duplicate sub items
SORT it_result BY matnr .
DELETE ADJACENT DUPLICATES FROM it_result .
children[] = it_result[] .
ENDFUNCTION .
FUNCTION zbomexplode2 .
*"---------------------------------------------------------- *"
*"Local Interface: *" IMPORTING
*" VALUE(MATNR) TYPE MATNR
*" VALUE(WERKS) TYPE WERKS_D
*" TABLES
*" CHILDREN STRUCTURE SBOM
*" EXCEPTIONS *" NO_BOM_FOUND
*"----------------------------------------------------------
DATA : it_result TYPE TABLE OF sbom ,
wa_bom TYPE sbom .
SELECT stpo ~idnrk
INTO TABLE it_result
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
LOOP AT it_result INTO wa_bom .
SELECT stpo ~idnrk
APPENDING TABLE it_result
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = wa_bom -matnr
AND mast ~werks = werks .
ENDLOOP .
* delete duplicate sub items
sort it_result by matnr .
delete adjacent duplicates from it_result .
children[] = it_result[] .
ENDFUNCTION .
*调用BAPI实现
FUNCTION zbomexplode .
*"--------------------------------------------------------- *"
*"Local Interface: *" IMPORTING
*" VALUE(MATNR) LIKE MARA-MATNR
*" VALUE(WERKS) LIKE MARC-WERKS OPTIONAL
*" VALUE(CAPID) LIKE TC04-CAPID DEFAULT 'PP01'
*" TABLES
*" STB STRUCTURE STPOX
*" RETURN STRUCTURE BAPIRET2
*"---------------------------------------------------------
IF werks IS INITIAL . "Added in case external call does not know
werks = '1000' .
ENDIF .
IF capid IS INITIAL .
capid = 'PP01' .
ENDIF .
CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
EXPORTING
capid = capid
datuv = sy -datum
mehrs = 'X'
mtnrv = matnr
werks = werks
TABLES
stb = stb
EXCEPTIONS
no_bom_found = 1 .
IF sy -subrc <> 0 .
msg_typ = 'E' .
msg_id = 'Z_EF' .
msg_no = '002' .
msg_v1 = matnr .
IF NOT msg_typ IS INITIAL .
* append error to table RETURN
CALL FUNCTION 'BALW_BAPIRETURN_GET2'
EXPORTING
type = msg_typ
cl = msg_id
number = msg_no
par1 = msg_v1
par2 = msg_v2
par3 = msg_v3
par4 = msg_v4
parameter = space
row = space
field = space
IMPORTING
return = wa_return_tmp .
APPEND wa_return_tmp TO return .
ENDIF .
ENDIF .
ENDFUNCTION
FUNCTION zbomexplode .
*"--------------------------------------------------------- *"
*"Local Interface:
*"IMPORTING
*"REFERENCE(MATNR) TYPE MATNR
*"REFERENCE(WERKS) TYPE WERKS_D
*"TABLES
*"PARENT STRUCTURE SBOM
*"CHILDREN STRUCTURE SBOM
*"EXCEPTIONS
*" NO_BOM_FOUND *"----------------------------------------------------------
DATA : it_a TYPE TABLE OF sbom .
DATA : it_b TYPE TABLE OF sbom .
IF parent[] IS INITIAL .
* first time that call to the FM
SELECT stpo ~idnrk INTO TABLE it_a
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
IF it_a[] IS INITIAL .
RAISE no_bom_found .
ENDIF .
ELSE .
SELECT stpo ~idnrk INTO TABLE it_a
FROM mast
INNER JOIN stpo ON mast ~stlnr = stpo ~stlnr
FOR ALL ENTRIES IN parent
WHERE mast ~matnr = parent -matnr
AND mast ~werks = werks .
* if there is no any sub item, then stop the recursion IF it_a[] IS INITIAL.
EXIT .
ENDIF .
ENDIF .
APPEND LINES OF it_a TO children .
* get sub items recursively
CALL FUNCTION 'Z_BOM_EXPLODE'
EXPORTING
matnr = ''
werks = werks
TABLES
parent = it_a
children = it_b .
APPEND LINES OF it_b TO children .
* delete duplicate sub items at the end
IF parent[] IS INITIAL .
SORT children BY matnr .
DELETE ADJACENT DUPLICATES FROM children .
ENDIF .
ENDFUNCTION .
*使用循环代替递归的一种做法1,更便于做异常处理,程序运行时系统也不要维护递归堆栈。这个程序不好的地方在于要用两个itab频繁copy数据。
FUNCTION zbomexplode1 .
*"--------------------------------------------------------- *"
*"Local Interface:
*" IMPORTING
*" VALUE(MATNR) TYPE MATNR
*" VALUE(WERKS) TYPE WERKS_D *" TABLES
*" CHILDREN STRUCTURE SBOM *" EXCEPTIONS
*" NO_BOM_FOUND *"---------------------------------------------------------
DATA : it_a TYPE TABLE OF sbom ,
it_b TYPE TABLE OF sbom ,
it_result TYPE TABLE OF sbom .
SELECT stpo ~idnrk
INTO TABLE it_a
FROM mast
INNER JOIN stpo ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
APPEND LINES OF it_a TO it_result .
WHILE NOT it_a[] IS INITIAL .
SELECT stpo ~idnrk
INTO TABLE it_b
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
FOR ALL ENTRIES IN it_a
WHERE mast ~matnr = it_a -matnr
AND mast ~werks = werks .
APPEND LINES OF it_b TO it_result .
it_a[] = it_b[] .
ENDWHILE .
* delete duplicate sub items
SORT it_result BY matnr .
DELETE ADJACENT DUPLICATES FROM it_result .
children[] = it_result[] .
ENDFUNCTION .
FUNCTION zbomexplode2 .
*"---------------------------------------------------------- *"
*"Local Interface: *" IMPORTING
*" VALUE(MATNR) TYPE MATNR
*" VALUE(WERKS) TYPE WERKS_D
*" TABLES
*" CHILDREN STRUCTURE SBOM
*" EXCEPTIONS *" NO_BOM_FOUND
*"----------------------------------------------------------
DATA : it_result TYPE TABLE OF sbom ,
wa_bom TYPE sbom .
SELECT stpo ~idnrk
INTO TABLE it_result
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = matnr
AND mast ~werks = werks .
LOOP AT it_result INTO wa_bom .
SELECT stpo ~idnrk
APPENDING TABLE it_result
FROM mast INNER JOIN stpo
ON mast ~stlnr = stpo ~stlnr
WHERE mast ~matnr = wa_bom -matnr
AND mast ~werks = werks .
ENDLOOP .
* delete duplicate sub items
sort it_result by matnr .
delete adjacent duplicates from it_result .
children[] = it_result[] .
ENDFUNCTION .
*调用BAPI实现
FUNCTION zbomexplode .
*"--------------------------------------------------------- *"
*"Local Interface: *" IMPORTING
*" VALUE(MATNR) LIKE MARA-MATNR
*" VALUE(WERKS) LIKE MARC-WERKS OPTIONAL
*" VALUE(CAPID) LIKE TC04-CAPID DEFAULT 'PP01'
*" TABLES
*" STB STRUCTURE STPOX
*" RETURN STRUCTURE BAPIRET2
*"---------------------------------------------------------
IF werks IS INITIAL . "Added in case external call does not know
werks = '1000' .
ENDIF .
IF capid IS INITIAL .
capid = 'PP01' .
ENDIF .
CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
EXPORTING
capid = capid
datuv = sy -datum
mehrs = 'X'
mtnrv = matnr
werks = werks
TABLES
stb = stb
EXCEPTIONS
no_bom_found = 1 .
IF sy -subrc <> 0 .
msg_typ = 'E' .
msg_id = 'Z_EF' .
msg_no = '002' .
msg_v1 = matnr .
IF NOT msg_typ IS INITIAL .
* append error to table RETURN
CALL FUNCTION 'BALW_BAPIRETURN_GET2'
EXPORTING
type = msg_typ
cl = msg_id
number = msg_no
par1 = msg_v1
par2 = msg_v2
par3 = msg_v3
par4 = msg_v4
parameter = space
row = space
field = space
IMPORTING
return = wa_return_tmp .
APPEND wa_return_tmp TO return .
ENDIF .
ENDIF .
ENDFUNCTION