Object Dependency
这是一篇关于特性相关性的文章,阐述了系统的逻辑和一些表格和函数,从这个或者对标准程序(VA03或MM03)DEBUG都可以发现函数CUOV_CHECK_CONDITION是可以检查相关性,以确定特性是否显示在配置界面的。
但直接使用CUOV_CHECK_CONDITION存在一个问题,在判断前提条件中某特性是否是事务码CT04中编程的值时,表CUDBD_AW_FACT_I没有值。所以在这时,需要找出CUDBD_AW_FACT_I如何赋值,并能在使用函数CUOV_CHECK_CONDITION时能够使用这个内表的值,函数CUDB_SET_VAL可以给CUDBD_AW_FACT_I赋值。
由于CUDBD_AW_FACT_I表被CUDB_SET_VAL赋值后,不能在使用CUOV_CHECK_CONDITION时取到,所以借用了函数内的代码,使用perform in program 的语法,实现判断相关性的功能
代码如下
FUNCTION zrfc_salesorder_get_txmc.
*"----------------------------------------------------------------------
*"*"局部接口:
*" IMPORTING
*" VALUE(I_MATNR) TYPE MATNR OPTIONAL
*" VALUE(I_WERKS) TYPE WERKS_D OPTIONAL
*" EXPORTING
*" VALUE(E_CODE) TYPE CHAR1
*" VALUE(E_MSG) TYPE CHAR100
*" VALUE(E_MAKTX) TYPE MAKTX
*" TABLES
*" ET_CECUFM STRUCTURE ZRFC_SO_CECUFM OPTIONAL
*"----------------------------------------------------------------------
TYPE-POOLS cudbt .
TABLES: cawn.
DATA: lt_cecusd LIKE TABLE OF cecusd WITH HEADER LINE,
ls_cecusd LIKE cecusd.
DATA: BEGIN OF lt_cecufm OCCURS 0.
INCLUDE STRUCTURE zrfc_so_cecufm.
DATA: line LIKE cecufm-line,
dsint LIKE cecusd-dsint,
atinn LIKE cecufm-atinn,
knobj LIKE cabn-knobj,
atvie LIKE cabn-atvie,
atinp LIKE cabn-atinp,
atfod LIKE cabn-atfod,
END OF lt_cecufm.
DATA: ls_cecufm LIKE lt_cecufm.
DATA: es_cecufm LIKE zrfc_so_cecufm.
DATA: l_ce_design TYPE ce_design,
num TYPE i.
DATA: configuration LIKE TABLE OF conf_out WITH HEADER LINE.
DATA: l_cuobj LIKE marc-cuobj.
DATA: l_knobj LIKE cabn-knobj,
l_knnum LIKE cukb-knnum,
l_knart LIKE cukb-knart,
* l_memas LIKE cuco-memas,
* l_atinn LIKE cabn-atinn,
* l_atwrt LIKE cawn-atwrt,
* l_fdpos LIKE sy-fdpos,
l_subrc LIKE sy-subrc.
* l_knblk LIKE cukn-knblk,
* l_atnam LIKE cabn-atnam,
* l_symnol(3),
* l_len TYPE i,
* l_len_not TYPE i,
* l_len_ne TYPE i.
* DATA: lt_cawn LIKE TABLE OF cawn WITH HEADER LINE,
* ls_cawn LIKE lt_cawn.
DATA: l_count TYPE i.
* DATA: BEGIN OF source OCCURS 100,
* source LIKE sel_cod-line, "字段必须参考 sel_cod-line,否则会报错
* END OF source.
DATA: value TYPE cudbt_val,
justificand TYPE cudbt_justificand,
f LIKE ddb_c02-fact,
result TYPE cudbt_result.
DATA: rflag,
vtype LIKE cabn-atfor.
* DATA: BEGIN OF domain OCCURS 0.
* INCLUDE STRUCTURE ddb_c03.
* DATA: END OF domain.
DATA: cuovd_knnum TYPE cukb-knnum.
DATA: result_i TYPE c,
x_code TYPE kbd_tree OCCURS 128.
DATA: ls_code LIKE cukr_01.
DATA: knnum LIKE cukb-knnum.
DATA: cuovd_root TYPE ddb_c02-instance,
cuovd_parent TYPE ddb_c02-instance,
cuovd_self TYPE ddb_c02-instance.
DATA: l_atwrt LIKE cawn-atwrt,
l_atfor LIKE cabn-atfor,
l_atflv LIKE cawn-atflv.
DATA: itype LIKE ddb_itp.
DATA: objkey LIKE ddb_itp-objkey,
instance LIKE ddb_c02-instance,
fact LIKE ddb_c02-fact.
TYPES:
cukna_compilat LIKE cukr_01,
cukna_compilat_tab TYPE cukna_compilat OCCURS 20,
BEGIN OF cukna_pr_pricing, "187960
knnum LIKE cukb-knnum, "187960
END OF cukna_pr_pricing, "187960
cukna_pr_pricing_tab TYPE cukna_pr_pricing OCCURS 20, "187960
BEGIN OF cukna_knowledge_node,
knobj LIKE cuob-knobj,
kntab LIKE cuob-kntab,
knpre TYPE c,
knsel TYPE c,
knact TYPE c,
knprc TYPE c,
knpre_comp TYPE cukna_compilat_tab,
knsel_comp TYPE cukna_compilat_tab,
knact_comp TYPE cukna_compilat_tab,
knprc_comp TYPE cukna_compilat_tab,
knprc_pricing TYPE cukna_pr_pricing_tab, "187960
END OF cukna_knowledge_node.
DATA: wa_icomp_n TYPE cukna_knowledge_node.
DATA: loc_x_result TYPE c,
true TYPE c.
DATA: false TYPE c VALUE 'F'.
DATA: BEGIN OF l_cudbd_aw_fact_i OCCURS 0,
instance TYPE cudbt_instance,
atinn TYPE cudbt_atinn,
atfor TYPE cudbt_val-atfor,
atwrt TYPE cudbt_val-atwrt,
atflv TYPE cudbt_val-atflv,
f TYPE cudbt_fact,
curr TYPE c,
END OF l_cudbd_aw_fact_i.
FIELD-SYMBOLS: <fs> TYPE ANY.
DATA: cndtype TYPE c.
DATA: objek LIKE cuco-objek.
IF i_matnr IS INITIAL.
e_code = 'E'.
e_msg = '物料号为空'.
ELSE.
objek = i_matnr.
SELECT SINGLE design INTO l_ce_design FROM cuco
WHERE objek = objek.
* CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
* EXPORTING
* input = i_matnr
* IMPORTING
* output = l_ce_design.
SELECT dsint grnam ce_design INTO CORRESPONDING FIELDS OF TABLE lt_cecusd FROM cecusd
WHERE ce_design = l_ce_design.
IF sy-subrc = 0.
READ TABLE lt_cecusd INTO ls_cecusd INDEX 1.
SELECT grnam atnam atbez line dsint cecufm~atinn
INTO CORRESPONDING FIELDS OF TABLE lt_cecufm FROM cecufm
INNER JOIN cabn ON cabn~atinn = cecufm~atinn
INNER JOIN cabnt ON cabnt~atinn = cecufm~atinn
WHERE dsint = ls_cecusd-dsint.
IF sy-subrc = 0.
SORT lt_cecufm BY grnam line atinn.
DELETE ADJACENT DUPLICATES FROM lt_cecufm.
SELECT SINGLE cuobj INTO l_cuobj FROM marc
WHERE matnr = i_matnr
AND werks = i_werks.
CHECK l_cuobj IS NOT INITIAL.
CALL FUNCTION 'VC_I_GET_CONFIGURATION' "调用函数"
EXPORTING
instance = l_cuobj
TABLES
configuration = configuration
EXCEPTIONS
instance_not_found = 1
internal_error = 2
no_class_allocation = 3
instance_not_valid = 4
OTHERS = 5.
* >> instance等特性数据初始化
objkey = i_matnr.
itype-objtyp = 'MARA'.
itype-cltyp = '300'.
itype-objkey = objkey.
CLEAR instance.
CALL FUNCTION 'CUDB_MAKE_PART_INSTANCE'
EXPORTING
itype = itype
parent = 0
pos = ''
kntype = ''
segm = 0
author = 0
trigger = 0
IMPORTING
instance = instance
fact = fact
EXCEPTIONS
internal_error = 1
invalid_type = 2
OTHERS = 3.
* DATA instance LIKE ddb_c02-instance.
* PERFORM ddbx_get_new_instance IN PROGRAM saplcudb USING instance.ins
CALL FUNCTION 'CUOV_SET_OVARS'
EXPORTING
parent = instance
root = instance
self = instance
EXCEPTIONS
internal_error = 1
OTHERS = 2.
SORT configuration BY atinn.
* >> 把物料非相关性的特性放入到表CUDBD_AW_FACT_I中,为之后相关性对比做准备
LOOP AT configuration.
CLEAR l_count.
LOOP AT configuration TRANSPORTING NO FIELDS WHERE atinn = configuration-atinn.
l_count = l_count + 1.
ENDLOOP.
IF l_count = 1.
rflag = 0.
ELSEIF l_count > 1.
rflag = 2.
ELSE.
l_knobj = 11.
ENDIF.
IF l_knobj NE 11.
CLEAR: l_atfor,
l_atwrt,
l_atflv.
SELECT SINGLE atfor INTO l_atfor FROM cabn WHERE atinn = configuration-atinn.
SELECT SINGLE atwrt atflv INTO (l_atwrt,l_atflv) FROM cawn
WHERE atinn = configuration-atinn
AND atwrt = configuration-atwrt.
PERFORM ddbx_check_vtype IN PROGRAM saplcudb USING l_atfor value-atfor.
value-atwrt = configuration-atwrt.
value-atflv = l_atflv.
* value-atobj = obj_value.
* justificand-kntype = kntype.
* justificand-segm = segm.
* justificand-author = author.
* justificand-trigger = trigger.
PERFORM ddbx_set_aw_val IN PROGRAM saplcudb USING
instance configuration-atinn rflag value justificand f." IF FOUND.
* CALL FUNCTION 'CUDB_SET_VAL'
* EXPORTING
* atinn = ls_cecufm-atinn
* instance = '00000001'
* num_value = l_atflv
* rflag = rflag
* sym_value = l_atwrt
* vtype = l_atfor
* EXCEPTIONS
* internal_error = 1
* unknown_instance = 2
* OTHERS = 3.
* AT LAST .
* ASSIGN ('(SAPLCUDB)CUDBD_AW_FACT_I[]') TO <fs>.
* ENDAT.
ENDIF.
CLEAR configuration.
ENDLOOP.
LOOP AT lt_cecufm INTO ls_cecufm.
CLEAR configuration.
READ TABLE configuration WITH KEY atinn = ls_cecufm-atinn.
IF sy-subrc = 0.
MOVE-CORRESPONDING ls_cecufm TO es_cecufm.
num = num + 1.
es_cecufm-num = num.
APPEND es_cecufm TO et_cecufm.
CLEAR es_cecufm.
ELSE.
CLEAR: l_knobj,
* l_memas,
l_knart,
l_knnum,
l_subrc.
SELECT SINGLE knobj atfod atinp atvie
INTO (ls_cecufm-knobj,ls_cecufm-atfod,ls_cecufm-atinp,ls_cecufm-atvie) FROM cabn
WHERE atinn = ls_cecufm-atinn.
IF sy-subrc = 0.
l_knobj = ls_cecufm-knobj.
IF l_knobj EQ space.
* >> 非活动的相关性特性直接加入特性值列表
IF ls_cecufm-atvie = ''.
MOVE-CORRESPONDING ls_cecufm TO es_cecufm.
num = num + 1.
es_cecufm-num = num.
APPEND es_cecufm TO et_cecufm.
CLEAR es_cecufm.
ENDIF.
* ELSE.
* SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_cawn FROM cawn WHERE atinn = ls_cecufm-atinn.
* IF sy-subrc = 0.
* LOOP AT lt_cawn INTO ls_cawn.
* ls_cawn-knobj = l_knobj.
* CALL FUNCTION 'CUD0_CONFIGURE_OBJECT'
* EXPORTING
* instance = l_cuobj
* key_date = sy-datum "#EC DOM_EQUAL
* objectid = 'CAWN'
* object = ls_cawn
* do_action = ' '
* do_condition = ' '
* do_precondition = 'X'
* do_procedure = ' '
* root_instance = '00000001'
* parent_instance = '00000001'
* object_has_instance = '00000001'
* EXCEPTIONS
* false = 1
* internal_error = 2
* unknown_instance = 3.
*
* CHECK sy-subrc = 0.
** PERFORM cudb_set_val USING ls_cecufm-atinn instance.
* MOVE-CORRESPONDING ls_cecufm TO es_cecufm.
* num = num + 1.
* es_cecufm-num = num.
* APPEND es_cecufm TO et_cecufm.
* CLEAR es_cecufm.
* ENDLOOP.
* ENDIF.
ELSE.
CLEAR l_knnum.
SELECT SINGLE knnum INTO l_knnum FROM cuob
WHERE knobj = l_knobj.
CHECK sy-subrc = 0.
CLEAR l_knart.
SELECT SINGLE knart INTO l_knart FROM cukb
WHERE knnum = l_knnum.
CHECK sy-subrc = 0.
* >> 获取 KNOWLEDGE_NODE
* IF <fs> IS NOT INITIAL.
* PERFORM cudb_init IN PROGRAM saplcudb IF FOUND.
* ASSIGN ('(SAPLCUDB)CUDBD_AW_FACT_I[]') TO <fs>.
* CLEAR <fs>.
* ENDIF.
CALL FUNCTION 'CUKNA_GET_KNOWLEDGE_NODE'
EXPORTING
knobj = l_knobj
date = sy-datum
IMPORTING
knowledge_node = wa_icomp_n
EXCEPTIONS
not_found = 1.
*--------------------------------------------------------------------*
* 活动的特性值对比相关性
* 因函数CUOV_CHECK_CONDITION直接使用时,无法从内存中读取表
* CUDBD_AW_FACT_I内容进行对比,所以借用函数CUOV_CHECK_CONDITION的代码
* 借用模式为P模式,即前提模式
*--------------------------------------------------------------------*
* knart = 2 即前提条件
IF l_knart = 2.
cndtype = 'P'.
ELSE.
cndtype = 'S'.
ENDIF.
IF wa_icomp_n-knpre NE space.
CLEAR loc_x_result.
CLEAR: ls_code,cuovd_knnum.
LOOP AT wa_icomp_n-knpre_comp INTO ls_code.
IF ls_code-knnum <> cuovd_knnum.
*..a new condition is processed........................................*
IF NOT cuovd_knnum IS INITIAL.
CASE cndtype.
WHEN 'P'.
PERFORM cuov_eval_precnd IN PROGRAM saplcuov USING x_code result_i.
IF result_i = false.
*..a precondition is violated..........................................*
result = false.
knnum = cuovd_knnum.
EXIT.
ENDIF.
WHEN OTHERS.
PERFORM cuov_eval_selcnd IN PROGRAM saplcuov USING x_code result_i.
IF result_i = true.
*..a selection condition is fulfilled..................................*
result = true.
knnum = cuovd_knnum.
EXIT.
ENDIF.
ENDCASE.
ENDIF.
cuovd_knnum = ls_code-knnum.
CLEAR x_code.
ENDIF.
APPEND ls_code-code TO x_code.
CLEAR ls_code.
ENDLOOP.
*..process last condition..............................................*
CASE cndtype.
WHEN 'P'.
PERFORM cuov_eval_precnd IN PROGRAM saplcuov USING x_code result_i.
WHEN OTHERS.
PERFORM cuov_eval_selcnd IN PROGRAM saplcuov USING x_code result_i.
ENDCASE.
* CALL FUNCTION 'CUOV_CHECK_CONDITION'
* EXPORTING
* cndtype = 'P'
* key_date = sy-datum
* IMPORTING
* RESULT = loc_x_result
* TABLES
* code = wa_icomp_n-knpre_comp
* EXCEPTIONS
* internal_error = 0
* unknown_instance = 0.
CASE result_i.
WHEN 'T'.
true = '1'.
WHEN 'F'.
true = ' '.
WHEN OTHERS.
true = ' '.
ENDCASE.
ELSE.
true = '1'.
ENDIF.
CHECK true = 1.
MOVE-CORRESPONDING ls_cecufm TO es_cecufm.
num = num + 1.
es_cecufm-num = num.
APPEND es_cecufm TO et_cecufm.
CLEAR es_cecufm.
ENDIF.
ENDIF.
ENDIF.
MODIFY lt_cecufm FROM ls_cecufm.
CLEAR ls_cecufm.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
ENDFUNCTION.