SAP ABAP 函数组组件缺失检查

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

有没有遇到如下几个场景
场景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为测试导入的意思即传输时那个测试导入的按钮意思可以在这个函数里面增强一个实施。我看了请求号什么的变量都有代码与上述的释放请求差不多大家自行脑补哈。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“SAP ABAP 函数组组件缺失检查” 的相关文章