有没有遇到如下几个场景
场景1
开发1,新建函数组1,创建函数1
开发2,在函数组1里,创建函数2
两者都传Q测试,开发2的先QAT完后发布生产,请求dump,找不到函数2
场景2
函数组1已传生产
开发1,在函数组1里,创建函数3
开发2,在函数组1里,创建函数4
两者都传Q测试,开发2的先QAT完后发布生产,请求dump,找不到函数3(因为函数组是的一个xxx include里面包括了函数组的所有函数名,运行时都会检查函数组的完整性,缺一不可)
这时要怎么做才能减少这种错误的概念,两个思路,一个是开发人员在释放请求时检查,一个是basis传输请求时检查(按理说sap要帮我们检查这些,但是实际测试没有发现,用了这么久也没有这个功能,note里面好像也没有找到相关功能,不如自己写一个)
实现1:在请求释放时检查
IF_EX_CTS_REQUEST_CHECK
实施如上接口
IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_RELEASE
method if_ex_cts_request_check~check_before_release.
if sy-uname eq 'JORDAN'.
* break jordan.
data:ls_tadir type tadir.
check sy-subrc is initial.
*********************** 检查是否有函数的,如果有的话,检查函数组中的对象是否都在下一个传输系统中
**** 比如新增了一个peform 或者新增了一个函数
* E071
**OR object = 'REPS' 函数池(函数组)与子例程(函数组中的子例程都不需要考虑?)
loop at objects transporting no fields where pgmid = 'LIMU' and ( object = 'FUNC' or object = 'REPS' ).
endloop.
check sy-subrc is initial.
***找出主程序,然后找出相应的函数
loop at objects assigning field-symbol(<fs_object>) where pgmid = 'LIMU' and ( object = 'FUNC' or object = 'REPS' ).
data:
lt_tfdir type table of tfdir,
lt_tfdir_all type table of tfdir,
lt_tfdir_include type table of tfdir,
lw_tfdir type tfdir,
lw_tfdir_include type tfdir.
if <fs_object>-object = 'REPS'.
select * from tfdir
into table lt_tfdir
where pname = <fs_object>-obj_name.
if sy-subrc is initial."找到的话,那么<fs_object>-obj_name就是函数池,会不会刚好同名?那也有可能哈,但是概率低
append lines of lt_tfdir to lt_tfdir_all.
endif.
elseif <fs_object>-object = 'FUNC'.
select single * from tfdir
into lw_tfdir
where funcname = <fs_object>-obj_name.
if sy-subrc is initial.
select * from tfdir
into table lt_tfdir
where pname = lw_tfdir-pname.
if sy-subrc is initial.
append lines of lt_tfdir to lt_tfdir_all.
endif.
endif.
endif.
endloop.
****通过主程序找出所有的相关函数与子例程
check lt_tfdir_all[] is not initial.
sort lt_tfdir_all by funcname.
delete adjacent duplicates from lt_tfdir_all comparing funcname.
data:lt_wbcrossi type table of wbcrossi,
lw_wbcrossi type wbcrossi.
select * from wbcrossi
into table lt_wbcrossi
for all entries in lt_tfdir_all
where otype = 'IC' and master = lt_tfdir_all-pname and include = lt_tfdir_all-pname .
****排除掉当前相当函数与子例程已经在请求中,找出那些没有在请求中的相关函数与子例程
loop at lt_wbcrossi assigning field-symbol(<fs_wbcrossi>).
data(lv_index) = sy-tabix.
read table objects with key pgmid = 'LIMU' object = 'REPS' obj_name = <fs_wbcrossi>-name transporting no fields.
if sy-subrc is initial."找到了就去掉
delete lt_wbcrossi index lv_index.
endif.
endloop.
loop at lt_tfdir_all assigning field-symbol(<fs_tfdir>).
lv_index = sy-tabix.
read table objects with key pgmid = 'LIMU' object = 'FUNC' obj_name = <fs_tfdir>-funcname transporting no fields.
if sy-subrc is initial."找到了就去掉
delete lt_tfdir_all index lv_index.
endif.
endloop.
***检查这些子例程在远程系统中是否存在,如果不存在,提醒
data:lv_exist type abap_bool.
data:lv_titlebar type string value '检查函数池完整性检查'.
data:lv_text_question type string.
data:lv_answer type string.
loop at lt_wbcrossi assigning <fs_wbcrossi>.
call method get_version
exporting
p_program = <fs_wbcrossi>-name
p_object = 'REPS'
importing
e_is_exist = lv_exist.
if lv_exist = abap_false.
if dialog = abap_true.
* 程序对象在远程系统不存在,请确认是否要发布
lv_text_question = '程序对象:' && <fs_wbcrossi>-name && '在远程系统不存在,请确认是否要发布'.
call function 'POPUP_TO_CONFIRM'
exporting
titlebar = lv_titlebar
* DIAGNOSE_OBJECT = ' '
text_question = lv_text_question
text_button_1 = '是的'(001)
* ICON_BUTTON_1 = ' '
text_button_2 = '否'(002)
* ICON_BUTTON_2 = ' '
* DEFAULT_BUTTON = '1'
* DISPLAY_CANCEL_BUTTON = 'X'
* USERDEFINED_F1_HELP = ' '
* START_COLUMN = 25
* START_ROW = 6
* POPUP_TYPE =
* IV_QUICKINFO_BUTTON_1 = ' '
* IV_QUICKINFO_BUTTON_2 = ' '
importing
answer = lv_answer
* TABLES
* PARAMETER =
exceptions
text_not_found = 1
others = 2.
if sy-subrc <> 0.
exit.
endif.
if lv_answer = '2'.
raise cancel.
else.
sy-subrc = 0.
endif.
endif.
endif.
endloop.
loop at lt_tfdir_all assigning <fs_tfdir>.
call method get_version
exporting
p_program = <fs_tfdir>-funcname
p_object = 'FUNC'
importing
e_is_exist = lv_exist.
if lv_exist = abap_false.
if dialog = abap_true.
* 程序对象在远程系统不存在,请确认是否要发布
lv_text_question = '函数对象:' && <fs_tfdir>-funcname && '在远程系统不存在,请确认是否要发布'.
call function 'POPUP_TO_CONFIRM'
exporting
titlebar = lv_titlebar
* DIAGNOSE_OBJECT = ' '
text_question = lv_text_question
text_button_1 = '是的'(001)
* ICON_BUTTON_1 = ' '
text_button_2 = '否'(002)
* ICON_BUTTON_2 = ' '
* DEFAULT_BUTTON = '1'
* DISPLAY_CANCEL_BUTTON = 'X'
* USERDEFINED_F1_HELP = ' '
* START_COLUMN = 25
* START_ROW = 6
* POPUP_TYPE =
* IV_QUICKINFO_BUTTON_1 = ' '
* IV_QUICKINFO_BUTTON_2 = ' '
importing
answer = lv_answer
* TABLES
* PARAMETER =
exceptions
text_not_found = 1
others = 2.
if sy-subrc <> 0.
exit.
endif.
if lv_answer = '2'.
raise cancel.
else.
sy-subrc = 0.
endif.
endif.
endif.
endloop.
*****有一种特例需要测试一下,即第一次创建函数组
endif.
endmethod.
新增三个方法
CK_CHECK_REMOTE_OBJECT
CK_CHECK_REMOTE_VERSIONS
GET_VERSION
点受保护的部分,把如下代码粘进去
private section.
methods ck_check_remote_object
importing
!pi_logdest type rfcdes-rfcdest
!pi_objname type vrsd-objname
changing
!pi_objtype type vrsd-objtype
!retcode type sy-subrc .
methods ck_check_remote_versions
importing
!pi_logdest type rfcdes-rfcdest
!pi_objname type vrsd-objname
changing
!pi_objtype type vrsd-objtype
!po_retcode type sy-subrc .
type-pools abap .
methods get_version
importing
!p_program type any
!p_object type tadir-object
exporting
!e_is_exist type abap_bool .
class ycl_im_object_ver_check definition
public
final
create public .
public section.
interfaces if_ex_cts_request_check .
protected section.
private section.
methods ck_check_remote_object
importing
!pi_logdest type rfcdes-rfcdest
!pi_objname type vrsd-objname
changing
!pi_objtype type vrsd-objtype
!retcode type sy-subrc .
methods ck_check_remote_versions
importing
!pi_logdest type rfcdes-rfcdest
!pi_objname type vrsd-objname
changing
!pi_objtype type vrsd-objtype
!po_retcode type sy-subrc .
type-pools abap .
methods get_version
importing
!p_program type any
!p_object type tadir-object
exporting
!e_is_exist type abap_bool .
endclass.
class ycl_im_object_ver_check implementation.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method YCL_IM_OBJECT_VER_CHECK->CK_CHECK_REMOTE_OBJECT
* +-------------------------------------------------------------------------------------------------+
* | [--->] PI_LOGDEST TYPE RFCDES-RFCDEST
* | [--->] PI_OBJNAME TYPE VRSD-OBJNAME
* | [<-->] PI_OBJTYPE TYPE VRSD-OBJTYPE
* | [<-->] RETCODE TYPE SY-SUBRC
* +--------------------------------------------------------------------------------------</SIGNATURE>
method ck_check_remote_object.
************************************************************************
* FUNKTION:
* Prüft nach, ob das angegebene System mittels REMOTE-Function-Call
* angesprochen werden kann.
* ----------------------------------------------------------------------
* PARAMETER:
* PI_LOGDEST: Name der logischen Destination
*
* PI_OBJTYPE: Name des Objekts ('REPO', 'DYNP', ETC.)
*
* PI_OBJNAME: Name des Objekts
*
* RETCODE: = 0 versions exist
* = 1 active object exists
* = 2/3 communication failures
* = 4 object does not exist at all
* = 5 object exists, but incompatible releases
************************************************************************
data: object_not_found type vrsd-versmode value ' '.
data: vrsd_entry type vrsd.
clear: retcode, object_not_found.
* Überprüfe, ob das Fremdsystem angesprochen werden kann und
* ob es dort Versionen dieses Objekts gibt.
* PERFORM ck_check_remote_versions
* USING pi_logdest pi_objname
* CHANGING pi_objtype
* retcode.
call method ck_check_remote_versions
exporting
pi_logdest = pi_logdest
pi_objname = pi_objname
changing
pi_objtype = pi_objtype
po_retcode = retcode.
if retcode = 1.
* Keine Versionen im Fremdsystem gefunden. Prüfe, ob das Objekt
* überhaupt im Zielsystem existiert.
call function 'FIND_OBJECT_40'
exporting
destination = pi_logdest
objname = pi_objname
objtype = pi_objtype
importing
object_not_found = object_not_found
exceptions
system_failure = 2
communication_failure = 3.
if sy-subrc <> 0.
retcode = sy-subrc.
else.
if object_not_found <> space.
retcode = 4.
else.
retcode = 1.
endif.
endif.
elseif retcode = 0.
* Versionen im Fremdsystem vorhanden, prüfen ob Vergleich
* überhaupt möglich ist, oder nur Anzeige.
* Bis jetzt gibt es bei fast allen Objekttypen Probleme
if pi_objtype = 'DYNP' or
pi_objtype = 'CUAD' or
pi_objtype = 'TABD' or
pi_objtype = 'VIED' or
pi_objtype = 'MCID' or
pi_objtype = 'MCOD' or
pi_objtype = 'ENQD' or
pi_objtype = 'TABT'.
data: head_type type vrsd-objtype value 'HEAD' ,
head_objname type vrsd-objname value '/HEADER-ENTRY',
head_versno type vrsd-versno value '99996'.
* Wir prüfen den Release-Stand anhand des Header Eintrages
call function 'GET_VRSD_ENTRY_46'
exporting
destination = pi_logdest
objname = head_objname
objtype = head_type
versno = head_versno
importing
vrsd_entry = vrsd_entry
exceptions
no_entry_found = 1
system_failure = 2
communication_failure = 3.
retcode = sy-subrc.
if retcode = 1.
* Wenn kein Header Eintrag vorhanden ist, dann handelt es
* sich um einen älteren Releasestand (< 30A).
retcode = 5.
elseif retcode = 0.
* Es gibt einen Header Eintrag, aber ist es ein richtiger?
if vrsd_entry-rels < '30A '. "#EC PORTABLE
retcode = 5.
endif.
endif.
endif.
endif.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method YCL_IM_OBJECT_VER_CHECK->CK_CHECK_REMOTE_VERSIONS
* +-------------------------------------------------------------------------------------------------+
* | [--->] PI_LOGDEST TYPE RFCDES-RFCDEST
* | [--->] PI_OBJNAME TYPE VRSD-OBJNAME
* | [<-->] PI_OBJTYPE TYPE VRSD-OBJTYPE
* | [<-->] PO_RETCODE TYPE SY-SUBRC
* +--------------------------------------------------------------------------------------</SIGNATURE>
method ck_check_remote_versions.
************************************************************************
* FUNKTION:
* Prüft nach, ob es in dem angegebenen System Versionen (in VRSD) des
* angegebenen Objektes gibt.
* ----------------------------------------------------------------------
* PARAMETER:
* PI_LOGDEST: Name der logischen Destination
*
* PI_OBJTYPE: Name des Objekts ('REPO', 'DYNP', ETC.)
*
* PI_OBJNAME: Name des Objekts
*
* PO_RETCODE: = 0 versions exist
* = 1 no versions
* = 2/3 communication failures
************************************************************************
data tfdir type tfdir .
data: versno type vrsd-versno value 0.
data: iname type vrsd-objname.
data: iobjtype type vrsd-objtype.
data: vrsd_entry type vrsd.
clear: po_retcode.
* Überprüfe, ob das Fremdsystem angesprochen werden kann und
* ob es dort Versionen dieses Objekts gibt.
call function 'GET_VRSD_ENTRY_46'
exporting
destination = pi_logdest
objname = pi_objname
objtype = pi_objtype
versno = versno
importing
vrsd_entry = vrsd_entry
exceptions
no_entry_found = 1
system_failure = 2
communication_failure = 3.
po_retcode = sy-subrc.
if po_retcode <> 1.
exit.
endif.
data: rept_type type vrsd-objtype value 'REPT' ,
reps_type type vrsd-objtype value 'REPS' ,
repo_type type vrsd-objtype value 'REPO' ,
func_type type vrsd-objtype value 'FUNC' .
if pi_objtype = rept_type or pi_objtype = reps_type or
pi_objtype = func_type.
* Für einige Objekttypen werden noch alte LIMU REPOs gesucht,
* in denen Versionen der ABAP-Source stehen könnten
if pi_objtype = func_type.
* wir brauchen zuerst den Include-Namen
clear: iname.
select single * from tfdir into tfdir where funcname = pi_objname.
iname(1) = 'L'.
iname+1(4) = tfdir-pname+4(4). "'4' ist OK, da REPOs nicht mehr
"versioniert werden.
iname+5(1) = 'U'.
iname+6(2) = tfdir-include.
* Nun können wir die Versionen suchen
iobjtype = repo_type.
call function 'GET_VRSD_ENTRY_46'
exporting
destination = pi_logdest
objname = iname
objtype = iobjtype
versno = versno
importing
vrsd_entry = vrsd_entry
exceptions
no_entry_found = 1
system_failure = 2
communication_failure = 3.
po_retcode = sy-subrc.
elseif pi_objtype = reps_type.
iobjtype = repo_type.
call function 'GET_VRSD_ENTRY_46'
exporting
destination = pi_logdest
objname = pi_objname
objtype = iobjtype
versno = versno
importing
vrsd_entry = vrsd_entry
exceptions
no_entry_found = 1
system_failure = 2
communication_failure = 3.
po_retcode = sy-subrc.
* Der Anzeigereport RSVRSTCO kann keine REPOs anzeigen
* elseif pi_objtype = rept_type.
* pi_objtype = repo_type.
* call function 'GET_VRSD_ENTRY_40'
* exporting
* destination = pi_logdest
* objname = pi_objname
* objtype = pi_objtype
* versno = versno
* importing
* vrsd_entry = vrsd_entry
* exceptions
* no_entry_found = 1
* system_failure = 2
* communication_failure = 3.
* po_retcode = sy-subrc.
endif.
endif.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method YCL_IM_OBJECT_VER_CHECK->GET_VERSION
* +-------------------------------------------------------------------------------------------------+
* | [--->] P_PROGRAM TYPE ANY
* | [--->] P_OBJECT TYPE TADIR-OBJECT
* | [<---] E_IS_EXIST TYPE ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method get_version.
data: dir_destination_qas type rfcdes-rfcdest. "Log. Dest. des R.-Systems
data: dir_destination_prd type rfcdes-rfcdest. "Log. Dest. des R.-Systems
data:lv_mtext_qas type string.
data:lv_mtext_prd type string.
* PROGRAM Version management: Directory table
data:ls_vrsd type vrsd.
** 取当前对象已经释放的请求里面最新的激活版本
select single * from vrsd
into ls_vrsd
where objname = p_program
and versno = 0
** 防止是第一次修改,并没有释放的情况
and korrnum is not null .
* AND korrnum eq abap_false.
if sy-subrc is initial.
* pw_yabap_check_002-dev = ls_vrsd.
e_is_exist = abap_true.
else.
e_is_exist = abap_false.
exit.
endif.
* TMSMCONF
*** 检查本系统是有传输请求配置的
data:ls_tmsmconf type tmsmconf.
select single * from tmsmconf into ls_tmsmconf .
check sy-subrc is initial.
*** TMSCSYS
** 查到本系统内的传输请求 这里可以区分 Q*与T*
data:lt_tmscsys type table of tmscsys.
select * from tmscsys into table lt_tmscsys
where extsys <> 'X'
or extsys is null
and nfsgrp eq ls_tmsmconf-nfsgrp.
check sy-subrc is initial.
data: dir_objtype type vrsd-objtype.
data: dir_objname type vrsd-objname.
data: no_entry type bool.
dir_objtype = ls_vrsd-objtype.
dir_objname = ls_vrsd-objname.
************************************************************************
* 获取当前对象的测试环境的版本信息 *
************************************************************************
data: lt_vrs_dir_vrs_qas type table of vrsd ,
lw_vrs_dir_vrs_qas type vrsd.
dir_destination_qas = 'TMSADM@QA1.DOMAIN_DEV'.
* Prüfe, ob Objekt im Zielsystem existiert und Versionen hat
data: returncode_qas like sy-subrc,
returncode_prd like sy-subrc.
* PERFORM ck_check_remote_object
* USING dir_destination_qas dir_objname
* CHANGING dir_objtype
* returncode_qas.
call method ck_check_remote_object
exporting
pi_logdest = dir_destination_qas
pi_objname = dir_objname
changing
pi_objtype = dir_objtype
retcode = returncode_qas.
case returncode_qas.
when 0 or 1.
when 2.
* 'Fehler im Zielsystem'
message id 'SB' type 'I' number 123 into lv_mtext_qas.
when 3.
* 'Keine Verbindung zum Zielsystem oder fehlerhafte Kommunikation'
message id 'SB' type 'I' number 124 into lv_mtext_qas.
when 4.
* 'Das Objekt existiert nicht im Zielsystem'.
message id 'SB' type 'I' number 131 into lv_mtext_qas.
endcase.
if returncode_qas eq 0 or returncode_qas eq 1.
e_is_exist = abap_true.
else.
e_is_exist = abap_false.
endif.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_IM_OBJECT_VER_CHECK->IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_ADD_OBJECTS
* +-------------------------------------------------------------------------------------------------+
* | [--->] REQUEST TYPE TRKORR(optional)
* | [--->] TYPE TYPE TRFUNCTION(optional)
* | [--->] OWNER TYPE TR_AS4USER(optional)
* | [--->] OBJECTS TYPE TR_OBJECTS(optional)
* | [--->] KEYS TYPE TR_KEYS(optional)
* | [--->] DIALOG TYPE TRBOOLEAN(optional)
* | [--->] IS_GTABKEY TYPE GTABKEY(optional)
* | [<-->] TEXT TYPE AS4TEXT(optional)
* | [<-->] ATTRIBUTES TYPE TRATTRIBUTES(optional)
* | [EXC!] CANCEL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_cts_request_check~check_before_add_objects.
break jordan.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_IM_OBJECT_VER_CHECK->IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_CHANGING_OWNER
* +-------------------------------------------------------------------------------------------------+
* | [--->] REQUEST TYPE TRKORR
* | [--->] TYPE TYPE TRFUNCTION
* | [--->] OLD_OWNER TYPE TR_AS4USER
* | [--->] NEW_OWNER TYPE TR_AS4USER
* | [EXC!] CANCEL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_cts_request_check~check_before_changing_owner.
break jordan.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_IM_OBJECT_VER_CHECK->IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_CREATION
* +-------------------------------------------------------------------------------------------------+
* | [--->] TYPE TYPE TRFUNCTION
* | [<-->] TEXT TYPE AS4TEXT
* | [<-->] ATTRIBUTES TYPE SCTS_ATTRS
* | [EXC!] CANCEL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_cts_request_check~check_before_creation.
* break jordan.
* Couldn't find Error Message: 1 SELECT 510 because the system is running
*with the database objects from release 740. The system has not
*completely upgraded to release 742.
data ls_yabap_check_001 type yabap_check_001.
"白名单里面有的不检查,白名单时面的截止日期如果是大于今天,则不检查
select single * from yabap_check_001
into ls_yabap_check_001 where bname eq sy-uname.
if sy-subrc is initial.
if ls_yabap_check_001-datum is initial.
exit.
elseif ls_yabap_check_001-datum >= sy-datum.
exit.
endif.
endif.
* break jordan.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_IM_OBJECT_VER_CHECK->IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_RELEASE
* +-------------------------------------------------------------------------------------------------+
* | [--->] REQUEST TYPE TRKORR(optional)
* | [--->] TYPE TYPE TRFUNCTION(optional)
* | [--->] OWNER TYPE TR_AS4USER(optional)
* | [--->] OBJECTS TYPE TR_OBJECTS(optional)
* | [--->] KEYS TYPE TR_KEYS(optional)
* | [--->] KEYS_STR TYPE E071K_STRTYP(optional)
* | [--->] DIALOG TYPE TRBOOLEAN(optional)
* | [--->] TARSYSTEM TYPE TR_TARGET(optional)
* | [--->] ADT TYPE TRBOOLEAN(optional)
* | [<-->] TEXT TYPE AS4TEXT(optional)
* | [<-->] ATTRIBUTES TYPE TRATTRIBUTES(optional)
* | [EXC!] CANCEL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_cts_request_check~check_before_release.
if sy-uname eq 'JORDAN'.
* break jordan.
data:ls_tadir type tadir.
check sy-subrc is initial.
*********************** 检查是否有函数的,如果有的话,检查函数组中的对象是否都在下一个传输系统中
**** 比如新增了一个peform 或者新增了一个函数
* E071
**OR object = 'REPS' 函数池(函数组)与子例程(函数组中的子例程都不需要考虑?)
loop at objects transporting no fields where pgmid = 'LIMU' and ( object = 'FUNC' or object = 'REPS' ).
endloop.
check sy-subrc is initial.
***找出主程序,然后找出相应的函数
loop at objects assigning field-symbol(<fs_object>) where pgmid = 'LIMU' and ( object = 'FUNC' or object = 'REPS' ).
data:
lt_tfdir type table of tfdir,
lt_tfdir_all type table of tfdir,
lt_tfdir_include type table of tfdir,
lw_tfdir type tfdir,
lw_tfdir_include type tfdir.
if <fs_object>-object = 'REPS'.
select * from tfdir
into table lt_tfdir
where pname = <fs_object>-obj_name.
if sy-subrc is initial."找到的话,那么<fs_object>-obj_name就是函数池,会不会刚好同名?那也有可能哈,但是概率低
append lines of lt_tfdir to lt_tfdir_all.
endif.
elseif <fs_object>-object = 'FUNC'.
select single * from tfdir
into lw_tfdir
where funcname = <fs_object>-obj_name.
if sy-subrc is initial.
select * from tfdir
into table lt_tfdir
where pname = lw_tfdir-pname.
if sy-subrc is initial.
append lines of lt_tfdir to lt_tfdir_all.
endif.
endif.
endif.
endloop.
****通过主程序找出所有的相关函数与子例程
check lt_tfdir_all[] is not initial.
sort lt_tfdir_all by funcname.
delete adjacent duplicates from lt_tfdir_all comparing funcname.
data:lt_wbcrossi type table of wbcrossi,
lw_wbcrossi type wbcrossi.
select * from wbcrossi
into table lt_wbcrossi
for all entries in lt_tfdir_all
where otype = 'IC' and master = lt_tfdir_all-pname and include = lt_tfdir_all-pname .
****排除掉当前相当函数与子例程已经在请求中,找出那些没有在请求中的相关函数与子例程
loop at lt_wbcrossi assigning field-symbol(<fs_wbcrossi>).
data(lv_index) = sy-tabix.
read table objects with key pgmid = 'LIMU' object = 'REPS' obj_name = <fs_wbcrossi>-name transporting no fields.
if sy-subrc is initial."找到了就去掉
delete lt_wbcrossi index lv_index.
endif.
endloop.
loop at lt_tfdir_all assigning field-symbol(<fs_tfdir>).
lv_index = sy-tabix.
read table objects with key pgmid = 'LIMU' object = 'FUNC' obj_name = <fs_tfdir>-funcname transporting no fields.
if sy-subrc is initial."找到了就去掉
delete lt_tfdir_all index lv_index.
endif.
endloop.
***检查这些子例程在远程系统中是否存在,如果不存在,提醒
data:lv_exist type abap_bool.
data:lv_titlebar type string value '检查函数池完整性检查'.
data:lv_text_question type string.
data:lv_answer type string.
loop at lt_wbcrossi assigning <fs_wbcrossi>.
call method get_version
exporting
p_program = <fs_wbcrossi>-name
p_object = 'REPS'
importing
e_is_exist = lv_exist.
if lv_exist = abap_false.
if dialog = abap_true.
* 程序对象在远程系统不存在,请确认是否要发布
lv_text_question = '程序对象:' && <fs_wbcrossi>-name && '在远程系统不存在,请确认是否要发布'.
call function 'POPUP_TO_CONFIRM'
exporting
titlebar = lv_titlebar
* DIAGNOSE_OBJECT = ' '
text_question = lv_text_question
text_button_1 = '是的'(001)
* ICON_BUTTON_1 = ' '
text_button_2 = '否'(002)
* ICON_BUTTON_2 = ' '
* DEFAULT_BUTTON = '1'
* DISPLAY_CANCEL_BUTTON = 'X'
* USERDEFINED_F1_HELP = ' '
* START_COLUMN = 25
* START_ROW = 6
* POPUP_TYPE =
* IV_QUICKINFO_BUTTON_1 = ' '
* IV_QUICKINFO_BUTTON_2 = ' '
importing
answer = lv_answer
* TABLES
* PARAMETER =
exceptions
text_not_found = 1
others = 2.
if sy-subrc <> 0.
exit.
endif.
if lv_answer = '2'.
raise cancel.
else.
sy-subrc = 0.
endif.
endif.
endif.
endloop.
loop at lt_tfdir_all assigning <fs_tfdir>.
call method get_version
exporting
p_program = <fs_tfdir>-funcname
p_object = 'FUNC'
importing
e_is_exist = lv_exist.
if lv_exist = abap_false.
if dialog = abap_true.
* 程序对象在远程系统不存在,请确认是否要发布
lv_text_question = '函数对象:' && <fs_tfdir>-funcname && '在远程系统不存在,请确认是否要发布'.
call function 'POPUP_TO_CONFIRM'
exporting
titlebar = lv_titlebar
* DIAGNOSE_OBJECT = ' '
text_question = lv_text_question
text_button_1 = '是的'(001)
* ICON_BUTTON_1 = ' '
text_button_2 = '否'(002)
* ICON_BUTTON_2 = ' '
* DEFAULT_BUTTON = '1'
* DISPLAY_CANCEL_BUTTON = 'X'
* USERDEFINED_F1_HELP = ' '
* START_COLUMN = 25
* START_ROW = 6
* POPUP_TYPE =
* IV_QUICKINFO_BUTTON_1 = ' '
* IV_QUICKINFO_BUTTON_2 = ' '
importing
answer = lv_answer
* TABLES
* PARAMETER =
exceptions
text_not_found = 1
others = 2.
if sy-subrc <> 0.
exit.
endif.
if lv_answer = '2'.
raise cancel.
else.
sy-subrc = 0.
endif.
endif.
endif.
endloop.
*****有一种特例需要测试一下,即第一次创建函数组
endif.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_IM_OBJECT_VER_CHECK->IF_EX_CTS_REQUEST_CHECK~CHECK_BEFORE_RELEASE_SLIN
* +-------------------------------------------------------------------------------------------------+
* | [--->] REQUEST TYPE TRKORR(optional)
* | [--->] TYPE TYPE TRFUNCTION(optional)
* | [--->] OWNER TYPE TR_AS4USER(optional)
* | [--->] OBJECTS TYPE TR_OBJECTS(optional)
* | [--->] KEYS TYPE TR_KEYS(optional)
* | [--->] KEYS_STR TYPE E071K_STRTYP(optional)
* | [--->] DIALOG TYPE TRBOOLEAN(optional)
* | [<-->] TEXT TYPE AS4TEXT(optional)
* | [<-->] ATTRIBUTES TYPE TRATTRIBUTES(optional)
* | [<-->] LV_CURRENT TYPE C(optional)
* | [<-->] LV_ERROR_TYPE TYPE TRWBO_CHARFLAG(optional)
* | [EXC!] CANCEL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_cts_request_check~check_before_release_slin.
break jordan.
endmethod.
endclass.
整 个类的基于源码如上,大家粘进去就可以,有什么问题留言
请求释放我没有找到实施点,可能需要使用隐式增强点,大概位置如下,这个我还没有做,
![!](https://img-blog.csdnimg.cn/533e8cc1075d43368b5af4882ff56d3b.png)
其中iv_test_import为测试导入的意思,即传输时那个测试导入的按钮意思,可以在这个函数里面增强一个实施。我看了请求号什么的变量都有,代码与上述的释放请求差不多,大家自行脑补哈。