Purpose
Check the number of phantoms on the same level of BOM which exceeds 99.
Overview
If the number of phantom items is over 99 on one level of BOM a dump occurs with error CO889 "Too many dummies on level / of BOM:" when production orders are created. There should not be more than 99 phantoms on one level in BOM as the length of field for which counts the phantoms is only 2, so the BOM structure need to be adjusted, e.g. reduce the number of phantoms, but it is not so easy to find those phantoms if the BOM is big and complex. Thus, a report program Z_NUMBER_OF_PHANTOMS_IN_BOM below is developed to identify and display them.
Any suggestions to make it better would be highly appreciated.
Here is the screen shot of the dump.
Source code
*&---------------------------------------------------------------------*
*& Report Z_NUMBER_OF_PHANTOMS_IN_BOM
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
report z_number_of_phantoms_in_bom line-size 160
no standard page heading.
tables: mast,
afpo,
stpox,
rc29l.
data: begin of stb occurs 1000.
include structure stpox.
data: number(8) type p.
data: seq type p. "To remember the position of component
data: end of stb.
* Materialkatalog
data: begin of matcat occurs 50.
include structure cscmat.
data: end of matcat.
data: begin of level occurs 50,
astov type stpox-astov,
overflow(1) type c,
totalnum(8) type p. "Total number of phantoms.
data: end of level.
data: begin of selpool.
include structure cstmat.
data: end of selpool.
data: dstst_flag like csdata-xfeld,
bomexist like sy-tabix,
l_stufe_max type aufst,
l_weg_max type aufwg.
* set maximum values.
clear: l_stufe_max with '9',
l_weg_max with '9'.
* Material BOM
parameters: material type mast-matnr obligatory,
plant type mast-werks obligatory,
usage type mast-stlan obligatory,
alt_bom type mast-stlal,
applictn type rc29l-capid default 'PP01',
key_date type sy-datum default sy-datum,
maxlevel type rc29l-maxst.
* Sales order BOM
selection-screen begin of block order_bom with frame title text2.
parameters: ord_num like afpo-kdauf,
ord_item like afpo-kdpos.
selection-screen end of block order_bom.
* WBS BOM
selection-screen begin of block wbs_bom with frame title text3.
parameters: wbs like afpo-projn.
selection-screen end of block wbs_bom.
initialization.
text2 = 'Sales order BOM'.
text3 = 'WBS BOM'.
top-of-page.
perform print_header.
start-of-selection.
* BOM explosion
perform bom_explosion.
* Check the number of phanotoms
perform stufe_weg_renumber tables stb.
* Display BOM.
perform display_bom.
*&---------------------------------------------------------------------*
*& Form BOM_EXPLOSION
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form bom_explosion .
if ord_num is initial and wbs is initial and not material is initial.
perform material_bom_explosion.
elseif not ord_num is initial and wbs is initial.
perform sales_order_bom_explosion.
elseif ord_num is initial and not wbs is initial.
perform wbs_bom_explosion.
elseif not ord_num is initial and not wbs is initial.
message 'Please input the sales order number OR the WBS number, not both.' type 'I'.
endif.
endform. " BOM_EXPLOSION
*&---------------------------------------------------------------------*
*& Form MATERIAL_BOM_EXPLOSION
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form material_bom_explosion .
call function 'CS_BOM_EXPL_MAT_V2'
exporting
verid = ' '
svwvo = 'X'
mktls = space
mmory = '1'
aumgb = 'X' "Ausschu? berechnen
aufsw = 'X'
auskz = 'X' "Ausschu? berücks.
amind = 'X' "Baugrp.ausschu? gesetzt
aumng = 0 "Ausschuss-Menge
bgixo = 'X'
capid = applictn "Anwken.TC04
cospr = 'X'
cuobj = 0
cuovs = 0
cuols = 'X'
datuv = key_date "Datum gültig am
emeng = 1 "Einsatzmenge
mehrs = 'X' "mehrstufige Aufl?sung
splww = ' ' "kein Stopp bei Werkswechsel
mtnrv = material "Material
mdmps = 'X' "Limited multi-level - explode phantom assemblies at least !!!
rndkz = '3'
sanfr = 'X'
stlal = alt_bom
stlan = usage
werks = plant "Werk
ftrel = 'X' "Limited multi-level - stop explosion at items not relevant to production !!!
mkmat = 'X' "Kz. Lagertype
panot = 'X' "This should be 'X', otherwise a raw is treated as a phantom !!!!!
ehndl = '2' "dummy mit ewahr
qverw = '6'
chlst = 'X' "new sel method with quota
knfba = space
stpst = maxlevel
importing
topmat = selpool
dstst = dstst_flag "YHG132854
tables
stb = stb
matcat = matcat
exceptions
material_not_found = 4
no_plant_data = 8
no_bom_found = 12
no_suitable_bom_found = 16
alt_not_found = 24
missing_authorization = 28 "HGD059252
conversion_error = 36. "HGD059252
clear bomexist.
describe table stb lines bomexist.
if bomexist = 0.
message 'No BOM is found.' type 'E'.
endif.
endform. " MATERIAL_BOM_EXPLOSION
*&---------------------------------------------------------------------*
*& Form SALES_ORDER_BOM_EXPLOSION
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form sales_order_bom_explosion .
call function 'CS_BOM_EXPL_KND_V1'
exporting
vbeln = ord_num
vbpos = ord_item
verid = ' '
svwvo = 'X'
mktls = space
mmory = '1'
aumgb = 'X' "Ausschuß berechnen
aufsw = 'X'
auskz = 'X' "Ausschuß berücks.
amind = 'X' "Baugrp.ausschuß gesetzt
aumng = 0 "Ausschuss-Menge
bgixo = 'X'
capid = applictn "Anwken.TC04
cospr = 'X'
cuobj = 0
cuovs = 0
cuols = 'X'
datuv = key_date "Datum gültig am
emeng = 1 "Einsatzmenge
mehrs = 'X' "mehrstufige Auflösung
* splww = ' ' "kein Stopp bei Werkswechsel
mtnrv = material "Material
mdmps = 'X' "Limited multi-level - explode phantom assemblies at least !!!
rndkz = '3'
sanfr = 'X'
stlal = alt_bom
stlan = usage
werks = plant "Werk
ftrel = 'X' "Limited multi-level - stop explosion at items not relevant to production !!!
* mkmat = space "Kz. Lagertype
panot = 'X' "This should be 'X', otherwise a raw is treated a phantom !!!!!
ehndl = '2' "dummy mit ewahr
qverw = '6'
chlst = 'X' "new sel method with quota
knfba = space
stpst = maxlevel
importing
topmat = selpool
dstst = dstst_flag "YHG132854
tables
stb = stb
matcat = matcat
exceptions
material_not_found = 4
no_plant_data = 8
no_bom_found = 12
no_suitable_bom_found = 16
alt_not_found = 24
missing_authorization = 28 "HGD059252
conversion_error = 36. "HGD059252
clear bomexist.
describe table stb lines bomexist.
if bomexist = 0.
message 'No BOM is found.' type 'E'.
endif.
endform. " SALES_ORDER_BOM_EXPLOSION
*&---------------------------------------------------------------------*
*& Form WBS_BOM_EXPLOSION
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form wbs_bom_explosion .
call function 'CS_BOM_EXPL_PSP_V1'
exporting
pspnr = wbs
verid = ' '
svwvo = 'X'
mktls = space
mmory = '1'
aumgb = 'X' "Ausschuß berechnen
aufsw = 'X'
auskz = 'X' "Ausschuß berücks.
amind = 'X' "Baugrp.ausschuß gesetzt
aumng = 0 "Ausschuss-Menge
bgixo = 'X'
capid = applictn "Anwken.TC04
cospr = 'X'
cuobj = 0
cuovs = 0
cuols = 'X'
datuv = key_date "Datum gültig am
emeng = 1 "Einsatzmenge
mehrs = 'X' "mehrstufige Auflösung
* splww = ' ' "kein Stopp bei Werkswechsel
mtnrv = material "Material
mdmps = 'X' "Limited multi-level - explode phantom assemblies at least !!!
rndkz = '3'
sanfr = 'X'
stlal = alt_bom
stlan = usage
werks = plant "Werk
ftrel = 'X' "Limited multi-level - stop explosion at items not relevant to production !!!
* mkmat = space "Kz. Lagertype
panot = 'X' "This should be 'X', otherwise a raw is treated a phantom !!!!!
ehndl = '2' "dummy mit ewahr
qverw = '6'
chlst = 'X' "new sel method with quota
knfba = space
stpst = maxlevel
importing
topmat = selpool
dstst = dstst_flag "YHG132854
tables
stb = stb
matcat = matcat
exceptions
material_not_found = 4
no_plant_data = 8
no_bom_found = 12
no_suitable_bom_found = 16
alt_not_found = 24
missing_authorization = 28 "HGD059252
conversion_error = 36. "HGD059252
clear bomexist.
describe table stb lines bomexist.
if bomexist = 0.
message 'No BOM is found.' type 'E'.
endif.
endform. " WBS_BOM_EXPLOSION
*&---------------------------------------------------------------------*
*& Form stufe_weg_renumber
*&---------------------------------------------------------------------*
form stufe_weg_renumber tables ct_stb structure stb.
types: begin of s_stufe_weg,
astov_old like stb-astov,
awgov_old like stb-awgov,
astov like stb-astov,
awgov like stb-awgov,
end of s_stufe_weg.
data: l_stufe_act like stb-astov,
l_weg_act like stb-awgov,
lts_stufe_weg type sorted table of s_stufe_weg
with unique key astov_old awgov_old,
ls_stufe_weg type s_stufe_weg,
l_seq type p.
* Remember the original position of component in BOM structure before being sorted.
clear: l_seq, ct_stb.
loop at ct_stb.
l_seq = l_seq + 1.
ct_stb-seq = l_seq.
modify ct_stb.
endloop.
* sort by overflow fields
sort stb by astov awgov bstov posnr.
loop at ct_stb.
if ct_stb-astov <> ct_stb-bstov.
* dummy
if l_stufe_act <> ct_stb-astov.
* new level
l_stufe_act = ct_stb-astov.
clear l_weg_act.
endif.
l_weg_act = l_weg_act + 1.
* remember the number of phantom
ct_stb-number = l_weg_act.
modify ct_stb.
if ct_stb-awgov > l_weg_act.
* there is a gap in AUFWG => renumber
ls_stufe_weg-astov_old = ct_stb-astov.
ls_stufe_weg-awgov_old = ct_stb-awgov.
ct_stb-awgov = l_weg_act.
if ct_stb-astov <= l_stufe_max
and ct_stb-awgov <= l_weg_max.
ct_stb-aufst = ct_stb-astov.
ct_stb-aufwg = ct_stb-awgov.
else.
* we still have an overflow
clear: ct_stb-aufst,
ct_stb-aufwg.
endif.
ls_stufe_weg-astov = ct_stb-astov.
ls_stufe_weg-awgov = ct_stb-awgov.
modify ct_stb.
insert ls_stufe_weg into table lts_stufe_weg.
endif.
endif.
* check AUFST/AUFWG corresponding to BAUST/BAUWG
read table lts_stufe_weg into ls_stufe_weg
with key astov_old = ct_stb-bstov
awgov_old = ct_stb-bwgov.
if sy-subrc is initial.
* corresponding AUFST/AUFWG was renumbered
* => adjust BAUST/BAUWG
if ct_stb-astov = ct_stb-bstov.
* component => also adjust AUFST/AUFWG
ct_stb-astov = ls_stufe_weg-astov.
ct_stb-awgov = ls_stufe_weg-awgov.
if ct_stb-astov <= l_stufe_max
and ct_stb-awgov <= l_weg_max.
ct_stb-aufst = ct_stb-astov.
ct_stb-aufwg = ct_stb-awgov.
else.
* we still have an overflow
clear: ct_stb-aufst,
ct_stb-aufwg.
endif.
endif.
* now adjust BAUST/BAUWG
ct_stb-bstov = ls_stufe_weg-astov.
ct_stb-bwgov = ls_stufe_weg-awgov.
if ct_stb-bstov <= l_stufe_max
and ct_stb-bwgov <= l_weg_max.
ct_stb-baust = ct_stb-bstov.
ct_stb-bauwg = ct_stb-bwgov.
else.
* we still have an overflow
clear: ct_stb-baust,
ct_stb-bauwg.
endif.
modify ct_stb.
endif.
if ct_stb-aufst <> ct_stb-astov.
* still overflow in AUFST/AUFWG for dummies => dump because
* of too many dummies on one level (see note 431085)
* remember the level which has overflow.
loop at level where astov = ct_stb-astov.
if ct_stb-number > level-totalnum.
level-totalnum = ct_stb-number.
modify level.
clear level.
endif.
exit.
endloop.
if sy-subrc <> 0.
level-astov = ct_stb-astov.
level-overflow = 'X'.
level-totalnum = ct_stb-number.
append level.
clear level.
endif.
endif.
endloop.
* Delete the number of phantoms for the level which doesn't have overflow.
loop at ct_stb.
read table level with key astov = ct_stb-astov
overflow = 'X'.
if sy-subrc <> 0.
clear ct_stb-number.
modify ct_stb.
clear ct_stb.
endif.
endloop.
endform. " stufe_weg_renumber
*&---------------------------------------------------------------------*
*& Form PRINT_HEADER
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form print_header .
* Shows the levels who have more than 99/9999 phantoms.
loop at level where overflow = 'X'.
write:/ 'The level', level-astov, 'has', level-totalnum no-gap, 'phantoms which are more than', l_weg_max no-gap, '.'.
endloop.
format: color 1.
uline at /(82).
write: / '|', 2 'Material: ', material, 32 'Plant: ', plant,
46 'Alternative BOM: ', selpool-stlal,
68 'Usage: ', selpool-stlan, 82 '|'.
format: color off.
write: ' * This report simulates the BOM explosion of production orders, so only the'.
format: color 1.
write: / '|', 2 'Sales order number and item: ', ord_num, '/', ord_item,
82 '|'.
format: color off.
write: ' production necessary components are displayed.'.
format: color 1.
write: / '|', 2 'WBS Number: ', wbs, 82 '|'.
format: color off.
write: ' * Only the phantoms whose total number exceeds', l_weg_max, 'are highlighted in blue.'.
format: color 1.
write: / '|', 2 'Key date: ', key_date, 82 '|'.
format: color off.
write: ' * The last column is the counted number of current phantom on the same'.
format: color off.
uline at /(82).
write: ' level, so the last phantom has the total number of phantoms.'.
format: color 5.
write: / '|', 'Level No.', 16 'Item', 22 'Component', 41 'Quantity',
59 'Unit'.
format: color 7.
write: 64 'Count Phantoms'.
write: 82 '|'.
format: color off.
uline at /(82).
endform. " PRINT_HEADER
*&---------------------------------------------------------------------*
*& Form DISPLAY_BOM
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form display_bom .
* Sort by BOM original component position for display.
sort stb by seq.
loop at stb.
if stb-number > 0.
format: color 7.
endif.
write:/ '|' no-gap.
do stb-stufe times.
write '.' left-justified no-gap.
enddo.
write: stb-stufe.
if stb-number > 0.
format: color 4.
endif.
write: 16 stb-posnr, 22 stb-idnrk, 42 stb-mngko, 60 stb-meins.
if stb-number > 0.
format: color 7.
write: 65 stb-number, '|'.
format: color off.
else.
write: 65 ' ', '|'.
endif.
endloop.
uline at /(82).
endform. " DISPLAY_BOM
__________________________________________________________________________________________________________