SAP ABAP 函数组组件缺失检查

news2024/11/24 5:05:09

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168555.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编解码-性能优化-SIMD

文章目录前言MMXSSEAVX使用内置函数使用SSE/AVX命名规则SSE/AVX操作类别实战汇编使用优化前代码详解优化后代码详解引用文章#mermaid-svg-cWLDz5Rki1i4TgZ1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#fff;}#mermaid-svg-cWLDz5Rki…

【JavaGuide面试总结】MySQL篇·中

【JavaGuide面试总结】MySQL篇中1.MySQL 的隔离级别是基于锁实现的吗&#xff1f;2.表级锁和行级锁了解吗&#xff1f;有什么区别&#xff1f;3.共享锁和排他锁简单说说4.意向锁有什么作用&#xff1f;5.InnoDB 有哪几类行锁&#xff1f;6.当前读和快照读有什么区别&#xff1f…

Go语言循环语句

Go语言循环语句 资料参考至菜鸟教程。 在不少实际问题中有许多具有规律性的重复操作&#xff0c;因此在程序中就需要重复执行某些语句。 以下为大多编程语言循环程序的流程图&#xff1a; Go语言提供了以下几种类型循环处理语句&#xff1a; 循环类型描述for循环重复执行语句块…

Base64

概述 Base64是一种基于64个字符的编码算法,经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。经Base64编码后的字符串的字符数是以4为单位的整数倍。 编码表 即64个字符分别是: 字符个数A-Z26a-z260-910+1/1=用于补位 在电子邮件中,每行为76个字符,每行末需添加一…

【青训营】Go的依赖管理

Go的依赖管理 本节内容来自于&#xff1a;字节跳动青年训练营第五届 后端组 1.什么是依赖 实际开发的工程需要使用许多第三方库&#xff0c;这能够使得我们站在巨人的肩膀上&#xff0c;使用第三方库中封装好的函数&#xff0c;可以大大方便我们的程序开发&#xff0c;第三方…

Microsoft Teams上的编程教育

内容提示&#xff1a;Microsoft Teams上的 MakeCode Arcade 使用形式&#xff1a;Microsoft Teams中的 “作业” 服务 应用场景&#xff1a;编程教育 社团活动 个人经验&#xff1a;在校期间&#xff0c;每周学校都会有社团活动&#xff0c;学生们根据自己的兴趣爱好来选择社…

struct 结构体的内存对齐

&#x1f499;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;一起学习C言 本文目录 在内存中观察 结构体内存对齐的规则&#xff1a; 为什么存在内存对齐&#xff1f; 编程中我们该如何设计结构体&#xff1f; 修改默认对齐数 相关笔试题 在内存中观察 首先…

el-date-picker 目前只能通过点击input输入框触发日期选择器,怎么通过其他方式触发日期选择器同时把input输入框去掉,如点击按钮

依然是该模块由于后端接口数据传输限制 在前面文章里做了些许改动。 需求左右切换 可以快速找到年份&#xff0c;于是添加了element选择年份的日期组件。 图中隐藏了el-data-picker日期组件&#xff0c;手动添加样式展示时间栏选择的数据进行 0 回显。 点击时间时&#xff0c;…

想看看一个影片评论怎么样?python带你采集数据做词云

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 目录前言环境使用:模块使用安装python第三方模块:思路分析代码展示数据采集词云图尾语 &#x1f49d;环境使用: Python 3.8 解释器 Pycharm 编辑器 模块使用 import parsel >>> pip install parsel import req…

《玩转 Spring 全家桶》学习笔记Day1

Spring 诞生于2002年&#xff0c;成型于2003年。Spring Boot 负责构建、Spring Cloud 协调、Spring Cloud Data Flow 负责连接一切。Spring Framework理念&#xff0c;向后兼容&#xff0c;专注API设计&#xff0c;让选择无处不在&#xff0c;海纳百川&#xff0c;严苛的代码质…

N+1终于等到了 但却放弃了

在公司呆了8年了&#xff0c;做梦都想被开除&#xff0c;年底等到了。但......2021年年底绩效B&#xff0c;可是公司年终奖泡沫了&#xff1b;估摸着2022年公司可能会发奖金&#xff0c;那我也悄悄的给自己定了目标&#xff0c;大干一场&#xff0c;争取过年拿个好结果。跟着公…

Go语言的数据类型

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点&#xff0c;以及职场小菜鸡的生活。&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知…

功率放大器模块在超微晶合金磁特性测量研究中的应用

客户需求&#xff1a;对超微晶合金磁特性测量中的波形发生与控制问题进行研究&#xff0c;实验系统有严格的体积要求&#xff0c;上位机可外置&#xff0c;测试系统需集成于机箱&#xff0c;机箱尺寸&#xff1a;1900mm500mm600mm。 解决方案&#xff1a;功率放大器模块采用安泰…

Golang的error和panic

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点&#xff0c;以及职场小菜鸡的生活。&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知…

Python入门自学进阶-Web框架——30、DjangoAdmin项目应用-自定义用户认证续

一、前面实现的是DjangoAdmin实现的自定义用户认证管理&#xff0c;现在自己来实现管理功能&#xff0c;即在mytestapp中增加用户认证管理功能。 在UserProfile的model中&#xff0c;对password字段增加help_text属性&#xff1a; password models.CharField(_(password), m…

Linux 环境安装 jdk 或 openjdk

一、linux 环境安装JDK的tar.gz包&#xff0c;通用命令&#xff1a; 1、查看已安装的JDK版本rpm -qa | grep jdk2、删除不需要的JDK版本&#xff1a;rpm -e --nodeps java-1.8.0-openjdk3、解压新JDK至/usr/lib/jvm目录下tar -zxvf openjdk-1044_linux-x64_bin_ri.tar.gz -C /…

AOSP刷机笔记

下载官方镜像&#xff0c;下载对应AOSP&#xff0c;编译出的*.img替换到官方镜像对应的文件, 刷入 把证书放到aosp源码的system/ca-certificates/files文件夹里&#xff0c;lunch aosp_sailfish-user编译可以实现无root抓包 mkdir ~/bin PATH~/bin:$PATH curl -sSL https://ger…

什么是集中采购 集中采购管理软件介绍

什么是集中采购&#xff1f; 集中采购是指企业总部某特定部门对企业所有采购进行管控&#xff0c;他们负责获取整个组织需要的物资。这个部门负责与供应商联络、供应商寻源、合同管理、风险分析&#xff0c;以及从供应商那里获得所需物资的每项工作。 企业采用集中采购管理模…

什么叫joinquant量化策略?

joinquant量化主要是在数据挖掘上有特别的意义&#xff0c;不像平时我们在执行各个量化选股策略时&#xff0c;还要一个一个去输入去查询。而joinquant量化策略在开发方面就简便了很多&#xff0c;joinquant量化策略是运用到个股量化交易中能够针对各个股票数据都能快速挖掘出来…

mongodb安装和部署,并整合到Springboot

mongodb安装和部署,并整合到Springboot 1.linux上docker安装mongodb docker pull mongo:4.4.18使用docker命令启动&#xff1a; docker run -p 27017:27017 --name mongo \ -v /mydata/mongo/db:/data/db \ -d mongo:4.4.18运行容器 docker exec -it mongo /bin/bash# 进入…