Quantcast
Channel: SCN : Document List - ABAP Development
Viewing all 935 articles
Browse latest View live

Maintaining Documentation for Error Message with dynamic values

$
0
0

Dear Friends ,

 

 

Recently  had an Requirement , in that requirement , i have to display Information type message and while clicking F1 on message it will show more details about that message.

 

steps :

1. Created message class in SE91 . ie YMSG

2. message no 001 and i have maintain "Invalid Date".

3.Customer wants what was the error in Date field , so i have to maintain the cause and solution in the long text.

4. Select Message 001 and click 'Long text' or Ctrl + F7

5.U can see the Documentation space there.

6.Fill with the details and activate.

7.We can display the documentation by calling message class with no.

 

 

Thanks and Regards.

 

Palaniyappan subbiah.


How to activate next page, last page buttons in ALV reports

$
0
0

Standard ALV calls status STANDARD_FULLSCREEN (program SAPLKKBL) in which next/previous/first/last page is deactivated by default. The same program consist another status APPEND which has these buttons activated. Hence we need to overwrite the PF-STATUS call from STANDARD_FULLSCREEN to APPEND.

 

  1. Copy the APPEND status of program SAPLKKBL to your custom program using t-code SE41. [In this case I have used the same name for status for my program]

Image1.jpg

2. Function codes for the page scrolling already exist. Activate your status.


Image2.png


Changes in the custom program


3. Create subroutine SET_PF_STATUS to set the new PF-STATUS. Note, that this is called dynamically through FM   REUSE_ALV_GRID_DISPLAY


    FORM set_pf_statusUSING rt_extabTYPE slis_t_extab.

      SET PF-STATUS 'APPEND'. 
   
ENDFORM
.    
"Set_pf_status


4. Create subroutine USER_COMMAND which will contain the action upon clicking next/previous/first/last page buttons.

Note, function codes for First Page is ‘P--’, Last Page is ‘P++’, Next Page is ‘P+’ and Previous Page is ‘P-’


FORM user_command USING r_ucomm     LIKE sy-ucomm
                        rs_selfield
TYPE slis_selfield.

REFRESH lt_data.
CASE r_ucomm.
WHEN 'P--'.    "First Page
  
LOOP AT gt_data INTO lw_data
     
WHERE page = 1.
     
APPEND lw_data TO lt_data.

      ENDLOOP.

   g_page = 1.
WHEN 'P++'.    "Last Page
  
LOOP AT gt_data INTO lw_data
     
WHERE page = g_lastpage.
     
APPEND lw_data TO lt_data.
     
CLEAR lw_data.
  
ENDLOOP.
   g_page
= g_lastpage.
WHEN 'P+'.     "Next page
  
IF g_page EQ g_lastpage.
    
EXIT.
  
ELSE.
     g_page
= g_page + 1.
  
ENDIF.
  
LOOP AT gt_data INTO lw_data
     
WHERE page = g_page.
     
APPEND lw_data TO lt_data.
     
CLEAR lw_data.
   
ENDLOOP.
WHEN 'P-'.     "Previous Page
IF g_page EQ 1.
  
EXIT.
ELSE.
   g_page
= g_page - 1.
ENDIF.
LOOP AT gt_data INTO lw_data
  
WHERE page = g_page.
  
APPEND lw_data TO lt_data.
  
CLEAR lw_data.
ENDLOOP.
ENDCASE.

ENDFORM"User_command


5.  In  REUSE_ALV_GRID_DISPLAY, call the subroutine for new PF-STATUS and USER_COMMAND


CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program         
= sy-repid
is_layout                  
= lw_layout
i_callback_pf_status_set   
= 'SET_PF_STATUS'
i_callback_user_command    
= 'USER_COMMAND'


6.  In SET_PF_STATUS, add code to get to selection screen when clicking Back/Exit/Cancel button


FORM set_pf_status USING gt_extab TYPE slis_t_extab .
  SET PF-STATUS 'APPEND'.
  IF sy-ucomm EQ '&F03'
  OR sy-ucomm EQ '&F12'
  OR sy-ucomm EQ '&F15'.
    SUBMIT ztrading_boe WITH SELECTION-TABLE gt_seltab VIA SELECTION-SCREEN.
  ENDIF.
ENDFORM. "Set_pf_status


7.Populate selection screen values in GT_SELTAB in START-OF-SELECTION. This will retain the selection screen values when clicking Back/Exit/Cancel button


START-OF-SELECTION.
* Get selection screen data
PERFORM get_selections_values.

 

FORM get_selections_values.

CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS'
EXPORTING
  curr_report    
= sy-repid
TABLES
  selection_table
= gt_seltab
EXCEPTIONS
  not_found      
= 1
  no_report      
= 2.
IF sy-subrc <> 0.
 
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
 
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM.                    " GET_SELECTIONS_VALUES


Document Your ABAP Development with KCT ABAPDoc

$
0
0

KCT ABAPDoc is a tool that allows you to generate documentation of your ABAP development directly from your SAP system. It combines information available in ABAP Dictionary with in-code comments to provide comprehensive documentation.

 

KCT ABAPDoc is provided free of charge under GNU GPL license. It has modular structure that allows easy enhancement of its functionality with plugins. The architecture is actually very similar to popular tool SAPLink. There is a core that does common functionality and every type of ABAP object has its own plugin that can be added at any time. We at KCT Data hope that other developers will create and share their plugins. We hope this will become a collaborative effort.

 

With KCT ABAP Doc you can either create substitute documentation for your undocumented legacy code, create template for documentation for new code or with smart use of in code comments fully fledged documentation of your development. The main advantage is that generated documentation is always up to date.

 

Work with KCT ABAP Doc is really simple. You select objects you want to document. The most commons situation is that you want to document package or transport, but you can also do your own selection. The tool can also run in background and for example put documentation of all released transports to certain folder.

abap_doc_1.png

Detailed selection of objects allows you to document only these kinds of objects you need. You can only document those objects for which plugins exist in your system.

abap_doc_2.png

Quality of the resulting documentation is dependent on your coding style. In all situations you will receive interface information. However, if you fill short descriptions properly and use code comments, resulting documentation can be comprehensive without need for manual changes.

abap_doc_3.png

 

You can download KCT ABAP Doc from GitHub (https://github.com/kctdata/abapDoc) in a form of workbench transport. You can also find example documentation generated with this tool. If you try it, we would appreciate to hear your opinion.

Create Custom report for table maintenance entries

$
0
0

Requirement Details : Maintain data or particular columns in table depending upon Country Value

Solution :  1. Create 2 screens for your Z program via SE51.. First screen with certain fields from Ztable and other with certain fields as per your requirement

                2. Create table control via wizard with Scroll button checked for both the screens

                3. Create PF status for both custom screens in your status PBO module of respective screens

                4. Make sure you have buttons like New entry , Delete  and Display/change same as we have in SM30 maintenance tool and we can use

                    standard buttons for BACK , SAVE , CANCEL , EXIT.

                5. in TABLE_INIT_OUTPUT and User command module of respective table controls write code depending upon  User Command i.e. SY-UCOMM

                5.1. For new entries :

                       loop at screen.

                           screen-input = 1.

                           modify screen.

                       endloop.

                 5.2.  For display/change : here we will loop key fields onwards i.e. they are non editable while maintaining entries e.g. if we have first 3 as key then

                         loop at screen where index GT 3.

                             if screen-name eq 'ZABC' and screen-input = 1.

                                     screen-input = 0.

                                     modify screen.

                              else

                                    screen-input = 1.

                                     modify screen.

                           endif.

                       endloop.

                      likewise repeat for fields other than key fields make sure screen-name is in  upper case.

               5.3.  For Delete/Save : Please use insert , modify and delete and make sure to perform these operations on table control itab as well.

            6. When coming back from custom screens please make use of call selection screen statement and set screen 0/ leave to screen 0 statements.

I have implemented stuff like SM30 does and with V_SCROLL = 'X' and it works just fine. 

ABAP Dump Notification via email to ABAP DL

$
0
0

Hi All,


I have designed a custom report program to notify in case of multiple ABAP dump occurrences. This program will send a notification mail to intended recipients (maintained in tcode SO23) if the dump is occurring above a threshold number of times. The users can then take required corrective action.

Report Display:The report will generate ALV output.

Email Mode: Main advantage of this program is in scheduling it in background.

The logic is such that in daily job

- program will check for dumps occurring above the input threshold value, will notify ABAP DL users via email, and updated in a custom table.

- A dump notified once in a day will not be notified again.

- the table will be refreshed on date change, hence, it will be daily notification activity.

 

Below is the table used in the program and code is attached as a text document.


Table.JPG



Kindly let me know your view.


Regards,

DN.

Create Custom report for table maintenance entries

$
0
0

Requirement Details : Maintain data or particular columns in table depending upon Country Value

Solution :  1. Create 2 screens for your Z program via SE51.. First screen with certain fields from Ztable and other with certain fields as per your requirement

                2. Create table control via wizard with Scroll button checked for both the screens

                3. Create PF status for both custom screens in your status PBO module of respective screens

                4. Make sure you have buttons like New entry , Delete  and Display/change same as we have in SM30 maintenance tool and we can use

                    standard buttons for BACK , SAVE , CANCEL , EXIT.

                5. in TABLE_INIT_OUTPUT and User command module of respective table controls write code depending upon  User Command i.e. SY-UCOMM

                5.1. For new entries :

                       loop at screen.

                           screen-input = 1.

                           modify screen.

                       endloop.

                 5.2.  For display/change : here we will loop key fields onwards i.e. they are non editable while maintaining entries e.g. if we have first 3 as key then

                         loop at screen where index GT 3.

                             if screen-name eq 'ZABC' and screen-input = 1.

                                     screen-input = 0.

                                     modify screen.

                              else

                                    screen-input = 1.

                                     modify screen.

                           endif.

                       endloop.

                      likewise repeat for fields other than key fields make sure screen-name is in  upper case.

               5.3.  For Delete/Save : Please use insert , modify and delete and make sure to perform these operations on table control itab as well.

            6. When coming back from custom screens please make use of call selection screen statement and set screen 0/ leave to screen 0 statements.


P.S. : Make sure here my requirement was based on country so I will call custom screen base on country value and then on BACK please set screen 0 to

          ensure proper functionality working.

Debugging Smart Forms in production environment

$
0
0

If you want to debug Smart form in non-modifiable client, then you can debug Smart forms Function Module using session break point.

Step 1: go to transaction SMARTFORMS and provide your smart form name, open it in display mode


            


Step 2: expand the page, select code, and copy its name i.e. %CODE35


             


Step 3: Test (F8) smart form


Step 4: now open this function module in display mode

Note: Whenever a form is activated a Function Module is generated


              


Step 5: find string %CODE35 which was selected in step 2

Note: Instead of using (Ctrl+F) short cut uses  this option.


               


Step 6: double click on search result


               


Step 7: place session break point wherever you want in your code



                

 

Line number 1867 triggers when user dev01 executing the smart form &line number 1870 triggers session break point for all users.

Configuring HTTP Content Server (1) - Creation of the Content Repository

$
0
0

Creation of the content repository

 

A content repository is like a directory. It's a place were you could put several kind of data. You could use only one content repository to store all your data. You could use several content repository to be able to move it to another content server, for size issue, ...

 

Transaction OAM1

This is the global transaction where you will find all the customizing of the content server.

oam1.png

 

Go in the menu :

oam1.png

you could access directly using the transaction OAC0.

 

oam1.png

Press the button create (blank page), and press "Full administration"

 

oam1.png

First, set a name of content repository on two digits (you will have problems in some customizing of ArchivLink if you set more)

Set the version (should be 0046)

Set the host or the IP address of the content server

Set the port number (should be 1090)

Set the HTTP Script (should be ContentServer/ContentServer.dll)

Set the OutputDevice to "ARCH"

 

and save it

 

You have create the content repository in the ECC system, not in the Content Server.

 

Now, you could press the button "CS Admin"

oam1.png

When you use MaxDB, you have to set the setting for the driver.

And press the SAVE button

 

A new tab will appear

oam1.png

 

Now we will have to generate the certificat, go in the certificat tab:

oam1.png

 

Press the SEND button send.png

Select the new line that appears and press the button activate send.png

 

Now the Content server is ready

send.png

 

 

 

 

 

Check if the server is Up and Running

 

 

First, you could check quickly using your internet browser :

http://my_content_server_host:1090/ContentServer/ContentServer.dll?serverInfo

(special thanks to Yann to remember me this helpful link)

 

This link must display a list of variables like this :

send.png

 

One of this variable gives you the status : serverStatus="running";

You could see also there is one ContentRepository : Z1

 

 

The second method is to run the report : RSCMST

 

Enter you ContentRepository and press F8

send.png

 

You must run all the steps of this report :

send.png

if you have any problem on your HTTP Content Server, launch this report to have informations on the errors.


Configuring HTTP Content Server (2) - Save printed document (1/2)

$
0
0

I will not speak about installing and configuring the HTTP Content Server, there is already very good documentation about it. Here we will see how to use the content server to store printed document.

For the example, I will used the Sales Order in an IDES Server.

Configuring the output

 

The configuration of the output is done using the transaction NACE.

nace_1.png

To configure Sales Order output, you have to select the Application "V1" and press the button "Output types"

 

 

nace_1.png

The standard Output Types for the sales order is BA00, I will use it.

Select the Output type in the right part, and double click on "Processing routines".

 

 

nace_1.png

The configuration of the Output type "BA00" for printing is this one. Program "ZSD_RVADOR01" and Smartform "ZSD_SALES_ORDER".

 

 

 

 

Now we could open a Sales Order and check if the message BA00 works.

Transaction VA02.

va01_1.png

 

 

Press the button "Print preview" to display the default output type :va02_4.png

 

 

va02_5.png

 

The Smartforms works (good).

 

 

To display witch output type was used, you have to go in the menu :

va02_2.png

 

va02_3.png

 

This output is yellow because it's not already processed. Print preview doesn't process the message, even if you print during a preview !

To configure the automatic creation of this message you have to configure the transaction VV12.

 

vv12.png

(in your system, you could have several key combinations, for example to be able to specify the printer by plant / sales org / ...)

 

if you go in detail of the condition record you will see something like this :

vv12.png

In this doc, we will try to use the option of the last parameter :

vv12.png

 

 

 

 

 

 

Configure the archiving of the Sales order

 

A long preparation for a quick configuration ..

 

 

Define document type :

 

Transaction OAM1, go in the menu :

oam1.png

(or directly using transaction OAC2)

 

oam1.png

I specify to the system to save the document in PDF format. I could set "*" if I will be able to store PDF, Word, Excel, ...

 

 

 

Define the links

 

Transaction OAM1, go in the menu :

send.png

(or directly using transaction OAC3)

 

The key corresponding to Sales Order is VBAK :

oam1.png

In the OAC3 trans. we specify for this kind of document to store the document in the ContentRepository Z1 and to use the link table TOA01.

(You could use 99 link tables TOA01 -> TOA99)

Save it

 

 

Test

 

Now, we come back to the configuration of the output type in the VA02 transaction.

(menu : Extras -> Output -> Header -> Edit)

oac3.png

Select the line and Click on the button "Communication method" and select "Print & Archiv"

 

oac3.png

(don't forget to set with the button "Further Data" : "Send immediately" )

 

Back and Save.

 

 

Result

 

In transaction VA03, go in the output type.

oam1.png

 

Select the line and go in the menu :

oam1.png

 

With Sales order you will have a popup like that, but with others transaction like Invoice you won't.

oam1.png

 

Double-click on the document will open you an internet browser :

oam1.png

Configuring HTTP Content Server (2) - Save printed document (2/2)

$
0
0

More details

 

 

 

The tables :

 

 

If you go in the table you have specify in the transaction OAC3. You will find a new line.

oam1.png

 

 

 

I don't know the ObjectType or the DocumentType

 

Use a trace: Transaction ST05

You will find some select with the good key.

Trans. OAC2 --> Table TOASP

Trans. OAC3 --> Table TOAOM

 

 

 

I don't have an HTTP Content Server but I would like to archive doc

 

It's possible.

You have to create your Content Repository with a different parameter :

oam1.png

(there is not the part of the CS Admin, because you didn't work with Content Server)

 

 

Now create the table : Trans. SE11, copy the SDOKCONT1 table (activate it)

 

 

Now in OAC3, I will set the Content Repository to Z2.

oam1.png

 

I go back in VA02 to repeat output, and when you will ask to display original :

oam1.png

You can see in the URL the parameter : contRep=Z2

 

The table TOA01 now contains an entry for Z2 :

oam1.png

And the table created for the Content Repository Z2 have the entries :

oam1.png

 

 

 

I want to save all the printed Sales Order

 

At the beginning of the doc. I speak about the transaction VV12. You could configure to generate message with the option Print & Archive.

You can't for the value if your users would like to remove-it. But you could force it in the ABAP of the driver program of the Form.

 

 

 

My user don't want to open the document in the internet browser

 

 

Change your user or go in the transaction OAM1 :

oam1.png

 

You could choose between Internet browser or WebGUI (Dynpro including internet browser)

oam1.png

 

If you choose "Use HTML Control" you will have this kind of window :

oam1.png

 

 

Nothing append, is there a log somewhere

 

Yes, you could check your SM58.

For example, if your HTTP Content Server is down for a time. Go in SM58, you will see all the Archive document waiting for the Content Server. You could relaunch the request to create the data. That means, you don't need to have the HTTP Content Server up all the time.

 

 

 

 

Displaying the document in the GOS

 

 

First the GOS is this icon you could see in some transaction :

 

oam1.png

oam1.png

(The menu could change depending of your SAP release)

 

 

We are in a special case with the transaction VA02 (VA01, VA03), we only need to use parameter ID (SU3) "SD_SWU_ACTIVE". You have to set the value "X"

After that, when you call the VA02 the button will appear.

If you select the line "Attachment list", SAP will list all the document link to the object corresponding to your Sales order.

 

If you want to add this button in other transaction, you need to modify the object corresponding in the SWO1 transaction.

I would like to write a doc about that, but there is already one : Activating Generic Object Services Toolbar in SAP Objects  writes by Abhijeet Kapgate

Configuring HTTP Content Server (3) - GOS

$
0
0

Generic Object Services

 

SAP define GOS has the link between ArchiveLink and the SAP Business Workflow.

Simply, GOS is a set of tools you could find in a lot of standard transaction. These tools allow you to save document, URL, .. and link them to transaction.

 

 

GOS quickly

 

You will have a GOS active (sometimes is not active) when you see this icon in the left upper :

 

oam1.png

 

When you click on the arrow you will find a menu like this one :

oam1.png

This menu could change with the SAP Release.

 

 

Example : Transaction MM03

 

If I open the transaction MM03, enter a material number, select the first view, I will have :

oam1.png

I could attach a file using the menu :

oam1.png

 

SAP will open you a pop-up windows to select a file.

 

And when it's done, the option "Attachment list" is activated.

oam1.png

oam1.png

You could have lines without the creator name. It's the case of the document store in the content server.

 

 

 

Modification of the menu

 

First, remember that GOS is mutual of all the transaction where it's activated.

 

 

The table SGOSATTR

 

The table SGOSATTR contain the menu, you could change it using the SM30 transaction.

The logic of the menu order is done with the column NEXT

The logic of the folder entry is done with the column SUBSERVICE

 

pomme.png

 

The line CREATE_ATTA is a directory, the type is set to "3"

The line PCATTA_CREA is an action line, the type is set to "1"

 

You could also find into this table the class. For example the line PCATTA_CREA is link to the class CL_GOS_SRV_ATTACHMENT_CREATE

You could insert your own entry into this table (don't forget to set the correct class), or you could set your own class.

 

 

 

The BADI GOS_SRV_SELECT

 

You could modify the menu using this BADI by filtering.

 

Example : I would like to keep only the possibility to create an attachment and display the list of attachment for the MM03 transaction.

 

 

Code

METHOD if_ex_gos_srv_select~select_services.

   data is_option type SGOS_SELS.


* For Material Master
   IF is_lpor-typeid EQ 'BUS1001006'.

*   Create ...
     MOVE : 'I'           TO is_option-sign ,
            'EQ'          TO is_option-option ,
            'CREATE_ATTA' TO is_option-low.
     APPEND is_option to et_options.

*   Create attachement
     MOVE : 'I'           TO is_option-sign ,
            'EQ'          TO is_option-option ,
            'PCATTA_CREA' TO is_option-low.
     APPEND is_option to et_options.

*   Attachment list
     MOVE : 'I'           TO is_option-sign ,
            'EQ'          TO is_option-option ,
            'VIEW_ATTA'   TO is_option-low.
     APPEND is_option to et_options.

   ENDIF.


ENDMETHOD.

 

The result will be

oam1.png

 

 

 

I'm sure you will say "OK, that"s cool, but why doing this ?"

When you store document inside SAP, not in HTTP Content Server, most of the time the document is saved in the table SOFFCONT1. If you have users like to doing this, your table will grow very quickly. In my previous job, this table was 1/4 of the SAP database size.

So I lock all the possibility to create attachment with this BADI.

 

And others point, is to create specific document type, lets do an example.

 

 

 

 

Add specific entries in Material Master GOS

 

 

Declare document type

 

Transaction OAC2

oam1.png

We define two document types : A picture and the documentation in PDF format.

 

 

Declare the links

 

Transaction OAC3

oam1.png

For the two document type, we define the link. We will used the Content Repository Z1 (define in the first doc) and the link table TOA01

 

 

Modify the menu

 

Transaction SM30 + SGOSATTR

oam1.png

(it's a screenshot of SE16)

First we need to modify a line to insert the new key. We modify the NEXTSRV of the existing line BARCODE

We insert a new line ZMM_MATERIAL with the class CL_ARL_SRV_LINK.

 

 

Insert the code to limit the menu for the MM0(1,2,3) transaction

 

SE19 for the BADI GOS_SRV_SELECT

 

CODE

METHOD if_ex_gos_srv_select~select_services.

   data is_option type SGOS_SELS.


* For Material Master
   IF is_lpor-typeid EQ 'BUS1001006'.

*   Create material attachment
     MOVE : 'I'            TO is_option-sign ,
            'EQ'           TO is_option-option ,
            'ZMM_MATERIAL' TO is_option-low.
     APPEND is_option to et_options.


*   Attachment list
     MOVE : 'I'           TO is_option-sign ,
            'EQ'          TO is_option-option ,
            'VIEW_ATTA'   TO is_option-low.
     APPEND is_option to et_options.

*   Archive (delete)
     MOVE : 'I'           TO is_option-sign ,
            'EQ'          TO is_option-option ,
            'ARL_LINK'   TO is_option-low.
     APPEND is_option to et_options.

   ENDIF.


ENDMETHOD.

 

 

Result

 

oam1.png

You see only the 3 entries filtered

 

If you select Material attachment you will have a pop-up :

oam1.png

 

To post document or picture you only have to make a drag & drop or you could double click on the element : Document or Picture of material.

oam1.png

 

If I ask for the attachment list

oam1.png

 

The entry was created in the TOA01 table

 

oam1.png

Configuring HTTP Content Server (4) : ABAP code (1/2) : Read

$
0
0

The goal of this doc, is to give some tools to access to file store using GOS & ArchiveLink

 

The big problem of GOS is: you could store documents in different places. You will need to use different method / functions to read the document depending of the location.

 

Lets take an example, a Sales Order :

 

example1.png

 

example1.png

 

At first you could think all the documents are stored in the same place, but it's not. A detail could give you this information quickly. There is no creator for object post on a HTTP Content Server.

 





1. Get the list of document store in the HTTP Content Server.



Code


DATA : lw_objecttype  TYPE saeanwdid ,
        lw_object_id   TYPE saeobjid ,

        lt_connections TYPE toav0_t .


MOVE : '0000009122' TO lw_object_id ,
       'VBAK'       TO lw_objecttype .

CALL FUNCTION 'ARCHIV_GET_CONNECTIONS'
   EXPORTING
     objecttype    = lw_objecttype
     object_id     = lw_object_id
   TABLES
     connections   = lt_connections
   EXCEPTIONS
     nothing_found = 1
     OTHERS        = 2.



The result in debug is


example1.png


5 documents store in the Content Repository Z1

1 document store in the Content Repository Z2




Sample code to read the content of the last file.


 

Code
DATA : lw_objecttype  TYPE saeanwdid ,
        lw_object_id   TYPE saeobjid  ,
        lw_file        TYPE string ,
        lw_path        TYPE string ,
        lw_fullpath    TYPE string ,
        lw_doctype     TYPE saedoktyp ,
        lw_length      TYPE num12 ,
        lw_offset      TYPE num12 ,
        lw_size        TYPE i ,
        ls_connection  TYPE toav0 ,

        lt_connections TYPE toav0_t ,
        lt_data        TYPE tabl1024_t .


MOVE : '0000009122' TO lw_object_id ,
       'VBAK'       TO lw_objecttype .


* Get the list of documents link to the Sales Order
CALL FUNCTION 'ARCHIV_GET_CONNECTIONS'
   EXPORTING
     objecttype    = lw_objecttype
     object_id     = lw_object_id
   TABLES
     connections   = lt_connections
   EXCEPTIONS
     nothing_found = 1
     OTHERS        = 2.



* Get the last entry.
LOOP AT lt_connections
      INTO ls_connection.
ENDLOOP.


* Change the type of the field for Document Type (=PDF)
MOVE ls_connection-reserve TO lw_doctype.


* Get the Content of the entry in Binary Mode (more simple for PDF)
CALL FUNCTION 'ARCHIVOBJECT_GET_BYTES'
   EXPORTING
     archiv_id                = ls_connection-archiv_id
     archiv_doc_id            = ls_connection-arc_doc_id
     document_type            = lw_doctype
     length                   = lw_length
     offset                   = lw_offset
   IMPORTING
     binlength                = lw_length
   TABLES
     binarchivobject          = lt_data
   EXCEPTIONS
     error_archiv             = 1
     error_communicationtable = 2
     error_kernel             = 3
     OTHERS                   = 4.
CHECK sy-subrc EQ space.



* Ask user for the name and the location of the file
CALL METHOD cl_gui_frontend_services=>file_save_dialog
   CHANGING
     filename             = lw_file
     path                 = lw_path
     fullpath             = lw_fullpath
   EXCEPTIONS
     cntl_error           = 1
     error_no_gui         = 2
     not_supported_by_gui = 3
     OTHERS               = 4.


MOVE lw_length TO lw_size.


* Save the file.
CALL METHOD cl_gui_frontend_services=>gui_download
   EXPORTING
     bin_filesize            = lw_size
     filename                = lw_file
     filetype                = 'BIN'
   CHANGING
     data_tab                = lt_data
   EXCEPTIONS
     OTHERS                  = 24.





2. Get the list of document store in the default SAP tables.



Code

 


DATA : w_file_type  TYPE fileformat ,

        is_role      TYPE obl_s_rolt ,
        is_object    TYPE sibflporb  ,
        is_relation  TYPE obl_s_relt ,

        it_objects   TYPE sibflporbt,
        it_link_a    TYPE obl_t_link ,
        it_roles     TYPE obl_t_rolt ,
        it_relations TYPE obl_t_relt.


* The object Key
MOVE : '0000009122' TO is_object-instid ,
        'BUS2032'    TO is_object-typeid ,
        'BO'         TO is_object-catid .
APPEND is_object TO it_objects.


* The kind of object
MOVE : 'I'          TO is_role-sign ,
        'EQ'         TO is_role-option ,
        'GOSAPPLOBJ' TO is_role-low.
APPEND is_role TO it_roles.
MOVE : 'I'          TO is_relation-sign ,
        'EQ'         TO is_relation-option ,
        'ATTA'       TO is_relation-low .
APPEND is_relation TO it_relations.

MOVE : 'BIN' TO w_file_type.



* Extraction des liens.
TRY.
     CALL METHOD cl_binary_relation=>read_links_of_objects
       EXPORTING
         it_objects          = it_objects
*       ip_logsys           =
         it_role_options     = it_roles
         it_relation_options = it_relations
*       ip_no_buffer        = SPACE
       IMPORTING
         et_links_a          = it_link_a.
   CATCH cx_obl_model_error .
   CATCH cx_obl_parameter_error .
   CATCH cx_obl_internal_error .
ENDTRY.


The result in debug mode will be :

example1.png



To read the data, we will used a SAP Office function. Because the file are stored in the SAP Office table SOO*


 

Code
DATA : lw_file_type  TYPE fileformat ,
        lw_file       TYPE string ,
        lw_path       TYPE string ,
        lw_fullpath   TYPE string ,
        lw_doc_id     TYPE so_entryid ,

        ls_role      TYPE obl_s_rolt ,
        ls_object    TYPE sibflporb  ,
        ls_relation  TYPE obl_s_relt ,
        ls_link_a    TYPE obl_s_link ,
        ls_doc_data  TYPE sofolenti1 ,

        lt_objects   TYPE sibflporbt ,
        lt_link_a    TYPE obl_t_link ,
        lt_roles     TYPE obl_t_rolt ,
        lt_relations TYPE obl_t_relt ,
        lt_content   TYPE TABLE OF solisti1  ,
        lt_contentx  TYPE solix_tab.


* The object Key
MOVE : '0000009122' TO ls_object-instid ,
        'BUS2032'    TO ls_object-typeid ,
        'BO'         TO ls_object-catid .
APPEND ls_object TO lt_objects.


* The kind of object
MOVE : 'I'          TO ls_role-sign ,
        'EQ'         TO ls_role-option ,
        'GOSAPPLOBJ' TO ls_role-low.
APPEND ls_role TO lt_roles.
MOVE : 'I'          TO ls_relation-sign ,
        'EQ'         TO ls_relation-option ,
        'ATTA'       TO ls_relation-low .
APPEND ls_relation TO lt_relations.

MOVE : 'BIN' TO lw_file_type.



* Extraction des liens.
TRY.
     CALL METHOD cl_binary_relation=>read_links_of_objects
       EXPORTING
         it_objects          = lt_objects
         it_role_options     = lt_roles
         it_relation_options = lt_relations
       IMPORTING
         et_links_a          = lt_link_a.
   CATCH cx_obl_model_error .
   CATCH cx_obl_parameter_error .
   CATCH cx_obl_internal_error .
ENDTRY.



LOOP AT lt_link_a
      INTO ls_link_a.
ENDLOOP.

MOVE ls_link_a-instid_b TO lw_doc_id .


CALL FUNCTION 'SO_DOCUMENT_READ_API1'
   EXPORTING
     document_id                = lw_doc_id
   IMPORTING
     document_data              = ls_doc_data
   TABLES
     object_content             = lt_content
     contents_hex               = lt_contentx
   EXCEPTIONS
     document_id_not_exist      = 1
     operation_no_authorization = 2
     x_error                    = 3
     OTHERS                     = 4.





* Ask user for the name and the location of the file
CALL METHOD cl_gui_frontend_services=>file_save_dialog
   CHANGING
     filename             = lw_file
     path                 = lw_path
     fullpath             = lw_fullpath
   EXCEPTIONS
     cntl_error           = 1
     error_no_gui         = 2
     not_supported_by_gui = 3
     OTHERS               = 4.



* Save the file.
CALL METHOD cl_gui_frontend_services=>gui_download
   EXPORTING
*   bin_filesize = lw_size
     filename     = lw_file
     filetype     = 'BIN'
   CHANGING
     data_tab     = lt_contentx
   EXCEPTIONS
     OTHERS       = 24.


HTTP Content Server & GOS

$
0
0

The list of all the docs I have created about Content Server, and the doc I will try to write.

If you need a doc about Content Server and it's not listed .. just give me the idea

 

 

Configuring HTTP Content Server (1) - Creation of the Content Repository

 

Configuring HTTP Content Server (2) - Save printed document (1/2)

Configuring HTTP Content Server (2) - Save printed document (2/2)

 

Configuring HTTP Content Server (3) - GOS

 

Configuring HTTP Content Server (4) : ABAP code (1/2) : Read

... write

 

... Bar Code logic

 

 

 

 

 

Fred

ABAP cross system object recursive dependencies check with transport

$
0
0
tools.jpg

If you need to know the scope and dependencies of a repository workbench object and if needed at the end prepare a coherent transport request this tool is what you are looking for.

 

You can even run cross-system version checks to detect objects differences and decide what to include in your transport or analyze each object using direct object editor navigation with all standard features.

 

Since SAP objects hierarchy is complex to understand this tool will be versioned and I hope one day more objects can be added.

Standard features:

  • Normally attached to each ABAP objects development transactions you can run Environment Analysis (menu Utilities) to list all used objects but without recursive check in founded ones.
  • The same for existent standard reports like RSDEPEND where you can display dependencies but without recursive check.

 

If none of these standard methods are suitable for you please implement the tool bellow.

How to implement:

  • Create a executable report in your SAP development system with name ZNM_OBJS_DEP_TRANS and description Object Dependencies and Transport using transaction SE38;
  • Copy past code bellow and activate the program;
  • Create/Fill corresponding Text Symbols and Selection Texts. Please check the meaning at top comments of the program;
  • Create GUI Status with name STATUS and add standard functions &ALL, &SAL, &OUP, &ODN, &ILT, %PC, &OL0, &OAD and &AVE.

Create customer function code TR :

Untitled.png

Untitled.png

After conversion change reference of global object variable GO_ODT to the new Global class and delete local class definition and implementation from code.


If you are not able to activate the program because of nonexistent standard objects please downgrade for earlier SAP versions. If you need help on it,please kept me informed.


Copy past the code bellow or download the attached file:


REPORT znm_obj_dep_trans MESSAGE-ID 00.
*----------------------------------------------------------------------*
* Created by NM for Object Dependencies Checks and Transport
*----------------------------------------------------------------------*
* Text Symbols
* B01  Object selection
* B02  Aditional options
* C01  Remote
* C02  Obj. Desc.
* C03  Deepness
* C04  Scope
* CM1  Cross-system objects version check
* M01  Objects not found
* M02  Please fill all required fields
* M03  Critical error
* M04  No objects selected
* M05  Transport not allowed for multiple targets
* M06  Error creating transport request
* M07  Objects added to request (
* M08  Please select a remote system
* M09  RFCs destinations missing
* M10  Request canceled, object with $TEMP detected
* M11  Navigation not suported
* M12  Transport canceled
* M13  Object dependencies check not support
* M14  No dependecies found
* M15  Error treating transport request
* M16  Please fill deepness for standard objects
* O01  Equal
* O02  Different
* O03  New
* O04  No version
* P01  Adding object
* P02  Checking Dependecies
* P03  Checking Remote
* P04  Display objects
* P05  Processing options
* PB1  % Complete
*
* Selection Texts
* P_DEEP  Dependencies Deepness
* P_ERFC  Exclude RFCs if exist
* P_ICD  Include Tables CDs
* P_ILO  Include Tables Locks
* P_ITM  Include Tables Maintenances
* P_OBJECT  Object Type
* P_OBJ_N  Object Name
* P_PGMID  Program ID
* P_RFC  Remote Versions Checks
* P_RFC_D  System Name
* P_ST  Include Standard Objects
* P_TR  Transport Request
* R_OBJ  Check Workbench Object
* R_TR  Check Transport Request
*
* Standard Status GUI function codes: &ALL, &SAL, &OUP, &ODN, &ILT, %PC, &OL0, &OAD and &AVE
* Status GUI function code: TR Create Transport
*
*---------------------------------------------- LOCAL CLASS DEFINITION *
CLASS obj_dep_trans DEFINITION FINAL.   PUBLIC SECTION.     TYPE-POOLS: abap, icon.
*--------------------------------------------------- Public Structures *     TYPES:       BEGIN OF ty_objects,         status   TYPE icon_d,       "Check status         pgmid    TYPE pgmid,        "Program ID in Requests and Tasks         object   TYPE trobjtype,    "Object Type         obj_name TYPE sobj_name,    "Object Name in Object Directory         obj_desc TYPE ddtext,       "Object Explanatory short text         deep     TYPE i,            "Object deepness position         scope    TYPE icon_d,       "Object Scope         devclass TYPE developclass, "Development Package         target   TYPE tr_target,    "Transport Target of Request         remote(10),                 "Remote check status       END OF ty_objects.     DATA:       t_objects   TYPE TABLE OF ty_objects, "Objects to transport       t_objs_desc TYPE TABLE OF ko100,      "Objects prograns IDs       t_e071      TYPE TABLE OF e071,       "Object Entries of Requests/Tasks       t_e071k     TYPE TABLE OF e071k.
*------------------------------------------------------ Public Methods *     METHODS:
*---------- Public Methods Constructor Definition ----------*       constructor,
*---------- Set global values ----------*       set_values IMPORTING i_robj   TYPE abap_bool   "Add from Object                            i_pgmid  TYPE pgmid       "Program ID in Requests and Tasks                            i_object TYPE trobjtype   "Object Type                            i_obj_n  TYPE sobj_name   "Object Name in Object Directory                            i_rtr    TYPE abap_bool   "Add from TR                            i_tr     TYPE trkorr      "Transport request                            i_deep   TYPE i           "Dependencies deepness                            i_rfc    TYPE abap_bool   "Remote versions checks                            i_rfc_d  TYPE tmssysnam   "System Name                            i_st     TYPE abap_bool   "Include standard objects                            i_itm    TYPE abap_bool   "Include Tables Maintenance                            i_ilo    TYPE abap_bool   "Include Lock objects                            i_icd    TYPE abap_bool   "Include Change documents                            i_erfc   TYPE abap_bool,  "Exclude RFCs if exist
*---------- Public Methods PGMID Definition ----------*       pgmid_f4,
*---------- Public Methods Object F4 Definition ----------*       object_f4 CHANGING c_pgmid  TYPE pgmid      "Program ID in Requests and Tasks                          c_object TYPE trobjtype, "Object Type
*---------- Public Methods Object Name F4 Definition ----------*       object_name_f4 IMPORTING i_object TYPE trobjtype  "Object Type                       CHANGING c_obj_n  TYPE sobj_name, "Object Name in Object Directory
*---------- Public Methods Transport Request F4 Definition ----------*       tr_f4 CHANGING c_tr TYPE trkorr,  "Request/Task
*---------- Public Methods RFC F4 Definition ----------*       rfc_f4 CHANGING c_rfc_d TYPE tmssysnam, "TMS: System Name
*---------- Public Methods Screen PAI Definition ----------*       screen_pai,
*---------- Public Methods Run Checks Definition ----------*       run_checks,
*---------- Public Methods Display Objects Definition ----------*       display_objects.
*----------------------------------------------------- Public Handlers *     METHODS:
*---------- Public Handler On User Command Definition ----------*       on_user_command FOR EVENT added_function OF cl_salv_events  IMPORTING e_salv_function,
*---------- Public Handler On Double Click Definition ----------*       on_double_click FOR EVENT double_click OF cl_salv_events_table IMPORTING row column. "#EC NEEDED   PRIVATE SECTION.
*--------------------------------------------------- Private Constants *     DATA:       c_r3tr TYPE pgmid        VALUE 'R3TR',  "Main object       c_tobj TYPE trobjtype    VALUE 'TOBJ',  "Table content in transport       c_chdo TYPE trobjtype    VALUE 'CHDO',  "Change documents       c_fugr TYPE trobjtype    VALUE 'FUGR',  "Function group       c_tabl TYPE trobjtype    VALUE 'TABL',  "Table       c_devc TYPE trobjtype    VALUE 'DEVC',  "Development class       c_temp TYPE developclass VALUE '$TMP'.  "Local development class
*--------------------------------------------------- Private Variables *     DATA:       v_robj    TYPE abap_bool, "Add from Object       v_pgmid   TYPE pgmid,     "Program ID in Requests and Tasks       v_object  TYPE trobjtype, "Object Type       v_obj_n   TYPE sobj_name, "Object Name in Object Directory       v_rtr     TYPE abap_bool, "Add from TR       v_tr      TYPE trkorr,    "Transport request       v_deep    TYPE i,         "Dependencies deepness       v_rfc     TYPE abap_bool, "Remote versions checks       v_rfc_d   TYPE tmssysnam, "System Name       v_st      TYPE abap_bool, "Include standard objects       v_itm     TYPE abap_bool, "Include Tables Maintenance       v_ilo     TYPE abap_bool, "Include Lock objects       v_icd     TYPE abap_bool, "Include Change documents       v_erfc    TYPE abap_bool, "Exclude RFCs if exist       v_percent TYPE i.         "Progress bar percentage
*--------------------------------------------------- Private Class ALV *     DATA o_objects TYPE REF TO cl_salv_table. "Objects ALV
*----------------------------------------------------- Private Methods *     METHODS:
*---------- Private Methods Progress Bar Definition ----------*       progress_bar IMPORTING value(i_value) TYPE itex132 "#EC CI_VALPAR                                    i_tabix  TYPE i,
*---------- Private Methods Execute Add Objects Definition ----------*       execute_add_objects,
*---------- Private Methods Execute Add From Transport Definition ----------*       execute_add_from_transport,
*---------- Private Methods Check Add Object Definition *       check_add_object IMPORTING value(i_pgmid)  TYPE pgmid "Program ID in Requests and Tasks                                  value(i_object) TYPE any   "Object Type                                  value(i_obj_n)  TYPE any   "Object Name in Object Directory                                  is_env_tab      TYPE senvi "Info system                                  i_deep          TYPE i,    "Deepness       add_objects_of_devclass IMPORTING i_obj_n TYPE any "Object Name in Object Directory                                         i_deep  TYPE i,  "Deepness
*---------- Private Methods Add Object Definition ----------*       add_object IMPORTING i_deep    TYPE i            "Deepness                   CHANGING cs_object TYPE ty_objects,  "Objects table
*---------- Private Methods Objects Dependencies Check Definition ----------*       objects_dependencies_check,
*---------- Private Methods Remote Objects Check Definition ----------*       remote_objects_check,
*---------- Private Methods Exclude RFCs Definition ----------*       exclude_rfcs IMPORTING i_obj_name TYPE sobj_name  "Object Name in Object Directory                     CHANGING c_no_rfc   TYPE abap_bool, "Found RFC flag
*---------- Private Methods Include Maintenances Definition ----------*       include_maintenances,
*---------- Private Methods Include Locks Definition ----------*       include_locks,
*---------- Private Methods CDs Definition ----------*       include_cds,
*---------- Private Methods Add TOBJ Content Definition ----------*       add_tobj_content IMPORTING i_obj_name TYPE sobj_name, "Object Name in Object Directory
*---------- Private Methods Object Header Definition ----------*       add_object_header IMPORTING i_pgmid   TYPE pgmid    "Program ID in Requests and Tasks                                   i_object  TYPE any      "Object Type                                   i_obj_n   TYPE any      "Object Name in Object Directory                                   i_objfunc TYPE objfunc, "Object function
*---------- Private Methods Object Keys Definition ----------*       add_object_keys IMPORTING i_pgmid  TYPE pgmid "Program ID in Requests and Tasks                                 i_object TYPE any   "Object Type                                 i_obj_n  TYPE any   "Object Name in Object Directory                                 i_tabkey TYPE any.  "Table key
ENDCLASS.                    "obj_dep_trans DEFINITION
*--------------------------------------------------------- GLOBAL DATA *
DATA go_odt TYPE REF TO obj_dep_trans.                      "#EC NEEDED
*---------------------------------------------------- SELECTION SCREEN *
*---------------------------------------------------- Object selection *
SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE text-b01.
SELECTION-SCREEN SKIP 1.
PARAMETERS r_obj RADIOBUTTON GROUP rbt USER-COMMAND rbt DEFAULT 'X'.  "Add from Objects or Development Package
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN POSITION 4.
PARAMETERS:   p_pgmid  TYPE pgmid DEFAULT 'R3TR', "Program ID in Requests and Tasks   p_object TYPE trobjtype,            "Object Type   p_obj_n  TYPE sobj_name.            "Object Name in Object Directory
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN SKIP 1.
PARAMETERS r_tr RADIOBUTTON GROUP rbt.  "Add from TR
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN POSITION 4.
PARAMETERS p_tr TYPE trkorr.  "Transport request
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN SKIP 1.
PARAMETERS p_deep TYPE i DEFAULT 0. "Dependencies deepness
SELECTION-SCREEN END OF BLOCK b01.
*-------------------------------------------------- Aditional options *
SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME TITLE text-b02.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS p_rfc AS CHECKBOX. "Remote versions checks
SELECTION-SCREEN COMMENT (37) com_rfc.
PARAMETERS p_rfc_d TYPE tmssysnam.  "System Name
SELECTION-SCREEN END OF LINE.
PARAMETERS p_st AS CHECKBOX.  "Include standard objects
SELECTION-SCREEN SKIP 1.
PARAMETERS:   p_itm  AS CHECKBOX, "Include Tables Maintenance   p_ilo  AS CHECKBOX, "Include Lock objects   p_icd  AS CHECKBOX, "Include Change documents   p_erfc AS CHECKBOX. "Exclude RFCs if exist
SELECTION-SCREEN END OF BLOCK b02.
*------------------------------------------ SELECTION SCREEN PAI HELPS *
*------------------------------------------------------- Program ID F4 *
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_pgmid.   go_odt->pgmid_f4( ).
*------------------------------------------------------ Object Type F4 *
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_object.   go_odt->object_f4( CHANGING c_pgmid = p_pgmid c_object = p_object ).
*------------------------------------------------------ Object Name F4 *
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_obj_n.   go_odt->object_name_f4( EXPORTING i_object = p_object CHANGING c_obj_n = p_obj_n ).
*------------------------------------------------ Transport request F4 *
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_tr.   go_odt->tr_f4( CHANGING c_tr = p_tr ).
*-------------------------------------------------- Systems and RFC F4 *
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_rfc_d.   go_odt->rfc_f4( CHANGING c_rfc_d = p_rfc_d ).
*------------------------------------------------ SELECTION SCREEN PAI *
AT SELECTION-SCREEN.   go_odt->set_values( i_robj   = r_obj      "Add from Object                       i_pgmid  = p_pgmid    "Program ID in Requests and Tasks                       i_object = p_object   "Object Type                       i_obj_n  = p_obj_n    "Object Name in Object Directory                       i_rtr    = r_tr       "Add from TR                       i_tr     = p_tr       "Transport request                       i_deep   = p_deep     "Dependencies deepness                       i_rfc    = p_rfc      "Remote versions checks                       i_rfc_d  = p_rfc_d    "System Name                       i_st     = p_st       "Include standard objects                       i_itm    = p_itm      "Include Tables Maintenance                       i_ilo    = p_ilo      "Include Lock objects                       i_icd    = p_icd      "Include Change documents                       i_erfc   = p_erfc ).  "Exclude RFCs if exist   go_odt->screen_pai( ).  "Screen Process after input
*------------------------------------------------------- REPORT EVENTS *
*----------------------------------------------- Initialization events *
INITIALIZATION.   com_rfc = 'Cross-system objects version check'(cm1).   CREATE OBJECT go_odt. "Create main class
*---------------------------------------------------- Executing events *
START-OF-SELECTION.   go_odt->run_checks( ).      "Execution   go_odt->display_objects( ). "Result display
*------------------------------------------ LOCAL CLASS IMPLEMENTATION *
CLASS obj_dep_trans IMPLEMENTATION.
*---------------------------- Public Method Constructor Implementation *   METHOD constructor.     CALL FUNCTION 'TR_OBJECT_TABLE' "Fill Program IDs       TABLES         wt_object_text = t_objs_desc.   ENDMETHOD.                    "constructor
*-------------------------- Public Method to Set Values Implementation *   METHOD set_values.     v_robj   = i_robj.   "Add from Object     v_pgmid  = i_pgmid.  "Program ID in Requests and Tasks     v_object = i_object. "Object Type     v_obj_n  = i_obj_n.  "Object Name in Object Directory     v_rtr    = i_rtr.    "Add from TR     v_tr     = i_tr.     "Transport request     v_deep   = i_deep.   "Dependencies deepness     v_rfc    = i_rfc.    "Remote versions checks     v_rfc_d  = i_rfc_d.  "System Name     v_st     = i_st.     "Include standard objects     v_itm    = i_itm.    "Include Tables Maintenance     v_ilo    = i_ilo.    "Include Lock objects     v_icd    = i_icd.    "Include Change documents     v_erfc   = i_erfc.   "Exclude RFCs if exist   ENDMETHOD.                    "set_values
*------------------------------- Public Method PGMID F4 Implementation *   METHOD pgmid_f4.     DATA lt_pgmids TYPE TABLE OF ko101.  "Program IDs with Description
*---------- Read PGMID ----------*     CALL FUNCTION 'TR_PGMID_TABLE'       TABLES         wt_pgmid_text = lt_pgmids.
*---------- Set PGMID F4 ----------*     CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' "#EC FB_RC "#EC CI_SUBRC       EXPORTING         retfield        = 'PGMID'         dynpprog        = sy-cprog         value_org       = 'S'         dynpnr          = '1000'         dynprofield     = 'TRE071X-PGMID'       TABLES         value_tab       = lt_pgmids       EXCEPTIONS         parameter_error = 1         no_values_found = 2         OTHERS          = 3.   ENDMETHOD.                    "pgmid_f4
*------------------------------ Public Method Object F4 Implementation *   METHOD object_f4.     CONSTANTS:       lc_object TYPE fieldname VALUE 'OBJECT', "Object field       lc_pgmid  TYPE fieldname VALUE 'PGMID'.  "Program ID in Requests and Tasks field     DATA:       lt_shlp          TYPE shlp_descr,           "Description of Search Help       lt_return_values TYPE TABLE OF ddshretval,  "Interface Structure Search Help       ls_return_values LIKE LINE OF lt_return_values,       lv_rc            TYPE sysubrc.              "Return Value of ABAP Statements     FIELD-SYMBOLS <interface> TYPE ddshiface. "Interface description of a F4 help method
*---------- Get search help ----------*     CALL FUNCTION 'F4IF_GET_SHLP_DESCR'       EXPORTING         shlpname = 'SCTSOBJECT'       IMPORTING         shlp     = lt_shlp.
*---------- Fill search help ----------*     LOOP AT lt_shlp-interface ASSIGNING <interface>.       IF <interface>-shlpfield = lc_object.         <interface>-valfield = abap_true.         <interface>-value    = c_object.       ENDIF.       IF <interface>-shlpfield = lc_pgmid.         <interface>-valfield = abap_true.         <interface>-value    = c_pgmid.       ENDIF.     ENDLOOP.
*---------- Call search help ----------*     CALL FUNCTION 'F4IF_START_VALUE_REQUEST'       EXPORTING         shlp          = lt_shlp       IMPORTING         rc            = lv_rc       TABLES         return_values = lt_return_values.
*---------- Set search help return ----------*     IF lv_rc IS INITIAL.       READ TABLE lt_return_values INTO ls_return_values WITH KEY fieldname = lc_object.       IF sy-subrc IS INITIAL.         c_object = ls_return_values-fieldval.       ENDIF.       READ TABLE lt_return_values INTO ls_return_values WITH KEY fieldname = lc_pgmid.       IF sy-subrc IS INITIAL.         c_pgmid = ls_return_values-fieldval.       ENDIF.     ENDIF.   ENDMETHOD.                    "object_f4
*------------------------- Public Method Object Name F4 Implementation *   METHOD object_name_f4.     DATA lv_object_type TYPE seu_obj.  "Object type
*---------- Get objects repository information ----------*     lv_object_type = i_object.     CALL FUNCTION 'REPOSITORY_INFO_SYSTEM_F4'  "#EC FB_RC "#EC CI_SUBRC       EXPORTING         object_type          = lv_object_type         object_name          = c_obj_n       IMPORTING         object_name_selected = c_obj_n       EXCEPTIONS         cancel               = 1         wrong_type           = 2         OTHERS               = 3.   ENDMETHOD.                    "object_name_f4
*------------------- Public Method Transport Request F4 Implementation *   METHOD tr_f4.     CALL FUNCTION 'TR_F4_REQUESTS'       IMPORTING         ev_selected_request = c_tr.   ENDMETHOD.                    "tr_f4
*--------------------------------- Public Method RFC F4 Implementation *   METHOD rfc_f4.     CALL FUNCTION 'TMS_UI_F4_SYSTEMS'       CHANGING         cv_system = c_rfc_d.   ENDMETHOD.                    "rfc_f4
*----------------------------- Public Method Screen Pai Implementation *   METHOD screen_pai.     IF sy-ucomm = 'ONLI'.
*---------- Check required data ----------*       IF ( v_robj IS NOT INITIAL AND ( v_pgmid IS INITIAL OR v_object IS INITIAL OR v_obj_n IS INITIAL ) ) OR          ( v_rtr IS NOT INITIAL AND v_tr IS INITIAL ) OR          ( v_rfc IS NOT INITIAL AND v_rfc_d IS INITIAL ).         MESSAGE e398(00) WITH 'Please fill all required fields'(m02) space space space DISPLAY LIKE 'W'.       ENDIF.       IF v_rfc IS NOT INITIAL AND v_rfc_d = sy-sysid.         MESSAGE e398(00) WITH 'Please select a remote system'(m08) space space space DISPLAY LIKE 'W'.       ENDIF.
*---------- Add first object ----------*       progress_bar( i_value = 'Adding object'(p01) i_tabix = '10' ).       CASE abap_true.         WHEN v_robj.  "Add object or dev class objects           execute_add_objects( ).         WHEN v_rtr. "Add TR objects           execute_add_from_transport( ).       ENDCASE.       IF t_objects IS INITIAL.         MESSAGE e398(00) WITH 'Objects not found'(m01) space space space DISPLAY LIKE 'W'.       ENDIF.       IF v_st IS NOT INITIAL AND ( v_deep IS INITIAL OR v_deep = 0 ). "Performance Test         MESSAGE e398(00) WITH 'Please fill deepness for standard objects'(m16) space space space DISPLAY LIKE 'I'.       ENDIF.     ENDIF.   ENDMETHOD.                    "screen_pai
*----------------------------- Public Method Run Checks Implementation *   METHOD run_checks.     IF t_objects IS NOT INITIAL.
*---------- Dependecies check ----------*       progress_bar( i_value = 'Checking Dependecies'(p02) i_tabix = '20' ).       objects_dependencies_check( ).       progress_bar( i_value = 'Processing options'(p05) i_tabix = '50' ).
*---------- Include Tables Maintenance ----------*       IF v_itm IS NOT INITIAL.         include_maintenances( ).         objects_dependencies_check( ).       ENDIF.
*---------- Include Lock objects ----------*       IF v_ilo IS NOT INITIAL. include_locks( ). ENDIF.
*---------- Include Change documents ----------*       IF v_icd IS NOT INITIAL. include_cds( ). ENDIF.
*---------- Remote check ----------*       IF v_rfc IS NOT INITIAL.         progress_bar( i_value = 'Checking Remote'(p03) i_tabix = '80' ).         remote_objects_check( ).       ENDIF.     ENDIF.   ENDMETHOD.                    "run_checks
*------------------------ Public Method Display Objects Implementation *   METHOD display_objects.     DATA:       lr_events        TYPE REF TO cl_salv_events_table,      "ALV Events       lr_display       TYPE REF TO cl_salv_display_settings,  "ALV Output Appearance       lr_columns       TYPE REF TO cl_salv_columns_table,     "ALV Columns       lr_column        TYPE REF TO cl_salv_column_table,       lr_selections    TYPE REF TO cl_salv_selections,        "ALV Selections       lr_layout        TYPE REF TO cl_salv_layout.            "ALV Layout     DATA:       lt_column_ref TYPE salv_t_column_ref, "Columns of ALV List       ls_column_ref TYPE salv_s_column_ref,       ls_key        TYPE salv_s_layout_key.     DATA:       lv_title   TYPE lvc_title,  "ALV title       lv_lines   TYPE i,          "Number of objects       lv_lines_c TYPE string.     IF t_objects IS NOT INITIAL.       progress_bar( i_value = 'Display objects'(p04) i_tabix = '90' ).       IF o_objects IS NOT BOUND.         TRY.             IF lines( t_objects ) = 1.               MESSAGE s398(00) WITH 'No dependecies found'(m14) space space space DISPLAY LIKE 'W'.             ELSE.               SORT t_objects BY deep pgmid object obj_name.             ENDIF.
*---------- Create ALV ----------*             cl_salv_table=>factory( IMPORTING r_salv_table = o_objects                                      CHANGING t_table      = t_objects ).
*---------- Set ALV Functions ----------*             o_objects->set_screen_status(               pfstatus      = 'STATUS'               report        = sy-cprog               set_functions = o_objects->c_functions_all ).
*---------- Set Layout ----------*             lr_layout = o_objects->get_layout( ).             ls_key-report = sy-repid.             lr_layout->set_key( ls_key ).             lr_layout->set_save_restriction( ).
*---------- Set ALV selections ----------*             lr_selections = o_objects->get_selections( ).             lr_selections->set_selection_mode( if_salv_c_selection_mode=>row_column ).
*---------- Set ALV Display and Title ----------*             lr_display = o_objects->get_display_settings( ).             lr_display->set_striped_pattern( if_salv_c_bool_sap=>true ).             lv_lines = lines( t_objects ).             lv_lines_c = lv_lines.             CONDENSE lv_lines_c NO-GAPS.             CONCATENATE '(' lv_lines_c ')' INTO lv_lines_c.             CONCATENATE sy-title lv_lines_c INTO lv_title SEPARATED BY space.             lr_display->set_list_header( lv_title ).
*---------- Set ALV Columns ----------*             lr_columns = o_objects->get_columns( ).             lr_columns->set_key_fixation( ).             lr_columns->set_optimize( ).             lt_column_ref = lr_columns->get( ).             LOOP AT lt_column_ref INTO ls_column_ref. "Default format for all columns               lr_column ?= lr_columns->get_column( ls_column_ref-columnname ).               lr_column->set_f4( if_salv_c_bool_sap=>false ).               lr_column->set_alignment( if_salv_c_alignment=>centered ).               IF ls_column_ref-columnname = 'STATUS' OR                  ls_column_ref-columnname = 'PGMID' OR                  ls_column_ref-columnname = 'OBJECT' OR                  ls_column_ref-columnname = 'OBJ_NAME'.                 lr_column->set_key( if_salv_c_bool_sap=>true ).               ENDIF.               IF ls_column_ref-columnname = 'OBJ_NAME' OR                  ls_column_ref-columnname = 'DEVCLASS'.                 lr_column->set_alignment( if_salv_c_alignment=>left ).               ENDIF.               IF ls_column_ref-columnname = 'OBJ_DESC'.                 lr_column->set_alignment( if_salv_c_alignment=>left ).                 lr_column->set_short_text( 'Obj. Desc.'(c02) ).                 lr_column->set_medium_text( 'Obj. Desc.'(c02) ).                 lr_column->set_long_text( 'Obj. Desc.'(c02) ).               ENDIF.               IF ls_column_ref-columnname = 'DEEP'.                 lr_column->set_short_text( 'Deepness'(c03) ).                 lr_column->set_medium_text( 'Deepness'(c03) ).                 lr_column->set_long_text( 'Deepness'(c03) ).               ENDIF.               IF ls_column_ref-columnname = 'SCOPE'.                 lr_column->set_short_text( 'Scope'(c04) ).                 lr_column->set_medium_text( 'Scope'(c04) ).                 lr_column->set_long_text( 'Scope'(c04) ).               ENDIF.               IF ls_column_ref-columnname = 'REMOTE'.                 IF v_rfc IS INITIAL.                   lr_column->set_visible( if_salv_c_bool_sap=>false ).                 ELSE.                   lr_column->set_short_text( 'Remote'(c01) ).                   lr_column->set_medium_text( 'Remote'(c01) ).                   lr_column->set_long_text( 'Remote'(c01) ).                 ENDIF.               ENDIF.             ENDLOOP.
*---------- Register ALV Events ----------*             lr_events = o_objects->get_event( ).             SET HANDLER on_user_command FOR lr_events.             SET HANDLER on_double_click FOR lr_events.
*---------- Display Objects ALV ----------*             o_objects->display( ).           CATCH cx_root.                                 "#EC CATCH_ALL             MESSAGE s398(00) WITH 'Critical error'(m03) space space space DISPLAY LIKE 'E'.         ENDTRY.       ELSE. "Refresh ALV         o_objects->refresh( ).       ENDIF.     ENDIF.   ENDMETHOD.                    "display_objects
*--------------- Public Handler On User Command Handler Implementation *   METHOD on_user_command.     CHECK e_salv_function = 'TR'.  "Create transport request     DATA lr_selections TYPE REF TO cl_salv_selections. "ALV Selections     DATA:       lt_rows       TYPE salv_t_row,          "ALV Rows       ls_row        TYPE i,       lt_e071_temp  TYPE TABLE OF e071,       "Change & Transport System: Object Entries of Requests/Tasks       ls_e071       LIKE LINE OF t_e071,       lt_e071k_temp TYPE TABLE OF e071k,       lt_objects    TYPE TABLE OF ty_objects, "Objects to transport       ls_object     LIKE LINE OF t_objects,       lt_targets    TYPE TABLE OF tr_target,  "Transport Target of Request       ls_target     LIKE LINE OF lt_targets.     DATA:       lv_order TYPE trkorr, "Request/Task       lv_task  TYPE trkorr.
*---------- Get selected lines ----------*     lr_selections = o_objects->get_selections( ).     lt_rows = lr_selections->get_selected_rows( ).
*---------- Get selected objects to transport ----------*     LOOP AT lt_rows INTO ls_row.       READ TABLE t_objects INTO ls_object INDEX ls_row.       IF sy-subrc IS INITIAL AND ls_object-scope = icon_transport AND ( ls_object-status = icon_led_yellow OR ls_object-status = icon_led_green ).         IF ls_object-devclass = c_temp.           MESSAGE i398(00) WITH 'Request canceled, object with $TEMP detected'(m10) space space space DISPLAY LIKE 'E'.           RETURN.         ENDIF.         APPEND ls_object TO lt_objects.         MOVE-CORRESPONDING ls_object TO ls_e071.         APPEND ls_e071 TO t_e071.         IF ls_object-object = c_tobj. "Add TABU object directly to the transport           add_tobj_content( i_obj_name = ls_object-obj_name ).  "Object Name in Object Directory         ENDIF.       ENDIF.     ENDLOOP.
*---------- Get possible target ----------*     LOOP AT lt_objects INTO ls_object.       ls_target = ls_object-target.       APPEND ls_target TO lt_targets.     ENDLOOP.     SORT lt_targets.     DELETE ADJACENT DUPLICATES FROM lt_targets.
*---------- Create transport request and task ----------*     IF lt_objects IS NOT INITIAL. "Objects selected to transport       IF lines( lt_targets ) = 1. "Only one valid target         CALL FUNCTION 'TRINT_ORDER_CHOICE'  "Create transport request           EXPORTING             iv_tarsystem           = ls_target           IMPORTING             we_order               = lv_order             we_task                = lv_task           TABLES             wt_e071                = lt_e071_temp             wt_e071k               = lt_e071k_temp           EXCEPTIONS             no_correction_selected = 1             display_mode           = 2             object_append_error    = 3             recursive_call         = 4             wrong_order_type       = 5             OTHERS                 = 6.         IF sy-subrc IS INITIAL AND lv_task IS NOT INITIAL.           ls_e071-pgmid    = c_r3tr.  "Add objects development class to transport           ls_e071-object   = c_devc.           ls_e071-obj_name = ls_object-devclass.           APPEND ls_e071 TO t_e071.           CALL FUNCTION 'TRINT_APPEND_COMM' "Add object to transport request             EXPORTING               wi_exclusive       = abap_false               wi_sel_e071        = abap_true               wi_sel_e071k       = abap_true               wi_trkorr          = lv_task             TABLES               wt_e071            = t_e071               wt_e071k           = t_e071k             EXCEPTIONS               e071k_append_error = 1               e071_append_error  = 2               trkorr_empty       = 3               OTHERS             = 4.           IF sy-subrc IS INITIAL. "Added with sucess
*---------- Sort and compress request --------*             CALL FUNCTION 'TR_SORT_AND_COMPRESS_COMM' "#EC FB_RC   "#EC CI_SUBRC               EXPORTING                 iv_trkorr                      = lv_task               EXCEPTIONS                 trkorr_not_found               = 1                 order_released                 = 2                 error_while_modifying_obj_list = 3                 tr_enqueue_failed              = 4                 no_authorization               = 5                 OTHERS                         = 6.             MESSAGE i001(00) WITH 'Objects added to request ('(m07) lv_order ')' space.           ELSE.             MESSAGE s398(00) WITH 'Error creating transport request'(m06) space space space DISPLAY LIKE 'E'.           ENDIF.         ELSE.           MESSAGE s398(00) WITH 'Transport canceled'(m12) space space space DISPLAY LIKE 'W'.         ENDIF.       ELSE.         MESSAGE i398(00) WITH 'Transport not allowed for multiple targets'(m05) space space space.       ENDIF.     ELSE.       MESSAGE i398(00) WITH 'No objects selected'(m04) space space space.     ENDIF.   ENDMETHOD.                    "on_user_command
*----------------------- Public Handler On Double Click Implementation *   METHOD on_double_click.     DATA ls_object LIKE LINE OF t_objects.  "Objects to transport     READ TABLE t_objects INTO ls_object INDEX row.  "Get selected Row     IF sy-subrc IS INITIAL.       IF column = 'DEVCLASS' OR column = 'TARGET'.  "Call Development Package         IF ls_object-devclass IS NOT INITIAL.           SET PARAMETER ID 'PACKNAME' FIELD ls_object-devclass.           CALL TRANSACTION 'SE21' AND SKIP FIRST SCREEN. "#EC CI_CALLTA         ENDIF.       ELSE.
*---------- Display objects ----------*         CASE ls_object-object.           WHEN c_tobj.  "Display Tables Maintenance             SET PARAMETER ID 'DVI' FIELD ls_object-obj_name.             CALL TRANSACTION 'SE54'.                     "#EC CI_CALLTA           WHEN c_chdo.  "Display change documents             CALL TRANSACTION 'SCDO'.                     "#EC CI_CALLTA           WHEN OTHERS.  "Display all             CALL FUNCTION 'RS_TOOL_ACCESS'               EXPORTING                 operation           = 'SHOW'                 object_name         = ls_object-obj_name                 object_type         = ls_object-object               EXCEPTIONS                 not_executed        = 1                 invalid_object_type = 2                 OTHERS              = 3.             IF sy-subrc IS NOT INITIAL.               MESSAGE s398(00) WITH 'Navigation not suported'(m11) space space space DISPLAY LIKE 'W'.             ENDIF.         ENDCASE.       ENDIF.     ENDIF.   ENDMETHOD.                    "on_double_click
*-------------------------- Private Method Progress Bar Implementation *   METHOD progress_bar.     DATA:       lv_text(40),       lv_percentage TYPE p,       lv_percent_char(3).     lv_percentage = ( i_tabix / 100 ) * 100.     lv_percent_char = lv_percentage.     SHIFT lv_percent_char LEFT DELETING LEADING ' '.     CONCATENATE i_value '...' INTO i_value.     CONCATENATE i_value lv_percent_char '% Complete'(pb1) INTO lv_text SEPARATED BY space.     IF lv_percentage GT v_percent OR i_tabix = 1.       CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'         EXPORTING           percentage = lv_percentage           text       = lv_text.       v_percent = lv_percentage.     ENDIF.   ENDMETHOD.                    "progress_bar
*------------------- Private Method Execute Add Objects Implementation *   METHOD execute_add_objects.     DATA ls_env_dummy  TYPE senvi.     CASE v_object.
*---------- Development class ----------*       WHEN c_devc.         add_objects_of_devclass( i_obj_n = v_obj_n  "Object Name in Object Directory                                  i_deep  = '0' ).   "Deepness
*---------- All others object ----------*       WHEN OTHERS.         check_add_object( i_pgmid    = v_pgmid      "Program ID in Requests and Tasks                           i_object   = v_object     "Object Type                           i_obj_n    = v_obj_n      "Object Name in Object Directory                           is_env_tab = ls_env_dummy "Info system                           i_deep     = '0' ).       "Deepness     ENDCASE.   ENDMETHOD.                    "execute_add_objects
*------------ Private Method Execute Add from Transport Implementation *   METHOD execute_add_from_transport.     DATA:       lt_request_headers TYPE trwbo_request_headers,  "Context of a request       ls_request_headers TYPE trwbo_request_header,       lt_objects         TYPE tr_objects,             "Objects       ls_object          TYPE e071,                   "Object Entries of Requests/Tasks       ls_env_dummy       TYPE senvi.                  "System Info Environement
*---------- Read Requests and Tasks ----------*     CALL FUNCTION 'TR_READ_REQUEST_WITH_TASKS'       EXPORTING         iv_trkorr          = v_tr       IMPORTING         et_request_headers = lt_request_headers       EXCEPTIONS         invalid_input      = 1         OTHERS             = 2.     IF sy-subrc IS NOT INITIAL.       MESSAGE e398(00) WITH 'Error treating transport request'(m15) space space space DISPLAY LIKE 'W'.     ENDIF.
*---------- Read objects inside main request ----------*     READ TABLE lt_request_headers INTO ls_request_headers WITH KEY trfunction = 'K'.     IF sy-subrc IS NOT INITIAL.       MESSAGE e398(00) WITH 'Error treating transport request'(m15) space space space DISPLAY LIKE 'W'.     ENDIF.     CALL FUNCTION 'TR_GET_OBJECTS_OF_REQ_AN_TASKS'       EXPORTING         is_request_header      = ls_request_headers         iv_condense_objectlist = 'X'       IMPORTING         et_objects             = lt_objects       EXCEPTIONS         invalid_input          = 1         OTHERS                 = 2.     IF sy-subrc IS NOT INITIAL.       MESSAGE e398(00) WITH 'Error treating transport request'(m15) space space space DISPLAY LIKE 'W'.     ENDIF.     CALL FUNCTION 'TR_SORT_OBJECT_AND_KEY_LIST'       CHANGING         ct_objects = lt_objects.     LOOP AT lt_objects INTO ls_object.  "Add found objects to processing       check_add_object( i_pgmid    = ls_object-pgmid    "Program ID in Requests and Tasks                         i_object   = ls_object-object   "Object Type                         i_obj_n    = ls_object-obj_name "Object Name in Object Directory                         is_env_tab = ls_env_dummy       "Info system                         i_deep     = '0' ).             "Deepness     ENDLOOP.   ENDMETHOD.                    "execute_add_from_transport
*---------------------- Private Method Check Add Object Implementation *   METHOD check_add_object.     DATA lo_wb_object TYPE REF TO cl_wb_object. "Repository Object     DATA:       ls_tadir          TYPE tadir,             "Directory of Repository Objects       ls_wb_object_type TYPE wbobjtype,         "Global WB Type       ls_object         LIKE LINE OF t_objects. "Objects to transport line     DATA:       lv_tr_object   TYPE trobjtype,  "Object Type       lv_tr_obj_name TYPE trobj_name, "Object Name in Object List       lv_trans_pgmid TYPE pgmid.      "Program ID in Requests and Tasks
*---------- Object convertions ----------*     IF i_pgmid <> c_r3tr.       SELECT pgmid UP TO 1 ROWS FROM tadir              "#EC CI_GENBUFF         INTO i_pgmid        WHERE object   = i_object          AND obj_name = i_obj_n.       ENDSELECT.
*---------- Is not a TADIR object and Conversion required ----------*       IF sy-subrc IS NOT INITIAL.         lv_tr_object   = i_object.         lv_tr_obj_name = i_obj_n.         cl_wb_object=>create_from_transport_key( EXPORTING p_object                = lv_tr_object                                                            p_obj_name              = lv_tr_obj_name                                                  RECEIVING p_wb_object             = lo_wb_object                                                 EXCEPTIONS objecttype_not_existing = 1                                                            empty_object_key        = 2                                                            key_not_available       = 3                                                            OTHERS                  = 4 ).         IF sy-subrc IS INITIAL.           lo_wb_object->get_global_wb_key( IMPORTING p_object_type     = ls_wb_object_type                                           EXCEPTIONS key_not_available = 1                                                      OTHERS            = 2 ).           IF sy-subrc IS INITIAL.             lo_wb_object->get_transport_key( IMPORTING p_pgmid           = lv_trans_pgmid "#EC CI_SUBRC                                             EXCEPTIONS key_not_available = 1                                                        OTHERS            = 2 ).
*---------- Check Program ID ----------*             CASE lv_trans_pgmid.               WHEN c_r3tr.  "Main objects                 i_pgmid = lv_trans_pgmid.               WHEN 'LIMU'.  "Sub object                 CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ'                   EXPORTING                     p_limu_objtype = lv_tr_object                     p_limu_objname = lv_tr_obj_name                   IMPORTING                     p_r3tr_objtype = lv_tr_object                     p_r3tr_objname = lv_tr_obj_name                   EXCEPTIONS                     no_mapping     = 1                     OTHERS         = 2.                 IF sy-subrc IS INITIAL.                   ls_object-pgmid    = c_r3tr.                   ls_object-object   = lv_tr_object.                   ls_object-obj_name = lv_tr_obj_name.                   add_object( EXPORTING i_deep    = i_deep        "Deepness                                CHANGING cs_object = ls_object ).  "Objects table                   RETURN.                 ENDIF.               WHEN OTHERS.  "Include objects                 i_pgmid = c_r3tr.                 CALL FUNCTION 'GET_TADIR_TYPE_FROM_WB_TYPE'                   EXPORTING                     wb_objtype        = ls_wb_object_type-subtype_wb                   IMPORTING                     transport_objtype = lv_tr_object                   EXCEPTIONS                     no_mapping_found  = 1                     no_unique_mapping = 2                     OTHERS            = 3.                 IF sy-subrc IS INITIAL.                   i_object = lv_tr_object.                   IF is_env_tab-encl_obj IS NOT INITIAL.                     i_obj_n = is_env_tab-encl_obj.                   ENDIF.                 ENDIF.             ENDCASE.           ENDIF.         ENDIF.       ENDIF.     ENDIF.
*---------- Check in TADIR ----------*     SELECT SINGLE * FROM tadir       INTO ls_tadir      WHERE pgmid    = i_pgmid        AND object   = i_object        AND obj_name = i_obj_n.
*---------- Add object ----------*     IF ls_tadir IS NOT INITIAL.       MOVE-CORRESPONDING ls_tadir TO ls_object.
*---------- Set SAP Generated object status ----------*       IF ls_tadir-genflag IS NOT INITIAL.         ls_object-status = icon_generate.       ENDIF.
*---------- Add object to be checked ----------*       add_object( EXPORTING i_deep    = i_deep        "Deepness                    CHANGING cs_object = ls_object ).  "Objects table
*---------- Error Object not valid ----------*     ELSE.       IF lines( t_objects ) > 0. "Skip first object         ls_object-pgmid    = i_pgmid.         ls_object-object   = i_object.         ls_object-obj_name = i_obj_n.         ls_object-status   = icon_led_red.         add_object( EXPORTING i_deep    = i_deep        "Deepness                      CHANGING cs_object = ls_object ).  "Objects table       ENDIF.     ENDIF.   ENDMETHOD.                    "check_add_object
*--- Private Method Add Object from Development Package Implementation *   METHOD add_objects_of_devclass.     DATA:       ls_env_dummy  TYPE senvi,       lt_objectlist TYPE TABLE OF rseui_set,  "Transfer table (object list) - info system       ls_objectlist LIKE LINE OF lt_objectlist.     DATA:       lv_devclass TYPE devclass,  "Package       lv_deep     TYPE i.         "Deepness
*---------- Get Development Package Objects ----------*     lv_devclass = i_obj_n.     CALL FUNCTION 'RS_GET_OBJECTS_OF_DEVCLASS' "#EC FB_RC  "#EC CI_SUBRC       EXPORTING         devclass            = lv_devclass       TABLES         objectlist          = lt_objectlist       EXCEPTIONS         no_objects_selected = 1         OTHERS              = 2.
*---------- Add found objects  ----------*     LOOP AT lt_objectlist INTO ls_objectlist.       lv_deep = i_deep.       IF ls_objectlist-obj_name <> lv_devclass.         ADD 1 TO lv_deep.       ENDIF.       check_add_object( i_pgmid    = c_r3tr                 "Program ID in Requests and Tasks                         i_object   = ls_objectlist-obj_type "Object Type                         i_obj_n    = ls_objectlist-obj_name "Object Name in Object Directory                         is_env_tab = ls_env_dummy           "Info system                         i_deep     = lv_deep ).             "Deepness     ENDLOOP.   ENDMETHOD.                    "add_objects_of_devclass
*---------------------------- Private Method Add Object Implementation *   METHOD add_object.     DATA:        ls_objs_desc LIKE LINE OF t_objs_desc, "Objects prograns ID line"Info Environment        lt_devclass  TYPE scts_devclass,       "Development Packages        ls_devclass  TYPE trdevclass.     DATA:       lv_object    TYPE trobjtype,  "Object Type       lv_objname   TYPE sobj_name,  "Object Name in Object Directory       lv_namespace TYPE namespace.  "Object Namespace
*---------- Check if already added ----------*     READ TABLE t_objects TRANSPORTING NO FIELDS WITH KEY pgmid    = cs_object-pgmid                                                          object   = cs_object-object                                                          obj_name = cs_object-obj_name.     IF sy-subrc IS NOT INITIAL. "New object
*---------- Check if is customer objects ----------*       lv_object  = cs_object-object.       lv_objname = cs_object-obj_name.       CALL FUNCTION 'TRINT_GET_NAMESPACE'      "#EC FB_RC "#EC CI_SUBRC         EXPORTING           iv_pgmid            = cs_object-pgmid           iv_object           = lv_object           iv_obj_name         = lv_objname         IMPORTING           ev_namespace        = lv_namespace         EXCEPTIONS           invalid_prefix      = 1           invalid_object_type = 2           OTHERS              = 3.       IF lv_namespace = '/0CUST/' OR v_st IS NOT INITIAL.  "Is customer object
*---------- Read object description ----------*         READ TABLE t_objs_desc INTO ls_objs_desc WITH KEY object = cs_object-object.         IF sy-subrc IS INITIAL.           cs_object-obj_desc = ls_objs_desc-text.  "Object type description         ENDIF.
*---------- Read development class tecnical information ----------*         IF cs_object-devclass IS INITIAL.           SELECT SINGLE devclass FROM tadir             INTO cs_object-devclass            WHERE pgmid    = cs_object-pgmid              AND object   = cs_object-object              AND obj_name = cs_object-obj_name.         ENDIF.         IF cs_object-devclass IS NOT INITIAL AND cs_object-devclass <> c_temp.           ls_devclass-devclass = cs_object-devclass.           APPEND ls_devclass TO lt_devclass.           CALL FUNCTION 'TR_READ_DEVCLASSES'             EXPORTING               it_devclass = lt_devclass             IMPORTING               et_devclass = lt_devclass.           READ TABLE lt_devclass INTO ls_devclass INDEX 1.           IF sy-subrc IS INITIAL.             cs_object-target = ls_devclass-target.  "Development package target           ENDIF.         ENDIF.
*---------- Add object deepness ----------*         IF cs_object-deep IS INITIAL.           cs_object-deep = i_deep.         ENDIF.
*---------- Add object scope ----------*         IF lv_namespace = '/0CUST/' AND cs_object-target IS NOT INITIAL.           cs_object-scope = icon_transport.         ENDIF.
*---------- Add object to transport ----------*         APPEND cs_object TO t_objects.       ENDIF.     ENDIF.   ENDMETHOD.                    "add_object
*------------ Private Method Objects Dependencies Check Implementation *   METHOD objects_dependencies_check.     DATA:       lt_env_tab  TYPE TABLE OF senvi,  "Object to check dependencies       ls_env_tab  TYPE senvi.           "Info Environment     DATA:       lv_obj_type TYPE seu_obj,   "Object type       lv_no_rfc   TYPE abap_bool, "RFC Flag       lv_deep     TYPE i,         "Actual Deepness       lv_tcode    TYPE tcode.     "Transaction Code     FIELD-SYMBOLS <ls_object> LIKE LINE OF t_objects.  "Objects to transport     LOOP AT t_objects ASSIGNING <ls_object> WHERE status IS INITIAL.
*---------- Check if Transaction exist ----------*       IF <ls_object>-object = 'PROG'.         CLEAR lv_tcode.         SELECT tcode FROM tstc UP TO 1 ROWS "#EC CI_SEL_NESTED "#EC CI_GENBUFF           INTO lv_tcode          WHERE pgmna = <ls_object>-obj_name.         ENDSELECT.         IF sy-subrc IS INITIAL.           check_add_object( i_pgmid    = c_r3tr         "Program ID in Requests and Tasks                             i_object   = 'TRAN'         "Object Type                             i_obj_n    = lv_tcode       "Object Name in Object Directory                             is_env_tab = ls_env_tab     "Info system                             i_deep     = lv_deep + 1 ). "Deepness         ENDIF.       ENDIF.
*---------- Check deepness ----------*       lv_deep = <ls_object>-deep + 1. "Set Deepness       IF v_deep IS NOT INITIAL AND lv_deep > v_deep.         <ls_object>-status = icon_led_yellow.  "Status checked         CONTINUE.       ENDIF.
*---------- Exclude RFCs if exist ----------*       IF v_erfc IS NOT INITIAL AND <ls_object>-object = c_fugr.         CLEAR lv_no_rfc.         exclude_rfcs( EXPORTING i_obj_name = <ls_object>-obj_name "Object Name in Object Directory                        CHANGING c_no_rfc   = lv_no_rfc ).         "Found RFC Flag         IF lv_no_rfc IS INITIAL.           <ls_object>-status = icon_led_red.           CONTINUE.         ENDIF.       ENDIF.
*---------- Get object dependecies ----------*       REFRESH lt_env_tab.       lv_obj_type = <ls_object>-object.       CALL FUNCTION 'REPOSITORY_ENVIRONMENT_RFC'         EXPORTING           obj_type        = lv_obj_type           object_name     = <ls_object>-obj_name         TABLES           environment_tab = lt_env_tab.       IF lines( lt_env_tab ) IS INITIAL AND lines( t_objects ) = 1.         MESSAGE s398(00) WITH 'Object dependencies check not support'(m13) space space space DISPLAY LIKE 'E'.         <ls_object>-status = icon_led_red.       ELSE.         DELETE lt_env_tab WHERE type   = lv_obj_type                             AND object = <ls_object>-obj_name.
*---------- Add founded dependecies ----------*         LOOP AT lt_env_tab INTO ls_env_tab.              "#EC CI_NESTED           CASE ls_env_tab-type.             WHEN c_devc.  "Add from Development class               add_objects_of_devclass( i_obj_n = ls_env_tab-object  "Object Name in Object Directory                                        i_deep  = lv_deep ).         "Deepness             WHEN OTHERS.  "Add all others object               check_add_object( i_pgmid    = space              "Program ID in Requests and Tasks                                 i_object   = ls_env_tab-type    "Object Type                                 i_obj_n    = ls_env_tab-object  "Object Name in Object Directory                                 is_env_tab = ls_env_tab         "Info system                                 i_deep     = lv_deep ).         "Deepness           ENDCASE.         ENDLOOP.         <ls_object>-status = icon_led_green.  "Status checked       ENDIF.     ENDLOOP.   ENDMETHOD.                    "objects_dependencies_check
*------------------ Private Method Remote Objects Check Implementation *   METHOD remote_objects_check.     DATA:       ls_e071 TYPE e071,          "Change & Transport System: Object Entries of Requests/Tasks       lt_vrso TYPE TABLE OF vrso, "Version control: Object list (subset of VRSD)       ls_vrso LIKE LINE OF lt_vrso.     DATA:       lv_diagnosis(20),                 "Version check result       lv_local_rfc_dest  TYPE rfcdest,  "Logical Destinations       lv_remote_rfc_dest TYPE rfcdest.     FIELD-SYMBOLS <ls_object> LIKE LINE OF t_objects. "Objects to transport
*---------- Get local rfc destination ----------*     SELECT desadm FROM tmscsys UP TO 1 ROWS             "#EC CI_NOFIRST       INTO lv_local_rfc_dest      WHERE sysnam = sy-sysid.     ENDSELECT.
*---------- Get remote rfc destination ----------*     SELECT desadm FROM tmscsys UP TO 1 ROWS             "#EC CI_NOFIRST       INTO lv_remote_rfc_dest      WHERE sysnam = v_rfc_d.     ENDSELECT.
*---------- Check objects versions ----------*     IF lv_local_rfc_dest IS NOT INITIAL AND lv_remote_rfc_dest IS NOT INITIAL.       LOOP AT t_objects ASSIGNING <ls_object>.
*---------- Get Sub Objects ----------*         ls_e071-object   = <ls_object>-object.         ls_e071-obj_name = <ls_object>-obj_name.         REFRESH lt_vrso.         CALL FUNCTION 'TRINT_RESOLVE_OBJ'           EXPORTING             is_e071             = ls_e071           TABLES             et_vrso             = lt_vrso           EXCEPTIONS             not_versionable     = 1             communication_error = 2             OTHERS              = 3.         IF sy-subrc IS INITIAL.
*---------- Remote check all objects and subobjects ----------*           LOOP AT lt_vrso INTO ls_vrso WHERE objtype <> 'DOCU'. "#EC CI_NESTED             CLEAR lv_diagnosis.             CALL FUNCTION 'TRINT_COMP_VERSION'               EXPORTING                 is_vrso          = ls_vrso                 dest1            = lv_local_rfc_dest                 dest2            = lv_remote_rfc_dest               IMPORTING                 ev_diagnosis     = lv_diagnosis               EXCEPTIONS                 rfc_error_loc    = 1                 rfc_error_rem    = 2                 intern_error_loc = 3                 intern_error_rem = 4                 OTHERS           = 5.             IF sy-subrc IS INITIAL.               CASE lv_diagnosis.                 WHEN 0.                   <ls_object>-remote = 'Equal'(o01).                 WHEN 1.                   <ls_object>-remote = 'Different'(o02).                   EXIT.                 WHEN 3.                   <ls_object>-remote = 'New'(o03).                   EXIT.               ENDCASE.             ENDIF.           ENDLOOP.         ELSE.           <ls_object>-remote = 'No version'(o04).         ENDIF.       ENDLOOP.     ELSE.       MESSAGE s398(00) WITH 'RFCs destinations missing'(m09) space space space DISPLAY LIKE 'W'.     ENDIF.   ENDMETHOD.                    "remote_objects_check
*-------------------------- Private Method Exclude RFCs Implementation *   METHOD exclude_rfcs.     DATA lt_fbinfo_remote TYPE TABLE OF fbinfor.  "Function Module Information     DATA lv_complete_area TYPE rs38l_area.        "Function group, to which the function module belongs
*---------- Check if all are RFCs ----------*     lv_complete_area = i_obj_name.     CALL FUNCTION 'FUNCTION_SELECT_TFDIR'      "#EC FB_RC "#EC CI_SUBRC       EXPORTING         im_complete_area        = lv_complete_area       IMPORTING         ex_fbinfo_remote        = lt_fbinfo_remote       EXCEPTIONS         include_not_found_trdir = 1         report_source_not_found = 2         permission_failure      = 3         OTHERS                  = 4.     LOOP AT lt_fbinfo_remote TRANSPORTING NO FIELDS WHERE remote <> 'R'.       c_no_rfc = abap_true. "One function found that are not RFCs       EXIT.     ENDLOOP.   ENDMETHOD.                    "exclude_rfcs
*------------------ Private Method Include Maintenances Implementation *   METHOD include_maintenances.     DATA:       ls_tvdir      TYPE tvdir,             "View Directory       ls_object     LIKE LINE OF t_objects, "Objects to transport line       ls_object_add LIKE LINE OF t_objects.     DATA:       lv_obj_type,                  "Object type       lv_tobj_name  TYPE sobj_name, "Object Name in Object Directory       lv_objectname TYPE ob_object. "Object Name     LOOP AT t_objects INTO ls_object WHERE object = c_tabl AND status = icon_led_green.       CLEAR ls_tvdir.       SELECT SINGLE * FROM tvdir                     "#EC CI_SEL_NESTED         INTO ls_tvdir        WHERE tabname = ls_object-obj_name.       IF sy-subrc IS INITIAL.
*---------- Add Function Group if exist ----------*         ls_object_add-pgmid    = c_r3tr.         ls_object_add-object   = c_fugr.         ls_object_add-obj_name = ls_tvdir-area.         add_object( EXPORTING i_deep    = ls_object-deep + 1  "Deepness                      CHANGING cs_object = ls_object_add ).    "Objects table         IF ls_tvdir-bastab IS INITIAL. lv_obj_type = 'V'. ELSE. lv_obj_type = 'S'. ENDIF.
*---------- Add Definition of a Maintenance and Transport Object ----------*         CLEAR lv_tobj_name.         lv_objectname = ls_object-obj_name.         CALL FUNCTION 'CTO_OBJECT_GET_TADIR_KEY'           EXPORTING             iv_objectname = lv_objectname             iv_objecttype = lv_obj_type           IMPORTING             ev_obj_name   = lv_tobj_name.         ls_object_add-pgmid    = c_r3tr.         ls_object_add-object   = c_tobj.         ls_object_add-obj_name = lv_tobj_name.         ls_object_add-status   = icon_led_green.         add_object( EXPORTING i_deep    = ls_object-deep + 1  "Deepness                      CHANGING cs_object = ls_object_add ).    "Objects table       ENDIF.     ENDLOOP.   ENDMETHOD.                    "include_maintenances
*------------------------- Private Method Include Locks Implementation *   METHOD include_locks.     DATA:       ls_object     LIKE LINE OF t_objects,  "Objects to transport line       ls_object_add LIKE LINE OF t_objects.     DATA lv_viewname TYPE viewname. "Maintenance view name
*---------- Add lock objects if exist ----------*     LOOP AT t_objects INTO ls_object WHERE object = c_tabl AND status = icon_led_green.       CLEAR lv_viewname.       SELECT viewname FROM dd25l UP TO 1 ROWS "#EC CI_SEL_NESTED "#EC CI_NOFIRST         INTO lv_viewname        WHERE aggtype = 'E'          AND roottab = ls_object-obj_name.       ENDSELECT.       IF sy-subrc IS INITIAL.         ls_object_add-pgmid    = c_r3tr.         ls_object_add-object   = 'ENQU'.         ls_object_add-obj_name = lv_viewname.         ls_object_add-status   = icon_led_green.         add_object( EXPORTING i_deep    = ls_object-deep + 1  "Deepness                      CHANGING cs_object = ls_object_add ).    "Objects table       ENDIF.     ENDLOOP.   ENDMETHOD.                    "include_locks
*--------------------------- Private Method Include CDs Implementation *   METHOD include_cds.     DATA:       ls_object     LIKE LINE OF t_objects,  "Objects to transport line       ls_object_add LIKE LINE OF t_objects.     DATA lv_object TYPE cdobjectcl. "Object class
*---------- Add change document object if exist ----------*     LOOP AT t_objects INTO ls_object WHERE object = c_tabl AND status = icon_led_green.       CLEAR lv_object.       SELECT object FROM tcdob UP TO 1 ROWS "#EC CI_SEL_NESTED "#EC CI_GENBUFF         INTO lv_object        WHERE tabname = ls_object-obj_name.       ENDSELECT.       IF sy-subrc IS INITIAL.         ls_object_add-pgmid    = c_r3tr.         ls_object_add-object   = c_chdo.         ls_object_add-obj_name = lv_object.         ls_object_add-status   = icon_led_green.         add_object( EXPORTING i_deep = ls_object-deep + 1   "Deepness                      CHANGING cs_object = ls_object_add ).  "Objects table       ENDIF.     ENDLOOP.   ENDMETHOD.                    "include_cds
*---------------------- Private Method Add TOBJ Content Implementation *   METHOD add_tobj_content.     CONSTANTS:       lc_tabu  TYPE trobjtype VALUE 'TABU',       lc_tvdir TYPE sobj_name VALUE 'TVDIR',       lc_tddat TYPE sobj_name VALUE 'TDDAT',       lc_tvimf TYPE sobj_name VALUE 'TVIMF'.     DATA:       lt_tvimf TYPE TABLE OF tvimf,   "User routines called from view maintenance       ls_tvimf LIKE LINE OF lt_tvimf.     DATA lv_tabkey TYPE tabkey.  "Table Key
*---------- Add table content ----------*     add_object_header( i_pgmid   = c_r3tr   "Program ID in Requests and Tasks                        i_object  = lc_tabu  "Object Type                        i_obj_n   = lc_tvdir "Object Name in Object Directory                        i_objfunc = 'K' ).   "Object function     add_object_keys( i_pgmid  = c_r3tr        "Program ID in Requests and Tasks                      i_object = lc_tabu       "Object Type                      i_obj_n  = lc_tvdir      "Object Name in Object Directory                      i_tabkey = i_obj_name ). "Table Key     CLEAR lt_tvimf. "Read User routines called from view maintenance     SELECT * FROM tvimf                                 "#EC CI_GENBUFF       INTO TABLE lt_tvimf      WHERE tabname = i_obj_name.     LOOP AT lt_tvimf INTO ls_tvimf.       AT FIRST.         add_object_header( i_pgmid  = c_r3tr    "Program ID in Requests and Tasks                            i_object  = lc_tabu  "Object Type                            i_obj_n   = lc_tvimf "Object Name in Object Directory                            i_objfunc = 'K' ).   "Object function       ENDAT.       lv_tabkey    = i_obj_name.       lv_tabkey+30 = ls_tvimf-event.       add_object_keys( i_pgmid  = c_r3tr        "Program ID in Requests and Tasks                        i_object = lc_tabu       "Object Type                        i_obj_n  = lc_tvimf      "Object Name in Object Directory                        i_tabkey = lv_tabkey ).  "Table Key       CLEAR lv_tabkey.     ENDLOOP.     add_object_header( i_pgmid   = c_r3tr   "Program ID in Requests and Tasks                        i_object  = lc_tabu  "Object Type                        i_obj_n   = lc_tddat "Object Name in Object Directory                        i_objfunc = 'K' ).   "Object function     add_object_keys( i_pgmid  = c_r3tr        "Program ID in Requests and Tasks                      i_object = lc_tabu       "Object Type                      i_obj_n  = lc_tddat      "Object Name in Object Directory                      i_tabkey = i_obj_name ). "Table Key   ENDMETHOD.                    "add_tobj_content
*--------------------- Private Method Add Object Header Implementation *   METHOD add_object_header.     DATA ls_e071 LIKE LINE OF t_e071.     READ TABLE t_e071 TRANSPORTING NO FIELDS WITH KEY pgmid    = i_pgmid                                                       object   = i_object                                                       obj_name = i_obj_n                                                       objfunc  = i_objfunc.     IF sy-subrc IS NOT INITIAL.       ls_e071-pgmid    = i_pgmid.       ls_e071-object   = i_object.       ls_e071-obj_name = i_obj_n.       ls_e071-objfunc  = i_objfunc.       APPEND ls_e071 TO t_e071.     ENDIF.   ENDMETHOD.                    "add_object_header
*----------------------- Private Method Add Object Keys Implementation *   METHOD add_object_keys.     DATA ls_e071k LIKE LINE OF t_e071k.     ls_e071k-pgmid      = i_pgmid.     ls_e071k-object     = i_object.     ls_e071k-objname    = i_obj_n.     ls_e071k-mastertype = i_object.     ls_e071k-mastername = i_obj_n.     ls_e071k-tabkey     = i_tabkey.     APPEND ls_e071k TO t_e071k.   ENDMETHOD.                    "add_object_keys
ENDCLASS.                    "obj_dep_trans IMPLEMENTATION


Selection screen layout after implementation:

Untitled.png

Result objects list layout:

Untitled.png

Please consider before using:

  • This tool is not full tested and is not possible to ensure that all repository workbench objects can be checked or dependencies detected. Please give feedback if you notice missing objects to be improved.
  • ZNM_OBJS_DEP_TRANS works with most common and used objects. Exotic objects like Sapscript, Smart forms, IDOCs, Workflows and others for the moment are not fully supported.
  • For complex and big developments you should use it as an auxiliary tool and kept in mind that your brain is still needed to validate and create coherent transports.
  • You should have some technical background and ABAP knowledge to use and understand how to take full advantage of it.
  • Dependencies result objects list only includes main objects to be transported. This mean that for example if a function module and/or class method are detected the full function group and class are included and not their sub-objects. The same for special SAP code generated objects, only main objects are included because they are generated at import step and should not be transported.
  • Development packages and tables data are not displayed on dependencies result list and are added directly to transport request.

How to use:

  • Fill object selection using main objects like Tables, Programs, Classes, Functions Groups, development packages, etc to be checked.

Example to check dependencies in program ZNM_OBJS_DEP_TRANS:

          Untitled.png

If you don't know the key of the object you what to check on each ABAP object editor open menu Go To and select Object Directory Entry:

ex1.png

  • Check from existent transport request:

Untitled.png

  • If needed please define the dependence deepness or kept black or 0 to check all:

Untitled.png

  • To detected objects changes in destination system please flag Cross-system objects version check:

         ex2.png

  • Include Standard objects option can lean to performance problems:

Untitled.png

  • Flag additional options if needed to include or exclude specials objects:

          ex9.png

    • Include Tables Maintenances: If exist in detected tables function groups and related table maintenance objects are included;
    • Include Tables Locks: If exist in detected tables lock objects are included;
    • Include Tables CDs: If exist in detected tables change documents are included;
    • Exclude RFCs if exist: Depending of your SAP systems landscape this option can be useful to exclude RFCs functions modules.


  • Double click rows to direct object editor navigation:

Untitled.png

  • Select lines and click button ex1.png to create or add objects to transport request.

 

Nuno Morais's Blog

 

Nuno Morais | LinkedIn

CREATING DYNAMIC TEMPLATES IN SMART FORMS.

$
0
0

The common problem while using the template for address or header information is that when the data is not available for that particular column the line appears blank. This problem can be avoided as seen in SAP SCRIPTS by using SCRIPT CONTROL COMMAND <IF>…<END IF>.Unfortunately the same cannot be done while designing TEMPLATES in SMART FORMS.

 

One way to avoid this is by using TABLES without data option i.e. by UN-checking the Internal table option as shown below in the screenshot.


                        Image1.JPG

By doing so our table becomes and behaves like a dynamic template.


Steps to Design Dynamic Template.


Step-1.  Create a sample smart form  & add the interface fields as shown below.


                         Image2.JPG


Step-2. Create a secondary window to place your dynamic template as shown below.

 

                                 Image4.JPG

 

Step-3.  Create LINE TYPES with required columns to be displayed. Shown below is the dynamic template created for testing.

                              Image3.JPG

Step-4.  Provide conditions in Conditions Tab as shown below.

 

                              Image5.JPG


Step-5  Wrap the fields and map the corresponding values to line types.


Execute the SMART FORM after mapping. The interface values are passed as shown below.



TEST-1.  Passing all values to the interface parameters and then execute.

           

                              Image6.JPG

 

                    Image7.JPG


Test-2.   Passing empty values to the interface parameter LINE3_DATA and then execute.


                          Image8.JPG

                                   Image9.JPG



Output :- As you can see in the Dynamic template the LINE3_DATA value was empty. As per the condition provided the Line type has not appeared and the space has been automatically adjusted WHEREAS in Static template the line appears even when no data is passed.


Please find the attached sample program for better understanding.


SAP Package Dependencies

$
0
0

Spaghetti.png

 

 

SAP R/3 repository is a wonderful thing. A vast warehouse of data elements, structures, tables and much more, readily available to one and all.  As developers, it is extremely convenient to quickly pick these elements and pull them into our programs as necessity conveys, while our string of thought remains virtually uninterrupted.

 

Well, not all is sunshine and roses. If you are not careful with the mushrooms you pick you might get a poisoned one. Imagine the common scenario in which you pick a customer convenient data element. It looks OK and well suited for your requirements. So you happily include it in your data declarations and pay no more attention to it. What you just failed to realize is that this small data element “belongs” to one of your colleague’s applications and, conceptually, it should never be referred in your application, simply because they are two completely independent and unrelated applications that now share a poisonous bond: they became interdependent.

 

Application spaghetti is a common scenario in SAP IT teams and it sometimes evolves into some unwanted-dependencies troublesome situations. For instance:

 

  • If your colleague decides he needs to change his data element, your application will suffer the impacts of this change;
  • If you need to deploy your application into another system you will have to include the rogue data element and its package definition has well;
  • If you are working on a team environment, you’ll have to guarantee that your colleague has already transported all the objects you require before you can safely deploy your solution.

 

These issues can be easily avoided through careful package design and package checking all your developments.

As a developer you might find that SAP Package Concept goes beyond being just an object container. Using a combination of structure packages, main packages and development packages interconnected by package interfaces and use accesses, you can safeguard your applications from unwanted object picking.

 

Here are some basic package concept guidelines:

 

  1. Stand on your one. Always try to view your application as an isolated software component and encapsulate it accordingly using package hierarchies;
  2. Be aware of your dependencies. Choose to create a new object instead of using unrelated-application objects. Determine your mandatory dependencies through use accesses to other applications;
  3. Create gateways. Using package interfaces, create doorways (APIs really) to your own applications. Make sure you grant public visibility only to stable objects that you feel may bring value to others;
  4. Activate package checks. If you haven’t done it already, go ahead and do it. Package check is integrated with ATC and can quickly give you an overview of your dependency issues. Be aware that this is a global switch. Make sure all the developers are aware of the fact so that they don’t get too scared with package violation messages.
  5. Explore. Create a test package hierarchy, fill it with some dummy objects and package interfaces. Implement a test program and mess around with object permissibility settings.

 

And now for some golden references to get you started:

 

  1. SAP Help Package Builder– Detailed step by step guide for setting up your package-conscientious environment
  2. ABAP Package Concept– Detailed blog series view on the package concept directly from one of SAP’s Gurus
  3. Abapinho– Scavenge Abapinho blog for new tricks, tips and how-tos that will help you on your Package Design quest

A list of Javascript interesting features compared with ABAP

$
0
0


There are already two great blogs which stress why ABAPers should learn Javascript and some essential Javascript features.


Top 10 things ABAP developers should know when learning JavaScript

JavaScript for ABAP Developers


In this document, I will collect some interesting and useful Javascript features compared with ABAP by using examples for demonstration. I will keep it updated once I have learned new stuff.

 

 

1. An object could consume a function which it does not own

 

Paste this source code below into a new .html file and run it in Chrome.

 

<html><script>
function ABAPDeveloper(name, year)
{  this.name = name;  this.year = year;  this.codeABAP = function() {  console.log("Hello, my name is: " + this.name + " I have " + this.year  + " year's ABAP development experience");  }
}
function CDeveloper(name, year, os)
{  this.name = name;  this.year = year;  this.os = os;  this.codeC = function() {  console.log("Hello, my name is: " + this.name + " I have " + this.year  + " year's C development experience focus on " + os + " system.");  }
}
var iJerry = new ABAPDeveloper("Jerry", 7);
iJerry.codeABAP();
var iTom = new CDeveloper("Tom", 20, "Linux");
iTom.codeC();
iTom.codeC.call(iJerry);</script></html>

All the codes are very easy to understand except this "iTom.codeC.call(iJerry)".

 

As mentioned in Kevin Small's blog, "In JavaScript Functions are First Class", we can consider currently Javascript uses the keyword "function" to implement  the OO concept with different approach than ABAP. In this example, although Jerry has no C development experience, now I suddenly owned 7 years' C development experience on Linux

 

clipboard1.png

If you debug in Chrome, you can find the magic of iTom.codeC.call(iJerry). Here the function codeC owned by Object CDeveloper is called by explicitly specifying the context as instance iJerry, this could be observed by checking "this" variable in Chrome debugger, currently "this" points to instance iJerry.


clipboard2.png

This quite flexible feature is not available in ABAP. As we know, the class instance in ABAP could only consume its own method or those inherited from its parent.

 

2. Anonymous object

 

in below example, we define two simple functions a and b, and assign them separately to variable d and e, so those two functions could also be called via d and e as well. In the meantime, another anonymous function with one argument name is also defined. in this context, there is no way to assign this anonymous function to another variable, it has to be executed immediately once having been defined. In this example it is called with argument name = "c",

 

<html><p>hello</p><script>
function a() { console.log("I am function a");}
function b() { console.log("I am function b");}
var d = a;
var e = b;
a();
b();
d();
e();
(function(name) { console.log("I am function: " + name); })("c");</script></html>

 

Check the variable a , b, d, e in Chrome debugger. There is a tab "anonymous function" which enables you to have a list of all anonymous functions used.

 

clipboard3.png

Finally it generates output like below:

clipboard4.png

Go back to ABAP, since we don't treat function module as an object, and every function module should have a name so that it could be called via name.

 

And for the anonymous function in Javascript, since once it is defined and executed, it could not be reused later, I personaly would like to compare this "transient" feature with ABAP keyword GENERATE SUBROUTINE POOL itab NAME prog. Just execute this code which could be found in ABAP help:


DATA itab TYPE TABLE OF string.
DATA prog  TYPE string.
DATA class TYPE string.
DATA oref TYPE REF TO object.
APPEND `program.`                     TO itab.
APPEND `class main definition.`       TO itab.
APPEND `  public section.`            TO itab.
APPEND `    methods meth.`            TO itab.
APPEND `endclass.`                    TO itab.
APPEND `class main implementation.`   TO itab.
APPEND `  method meth.`               TO itab.
APPEND `    message 'Test' type 'I'.` TO itab.
APPEND `  endmethod.`                 TO itab.
APPEND `endclass.`                    TO itab.
GENERATE SUBROUTINE POOL itab NAME prog.
class = `\PROGRAM=` && prog && `\CLASS=MAIN`.
CREATE OBJECT oref TYPE (class).
CALL METHOD oref->('METH').


clipboard5.png

In the runtime, a temporary class type is created and it is allowed to create new object instance based on this type. And this type is transient so could only be used in current transaction.


3. Overwrite builder-in code


Let's review how could this be done in ABAP. It is one of the most powerful abilities I appreciate in ABAP to change the behavior of standard code via pre-exit, post-exit and overwrite-exit. It is a good tool especially for those consultant working for customer project. By creating an overwrite-exit, you can completely deactivate the standard method execution and make your own exit run. For details about how to create the exit, please see this document.


clipboard6.png


And in Javascript, it is even much easier to overwrite the build-in code. Suppose I would like to rewrite the build-in function console.log.


Just paste this code below in the beginning of <script> node in example 2:


var _log = console.log;
console.log = function() {  _log.call(console, '%c' + [].slice.call(arguments).join(' '), 'color:green;text-shadow:0 0 4px rgba(100,200,23,.5);');
};

 

execute example 2 again, the output is generated with our customized color:

 

clipboard7.png

4. Constructor redefinition

 

In ABAP it is not possible to redefine a constructor method.

 

clipboard8.png

clipboard9.png

 

However in Javascript, it is allowed to redefine a function implemention inside itself, sounds crazy?

 

Let's first have a look at this small piece of code:

 

 

<html</html><script>
function Person(name)
{    this.name = name;
}
var person1 = new Person("Jerry");
var person2 = new Person("Jerry");
alert( person1 === person2 ? "Yes":"No");</script>

 

 

it pops up No, since we use "===" comparator and person1 and person2 are two different object instance.

 

clipboard10.png

 

Now inside function Person, I overwrite it by just return the buffered "this" instance, so all the subsequence call of new Person will always return that bufferred instance, and this time I will save a pop up with Yes.

 

<html>

<script>

function Person(name) {

         var instance = this;

         this.name = name;

         Person = function() {

             return instance;

        }

    }

     var iJerry1 = new Person("Jerry");

     var iJerry2 = new Person("Jerry");

     alert( iJerry1 === iJerry2 ? "Yes":"No");

</script>

</html>

 

 

5. Comma and colon

 

In example 2, you could call function a and b one by one with the following code:

 

a(), b();

 

And get the following output:

clipboard11.png

with the help of the so called comma expression, some interesting requirement could be filfilled.

For example, there is a famous interview question: how to exchange the content of two variables WITHOUT using intermediate variable?

 

Using comma expression in Javascript, this could be done via a simple line of code:

 

<html>

</html>

<script>

var a =1,b=2;

a=[b,b=a][0];

console.log("a:" + a);

console.log("b:" + b);

</script>

 

 

clipboard12.png


In ABAP the usage of comma like this is not allowed.


PERFORM list1, list2.


You will meet with this syntax error below.

clipboard13.png

6. Dynamically change inheritance relationship in the runtime

 

In ABAP once a class is assigned with a super class, this parent-child relationship could not be changed in the runtime. However for Javascript, since the OO concept is implemented differently, this relationship did allow change in the runtime.

Suppose we have defined a class Employee which owns two sub class OracleEmployee and SAPEmployee. The both subclass have been inherited from Employee by making their prototype attribute pointing to Employee.prototype( line 21 and 22 ), and in their constructor, explicitly call the parent's constructor via the keyword call which is explained in example 1. Both sub class can use the function displayName since it is inherited from Employee.prototype.

 

<html>

</html>

<script>

function Employee(name, language) {

    this.name = name;

    this.language = language;

    this.company = "";

}

Employee.prototype.displayName = function() {

    console.log("My name is: " + this.name, " I am good at " + this.language + " and currently work at "

    + this.company );

}

function SAPEmployee(name, language) {

    Employee.call(this, name, language);

    this.company = "SAP";

}

function OracleEmployee(name, language) {

    Employee.call(this, name, language);

    this.company = "Oracle";

}

SAPEmployee.prototype = Object.create(Employee.prototype);

OracleEmployee.prototype = Object.create(Employee.prototype);

var iTom = new OracleEmployee("Tom", "Java");

iTom.displayName();

console.log( "Is Tom working at Oracle? " + ( iTom instanceof OracleEmployee ));

 

Execute the script and we could have expected output.

 

clipboard14.png

Now let's append several lines below:

 

OracleEmployee.prototype = SAPEmployee.prototype;

OracleEmployee.prototype.constructor = SAPEmployee;

var iJerry = new OracleEmployee("Jerry", "Java");

console.log( "Is Jerry working at SAP? " + ( iJerry instanceof SAPEmployee ));

 

 

Now although the instance iJerry is initialized via constructor OracleEmployee, however since the prototype attribute of it has been modified to point to SAPEmployee, so in this case iJerry instanceof SAPEmployee will return true.

 

clipboard15.png


This could be observed in Chrome debugger, in this case the parent of instance iJerry is actually changed to class SAPEmployee instead.

clipboard16.png

I will keep updating this document once new comparisons between Javascript and ABAP have been found.list

Create Custom report for table maintenance entries

$
0
0

Requirement Details : Maintain data or particular columns in table depending upon Country Value

Solution :  1. Create 2 screens for your Z program via SE51.. First screen with certain fields from Ztable and other with certain fields as per your requirement

                2. Create table control via wizard with Scroll button checked for both the screens

                3. Create PF status for both custom screens in your status PBO module of respective screens

                4. Make sure you have buttons like New entry , Delete  and Display/change same as we have in SM30 maintenance tool and we can use

                    standard buttons for BACK , SAVE , CANCEL , EXIT.

                5. in TABLE_INIT_OUTPUT and User command module of respective table controls write code depending upon  User Command i.e. SY-UCOMM

                5.1. For new entries :

                       loop at screen.

                           screen-input = 1.

                           modify screen.

                       endloop.

                 5.2.  For display/change : here we will loop key fields onwards i.e. they are non editable while maintaining entries e.g. if we have first 3 as key then

                         loop at screen where index GT 3.

                             if screen-name eq 'ZABC' and screen-input = 1.

                                     screen-input = 0.

                                     modify screen.

                              else

                                    screen-input = 1.

                                     modify screen.

                           endif.

                       endloop.

                      likewise repeat for fields other than key fields make sure screen-name is in  upper case.

               5.3.  For Delete/Save : Please use insert , modify and delete and make sure to perform these operations on table control itab as well.

            6. When coming back from custom screens please make use of call selection screen statement and set screen 0/ leave to screen 0 statements.


P.S. : Make sure here my requirement was based on country so I will call custom screen base on country value and then on BACK please set screen 0 to

          ensure proper functionality working.

Debugging Smart Forms in production environment

$
0
0

If you want to debug Smart form in non-modifiable client, then you can debug Smart forms Function Module using session break point.

Step 1: go to transaction SMARTFORMS and provide your smart form name, open it in display mode


            


Step 2: expand the page, select code, and copy its name i.e. %CODE35


             


Step 3: Test (F8) smart form


Step 4: now open this function module in display mode

Note: Whenever a form is activated a Function Module is generated


              


Step 5: find string %CODE35 which was selected in step 2

Note: Instead of using (Ctrl+F) short cut uses  this option.


               


Step 6: double click on search result


               


Step 7: place session break point wherever you want in your code



                

 

Line number 1867 triggers when user dev01 executing the smart form &line number 1870 triggers session break point for all users.

Document for bapi BAPI_PRICES_CONDITIONS

$
0
0

Hi All,

 

This attachment contains the detail documentation of bapi "BAPI_PRICES_CONDITIONS".This document mainly focus on the parameters that are passed to the bapi and the tables that are affected while the execution of bapi.


      


    BAPI_PRICES_CONDITIONS


Documentation


Short Text:  BAPI for Price and Rebate Usage Condition.

Functionality: Using this BAPI we can change the price of the condition records.

Parameters:

                        PI_INITIALMODE

                        PI_BLOCKNUMBER

                        PI_PHYSICAL_DELETION

Tables

             TI_BAPICONDCT

               TI_BAPICONDHD

               TI_BAPICONDIT

               TI_BAPICONDQS

               TI_BAPICONDVS

              TO_BAPIRET2

              TO_BAPIKNUMHS

              TO_MEM_INITIAL

 

 

Procedure:

                        Create a condition record using a tcode Vk11.

 

  

 

 

 

Once we enter condition type in the  vk11 it opens a popup  as below.

 

 

Based on the radio button we selects the respective table gets affected.

 

Suppose if we select  1st  radio button then the record gets created in the following tables

A305 , KONH,KONP.

 

Suppose if we select  2nd  radio button then the record gets created in the following tables

A306 , KONH,KONP.

 

Suppose if we select  3rd  radio button then the record gets created in the following tables

A304 , KONH,KONP.

 

Once the creation of records is completed .You can see the record in the above specified tables.


 

Now if we want to change the value of price (KBETR) for the above condition record (00000030830) present   in the KONP table.

 

The steps to be followed are listed below:

 

Open a se37 tcode and enter the bapi BAPI_PRICES_CONDITIONS  and select on display button. It opens  a bapi and you will find a function module on left top corner just click on it and then select execute option and then followed  by test sequences as shown below.

 

 

 

 

 

After  once you click on test sequences it opens a following screen.

 

 

 

Now enter the bapi’s under the function modules tab as shown above and click on execute button. As soon as you click on execute button the following screen appears.

 

 

 

Values to be passed for the table ti_bapicondct are:

 

Get  these details based on the table A304/A305/A306.

 

table_no   = '306'.              “ table name excluding the ‘A’          
COND_USAGE
= 'A'.                    
applicatio
= 'V'.                    
cond_type 
= 'PR00'.                 
operation 
= '023'.              “ modify-023     
varkey    
= '302014L1USD  E101_COPY'. “it is the combination of vkorg,

vtweg,pltyp,waerk and matnr
valid_to  
= '99991231'.             
valid_from
= '20050118'.             
cond_no   
= '0000030830'.       “Condition record number

 

 

You can refer the below screen while entering the values to the table it_bapicondct.

 

 

 

Values  to be passed for the table ti_bapicondhd are:

 

Get these details based on the table KONH.

 

operation  = '023'.                   
cond_no   
= '0000030830'.            
created_by
= 'PERRON'.
creat_date
= '20050318'.
cond_usage
= 'A'.                     
table_no  
= '306'.                   
applicatio
= 'V'.                     
cond_type 
= 'PR00'.                  
varkey    
= '302014L1USD  E101_COPY'.
valid_from
= '20050118'.              
valid_to  
= '99991231'.  

 

You can refer the below screen while entering the values to the table it_bapicondhd.

 

 

 

Values to be passed for the table it_bapicondit are:

 

Get these details based on the table KONP.

 

operation  = '023'.      
cond_no   
= '0000030830'.
cond_count
= '01'.       
applicatio
= 'V'.        
cond_type 
= 'PR00'.     
scaletype 
= 'A'.        
scalebasin
= ' '.        
scale_qty 
= '0'.        
calctypcon
= 'C'.        
cond_value
= '10.00'.    “ You can update the changed price value here.
condcurr  
= 'USD'.      
cond_p_unt
= '1'.        
cond_unit 
= 'SHT'.      

  

 

 

 

 

You can refer the below screen while entering the values to the table it_bapicondit.

 

 

       

 

Once the all values are passed to the tables of the bapi you can execute it. Once the bapi_prices_conditions  is executed then bapi_transaction_commit must be done.

 

 

 

Here you can provide the target system and then execute it.

 

 

Then you can see the changed value of price(KBETR) in the KONP table.

 

 

Regards,

Chakradhar.

Viewing all 935 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>