前言:
在SAP编写程序批量维护BOM时,可能会用到函数CSAP_MAT_BOM_MAINTAIN等。
而测试程序会发现一些“诡异情况”--函数调用成功,sy-subrc = 0,而数据却未更新。
该如何处理?
调试:
调试发现,函数CSAP_MAT_BOM_MAINTAIN,会进一步调用函数CS_DI_HEADER_OBJECT_CHECK/CS_DI_HEADER_CHECK/,而这些函数的调用发现的错误消息并没有直接返回到函数CSAP_MAT_BOM_MAINTAIN当中,FL_WARNING被置'X'。
方案:
原因是找到了,但是如何处理呢?
如何准确的判断上游函数执行的消息,并作为友好的消息返回给用户?
医界有句老话,毒物附近必有解药。
根据以往经验,就优先查找函数CSAP_MAT_BOM_MAINTAIN的函数组CSAP的其他函数,拎出了列表,初步一看表述,有点失望。
想着:被蛇咬不可能旁边就是解药,于是扩大范围:
表 TADIR
包 DEVCLASS LIKE 'CS*'
对象类型 OBJECT = 'FUGR'
再根据此函数组清单,找表 TFDIR的相关函数。
这个过程可简化为以下使用事务DB02,执行SQL:
SELECT TFDIR.*,ENLFDIR.AREA,TADIR.DEVCLASS,TADIR.AUTHOR FROM TFDIR
INNER JOIN ENLFDIR ON ENLFDIR.FUNCNAME = TFDIR.FUNCNAME
INNER JOIN TADIR ON ENLFDIR.AREA = TADIR.OBJ_NAME AND TADIR.PGMID = 'R3TR' AND TADIR.OBJECT = 'FUGR'
WHERE TADIR.DEVCLASS LIKE 'CS%' AND ( TADIR.OBJ_NAME LIKE '%MESSAGE%' OR TADIR.OBJ_NAME LIKE '%LOG%' OR TADIR.OBJ_NAME LIKE '%MSG%' )
为此,未找到入法眼的条目。
又想着:专科医生搞不掂。就找急诊科吧。
思路:
寻找BAPI消息返回的功能。
可简化为以下使用事务DB02,执行SQL:
SELECT TFDIR.*,ENLFDIR.AREA,TFDIR.FUNCNAME FROM TFDIR
INNER JOIN ENLFDIR ON ENLFDIR.FUNCNAME = TFDIR.FUNCNAME
WHERE TFDIR.FUNCNAME LIKE 'BAPI%' AND ( TFDIR.FUNCNAME LIKE '%MESSAGE%' OR TFDIR.FUNCNAME LIKE '%LOG%' OR TFDIR.FUNCNAME LIKE '%MSG%' )
找到入法眼的条目:
BAPI_LOG_CLOSE
BAPI_LOG_INIT
BAPI_DIALOG
经过程序编码,调试,最终发现需要获取嵌套调过的BAPI函数的消息,需要按以下步骤:
(一)初始化
调函数CSAP_MAT_BOM_MAINTAIN前,先调用
CALL FUNCTION 'BAPI_LOG_INIT'." 若不初始化会报错:没有为对象 CAPI 和子对象 CAPI_LOG 创建日志
(二)调函数CSAP_MAT_BOM_MAINTAIN
(三)收集消息,并根据消息决定后续逻辑
核心代码:
CALL FUNCTION 'BAPI_LOG_CLOSE'
TABLES
return = lt_bapi_msg.
LOOP AT lt_bapi_msg WHERE type = 'E' OR type = 'A'.
lv_icon = icon_red_light.
len = strlen( lv_msg ).
IF len > 0.
lv_msg = lv_msg && ';' && lt_bapi_msg-message.
ELSE.
lv_msg = lt_bapi_msg-message.
ENDIF.
ENDLOOP.
到此,可获取函数CSAP_MAT_BOM_MAINTAIN的详细消息。