Introduction
During a project where many workbench programs and objects are created, it is not rare to have transport errors because of missing objects not transported yet because they were in other transport requests.
This little program tries to detect them.
Right now, it can't detect "complex" errors like a program using a table field that has not been transported yet, it only works on missing objects.
You'll find many more information in the header comments of the ABAP program below.
Update by Sandra Rossi on 2012-10-24: there is a more recent version of the program supplied as an attachment to this wiki, it was built on a 7.11 system with 2 major extensions (it should take into account BW objects and missing fields), but its development was stopped at an early stage and the program was tested only on a few transport requests. Please feel free to correct/improve this program!!! |
Screen captures
You'll have to log in to the target system if the RFC destination is not trusted, or does not have a fixed user and password:
- Top ALV shows the transport requests entered on the selection screen. This is used to help understand messages in the middle ALV
- Middle ALV is the most important part, it shows the status for all objects of the transport requests + the objects required by these first objects
- Bottom ALV shows at the left the required objects, and at the right the objects from the transport requests that need these objects.
ABAP code
Important: this program requires the include from the ABAP program to read where-used lists.
You may need to adjust the text pool (or maybe not): go to text symbols screen, click menu Adjust, accept to create all the texts proposed, save and activate the text symbols.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'******************** * Z_SIMULATE_DEV_TRANSPORT * * Current version : 1.01 * Version date : 2010-11-22 * ******************** * REVISIONS * 2010-11-22 1.01 : corrections - Z_DEV_WHERE_USED_LIST also corrected * 2010-04-30 1.00 : Official release * 2009-12-13 0.01 : Creation * ******************** * SHORT OVERVIEW: * Determines if a development workbench transport will fail. * The program can be run before the transport request is released, * so that to include missing objects. * * Selection screen contains the list of transport requests you want to * transport and the target system (RFC destination). * * Result screen contains 3 parts: * 1) ALV with transport requests of selection screen * 2) ALV with each object of the transport * request(s), with a status 0, 4 or 8, and the status text * 3) lower one contains an ALV with relationships between objects * and again warnings and errors * * Tested on SAPKB70013 system * * ******************** * SELECTION SCREEN: * If you don't have an RFC destination. You may also use * HOSTNAME_SYSTEMID_INSTANCENUMBER notation (expl: mplsap101_T1V_00) * (you'll have to login manually with user name and password once for * each run) * By default, SAP standard include sources are not analyzed, but you may * request to do so if for example you want to transport SAP note * corrections. * If you will transport objects with the "overwrite originals" * option, then select the P_SRCSYS option so that the detection is not * performed (and so, you'll avoid incorrect error messages "source system * is different"). * * ******************** * THE TOOL DETECTS THE FOLLOWING POSSIBLE ERRORS: * (legend: TR means Transport Request) * Checks that the subobjects required by the transported objects are * either transproted in the same TR, or in a previous TR indicated * in S_TRKORR, or already exist in the target system * When it detects missing objects, it looks for the transport requests * which contains these objects, and displays them. You can then run * again the tool with these new transport requests * If the object already exists in target system, checks that source system * in the object directory entry is the same in the 2 systems * Checks that the sequence of transport requests is correct * * ******************** * TODO: * 1) if required object exists in target system but is inactivate, * program doesn't indicate an error * 2) if transport of LIMU REPS with one source only for the first time, * SAP will create a R3TR PROG but LIMU REPT will be missing, program * doesn't indicate an error * 3) add warning if some required objects are being modified in current * system, in TRs that are not entered in selection screen. That would * help identifying errors like a program which uses a table field * not yet transported * 4) if the same TR contains both a new search help B using method * table A, and table A field is changed to refer to search help B, * SAP will try to activate table before search help. They should be * transported in separate TRs. * * False positive: * A) as all RFC calls are considered as normal function module calls, * program indicates an error if the function module doesn't exist in * the target system (though it should not test it when it is called * in another system, but it's too much difficult to know) * * ******************** * REQUIRED CUSTOM TOOLS: * - Where-used list (cross references) = include Z_DEV_WHERE_USED_LIST * * ******************** * Standard function modules used: * SRTT_GET_REMOTE_TADIR_ENTRY : read TADIR table * TR_CHECK_TYPE : get frame object (MESS -> MSAG, PROG -> PROG, FUNC -> FUGR, etc.) * TRINT_CHECK_LOCKS : get the TR which locks a given object * TRINT_OBJECT_NAMESPACE_INFO : identify if object is custom * TRINT_RESOLVE_OBJ : get subobjects of a given object * (R3TR PROG ZZZ -> LIMU DYNP ZZZ...1200, LIMU REPS ZZZTOP, etc., * but R3TR MSAG -> nothing, and all LIMU -> LIMU unchanged, no error) INCLUDE Z_DEV_WHERE_USED_LIST. TYPE-POOLS ICON. PARAMETERS P_TARGET TYPE RFCDEST. * X = analyze standard programs PARAMETERS P_INCSTD TYPE FLAG AS CHECKBOX. * X = ignore errors "source system is different" PARAMETERS P_SRCSYS TYPE FLAG AS CHECKBOX. TABLES E070. SELECT-OPTIONS S_TRKORR FOR E070-TRKORR. * "time machine" : mostly used for test purposes PARAMETERS P_TIMEMA TYPE TZNTIMESTP. * dummy screen to display the 3 result ALVs SELECTION-SCREEN BEGIN OF SCREEN 1010. * parameters p_dummy. SELECTION-SCREEN END OF SCREEN 1010. TYPES TY_T_E071 TYPE TABLE OF E071 WITH DEFAULT KEY. TYPES TY_RESULT_RC TYPE I. CONSTANTS : BEGIN OF GCS_RESULT_RC, OK TYPE TY_RESULT_RC VALUE 0, WARN TYPE TY_RESULT_RC VALUE 4, ERR TYPE TY_RESULT_RC VALUE 8, END OF GCS_RESULT_RC. TYPES : BEGIN OF TY_S_RESULT2, OBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, END OF TY_S_RESULT2. TYPES : BEGIN OF TY_S_RESULT, OBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, TRKORR TYPE E070-TRKORR, RC TYPE TY_RESULT_RC, ICON TYPE ICON_D, MESSAGE TYPE STRING, END OF TY_S_RESULT. * 2010-11-22 scope of local lt_result2 variable from DISPLAY_RESULT * subroutine, changed into global (bug found by Kihoori Oct 21) * List of required objects + by which object(s) are they required TYPES : BEGIN OF TY_GS_RESULT2, OBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, RC TYPE TY_RESULT_RC, SUBOBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, END OF TY_GS_RESULT2. DATA GT_RESULT2 TYPE TABLE OF TY_GS_RESULT2. ****************************** *CLASS lcl_salv_handler DEFINITION. * PUBLIC SECTION. * METHODS react_to_double_click * FOR EVENT double_click * OF cl_salv_events_table * IMPORTING row column. *ENDCLASS. "lcl_salv_handler DEFINITION * ****************************** *CLASS lcl_salv_handler IMPLEMENTATION. * METHOD react_to_double_click. * ENDMETHOD. "react_to_double_click *ENDCLASS. "lcl_salv_handler IMPLEMENTATION ***************************** CLASS LCL_SAP_FM DEFINITION. PUBLIC SECTION. CLASS-METHODS TR_CHECK_TYPE IMPORTING WI_E071 TYPE E071 EXPORTING WE_LOCK_KEY TYPE TLOCK_INT WE_TADIR TYPE TADIR. ENDCLASS. "lcl_sap_fm DEFINITION *----------------------------------------------------------------------* CLASS LCL_SAP_FM IMPLEMENTATION. METHOD TR_CHECK_TYPE. DATA LS_E071 TYPE E071. * TR_CHECK_TYPE retourne vide si object = VARX ! * Avec VARI, ça retourne bien le programme LS_E071 = WI_E071. IF LS_E071-OBJECT = 'VARX'. LS_E071-OBJECT = 'VARI'. ENDIF. CALL FUNCTION 'TR_CHECK_TYPE' EXPORTING WI_E071 = LS_E071 IMPORTING WE_TADIR = WE_TADIR WE_LOCK_KEY = WE_LOCK_KEY. ENDMETHOD. "TR_CHECK_TYPE ENDCLASS. "lcl_sap_fm IMPLEMENTATION *----------------------------------------------------------------------* TYPES : BEGIN OF TYPE_S_DOCU_KEY, DOCU_ID TYPE DOKHL-ID, DOCU_OBJECT TYPE DOKHL-OBJECT, END OF TYPE_S_DOCU_KEY. TYPES : BEGIN OF TYPE_S_TOBJ_KEY, OBJECTNAME TYPE OBJH-OBJECTNAME, OBJECTTYPE TYPE OBJH-OBJECTTYPE, END OF TYPE_S_TOBJ_KEY. TYPES : BEGIN OF TYPE_S_SOTT_KEY, PAKET TYPE SOTR_PACK, CONCEPT TYPE SOTR_CONC, END OF TYPE_S_SOTT_KEY. TYPES TYPE_SPAD(5) TYPE C. TYPES : BEGIN OF TYPE_S_SPCS_KEY, SPAD_TYPE TYPE TYPE_SPAD, CODEPAGE TYPE TCP00-CPCODEPAGE, END OF TYPE_S_SPCS_KEY. TYPES : BEGIN OF TYPE_S_SPSV_KEY, SPAD_TYPE TYPE TYPE_SPAD, SERVER TYPE TSPSV-SERVER, END OF TYPE_S_SPSV_KEY. TYPES : BEGIN OF TYPE_S_SPDV_KEY, SPAD_TYPE TYPE TYPE_SPAD, DEVICE TYPE TSP03-PADEST, END OF TYPE_S_SPDV_KEY. TYPES : BEGIN OF TYPE_S_SPLO_KEY, SPAD_TYPE TYPE TYPE_SPAD, PAPER_FORMAT TYPE TSP1D-PAPART, END OF TYPE_S_SPLO_KEY. TYPES : BEGIN OF TYPE_S_PRIN_KEY, SPAD_TYPE TYPE TYPE_SPAD, PRINTER_TYPE TYPE TSP0A-PATYPE, END OF TYPE_S_PRIN_KEY. TYPES : BEGIN OF TYPE_S_SLOM_KEY, SPAD_TYPE TYPE TYPE_SPAD, LOGICAL_OUTPUT_SYSTEM TYPE TSPLOMS-NAME, END OF TYPE_S_SLOM_KEY. TYPES : BEGIN OF TYPE_S_SOMS_KEY, SPAD_TYPE TYPE TYPE_SPAD, READ_OUTPUT_SYSTEM TYPE TSPROMS-NAME, END OF TYPE_S_SOMS_KEY. TYPES : BEGIN OF TYPE_S_SCP_KEY, BCSET_ID TYPE SCPR_ID, CATEGORY TYPE SCPR_CTGRY, END OF TYPE_S_SCP_KEY. TYPES : BEGIN OF TYPE_S_DYNP_KEY, PROGRAM_NAME TYPE D020S-PROG, SCREEN_NUMBER TYPE D020S-DNUM, END OF TYPE_S_DYNP_KEY. TYPES : BEGIN OF TYPE_S_VARI_KEY, VARIANT_NAME TYPE VARI-VARIANT, PROGRAM_NAME TYPE VARI-REPORT, END OF TYPE_S_VARI_KEY. TYPES : BEGIN OF TYPE_S_MESS_KEY, MSG_CLASS_NAME TYPE T100-ARBGB, MSG_NUMBER TYPE T100-MSGNR, END OF TYPE_S_MESS_KEY. TYPES : BEGIN OF TYPE_S_METH_KEY, CLASS_NAME TYPE SEOCLSNAME, METHOD_NAME TYPE SEOCPDNAME, END OF TYPE_S_METH_KEY. TYPES : BEGIN OF TYPE_S_WDYC_KEY, WEBDYNPRO_NAME TYPE WDY_COMPONENT_NAME, CONTROLLER_NAME TYPE WDY_CONTROLLER_NAME, END OF TYPE_S_WDYC_KEY. TYPES : BEGIN OF TYPE_S_WDYV_KEY, WEBDYNPRO_NAME TYPE WDY_COMPONENT_NAME, VIEW_NAME TYPE WDY_VIEW_NAME, END OF TYPE_S_WDYV_KEY. TYPES : BEGIN OF TYPE_S_WAPP_KEY, APPL_NAME TYPE O2APPLNAME, PAGE_NAME TYPE O2PAGE, END OF TYPE_S_WAPP_KEY. TYPES : BEGIN OF TYPE_S_WBOBJ_KEY, OBJ_NAME TYPE E071-OBJ_NAME, OBJECT TYPE E071-OBJECT, S_DOCU TYPE TYPE_S_DOCU_KEY, INCLUDE TYPE PROGNAME, TRKORR TYPE TRKORR, S_TOBJ TYPE TYPE_S_TOBJ_KEY, S_SOTT TYPE TYPE_S_SOTT_KEY, S_SPCS TYPE TYPE_S_SPCS_KEY, S_SPSV TYPE TYPE_S_SPSV_KEY, S_SPDV TYPE TYPE_S_SPDV_KEY, S_SPLO TYPE TYPE_S_SPLO_KEY, S_PRIN TYPE TYPE_S_PRIN_KEY, S_SLOM TYPE TYPE_S_SLOM_KEY, S_SOMS TYPE TYPE_S_SOMS_KEY, S_SCP TYPE TYPE_S_SCP_KEY, FILE TYPE CTS_GUID32, S_DYNP TYPE TYPE_S_DYNP_KEY, S_VARI TYPE TYPE_S_VARI_KEY, S_MESS TYPE TYPE_S_MESS_KEY, S_METH TYPE TYPE_S_METH_KEY, S_WDYC TYPE TYPE_S_WDYC_KEY, S_WDYV TYPE TYPE_S_WDYV_KEY, S_WAPP TYPE TYPE_S_WAPP_KEY, END OF TYPE_S_WBOBJ_KEY. TYPES : BEGIN OF TY_S_REQUEST, SORT TYPE NUMC4, E070 TYPE E070, END OF TY_S_REQUEST. TYPES SOFT_OR_HARD TYPE C LENGTH 1. TYPES : BEGIN OF TYPE_S_E071_REL, REQUEST TYPE TY_S_REQUEST, OBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, SOFT_OR_HARD TYPE SOFT_OR_HARD, MMMM TYPE FLAG, SUBREQUEST TYPE TY_S_REQUEST, SUBOBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY, END OF TYPE_S_E071_REL. TYPES TYPE_T_E071_KEY TYPE SORTED TABLE OF LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY WITH UNIQUE KEY PGMID OBJECT OBJ_NAME. TYPES GTYP_T_E071 TYPE TABLE OF E071. TYPES TY_T_TRKORR TYPE TABLE OF E070-TRKORR. *----------------------------------------------------------------------* DEFINE MAC_COLLECT. PERFORM COLLECT USING &1 &2 &3 &4 &5. END-OF-DEFINITION. *----------------------------------------------------------------------* DATA GT_E071_DONT_EXIST_IN_TARGET TYPE TY_T_E071. DATA: BEGIN OF GS_CLUSTER_CONTENT, LASTGENTIME TYPE TZNTIMESTP, T_E070 TYPE TABLE OF E070 WITH DEFAULT KEY, T_E071 TYPE TY_T_E071, END OF GS_CLUSTER_CONTENT. FIELD-SYMBOLS <LS_RESULT2> TYPE TY_S_RESULT2. FIELD-SYMBOLS <LS_RESULT> TYPE TY_S_RESULT. DATA GT_RESULT TYPE TABLE OF TY_S_RESULT. DATA GO_SPLITTER_CONTAINER TYPE REF TO CL_GUI_SPLITTER_CONTAINER. DATA GO_SPLITTER_CONTAINER_2 TYPE REF TO CL_GUI_CONTAINER. DATA GO_CONTAINER_REQUEST TYPE REF TO CL_GUI_CONTAINER. DATA GO_CONTAINER_ERROR TYPE REF TO CL_GUI_CONTAINER. DATA GO_CONTAINER_REQUIREDBY TYPE REF TO CL_GUI_CONTAINER. DATA GO_ALV_REQUEST TYPE REF TO CL_SALV_TABLE. DATA GO_ALV_ERROR TYPE REF TO CL_SALV_TABLE. DATA GO_ALV_REQUIREDBY TYPE REF TO CL_SALV_TABLE. *DATA go_event_handler TYPE REF TO lcl_salv_handler. DATA LT_E071 TYPE TABLE OF E071. DATA GT_REQUEST TYPE TABLE OF TY_S_REQUEST. DATA GS_REQUEST_INITIAL TYPE TY_S_REQUEST. DATA GT_E071_KEY TYPE TABLE OF TYPE_S_E071_REL. DATA GT_E071_KEY_SORTED TYPE TYPE_T_E071_KEY. *DATA: BEGIN OF gth_error OCCURS 0, * text(30) TYPE c, * pgmid TYPE e071-pgmid, * object TYPE e071-object, * obj_name TYPE e071-obj_name, * END OF gth_error. DATA GT_E070_START TYPE TABLE OF E070. DATA GS_E070_START TYPE E070. *----------------------------------------------------------------------* INITIALIZATION. * disable HIGH field for transport request select-options TYPE-POOLS SSCR. DATA: RESTRICT TYPE SSCR_RESTRICT, OPT_LIST TYPE SSCR_OPT_LIST, ASS TYPE SSCR_ASS. CLEAR OPT_LIST. MOVE 'S_TRKORR' TO OPT_LIST-NAME. OPT_LIST-OPTIONS-EQ = 'X'. APPEND OPT_LIST TO RESTRICT-OPT_LIST_TAB. CONCATENATE SY-SYSID 'K9' INTO S_TRKORR-LOW. APPEND S_TRKORR. ASS-NAME = 'S_TRKORR'. ASS-KIND = 'S'. ASS-SG_MAIN = 'I'. ASS-SG_ADDY = SPACE. ASS-OP_MAIN = 'S_TRKORR'. APPEND ASS TO RESTRICT-ASS_TAB. CALL FUNCTION 'SELECT_OPTIONS_RESTRICT' EXPORTING RESTRICTION = RESTRICT EXCEPTIONS OTHERS = 1. * set default variant to initialize selection screen fields IF SY-SLSET IS INITIAL. DATA G_VARIANT TYPE RSVAR-VARIANT. CONCATENATE 'US' SY-UNAME INTO G_VARIANT. CALL FUNCTION 'RS_SUPPORT_SELECTIONS' EXPORTING REPORT = SY-CPROG "actual program name VARIANT = G_VARIANT "default variant name EXCEPTIONS VARIANT_NOT_EXISTENT = 1 VARIANT_OBSOLETE = 2 OTHERS = 3. IF SY-SUBRC = 1. CALL FUNCTION 'RS_SUPPORT_SELECTIONS' EXPORTING REPORT = SY-CPROG "actual program name VARIANT = 'SAPDEFAULT' "default variant name EXCEPTIONS VARIANT_NOT_EXISTENT = 0 VARIANT_OBSOLETE = 0 OTHERS = 0. ENDIF. ENDIF. *----------------------------------------------------------------------* AT SELECTION-SCREEN OUTPUT. IF SY-DYNNR = 1010. PERFORM DISPLAY_RESULT. ENDIF. *----------------------------------------------------------------------* AT SELECTION-SCREEN. IF SY-DYNNR = 1000 AND SY-UCOMM = 'ONLI'. * Sélectionner les ordres * - et ignorer les entrées qui sont des tâches * TODO: ignore released requests (problématique à traiter car il n'y a pas de versioning dans les cross-references) * AND trstatus IN ('D','L'). "modifiable SELECT * FROM E070 INTO TABLE GT_E070_START WHERE TRKORR IN S_TRKORR AND STRKORR = SPACE. IF LINES( S_TRKORR ) <> LINES( GT_E070_START ). MESSAGE E001(00) WITH 'You have entered tasks, replace them with requests'(015). ENDIF. * DATA ls_rfcsi TYPE rfcsi. DATA L_LOGIN_COMPLETE TYPE SYDEBUG. CALL FUNCTION 'RFC_LOGIN_INFO' DESTINATION P_TARGET IMPORTING RFC_LOGIN_COMPLETE = L_LOGIN_COMPLETE EXCEPTIONS COMMUNICATION_FAILURE = 1 SYSTEM_FAILURE = 1. IF SY-SUBRC <> 0 OR L_LOGIN_COMPLETE <> 'Y'. MESSAGE E001(00) WITH 'Invalid RFC destination or wrong user/password'(018). ENDIF. ENDIF. *----------------------------------------------------------------------* START-OF-SELECTION. PERFORM MAIN2. PERFORM PROCESS1. PERFORM PROCESS2. * Display results (ALV). Note: 1010 is a dummy screen CALL SELECTION-SCREEN 1010. ASSERT 1 = 1. *----------------------------------------------------------------------* FORM COLLECT USING X TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY "object SOFT_OR_HARD TYPE SOFT_OR_HARD MMMM TYPE FLAG Y TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY "subobject SUBREQUEST TYPE TY_S_REQUEST. DATA LS_E071 TYPE E071. DATA LS_TADIR TYPE TADIR. DATA L_LINES TYPE I. DATA L_NAMECLASS TYPE C LENGTH 1. DATA L_CASTING_OBJNAME TYPE TADIR-OBJ_NAME. DATA LS_E071_KEY TYPE TYPE_S_E071_REL. * Collect only custom objects except if user asked to analyze standard too * For this test, TRINT_OBJECT_NAMESPACE_INFO function module requires * R3TR, so first convert LIMU into R3TR (and R3TR remains unchanged) by * calling TR_CHECK_TYPE function module LS_E071-PGMID = Y-PGMID. LS_E071-OBJECT = Y-OBJECT. LS_E071-OBJ_NAME = Y-OBJ_NAME. CALL METHOD LCL_SAP_FM=>TR_CHECK_TYPE EXPORTING WI_E071 = LS_E071 IMPORTING WE_TADIR = LS_TADIR. * If target object doesn't exist in target system, then process it whatever it * is custom or standard READ TABLE GT_E071_DONT_EXIST_IN_TARGET WITH KEY PGMID = LS_TADIR-PGMID OBJECT = LS_TADIR-OBJECT OBJ_NAME = LS_TADIR-OBJ_NAME BINARY SEARCH TRANSPORTING NO FIELDS. IF SY-SUBRC = 0. L_NAMECLASS = 'C'. ELSE. CALL FUNCTION 'TRINT_OBJECT_NAMESPACE_INFO' EXPORTING IV_PGMID = LS_TADIR-PGMID IV_OBJECT = LS_TADIR-OBJECT IV_OBJNAME = LS_TADIR-OBJ_NAME IMPORTING EV_NAMECLASS = L_NAMECLASS EXCEPTIONS OTHERS = 4. ENDIF. * nameclass may have values 'S' (standard) or 'C' (customer) IF L_NAMECLASS = 'C' OR X IS INITIAL OR P_INCSTD = 'X'. * Object is custom READ TABLE GT_E071_KEY INTO LS_E071_KEY WITH KEY OBJECT = X SUBOBJECT = Y. IF SY-SUBRC <> 0. CLEAR LS_E071_KEY. * Object was maybe in a TR, get it along with its sequence READ TABLE GT_E071_KEY INTO LS_E071_KEY WITH KEY SUBOBJECT = X SOFT_OR_HARD = SPACE TRANSPORTING SUBREQUEST. LS_E071_KEY-REQUEST = LS_E071_KEY-SUBREQUEST. CLEAR LS_E071_KEY-SUBREQUEST. LS_E071_KEY-OBJECT = X. LS_E071_KEY-SOFT_OR_HARD = SOFT_OR_HARD. LS_E071_KEY-MMMM = MMMM. IF SUBREQUEST IS INITIAL. READ TABLE GT_E071_KEY INTO LS_E071_KEY WITH KEY SUBOBJECT = Y SOFT_OR_HARD = SPACE TRANSPORTING SUBREQUEST. ELSE. LS_E071_KEY-SUBREQUEST = SUBREQUEST. ENDIF. LS_E071_KEY-SUBOBJECT = Y. APPEND LS_E071_KEY TO GT_E071_KEY. ENDIF. ENDIF. ENDFORM. "collect *----------------------------------------------------------------------* FORM MAIN2. DATA LS_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. DATA LS_E071 TYPE E071. DATA LT_E070_BIS TYPE TABLE OF E070. DATA X TYPE I. DATA LT_RNG_TRKORR TYPE RANGE OF E070-TRKORR. DATA LS_RNG_TRKORR LIKE LINE OF LT_RNG_TRKORR. DATA LS_EMPTY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. DATA L_TRKORR TYPE E070-TRKORR. DATA LS_TRKORR LIKE LINE OF S_TRKORR. DATA LS_REQUEST TYPE TY_S_REQUEST. DATA L_TABIX TYPE SYTABIX. DATA LS_E071_PREV TYPE E071. DATA LS_REQUEST_PREV TYPE TY_S_REQUEST. DATA LS_E071_REL TYPE TYPE_S_E071_REL. DATA LT_E070 TYPE TABLE OF E070. DATA LS_E070 TYPE E070. * Build list of objects that exist in released transport requests * of the current system, but that don't exist in target system * This process is time consuming, so a buffering incremental method * is used (it's time consuming only first time a target system is * entered) PERFORM GET_E071_DONT_EXIST_IN_TARGET USING P_TARGET CHANGING GT_E071_DONT_EXIST_IN_TARGET. REFRESH LT_RNG_TRKORR. LOOP AT GT_E070_START INTO LS_E070. LS_RNG_TRKORR-SIGN = 'I'. LS_RNG_TRKORR-OPTION = 'EQ'. LS_RNG_TRKORR-LOW = LS_E070-TRKORR. APPEND LS_RNG_TRKORR TO LT_RNG_TRKORR. ENDLOOP. * Determine and store sequence number of the TR in S_TRKORR SORT GT_E070_START BY TRKORR. REFRESH GT_REQUEST. CLEAR LS_REQUEST. LOOP AT S_TRKORR INTO LS_TRKORR. READ TABLE GT_E070_START WITH KEY TRKORR = LS_TRKORR-LOW BINARY SEARCH INTO LS_E070. IF SY-SUBRC = 0. ADD 1 TO LS_REQUEST-SORT. LS_REQUEST-E070 = LS_E070. APPEND LS_REQUEST TO GT_REQUEST. ENDIF. ENDLOOP. * List of requests and tasks containing objects to analyze LT_E070_BIS = GT_E070_START. * Take into account tasks not released yet that belong to entered * transport requests (tasks: STRKORR <> blank; not released: TRSTATUS = 'D' or 'L') SELECT * FROM E070 INTO TABLE LT_E070 WHERE STRKORR IN LT_RNG_TRKORR AND TRSTATUS IN ('D','L'). "modifiable APPEND LINES OF LT_E070 TO LT_E070_BIS. LOOP AT LT_E070 INTO LS_E070. LS_RNG_TRKORR-SIGN = 'I'. LS_RNG_TRKORR-OPTION = 'EQ'. LS_RNG_TRKORR-LOW = LS_E070-TRKORR. APPEND LS_RNG_TRKORR TO LT_RNG_TRKORR. ENDLOOP. * Build list of objects ("initial objects") to transport SELECT * FROM E071 INTO TABLE LT_E071 WHERE TRKORR IN LT_RNG_TRKORR AND PGMID NE 'CORR'. "ignore CORR RELE lines, they pollute the result * Store initial objects, along with the transport request (not the * eventual task) to which they belong. * If same object appears several times, only take into account first occurrence * in the S_TRKORR sequence (smallest SORT) * TODO: here I didn't check when same object has 2 different keys (LIMU REPS * and R3TR PROG for example) SORT LT_E070_BIS BY TRKORR. SORT GT_REQUEST BY E070-TRKORR. SORT LT_E071 BY PGMID OBJECT OBJ_NAME. L_TABIX = 0. DO. IF L_TABIX > LINES( LT_E071 ). EXIT. ENDIF. ADD 1 TO L_TABIX. READ TABLE LT_E071 INTO LS_E071 INDEX L_TABIX. IF SY-SUBRC = 0. * Get the transport request number when the object is in a non released task CLEAR LS_E070. READ TABLE LT_E070_BIS WITH KEY TRKORR = LS_E071-TRKORR INTO LS_E070 BINARY SEARCH. IF LS_E070-STRKORR IS NOT INITIAL. L_TRKORR = LS_E070-STRKORR. ELSE. L_TRKORR = LS_E070-TRKORR. ENDIF. * Get the first transport request in S_TRKORR in which the object appears first * (when the object belongs to several transport requests) READ TABLE GT_REQUEST WITH KEY E070-TRKORR = L_TRKORR INTO LS_REQUEST BINARY SEARCH. ENDIF. IF L_TABIX <= LINES( LT_E071 ) AND LS_E071-PGMID = LS_E071_PREV-PGMID AND LS_E071-OBJECT = LS_E071_PREV-OBJECT AND LS_E071-OBJ_NAME = LS_E071_PREV-OBJ_NAME. * object appears twice, delete one occurrence IF LS_REQUEST-SORT <= LS_REQUEST_PREV-SORT. * keep current, delete previous SUBTRACT 1 FROM L_TABIX. DELETE LT_E071 INDEX L_TABIX. ELSE. * keep previous, delete current DELETE LT_E071 INDEX L_TABIX. * reposition for next iteration LS_REQUEST = LS_REQUEST_PREV. SUBTRACT 1 FROM L_TABIX. ENDIF. ELSEIF L_TABIX <> 1. * each time a new object is to be processed, or after last object, * add previous object LS_E071_KEY-PGMID = LS_E071_PREV-PGMID. LS_E071_KEY-OBJECT = LS_E071_PREV-OBJECT. LS_E071_KEY-OBJ_NAME = LS_E071_PREV-OBJ_NAME. MAC_COLLECT LS_EMPTY '' '' LS_E071_KEY LS_REQUEST_PREV. ENDIF. * current becomes "previous" for next iteration LS_E071_PREV = LS_E071. LS_REQUEST_PREV = LS_REQUEST. ENDDO. * Add subobjects (R3TR PROG may contain LIMU DYNP, etc.) LOOP AT GT_E071_KEY INTO LS_E071_REL. DATA LT_SUBOBJ TYPE TYPE_T_E071_KEY. DATA LS_SUBOBJ TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. PERFORM GET_SUBOBJ USING LS_E071_REL-SUBOBJECT LS_E071_REL-SUBREQUEST CHANGING LT_SUBOBJ. ENDLOOP. REFRESH GT_E071_KEY_SORTED. ENDFORM. "main2 *----------------------------------------------------------------------* FORM GET_SUBOBJ USING IS_SUBOBJECT TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY IS_SUBREQUEST TYPE TYPE_S_E071_REL-SUBREQUEST CHANGING ET_SUBOBJ TYPE TYPE_T_E071_KEY. DATA LT_T100 TYPE TABLE OF T100. DATA LS_T100 TYPE T100. DATA LT_VARID TYPE TABLE OF VARID. DATA LS_VARID TYPE VARID. DATA LS_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. DATA LS_E071 TYPE E071. DATA LT_VRSO_SOURCE TYPE TABLE OF VRSO. DATA LS_VRSO TYPE VRSO. IF IS_SUBOBJECT-PGMID = 'R3TR'. CASE IS_SUBOBJECT-OBJECT. WHEN 'MSAG'. SELECT * FROM T100 INTO TABLE LT_T100 WHERE ARBGB = IS_SUBOBJECT-OBJ_NAME. LOOP AT LT_T100 INTO LS_T100. LS_E071_KEY-PGMID = 'LIMU'. LS_E071_KEY-OBJECT = 'MESS'. CONCATENATE IS_SUBOBJECT-OBJ_NAME LS_T100-MSGNR INTO LS_E071_KEY-OBJ_NAME. MAC_COLLECT IS_SUBOBJECT '' 'X' LS_E071_KEY IS_SUBREQUEST. ENDLOOP. WHEN OTHERS. * Call TRINT_RESOLVE_OBJ on each system to check existence of all subobjects * If an object is a frame object (R3TR PROG, R3TR FUGR), consider that * all its subobjects (LIMU DYNP, LIMU FUNC, etc.) belong to the same * transport request LS_E071-OBJECT = IS_SUBOBJECT-OBJECT. LS_E071-OBJ_NAME = IS_SUBOBJECT-OBJ_NAME. REFRESH LT_VRSO_SOURCE. CALL FUNCTION 'TRINT_RESOLVE_OBJ' EXPORTING IS_E071 = LS_E071 TABLES ET_VRSO = LT_VRSO_SOURCE EXCEPTIONS NOT_VERSIONABLE = 1 COMMUNICATION_ERROR = 2 OTHERS = 3. LOOP AT LT_VRSO_SOURCE INTO LS_VRSO. LS_E071_KEY-PGMID = 'LIMU'. LS_E071_KEY-OBJECT = LS_VRSO-OBJTYPE. LS_E071_KEY-OBJ_NAME = LS_VRSO-OBJNAME. MAC_COLLECT IS_SUBOBJECT '' 'X' LS_E071_KEY IS_SUBREQUEST. ENDLOOP. ENDCASE. * 2010-11-22 * Line LIMU ADIR R3TRSOTR<name> transports implicitly R3TR SOTR <name> * object so it must be added ELSEIF IS_SUBOBJECT-PGMID = 'LIMU' AND IS_SUBOBJECT-OBJECT = 'ADIR'. LS_E071_KEY-PGMID = IS_SUBOBJECT-OBJ_NAME+0(4). LS_E071_KEY-OBJECT = IS_SUBOBJECT-OBJ_NAME+4(4). LS_E071_KEY-OBJ_NAME = IS_SUBOBJECT-OBJ_NAME+8. MAC_COLLECT IS_SUBOBJECT '' 'X' LS_E071_KEY IS_SUBREQUEST. ENDIF. CASE IS_SUBOBJECT-OBJECT. WHEN 'PROG' OR 'REPS' OR 'REPO'. * propose automatically system variants SELECT * FROM VARID CLIENT SPECIFIED INTO TABLE LT_VARID WHERE MANDT = '000' "system variants are only in client 000 AND REPORT = IS_SUBOBJECT-OBJ_NAME AND TRANSPORT = SPACE. "system variant LOOP AT LT_VARID INTO LS_VARID. LS_E071_KEY-PGMID = 'LIMU'. LS_E071_KEY-OBJECT = 'VARX'. CONCATENATE LS_VARID-REPORT LS_VARID-VARIANT INTO LS_E071_KEY-OBJ_NAME RESPECTING BLANKS. MAC_COLLECT IS_SUBOBJECT 'S' '' LS_E071_KEY IS_SUBREQUEST. ENDLOOP. ENDCASE. ENDFORM. "get_subobj *----------------------------------------------------------------------* FORM PROCESS1. DATA LS_E071_KEY TYPE TYPE_S_E071_REL. * look for all required subobjects LOOP AT GT_E071_KEY INTO LS_E071_KEY WHERE MMMM IS INITIAL AND SOFT_OR_HARD IS INITIAL. DATA LO_EXC TYPE REF TO CX_ROOT. DATA LT_OBJ TYPE LCL_DEV_CROSS_REF=>TYPE_T_E071_REL. DATA LS_OBJ TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_REL. REFRESH LT_OBJ. TRY. CALL METHOD LCL_DEV_CROSS_REF=>GET_REQOBJ EXPORTING IS_E071_KEY = LS_E071_KEY-SUBOBJECT IMPORTING ET_E071_KEY = LT_OBJ. CATCH CX_ROOT INTO LO_EXC. LO_EXC->GET_LONGTEXT( ). ENDTRY. LOOP AT LT_OBJ INTO LS_OBJ. MAC_COLLECT LS_E071_KEY-SUBOBJECT LS_OBJ-SOFT_OR_HARD LS_E071_KEY-MMMM LS_OBJ-SUBOBJECT GS_REQUEST_INITIAL. ENDLOOP. ENDLOOP. ENDFORM. "process1 *----------------------------------------------------------------------* FORM PROCESS2. DATA LT_E071_KEY TYPE TABLE OF TYPE_S_E071_REL. DATA LS_E071_KEY TYPE TYPE_S_E071_REL. DATA LS_E071_KEY_2 TYPE TYPE_S_E071_REL. DATA LS_TRKORR LIKE LINE OF S_TRKORR. DATA LS_REQUEST TYPE TY_S_REQUEST. DATA OBJNAME TYPE VRSD_OLD-OBJNAME. DATA OBJTYPE TYPE VRSD_OLD-OBJTYPE. DATA LS_E071 TYPE E071. DATA LT_VRSO_SOURCE TYPE TABLE OF VRSO. DATA LT_VRSO_TARGET TYPE TABLE OF VRSO. DATA LS_VRSO TYPE VRSO. DATA L_STRING_OBJECT TYPE STRING. DATA L_STRING_SUBOBJECT TYPE STRING. DATA LS_TADIR TYPE TADIR. DATA OBJNAME2 TYPE VRSD-OBJNAME. DATA OBJTYPE2 TYPE VRSD-OBJTYPE. DATA LT_VERSION_TARGET TYPE TABLE OF VRSD. DATA LT_VERSNO_TARGET TYPE TABLE OF VRSN. DATA LS_VERSION_TARGET TYPE VRSD. DATA L_SPRSL TYPE T100-SPRSL. DATA LT_DOCU_TAB TYPE TABLE OF RPY_OBJTAB. DATA LT_DOCU_TECH TYPE TABLE OF TLINE. DATA L_NOT_FOUND TYPE FLAG. DATA L_TRKORR TYPE E070-TRKORR. DATA L_LOCK TYPE FLAG. DATA L_SRCSYSTEM_IN_CURRENT TYPE TADIR-SRCSYSTEM. DATA L_SRCSYSTEM_IN_TARGET TYPE TADIR-SRCSYSTEM. SORT GT_E071_KEY BY SUBOBJECT. LT_E071_KEY = GT_E071_KEY. DELETE ADJACENT DUPLICATES FROM LT_E071_KEY COMPARING SUBOBJECT. * loop at all required objects * (MMMM = 'X' when object is included in another one which is * transported (expl: when R3TR MSAG is to be transported, all its * messages (LIMU MESS) also exist with MMMM = 'X') LOOP AT LT_E071_KEY INTO LS_E071_KEY WHERE MMMM IS INITIAL. * Initialize texts which will be used later CONCATENATE LS_E071_KEY-SUBOBJECT-PGMID LS_E071_KEY-SUBOBJECT-OBJECT LS_E071_KEY-SUBOBJECT-OBJ_NAME INTO L_STRING_SUBOBJECT SEPARATED BY '-'. IF LS_E071_KEY-SUBREQUEST IS NOT INITIAL. CONCATENATE L_STRING_SUBOBJECT ' (' 'TR:'(001) LS_E071_KEY-SUBREQUEST-E070-TRKORR ')' INTO L_STRING_SUBOBJECT. ENDIF. CONCATENATE LS_E071_KEY-OBJECT-PGMID LS_E071_KEY-OBJECT-OBJECT LS_E071_KEY-OBJECT-OBJ_NAME INTO L_STRING_OBJECT SEPARATED BY '-'. IF LS_E071_KEY-REQUEST IS NOT INITIAL. CONCATENATE L_STRING_OBJECT ' (' 'TR:'(001) LS_E071_KEY-REQUEST-E070-TRKORR ')' INTO L_STRING_OBJECT. ENDIF. READ TABLE GT_RESULT ASSIGNING <LS_RESULT> WITH KEY OBJECT = LS_E071_KEY-SUBOBJECT. IF SY-SUBRC <> 0. APPEND INITIAL LINE TO GT_RESULT ASSIGNING <LS_RESULT>. <LS_RESULT>-OBJECT = LS_E071_KEY-SUBOBJECT. <LS_RESULT>-TRKORR = LS_E071_KEY-SUBREQUEST-E070-TRKORR. ENDIF. PERFORM CHECK_EXISTS USING LS_E071_KEY-SUBOBJECT P_TARGET CHANGING L_NOT_FOUND L_LOCK L_TRKORR L_SRCSYSTEM_IN_CURRENT L_SRCSYSTEM_IN_TARGET. IF LS_E071_KEY-SOFT_OR_HARD IS INITIAL. IF L_NOT_FOUND IS INITIAL AND L_SRCSYSTEM_IN_CURRENT <> L_SRCSYSTEM_IN_TARGET. IF P_SRCSYS IS INITIAL. <LS_RESULT>-RC = GCS_RESULT_RC-ERR. <LS_RESULT>-ICON = ICON_RED_LIGHT. ELSE. <LS_RESULT>-RC = GCS_RESULT_RC-WARN. <LS_RESULT>-ICON = ICON_YELLOW_LIGHT. ENDIF. <LS_RESULT>-MESSAGE = 'Object has a different source system ' & 'between the 2 systems (TW103)'(002). ELSE. <LS_RESULT>-RC = GCS_RESULT_RC-OK. <LS_RESULT>-ICON = ICON_GREEN_LIGHT. IF LS_E071_KEY-OBJECT IS INITIAL. CONCATENATE 'OK as object is transported in TR'(003) LS_E071_KEY-REQUEST-E070-TRKORR INTO <LS_RESULT>-MESSAGE SEPARATED BY SPACE. ELSE. * TODO: not sure that this code is okay (wrong condition or wrong text) CONCATENATE 'OK as its using object'(004) L_STRING_OBJECT 'is transported in one of the TRs'(005) INTO <LS_RESULT>-MESSAGE SEPARATED BY SPACE. ENDIF. ENDIF. ELSE. ************************ * Processing of required objects ************************ IF LS_E071_KEY-SUBREQUEST IS NOT INITIAL AND LS_E071_KEY-SUBREQUEST-SORT = LS_E071_KEY-REQUEST-SORT. <LS_RESULT>-RC = GCS_RESULT_RC-OK. <LS_RESULT>-ICON = ICON_GREEN_LIGHT. <LS_RESULT>-MESSAGE = 'OK as required and using objects are' & ' in the same TR'(006). ELSEIF LS_E071_KEY-SUBREQUEST IS NOT INITIAL AND LS_E071_KEY-SUBREQUEST-SORT < LS_E071_KEY-REQUEST-SORT. <LS_RESULT>-RC = GCS_RESULT_RC-OK. <LS_RESULT>-ICON = ICON_GREEN_LIGHT. CONCATENATE 'OK as using object is in earlier TR'(007) LS_E071_KEY-SUBREQUEST-E070-TRKORR 'before required object'(016) INTO <LS_RESULT>-MESSAGE SEPARATED BY SPACE. ELSE. * If subobject is neither in current TR nor in one of previous TR (in S_TRKORR), * make sure that it already exists in target system * In case the object is "soft" required (missing package for example), * transport request won't fail, so it's just a warning IF L_NOT_FOUND = 'X'. IF LS_E071_KEY-SOFT_OR_HARD = 'S'. <LS_RESULT>-RC = GCS_RESULT_RC-WARN. <LS_RESULT>-ICON = ICON_YELLOW_LIGHT. CONCATENATE 'OK though required object is neither transported,'(017) ' nor exists in target system, but it is not mandatory'(008) INTO <LS_RESULT>-MESSAGE. ELSE. <LS_RESULT>-RC = GCS_RESULT_RC-ERR. <LS_RESULT>-ICON = ICON_RED_LIGHT. <LS_RESULT>-MESSAGE = 'Required object does not exist in ' & 'target system'(009). ENDIF. * Required subobject is provided in one of the TRs in S_TRKORR, but this * TR should be transported before IF LS_E071_KEY-SUBREQUEST IS NOT INITIAL AND LS_E071_KEY-SUBREQUEST-SORT > LS_E071_KEY-REQUEST-SORT. <LS_RESULT>-RC = GCS_RESULT_RC-WARN. <LS_RESULT>-ICON = ICON_YELLOW_LIGHT. CONCATENATE <LS_RESULT>-MESSAGE 'Required object is in TR '(010) LS_E071_KEY_2-SUBREQUEST-E070-TRKORR INTO <LS_RESULT>-MESSAGE. ELSE. * Propose a transport request containing the required object * (so that user adds it to the list of transport requests (S_TRKORR) IF L_NOT_FOUND IS INITIAL. IF L_LOCK = 'X'. <LS_RESULT>-RC = GCS_RESULT_RC-WARN. <LS_RESULT>-ICON = ICON_YELLOW_LIGHT. CONCATENATE <LS_RESULT>-MESSAGE 'Note: required object is locked in TR'(011) L_TRKORR INTO <LS_RESULT>-MESSAGE SEPARATED BY SPACE. ELSE. <LS_RESULT>-RC = GCS_RESULT_RC-WARN. <LS_RESULT>-ICON = ICON_YELLOW_LIGHT. CONCATENATE <LS_RESULT>-MESSAGE 'Note: object exists in TR '(012) L_TRKORR 'for example'(013) INTO <LS_RESULT>-MESSAGE SEPARATED BY SPACE. ENDIF. ENDIF. ENDIF. ELSE. <LS_RESULT>-RC = GCS_RESULT_RC-OK. <LS_RESULT>-ICON = ICON_GREEN_LIGHT. <LS_RESULT>-MESSAGE = 'OK as required object already exists in ' & 'target system'(014). ENDIF. ENDIF. ENDIF. ENDLOOP. ENDFORM. "process2 *&---------------------------------------------------------------------* *& Form display_result *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM DISPLAY_RESULT. DATA LS_E071_KEY TYPE TYPE_S_E071_REL. DATA LO_COLUMNS TYPE REF TO CL_SALV_COLUMNS_TABLE. * DATA lo_events TYPE REF TO cl_salv_events_table. TRY. CREATE OBJECT GO_SPLITTER_CONTAINER EXPORTING PARENT = CL_GUI_CONTAINER=>SCREEN0 ROWS = 3 COLUMNS = 1. GO_CONTAINER_REQUEST = GO_SPLITTER_CONTAINER->GET_CONTAINER( ROW = 1 COLUMN = 1 ). GO_CONTAINER_ERROR = GO_SPLITTER_CONTAINER->GET_CONTAINER( ROW = 2 COLUMN = 1 ). GO_CONTAINER_REQUIREDBY = GO_SPLITTER_CONTAINER->GET_CONTAINER( ROW = 3 COLUMN = 1 ). * Remind the entered sequence of transport requests CALL METHOD CL_SALV_TABLE=>FACTORY EXPORTING R_CONTAINER = GO_CONTAINER_REQUEST IMPORTING R_SALV_TABLE = GO_ALV_REQUEST CHANGING T_TABLE = GT_REQUEST. LO_COLUMNS = GO_ALV_REQUEST->GET_COLUMNS( ). LO_COLUMNS->SET_OPTIMIZE( ). GO_ALV_REQUEST->DISPLAY( ). * List of errors CALL METHOD CL_SALV_TABLE=>FACTORY EXPORTING R_CONTAINER = GO_CONTAINER_ERROR IMPORTING R_SALV_TABLE = GO_ALV_ERROR CHANGING T_TABLE = GT_RESULT. LO_COLUMNS = GO_ALV_ERROR->GET_COLUMNS( ). LO_COLUMNS->SET_OPTIMIZE( ). * lo_events = go_alv_error->get_event( ). * CREATE OBJECT go_event_handler. * SET HANDLER go_event_handler->react_to_double_click FOR lo_events. * TRY. * CALL METHOD go_alv_error->set_screen_status * EXPORTING * report = sy-repid * pfstatus = 'ALV' * set_functions = cl_salv_table=>c_functions_all. * CATCH cx_root. * IF 0 = 1. ENDIF. * ENDTRY. GO_ALV_ERROR->DISPLAY( ). DATA LS_RESULT2 TYPE TY_GS_RESULT2. REFRESH GT_RESULT2. LOOP AT GT_RESULT ASSIGNING <LS_RESULT>. CLEAR LS_RESULT2. LS_RESULT2-OBJECT = <LS_RESULT>-OBJECT. LS_RESULT2-RC = <LS_RESULT>-RC. * WRITE : / <ls_result>-object-pgmid, <ls_result>-object-object, <ls_result>-object-obj_name. * CASE <ls_result>-rc. * WHEN gcs_result_rc-ok. * WRITE 'OK' COLOR 5. * WHEN gcs_result_rc-warn. * WRITE 'OK' COLOR 7. * WHEN gcs_result_rc-err. * WRITE 'KO' COLOR 6. * ENDCASE. * WRITE : <ls_result>-message. DATA L_APPENDED TYPE FLAG. CLEAR L_APPENDED. READ TABLE GT_E071_KEY INTO LS_E071_KEY WITH KEY SUBOBJECT = <LS_RESULT>-OBJECT BINARY SEARCH. IF SY-SUBRC = 0. LOOP AT GT_E071_KEY INTO LS_E071_KEY FROM SY-TABIX WHERE SUBOBJECT = <LS_RESULT>-OBJECT. LS_RESULT2-SUBOBJECT = LS_E071_KEY-OBJECT. APPEND LS_RESULT2 TO GT_RESULT2. L_APPENDED = 'X'. * WRITE : / ' ', ls_e071_key-object-pgmid, ls_e071_key-object-object, ls_e071_key-object-obj_name. ENDLOOP. ENDIF. IF L_APPENDED IS INITIAL. APPEND LS_RESULT2 TO GT_RESULT2. ENDIF. ENDLOOP. *... Create requiredby ALV Instance CALL METHOD CL_SALV_TABLE=>FACTORY EXPORTING R_CONTAINER = GO_CONTAINER_REQUIREDBY IMPORTING R_SALV_TABLE = GO_ALV_REQUIREDBY CHANGING T_TABLE = GT_RESULT2. LO_COLUMNS = GO_ALV_REQUIREDBY->GET_COLUMNS( ). LO_COLUMNS->SET_OPTIMIZE( ). *... Display ALV GO_ALV_REQUIREDBY->DISPLAY( ). CATCH CX_SALV_MSG. ENDTRY. ENDFORM. "display_result *----------------------------------------------------------------------* FORM CHECK_EXISTS USING LS_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY I_TARGET TYPE RFCDEST CHANGING E_NOT_FOUND TYPE FLAG E_LOCK TYPE FLAG E_TRKORR TYPE E070-TRKORR E_SRCSYSTEM_IN_CURRENT TYPE TADIR-SRCSYSTEM E_SRCSYSTEM_IN_TARGET TYPE TADIR-SRCSYSTEM. DATA LS_E071 TYPE E071. DATA OBJTYPE2 TYPE VRSD-OBJTYPE. DATA OBJTYPE TYPE VRSD_OLD-OBJTYPE. DATA OBJNAME2 TYPE VRSD-OBJNAME. DATA LS_TADIR TYPE TADIR. DATA LT_VERSION_TARGET TYPE TABLE OF VRSD. DATA LT_VERSNO_TARGET TYPE TABLE OF VRSN. DATA LS_VERSION_TARGET TYPE VRSD. DATA L_SPRSL TYPE T100-SPRSL. DATA LT_DOCU_TAB TYPE TABLE OF RPY_OBJTAB. DATA LT_DOCU_TECH TYPE TABLE OF TLINE. DATA LS_LOCK_KEY TYPE TLOCK_INT. DATA LT_TLOCK TYPE TABLE OF TLOCK. DATA LS_TLOCK TYPE TLOCK. TYPES : BEGIN OF TYPE_S_TRKORR, AS4DATE TYPE E070-AS4DATE, AS4TIME TYPE E070-AS4TIME, TRKORR TYPE E070-TRKORR, END OF TYPE_S_TRKORR. DATA LT_TRKORR TYPE TABLE OF TYPE_S_TRKORR. DATA LS_TRKORR TYPE TYPE_S_TRKORR. DATA L_TIMESTAMP TYPE TZNTIMESTP. DATA L_TIMESTAMP2 TYPE TZNTIMESTP. CLEAR OBJTYPE2. CLEAR E_NOT_FOUND. CLEAR E_LOCK. CLEAR E_TRKORR. CLEAR E_SRCSYSTEM_IN_TARGET. CLEAR E_SRCSYSTEM_IN_CURRENT. LS_E071-PGMID = LS_E071_KEY-PGMID. LS_E071-OBJECT = LS_E071_KEY-OBJECT. LS_E071-OBJ_NAME = LS_E071_KEY-OBJ_NAME. CALL METHOD LCL_SAP_FM=>TR_CHECK_TYPE EXPORTING WI_E071 = LS_E071 IMPORTING WE_TADIR = LS_TADIR WE_LOCK_KEY = LS_LOCK_KEY. IF P_TIMEMA IS NOT INITIAL. * rechercher les OT qui contiennent l'objet, et prendre * la date et heure de l'OT le + ancien, ce qui donne * l'heure de création de l'OT donc de l'objet. PERFORM GET_CREATION_TIMESTAMP USING LS_TADIR-PGMID LS_TADIR-OBJECT LS_TADIR-OBJ_NAME CHANGING L_TIMESTAMP. * Si l'on a transporté un REPS sans que PROG soit transporté, cela * crée tout de même une entrée PROG IF LS_E071-OBJECT = 'REPS' OR LS_E071-OBJECT = 'REPO'. PERFORM GET_CREATION_TIMESTAMP USING LS_E071-PGMID LS_E071-OBJECT LS_E071-OBJ_NAME CHANGING L_TIMESTAMP2. IF L_TIMESTAMP2 IS NOT INITIAL AND L_TIMESTAMP2 < L_TIMESTAMP. L_TIMESTAMP = L_TIMESTAMP2. ENDIF. ENDIF. ENDIF. * Si l'objet a été créé après la date/heure choisis, considérer * qu'il n'existe pas IF P_TIMEMA IS NOT INITIAL AND L_TIMESTAMP >= P_TIMEMA. E_NOT_FOUND = 'X'. ELSE. CASE LS_E071_KEY-PGMID. WHEN 'LIMU'. CASE LS_E071_KEY-OBJECT. WHEN 'CINC' OR 'CLSD' OR 'CPRI' OR 'CPRO' OR 'CPUB' OR 'CUAD' OR 'DOMD' OR 'DTED' OR 'DYNP' OR 'ENQD' OR 'FUNC' OR 'INDX' OR 'METH' OR 'SHLD' OR 'SHLX' OR 'SQLD' OR 'TABD' OR 'TABT' OR 'TTYD' OR 'TYPD' OR 'VIED' OR 'VIET' OR 'WAPD' OR 'WDYC' OR 'WDYD' OR 'WDYV' OR 'REPO' OR 'REPS' OR 'REPT'. * Pour REPO, REPS, REPT, faut-il tester PROG ou FUGR ou CLAS ou autre chose? * RS_PROGNAME_SPLIT -> si fugr_is_name = 'X' alors chercher existence de TADIR FUGR? OBJTYPE = LS_E071_KEY-OBJECT. OBJNAME2 = LS_E071_KEY-OBJ_NAME. REFRESH LT_VERSION_TARGET. CALL FUNCTION 'SVRS_GET_VERSION_DIRECTORY_46' DESTINATION I_TARGET EXPORTING OBJNAME = OBJNAME2 OBJTYPE = OBJTYPE TABLES LVERSNO_LIST = LT_VERSNO_TARGET VERSION_LIST = LT_VERSION_TARGET EXCEPTIONS NO_ENTRY = 1 OTHERS = 2. IF SY-SUBRC <> 0. E_NOT_FOUND = 'X'. ELSE. READ TABLE LT_VERSION_TARGET INTO LS_VERSION_TARGET WITH KEY LOEKZ = 'I'. E_TRKORR = LS_VERSION_TARGET-KORRNUM. ENDIF. WHEN 'INTD'. OBJTYPE = 'INTF'. OBJNAME2 = LS_E071_KEY-OBJ_NAME. REFRESH LT_VERSION_TARGET. CALL FUNCTION 'SVRS_GET_VERSION_DIRECTORY_46' DESTINATION I_TARGET EXPORTING OBJNAME = OBJNAME2 OBJTYPE = OBJTYPE TABLES LVERSNO_LIST = LT_VERSNO_TARGET VERSION_LIST = LT_VERSION_TARGET EXCEPTIONS NO_ENTRY = 1 OTHERS = 2. IF SY-SUBRC <> 0. E_NOT_FOUND = 'X'. ELSE. READ TABLE LT_VERSION_TARGET INTO LS_VERSION_TARGET WITH KEY LOEKZ = 'I'. E_TRKORR = LS_VERSION_TARGET-KORRNUM. ENDIF. WHEN 'DEVP'. OBJTYPE2 = 'DEVC'. WHEN 'DOCU'. IF LS_E071_KEY-OBJ_NAME(2) = 'TX'. OBJTYPE2 = 'DOCT'. ELSE. OBJTYPE2 = 'DOCV'. ENDIF. WHEN 'FUGT'. OBJTYPE2 = 'FUGR'. WHEN 'MESS'. *VRSD-OBJTYPE *VRSD-OBJNAME DATA L_OBJNAME_LONG TYPE VRSD-OBJNAME. OBJTYPE2 = LS_E071_KEY-OBJECT. OBJNAME2 = LS_E071_KEY-OBJ_NAME. CALL FUNCTION 'SVRS_SHORT2LONG_NAME' EXPORTING OBJTYPE = OBJTYPE2 OBJNAME_SHORT = OBJNAME2 IMPORTING OBJNAME_LONG = L_OBJNAME_LONG. SELECT SINGLE SPRSL FROM T100 INTO L_SPRSL WHERE ARBGB = L_OBJNAME_LONG(20) AND MSGNR = L_OBJNAME_LONG+20(3). DATA L_CASTING_MSGNO TYPE SYMSGNO. L_CASTING_MSGNO = L_OBJNAME_LONG+20(3). CALL FUNCTION 'RPY_MESSAGE_COMPOSE' DESTINATION I_TARGET EXPORTING LANGUAGE = L_SPRSL MESSAGE_ID = L_OBJNAME_LONG(20) MESSAGE_NUMBER = L_CASTING_MSGNO EXCEPTIONS MESSAGE_NOT_FOUND = 1 OTHERS = 2. IF SY-SUBRC <> 0. E_NOT_FOUND = 'X'. ENDIF. CLEAR OBJTYPE2. WHEN 'MSAD'. OBJTYPE2 = 'MSAG'. WHEN 'SOTT' OR 'SOTU'. OBJTYPE2 = 'MSAG'. WHEN 'SQTT'. OBJTYPE2 = 'SQLS'. WHEN 'TTYX'. OBJTYPE2 = 'TTYP'. WHEN 'VARI' OR 'VARX'. OBJTYPE2 = 'PROG'. WHEN 'WAPP'. OBJTYPE2 = 'WAPA'. "?? WHEN 'ADIR' OR 'COMM' OR 'FSEL' OR 'MAPP' OR 'MCOD' OR 'PIFA' OR 'PIFH' OR 'XIND'. * Objets LIMU non gérés ENDCASE. WHEN 'R3TR'. OBJTYPE2 = LS_E071_KEY-OBJECT. ENDCASE. DATA L_OBJECT_CASTING TYPE E071-OBJECT. DATA L_OBJNAME_CASTING TYPE E071-OBJ_NAME. L_OBJECT_CASTING = LS_TADIR-OBJECT. L_OBJNAME_CASTING = LS_TADIR-OBJ_NAME. CALL FUNCTION 'SRTT_GET_REMOTE_TADIR_ENTRY' EXPORTING TADIR_OBJECT = L_OBJECT_CASTING TADIR_OBJNAME = L_OBJNAME_CASTING IMPORTING ET_TADIR = LS_TADIR EXCEPTIONS INVALID = 1 OTHERS = 2. E_SRCSYSTEM_IN_CURRENT = LS_TADIR-SRCSYSTEM. CALL FUNCTION 'SRTT_GET_REMOTE_TADIR_ENTRY' DESTINATION I_TARGET EXPORTING TADIR_OBJECT = L_OBJECT_CASTING TADIR_OBJNAME = L_OBJNAME_CASTING IMPORTING ET_TADIR = LS_TADIR EXCEPTIONS INVALID = 1 OTHERS = 2. IF SY-SUBRC <> 0 AND OBJTYPE2 IS NOT INITIAL. E_NOT_FOUND = 'X'. ENDIF. E_SRCSYSTEM_IN_TARGET = LS_TADIR-SRCSYSTEM. ENDIF. * rechercher l'OT dans le système courant où se trouve l'objet ********************************* * retourne la tâche ou l'OT dans lequel l'objet est verrouillé CALL FUNCTION 'TRINT_CHECK_LOCKS' EXPORTING WI_LOCK_KEY = LS_LOCK_KEY TABLES WT_TLOCK = LT_TLOCK EXCEPTIONS EMPTY_KEY = 1 OTHERS = 2. IF SY-SUBRC = 0 AND LT_TLOCK[] IS NOT INITIAL. READ TABLE LT_TLOCK INTO LS_TLOCK INDEX 1. IF SY-SUBRC = 0. E_TRKORR = LS_TLOCK-TRKORR. E_LOCK = 'X'. * chercher l'OT si le retour est une tâche SELECT SINGLE STRKORR FROM E070 INTO E_TRKORR WHERE TRKORR = E_TRKORR. ENDIF. ELSE. * Si l'objet n'est pas verrouillé, rechercher l'ordre de transport * libéré en dernier SELECT E070~AS4DATE E070~AS4TIME E070~TRKORR FROM E071 INNER JOIN E070 ON E071~TRKORR = E070~TRKORR INTO TABLE LT_TRKORR WHERE E071~PGMID = LS_E071_KEY-PGMID AND E071~OBJECT = LS_E071_KEY-OBJECT AND E071~OBJ_NAME = LS_E071_KEY-OBJ_NAME ORDER BY E070~AS4DATE DESCENDING E070~AS4TIME DESCENDING %_HINTS ORACLE 'FIRST_ROWS(1)'. READ TABLE LT_TRKORR INTO LS_TRKORR INDEX 1. E_TRKORR = LS_TRKORR-TRKORR. ENDIF. ENDFORM. "check_exists *&---------------------------------------------------------------------* *& Form TABLSTRUC_FIELD *&---------------------------------------------------------------------* FORM TABLSTRUC_FIELD USING IS_DD03P TYPE DD03P IS_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. DATA LS_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. * .APPEND_DU indique une récursivité, PRECFIELD est blanc. A ignorer. IF IS_DD03P-FIELDNAME = '.APPEND_DU'. * .INCLU-*** indique un include avec suffixe *** pour les composantes ELSEIF IS_DD03P-FIELDNAME = '.APPEND' OR IS_DD03P-FIELDNAME(6) = '.INCLU'. LS_E071_KEY-PGMID = 'R3TR'. LS_E071_KEY-OBJECT = 'TABL'. LS_E071_KEY-OBJ_NAME = IS_DD03P-PRECFIELD. MAC_COLLECT IS_E071_KEY 'H' '' LS_E071_KEY GS_REQUEST_INITIAL. * composantes avec type interne/longueur ont COMPTYPE = blanc * (bizarrement, parfois, ROLLNAME n'est pas à blanc!) ELSEIF NOT IS_DD03P-COMPTYPE IS INITIAL. LS_E071_KEY-PGMID = 'R3TR'. DATA L_LINK TYPE C LENGTH 1. L_LINK = 'H'. CASE IS_DD03P-COMPTYPE. WHEN 'E'. LS_E071_KEY-OBJECT = 'DTEL'. WHEN 'S'. LS_E071_KEY-OBJECT = 'TABL'. WHEN 'L'. LS_E071_KEY-OBJECT = 'TTYP'. WHEN 'R'. "type ref to CASE IS_DD03P-REFTYPE. WHEN 'C'. LS_E071_KEY-OBJECT = 'CLAS'. WHEN 'I'. LS_E071_KEY-OBJECT = 'INTF'. WHEN 'E'. LS_E071_KEY-OBJECT = 'DTEL'. WHEN 'S'. "structure or table LS_E071_KEY-OBJECT = 'TABL'. WHEN 'L'. LS_E071_KEY-OBJECT = 'TTYP'. WHEN SPACE. "undefined DATA L_TYPENAME TYPE TYPENAME. DATA L_TYPEKIND TYPE DDTYPEKIND. L_TYPENAME = IS_DD03P-ROLLNAME. CALL FUNCTION 'DDIF_TYPEINFO_GET' EXPORTING TYPENAME = L_TYPENAME IMPORTING TYPEKIND = L_TYPEKIND. IF L_TYPEKIND IS NOT INITIAL. LS_E071_KEY-OBJECT = L_TYPEKIND. ENDIF. WHEN 'B'. * reference to an internal data type, length, decimals -> IGNORE WHEN OTHERS. ASSERT IS_DD03P-REFTYPE = 'D' "data OR IS_DD03P-REFTYPE = 'O'. "object ENDCASE. WHEN 'N'. "structure inexistante (ou inactive) CI_* LS_E071_KEY-OBJECT = 'TABL'. L_LINK = 'S'. "l'include ci_* peut ne pas exister WHEN OTHERS. MESSAGE X001(00). ENDCASE. IF LS_E071_KEY-OBJECT IS NOT INITIAL. LS_E071_KEY-OBJ_NAME = IS_DD03P-ROLLNAME. MAC_COLLECT IS_E071_KEY L_LINK '' LS_E071_KEY GS_REQUEST_INITIAL. ENDIF. ENDIF. ENDFORM. "tablstruc_field *&---------------------------------------------------------------------* *& Form GET_TABLE_TYPE *&---------------------------------------------------------------------* FORM GET_TABLE_TYPE USING I_TABNAME CHANGING E_OBJECT. DATA L_TYPENAME TYPE TYPENAME. DATA L_GOTSTATE TYPE DDGOTSTATE. DATA L_TYPEKIND TYPE DDTYPEKIND. CLEAR E_OBJECT. L_TYPENAME = I_TABNAME. CALL FUNCTION 'DDIF_TYPEINFO_GET' EXPORTING TYPENAME = L_TYPENAME IMPORTING TYPEKIND = L_TYPEKIND GOTSTATE = L_GOTSTATE. E_OBJECT = L_TYPEKIND. ENDFORM. "get_table_type *&---------------------------------------------------------------------* *& Form CONVERT_WBOBJ_KEY_INTO_E071 *&---------------------------------------------------------------------* FORM CONVERT_WBOBJ_KEY_INTO_E071 USING IS_WBOBJ_KEY TYPE TYPE_S_WBOBJ_KEY CHANGING ES_E071_KEY TYPE LCL_DEV_CROSS_REF=>TYPE_S_E071_OBJKEY. DATA LS_KO100 TYPE KO100. * détermine si le type (PROG, CLAS, DYNP, etc.) correspond à R3TR ou à LIMU CALL FUNCTION 'TR_GET_PGMID_FOR_OBJECT' EXPORTING IV_OBJECT = IS_WBOBJ_KEY-OBJECT IMPORTING ES_TYPE = LS_KO100 EXCEPTIONS ILLEGAL_OBJECT = 1 OTHERS = 2. CLEAR ES_E071_KEY. ES_E071_KEY-PGMID = LS_KO100-PGMID. ES_E071_KEY-OBJECT = IS_WBOBJ_KEY-OBJECT. CASE IS_WBOBJ_KEY-OBJECT. * First we take care for objects that are unknown to RS_TOOL_ACCESS WHEN 'DOCU'. ES_E071_KEY-OBJ_NAME(2) = IS_WBOBJ_KEY-S_DOCU-DOCU_ID. ES_E071_KEY-OBJ_NAME+2 = IS_WBOBJ_KEY-S_DOCU-DOCU_OBJECT. WHEN 'SOTT' OR 'SOTU'. ES_E071_KEY-OBJ_NAME(30) = IS_WBOBJ_KEY-S_SOTT-PAKET. ES_E071_KEY-OBJ_NAME+30 = IS_WBOBJ_KEY-S_SOTT-CONCEPT. WHEN 'TOBJ'. CONCATENATE IS_WBOBJ_KEY-S_TOBJ-OBJECTNAME IS_WBOBJ_KEY-S_TOBJ-OBJECTTYPE INTO ES_E071_KEY-OBJ_NAME. WHEN 'MERG' OR 'RELE' OR 'COMM'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-TRKORR. WHEN 'SPCS'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SPCS-CODEPAGE. WHEN 'SPSV'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SPSV-SERVER. WHEN 'SPDV'. SELECT SINGLE NAME FROM TSP03D INTO ES_E071_KEY-OBJ_NAME WHERE PADEST = IS_WBOBJ_KEY-S_SPDV-DEVICE. WHEN 'SPLO'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SPLO-PAPER_FORMAT. WHEN 'PRIN'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_PRIN-PRINTER_TYPE. WHEN 'SLOM'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SLOM-LOGICAL_OUTPUT_SYSTEM. WHEN 'SOMS'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SOMS-READ_OUTPUT_SYSTEM. WHEN 'SCP1'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SCP-BCSET_ID. WHEN 'SCP2'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-S_SCP-BCSET_ID. WHEN 'FILE'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-FILE. WHEN 'REPO'. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-INCLUDE. WHEN 'DYNP'. ES_E071_KEY-PGMID = 'LIMU'. ES_E071_KEY-OBJ_NAME+GC_PROG(GC_DYNP) = IS_WBOBJ_KEY-S_DYNP-SCREEN_NUMBER. ES_E071_KEY-OBJ_NAME(GC_PROG) = IS_WBOBJ_KEY-S_DYNP-PROGRAM_NAME. WHEN 'VARI' OR 'VARX'. ES_E071_KEY-OBJ_NAME+GC_PROG(GC_VARI) = IS_WBOBJ_KEY-S_VARI-VARIANT_NAME. ES_E071_KEY-OBJ_NAME(GC_PROG) = IS_WBOBJ_KEY-S_VARI-PROGRAM_NAME. WHEN 'MESS'. ES_E071_KEY-PGMID = 'LIMU'. CONCATENATE IS_WBOBJ_KEY-S_MESS-MSG_CLASS_NAME IS_WBOBJ_KEY-S_MESS-MSG_NUMBER INTO ES_E071_KEY-OBJ_NAME. WHEN 'METH'. ES_E071_KEY-PGMID = 'LIMU'. ES_E071_KEY-OBJ_NAME+GC_CLAS(GC_METH) = IS_WBOBJ_KEY-S_METH-METHOD_NAME. ES_E071_KEY-OBJ_NAME(GC_CLAS) = IS_WBOBJ_KEY-S_METH-CLASS_NAME. * Web Dynpro controller WHEN 'WDYC'. ES_E071_KEY-OBJ_NAME+GC_WDYN(GC_WDYC) = IS_WBOBJ_KEY-S_WDYC-CONTROLLER_NAME. ES_E071_KEY-OBJ_NAME(GC_WDYN) = IS_WBOBJ_KEY-S_WDYC-WEBDYNPRO_NAME. * Web Dynpro view WHEN 'WDYV'. ES_E071_KEY-OBJ_NAME+GC_WDYN(GC_WDYV) = IS_WBOBJ_KEY-S_WDYV-VIEW_NAME. ES_E071_KEY-OBJ_NAME(GC_WDYN) = IS_WBOBJ_KEY-S_WDYV-WEBDYNPRO_NAME. * Page/Controller of a BSP Application WHEN 'WAPD' OR 'WAPP'. ES_E071_KEY-OBJ_NAME+GC_WAPA(GC_WAPP) = IS_WBOBJ_KEY-S_WAPP-PAGE_NAME. ES_E071_KEY-OBJ_NAME(GC_WAPA) = IS_WBOBJ_KEY-S_WAPP-APPL_NAME. WHEN OTHERS. ES_E071_KEY-OBJ_NAME = IS_WBOBJ_KEY-OBJECT. ENDCASE. ENDFORM. "convert_wbobj_key_into_e071 *&---------------------------------------------------------------------* *& Form GET_CREATION_TIMESTAMP *&---------------------------------------------------------------------* * Rechercher la date et l'heure de création d'un objet * en se basant sur la date du premier ordre de transport qui * le contient FORM GET_CREATION_TIMESTAMP USING I_PGMID TYPE E071-PGMID I_OBJECT TYPE E071-OBJECT I_OBJ_NAME TYPE CLIKE CHANGING E_TIMESTAMP TYPE TZNTIMESTP. DATA L_TABLE TYPE DD02L-TABNAME. DATA LT_OPTION TYPE TABLE OF RFC_DB_OPT. DATA LT_FIELD TYPE TABLE OF RFC_DB_FLD. DATA LTE_DATA TYPE TABLE OF TAB512. DATA LS_OPTION TYPE RFC_DB_OPT. DATA LS_FIELD TYPE RFC_DB_FLD. DATA L_DATA TYPE TAB512. DATA L_TRKORR TYPE E070-TRKORR. CONCATENATE 'PGMID = ''' I_PGMID '''' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. CONCATENATE 'AND OBJECT = ''' I_OBJECT '''' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. CONCATENATE 'AND OBJ_NAME = ''' I_OBJ_NAME '''' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. LS_FIELD-FIELDNAME = 'TRKORR'. APPEND LS_FIELD TO LT_FIELD. L_TABLE = 'E071'. CALL FUNCTION 'RFC_READ_TABLE' DESTINATION P_TARGET EXPORTING QUERY_TABLE = L_TABLE TABLES OPTIONS = LT_OPTION FIELDS = LT_FIELD DATA = LTE_DATA EXCEPTIONS TABLE_NOT_AVAILABLE = 1 TABLE_WITHOUT_DATA = 2 OPTION_NOT_VALID = 3 FIELD_NOT_VALID = 4 NOT_AUTHORIZED = 5 DATA_BUFFER_EXCEEDED = 6 OTHERS = 7. IF SY-SUBRC <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. REFRESH LT_OPTION. LOOP AT LTE_DATA INTO L_DATA. IF LT_OPTION[] IS INITIAL. CONCATENATE 'TRKORR = ''' L_DATA '''' INTO LS_OPTION-TEXT. ELSE. CONCATENATE 'OR TRKORR = ''' L_DATA '''' INTO LS_OPTION-TEXT. ENDIF. APPEND LS_OPTION TO LT_OPTION. ENDLOOP. REFRESH LT_FIELD. LS_FIELD-FIELDNAME = 'AS4DATE'. APPEND LS_FIELD TO LT_FIELD. LS_FIELD-FIELDNAME = 'AS4TIME'. APPEND LS_FIELD TO LT_FIELD. REFRESH LTE_DATA. L_TABLE = 'E070'. * A noter qu'on ne peut utiliser la table E070CREATE qui n'est pas * alimentée dans le cas de transport. Seule E070 contient la date * de création. AS4DATE et AS4TIME, qui sont normalement la date de * dernière modification, ne peuvent pas changer puisqu'on est dans * un système cible des OT qui sont libérés donc non modifiables * (alors que sur un système de dév, c'est E070CREATE qui contient * la date de création, et AS4DATE la date de création ou date de * dernière modif) CALL FUNCTION 'RFC_READ_TABLE' DESTINATION P_TARGET EXPORTING QUERY_TABLE = L_TABLE TABLES OPTIONS = LT_OPTION FIELDS = LT_FIELD DATA = LTE_DATA EXCEPTIONS TABLE_NOT_AVAILABLE = 1 TABLE_WITHOUT_DATA = 2 OPTION_NOT_VALID = 3 FIELD_NOT_VALID = 4 NOT_AUTHORIZED = 5 DATA_BUFFER_EXCEEDED = 6 OTHERS = 7. IF SY-SUBRC <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. SORT LTE_DATA BY TABLE_LINE ASCENDING. READ TABLE LTE_DATA INDEX 1 INTO E_TIMESTAMP. ENDFORM. "get_creation_timestamp *&---------------------------------------------------------------------* *& Form GET_E071_DONT_EXIST_IN_TARGET *&---------------------------------------------------------------------* FORM GET_E071_DONT_EXIST_IN_TARGET USING P_TARGET TYPE RFCDEST CHANGING CT_E071 TYPE TY_T_E071. DATA L_TABLE TYPE DD02L-TABNAME. DATA LT_OPTION TYPE TABLE OF RFC_DB_OPT. DATA LT_FIELD TYPE TABLE OF RFC_DB_FLD. DATA LTE_DATA TYPE TABLE OF TAB512. DATA LS_OPTION TYPE RFC_DB_OPT. DATA LS_FIELD TYPE RFC_DB_FLD. DATA L_DATA TYPE TAB512. DATA L_TRKORR TYPE E070-TRKORR. TYPE-POOLS CTSLG. DATA L_DIR_TYPE TYPE TSTRF01-DIRTYPE. DATA LS_SETTINGS TYPE CTSLG_SETTINGS. DATA L_SUPPRESS_DELETED_STEPS TYPE FLAG. DATA LT_COMM_SYSTEMS TYPE TMSCSYSLST_TYP. DATA LS_COFILE TYPE CTSLG_COFILE. DATA L_USER TYPE E070-AS4USER. DATA L_PROJECT TYPE TRKORR. DATA LT_E070 TYPE TABLE OF E070. DATA LT_E070_DONT_EXIST_IN_TARGET TYPE TABLE OF E070. DATA LS_E070 TYPE E070. DATA LT_E071 TYPE TABLE OF E071. DATA LT_E071_BIS TYPE TABLE OF E071. DATA LS_E071 TYPE E071. DATA LS_INDX TYPE INDX. CONCATENATE 'ZZCROSS_' P_TARGET INTO LS_INDX-SRTFD. IMPORT CONTENT TO GS_CLUSTER_CONTENT FROM DATABASE INDX(ZZ) ID LS_INDX-SRTFD. IF SY-SUBRC <> 0. CLEAR GS_CLUSTER_CONTENT. ENDIF. * CURRENT SYSTEM * Lire les OT libérés depuis la dernière date d'analyse. * IMPORTANT : cette requête fonctionne uniquement parce que * les OT sont importés dans le même système (pour gérer les * données mandant-dépendantes telles les variantes) donc * l'import met à jour AS4DATE et AS4TIME à la date d'import * (qui est un petit peu supérieure à la date d'export). * Sinon, pour connaître la date/heure d'export, il faudrait * passer par le module fonction TR_READ_GLOBAL_INFO_OF_REQUEST * pour lire la log de l'OT. SELECT * FROM E070 INTO TABLE LT_E070 WHERE STRKORR = SPACE AND TRSTATUS IN ('R','N') AND ( AS4DATE > GS_CLUSTER_CONTENT-LASTGENTIME(8) OR ( AS4DATE = GS_CLUSTER_CONTENT-LASTGENTIME(8) AND AS4TIME > GS_CLUSTER_CONTENT-LASTGENTIME+8 ) ). * SYSTEME CIBLE * Recherche des OT créés dans le système cible depuis la dernière date d'analyse REFRESH LT_OPTION. LS_OPTION-TEXT = 'STRKORR = '''''. APPEND LS_OPTION TO LT_OPTION. CONCATENATE 'AND ( AS4DATE > ''' GS_CLUSTER_CONTENT-LASTGENTIME(8) '''' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. CONCATENATE 'OR ( AS4DATE = ''' GS_CLUSTER_CONTENT-LASTGENTIME(8) '''' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. CONCATENATE 'AND AS4TIME > ''' GS_CLUSTER_CONTENT-LASTGENTIME+8 ''' ) )' INTO LS_OPTION-TEXT. APPEND LS_OPTION TO LT_OPTION. REFRESH LT_FIELD. LS_FIELD-FIELDNAME = 'TRKORR'. APPEND LS_FIELD TO LT_FIELD. REFRESH LTE_DATA. L_TABLE = 'E070'. CALL FUNCTION 'RFC_READ_TABLE' DESTINATION P_TARGET EXPORTING QUERY_TABLE = L_TABLE TABLES OPTIONS = LT_OPTION FIELDS = LT_FIELD DATA = LTE_DATA EXCEPTIONS TABLE_NOT_AVAILABLE = 1 TABLE_WITHOUT_DATA = 2 OPTION_NOT_VALID = 3 FIELD_NOT_VALID = 4 NOT_AUTHORIZED = 5 DATA_BUFFER_EXCEEDED = 6 OTHERS = 7. IF SY-SUBRC <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. * Y ajouter les OT analysés la fois précédente qui n'étaient pas * encore dans le système cible IF LT_E070[] IS NOT INITIAL OR LTE_DATA[] IS NOT INITIAL. APPEND LINES OF GS_CLUSTER_CONTENT-T_E070 TO LT_E070. SORT LT_E070 BY TRKORR ASCENDING. SORT LTE_DATA BY TABLE_LINE ASCENDING. LOOP AT LT_E070 INTO LS_E070. READ TABLE LTE_DATA WITH KEY TABLE_LINE = LS_E070-TRKORR BINARY SEARCH TRANSPORTING NO FIELDS. IF SY-SUBRC <> 0. APPEND LS_E070 TO LT_E070_DONT_EXIST_IN_TARGET. ENDIF. ENDLOOP. GS_CLUSTER_CONTENT-T_E070 = LT_E070_DONT_EXIST_IN_TARGET. IF LT_E070_DONT_EXIST_IN_TARGET[] IS NOT INITIAL. SORT LT_E070_DONT_EXIST_IN_TARGET BY TRKORR. DELETE ADJACENT DUPLICATES FROM LT_E070_DONT_EXIST_IN_TARGET COMPARING TRKORR. * déterminer tous les objets contenus dans ces OT SELECT * FROM E071 INTO TABLE LT_E071 FOR ALL ENTRIES IN LT_E070_DONT_EXIST_IN_TARGET WHERE TRKORR = LT_E070_DONT_EXIST_IN_TARGET-TRKORR. IF LT_E071[] IS NOT INITIAL. * déterminer tous les OT contenant ces objets SORT LT_E071 BY PGMID OBJECT OBJ_NAME. DELETE ADJACENT DUPLICATES FROM LT_E071 COMPARING PGMID OBJECT OBJ_NAME. SELECT * FROM E071 INTO TABLE LT_E071_BIS FOR ALL ENTRIES IN LT_E071 WHERE PGMID = LT_E071-PGMID AND OBJECT = LT_E071-OBJECT AND OBJ_NAME = LT_E071-OBJ_NAME. SORT LT_E071 BY TRKORR. LOOP AT LT_E071_BIS INTO LS_E071. * NE GARDER QUE les (objets des) OT qui existent dans les 2 systèmes READ TABLE LT_E071 WITH KEY TRKORR = LS_E071-TRKORR BINARY SEARCH TRANSPORTING NO FIELDS. IF SY-SUBRC = 0. DELETE LT_E071_BIS. ENDIF. ENDLOOP. * les objets des OT n'étant pas en cible, existent-ils dans un autre OT qui * est en cible SORT LT_E071 BY PGMID OBJECT OBJ_NAME. SORT LT_E071_BIS BY PGMID OBJECT OBJ_NAME. LOOP AT LT_E071 INTO LS_E071. READ TABLE LT_E071_BIS WITH KEY PGMID = LS_E071-PGMID OBJECT = LS_E071-OBJECT OBJ_NAME = LS_E071-OBJ_NAME BINARY SEARCH TRANSPORTING NO FIELDS. IF SY-SUBRC <> 0. APPEND LS_E071 TO CT_E071. ENDIF. ENDLOOP. ENDIF. ENDIF. SORT CT_E071 BY PGMID OBJECT OBJ_NAME. ENDIF. CONCATENATE SY-DATUM SY-UZEIT INTO GS_CLUSTER_CONTENT-LASTGENTIME. EXPORT CONTENT FROM GS_CLUSTER_CONTENT TO DATABASE INDX(ZZ) ID LS_INDX-SRTFD. ENDFORM. "get_e071_dont_exist_in_target
17 Comments
Unknown User (hq5cu6e)
Hi Sandra,
thank you very much for posting this article. It helped me a lot.
But I have a very important question. Right now, I created an internal table with numerous s_trkorr and I want to run your application through all of them and then display the result in the three ALV grids...
I just can't find the starting point...
Could you please give me a hint?
Kind regards,
Tommy
Sandra Rossi
Hi Tommy,
I'm not sure to understand. If you want to run the report from an external program
with a given list of transport requests, you can do it with SUBMIT report WITH s_trkorr IN list AND RETURN, where list is a range (DATA list TYPE RANGE OF trkorr), and you fill it with one line for each transport request from your internal table, by LOOP AT itab. list-sign = 'I', list-option = 'EQ', list-low = itab-trkorr APPEND list ENDLOOP).
sandra
Unknown User (hq5cu6e)
Morning Sandra,
sorry for the late reply. That's right. I have a given list of transport requests and want to submit all of them to your program.
I will try your solution today and will let you know.
Thanks for your help
Tommy
Anonymous
Hi Sandra,
I got an error ,"RMC_COMMUNICATION_FAILURE", when i try to fiind some missing objects from CTS which have many involved files.
So i've been looking for why this error occured and finally find out the reason.
In this code, the OUTTAB of 3rd ALV display function was declared locally in subroutine.
according to note 534857, you should declare your OUTTAB globally and not in subroutine.
Sandra Rossi
Hi Kihoori, thank you very much for your feedback. I have corrected the program based on your inputs
+ 2 minor corrections -> version 1.01
Former Member
Thanks Sandra
Once again an awesome development from you, but it's only for ECC. I'll have to wait a while or attempt to modify to 4.7
Regards, Adrian
Unknown User (vy8mp0d)
Thanks for the great program, Sandra!
One thing I noticed when we ran the program is that it does not seem to catch missing Function Groups. For example, a function module is moved to the target system but the function group definition itself is not moved, and your program did not catch it. I wonder if this is a limitation. I did not have a chance to debug it yet, but can you please let me know your thought on this? Thanks a lot in advance!
Alex
Sandra Rossi
Hi Alex,
thank you for your interest :-)
Well, it should have catched it. The relationship between function module and function group is determined in method GET_REQOBJ in these lines :
You can check by debug at this place. I've made a check, it should work.
Maybe the issue is with the namespace, it always check Y and Z objects, but only check SAP namespace if you check the P_INCSTD parameter. I'm not sure how it behaves with /customer/ namespaces
sandra
Guy Lamoureux
Bonne idée ce programme. Et commenté en français en plus. Ouvrons de nouveaux horizons culturels à l'abaper moyen.
Merci madame Rossi.
Guy
Boosa Srinivas
Hi Sandra,
Thank you for posting this and it is very useful.
I have found one problem when i am using this program, in method GET_REQOBJ you are using FM RS_PROGNAME_CONCATENATE. inside this function module for example : When we are doing firstt ime transport we create some object and deleted the object which is saved in the same trasport. when ever we execute this program it is going into dump. because the reference object is not found target system.
This is method inside the FM.
method GET_INSTANCE_BY_NAME .
data:
cifkey type seoclskey,
iref type ref to if_oo_clif_incl
cifkey = name.
call method get_instance_by_cifkey
exporting cifkey = cifkey
receiving cifref = iref
exceptions no_objecttype = 1
internal_error = 2
others = 3.
case sy-subrc.
when 0.
cifref = iref.
when 1.
raise no_objecttype.
when others.
raise internal_error.
endcase.
endmethod.
Please let me know if you can correct this
Regards,
Srini
Sandra Rossi
Hi Srini,
I saw that bug last week as I started to use this tool on my current project. In fact, I also saw many other problems. I will post new code in a few days. The bug you mention is that the transport request contains a class that is deleted, workaround is to remove that class from the transport request if possible, or, if you can't wait for the new code, you may change it by ignoring the classes from the transport requests that do not exist (R3TR CLAS entries, the class master table is SEOCLASS)
BR
Sandra
Former Member
Hi Sandra,
Thank you for your program. It´s so interesting for me.
I saw the last comments between Boosa and you, and i think that the Note 1444788 can help you with the Dump in the CLASS case.
I´m not sure because i can´t implement the Note yet, but i think i can try in next days and tell you the results (perhaps Boosa or you can test it early).
Regards.
Unknown User (vy8mp0d)
Sandra,
Thanks for keeping up with this thread. Did you have a chance to update this program based on the comments about the bugs? I do not see the updated header in the ABAP code, hence wanted to check with you.
Thanks in advance!
~ Alex.
Sandra Rossi
Hi Alex,
I couldn't really test it fully, and my client stopped the project. Thank you to recall me that I promised it, but I can only post the last version that was run, that you can find in the attachments.
It compiles/runs only on a 7.11 system, takes into account BW objects, and there was a part added to detect missing fields, but it is still a very early version with probably many flaws. If you or anyone can have a chance to spend time on it and update this wiki, I will be grateful to him/her.
Regards,
Sandra
Unknown User (hn7j0cn)
Hello Sandra,
I cant find function TRINT_RESOLVE_OBJ in my system. Do you know what it is replaced with? I'm on netweaver 7.31 sp7.
Salai.
Sandra Rossi
Hi Salai,
You may replace it with SVRS_RESOLVE_E071_OBJ function module, same parameters. It should also work from release 7.0.
Sandra
Haresh Manani
Hi Sandar,
The program throws dump as TSV_TNEW_PAGE_ALLOC_FAILED. Reason is when the function module RFC_READ_TABLE fails with some exceptions ( in my case sy-subrc = 5, No Authorization ). This also leads for not showing the login screen of RFC system.
Can we have some other function module for the same purpose or if we can by pass the authorization check ?
-Regards,
Haresh Manani