Sap Abap Tips

Embed Size (px)

DESCRIPTION

sap bap tips

Citation preview

ABAP/4 Query Hints and Tips

ABAP/4 Query Hints and Tips

The purpose of the SAP Query are for users with no programming knowledge. It is also used by abapers to create simple reports for the users.

You can easily create three types of query reports :

1. Basic lists (details list) 2. Statistics (counting etc.) 3. Ranked lists

When you start using version 4.6x, you can see a Quick Viewer button in the Query Main screen. It is suppose to be much simplier that the original Query but it is up to you to decide whether is it true.

To create a report with the QuickViewer, all you need to to do is enter texts such as titles, and select the fields and options that define the structure of the report. You can assign a specific sequence to the fields by numbering them.

If necessary, you can edit the lists either through drag and drop in WYSIWYG mode, or by using the functions in the available toolbars. Data can also be send to external programs such as MS Excel or MS Word for further processing.

The only problem with QuickViewer is that it cannot read cluster table.

Table of Contents

Understanding SAP Query

A functional area is where you group selected tables together to be reported on.

User groups are sections to build queries in.

A query is the report.

For example, lets say you wish to build a report (query) on the material master where you want to see certain fields from the MARA table and other fields from the MVKE table.

First you would create a functional area that has both the tables MARA and MVKE in it and appropriately linked. (Different tables need a valid join to be queried on)

There is no need to create the functional area if of course a functional area already exists with at least those 2 tables in it.

Also to note is the fact that the functional area determines which fields of the tables can be queried on. You can select the desired fields to be either on or off.

Second you would create a user group to put your queries into.

You may have a 'material master' user group which has material master queries in it, then later you might have a 'bill of materials' user group with BOM queries, etc.

You would also assign various users to the user groups to give them the ability to run the reports within that user group.

Finally you would create a query within a user group where that query is based on the functional area and can therefore show selected fields from the tables in the functional area.

Return to :-

ABAP/4 Query

Every business is unique and SAP provides reporting tools for its users. For simple reports, you can used the ABAP/4 Query instead of writing reporting programs. If the reports specifications is not very complex, using the query will save you a lot of time. In the query, you can create your own calculation variable, define the sorting criteria, define the field arrangement and define whether you want to have totals.

Steps to create a query :-

SQ02 - Create the Functional Areas

SQ02 - Assign to User groups

SQ00 - Create the Basic Lists/Statistic/Ranked List

Basic Lists are details reports. Every records in the table are printed.

Statistic are summary reports. The records with the same keys are group together.

Ranked list are ranking report. e.g. The top 10 sales values.

Return to :- Some ABAP/4 Query header line variable :-

&%NAME Name of user executing the query

&%DATE Current date when executing the query

&%TIME Current time when executing the query

&%PAGE Current page number (output 6 characters)

XXL (EXtended Export of Lists)

A tool for displaying and manipulating list objects from R/3 applications. XXL is based on the Microsoft Excel spreadsheet program.

e.g. on ABAP/4 Query using SAPGUI 4.0b

Further processing options - click Spreadsheet

execute your query and wait for the Export list object to XXL menu box to appear

click Excel 4 / SAP macros and click continue

in the Excel click Enable macros if prompted

the rest is Excel command which you can try on your own

ABAP Quick Viewer

In SAP 4.6x, you can used a simplified ABAP query. The Quick Viewer ( SQVI ) can be used to generate simple report without any programming.

You select fields according to your data source that determine the structure of your report. The report can be executed in basis mode with standard layout or may be edited using drag and drop and other toolbox functions available in WYSIWYG mode.

However, only transparent table are allow to be use in SQVI.

e.g. Your cannot use BSEG as it is a cluster table, instead use BSIS.

BKPF - Accounting Document Header

BSIS - Accounting: Secondary Index for G/L Accounts

ABAP Editor - Introduction

For complex reports specifications, SAP allows you to write customize ABAP/4 programs.

ABAP/4 allows SAP programmer more freedom in how they want to code the programs.

There are no one size fixed all software, with this in mind, SAP allows its users to create their own dialog or reports programs using the language ABAP/4.

Some Development transaction code are :- SE38 - ABAP Editor SE37 - Function Builder

ABAP/4 Development Code Efficiency Guidelines

ABAP/4 (Advanced Business Application Programming 4GL) language is an "event-driven", "top-down", well-structured and powerful programming language. The ABAP/4 processor controls the execution of an event. Because the ABAP/4 language incorporates many "event" keywords and these keywords need not be in any specific order in the code, it is wise to implement in-house ABAP/4 coding standards.

SAP-recommended customer-specific ABAP/4 development guidelines can be found in the SAP-documentation.

This page contains some general guidelines for efficient ABAP/4 Program Development that should be considered to improve the systems performance on the following areas:-

Physical I/O - data must be read from and written into I/O devices. This can be a potential bottle neck. A well configured system always runs 'I/O-bound' - the performance of the I/O dictates the overall performance.

Memory consumption of the database resources eg. buffers, etc.

CPU consumption on the database and application servers

Network communication - not critical for little data volumes, becomes a bottle neck when large volumes are transferred.

Policies and procedures can also be put into place so that every SAP-customer development object is thoroughly reviewed (quality program correctness as well as code-efficiency) prior to promoting the object to the SAP-production system. Information on the SAP R/3 ABAP/4 Development Workbench programming tools and its features can be found on the SAP Public Web-Server.

--------------------------------------------------------------------------------

CLASSIC GOOD 4GL PROGRAMMING CODE-PRACTICES GUIDELINES

Avoid dead-code

Remove unnecessary code and redundant processing

Spend time documenting and adopt good change control practices

Spend adequate time anayzing business requirements, process flows, data-structures and data-model

Quality assurance is key: plan and execute a good test plan and testing methodology

Experience counts

--------------------------------------------------------------------------------

SELECT * FROM CHECK: ENDSELECT

vs.

SELECT * FROM WHERE ENDSELECT

In order to keep the amount of data which is relevant to the query the hit set small, avoid using SELECT+CHECK statements wherever possible. As a general rule of thumb, always specify all known conditions in the WHERE clause (if possible). If there is no WHERE clause the DBMS has no chance to make optimizations. Always specify your conditions in the Where-clause instead of checking them yourself with check-statements. The database system can also potentially make use a database index (if possible) for greater efficiency resulting in less load on the database server and considerably less load on the network traffic as well.

Also, it is important to use EQ (=) in the WHERE clause wherever possible, and analyze the SQL-statement for the optimum path the database optimizer will utilize via SQL-trace when necessary.

Also, ensure careful usage of "OR", "NOT" and value range tables (INTTAB) that are used inappropriately in Open SQL statements.

--------------------------------------------------------------------------------

SELECT *

vs.

SELECT SINGLE *

If you are interested in exactly one row of a database table or view, use the SELECT SINGLE statement instead of a SELECT * statement. SELECT SINGLE requires one communication with the database system whereas SELECT * requires two.

--------------------------------------------------------------------------------

SELECT * FROM INTO APPEND ENDSELECT

vs.

SELECT * FROM INTO TABLE

It is usually faster to use the INTO TABLE version of a SELECT statement than to use APPEND statements

--------------------------------------------------------------------------------

SELECT ... WHERE + CHECK

vs.

SELECT using aggregate function

If you want to find the maximum, minimum, sum and average value or the count of a database column, use a select list with aggregate functions instead of computing the aggregates within the program. The RDBMS is responsible for aggregated computations instead of transferring large amount of data to the application. Overall Network, Application-server and Database load is also considerably less.

--------------------------------------------------------------------------------

SELECT INTO TABLE + LOOP AT T SELECT * FROM INTO TABLE . LOOP AT . ENDLOOP.

vs.

SELECT * FROM . ENDSELECT

If you process your data only once, use a SELECT-ENDSELECT loop instead of collecting data in an internal table with SELECT ... INTO TABLE. Internal table handling takes up much more space

--------------------------------------------------------------------------------

Nested SELECT statements: SELECT * FROM SELECT * FROM .. ENDSELECT. ENDSELECT

vs.

Select with view SELECT * FROM ENDSELECT

To process a join, use a view wherever possible instead of nested SELECT statements. Using nested selects is a technique with low performance. The inner select statement is executed several times which might be an overhead. In addition, fewer data must be transferred if another technique would be used eg. join implemented as a view in ABAP/4 Repository.

SELECT ... FORM ALL ENTRIES Explicit cursor handling (for more information, goto Transaction SE30 Tips & Tricks)

--------------------------------------------------------------------------------

Nested select: SELECT * FROM pers WHERE condition. SELECT * FROM persproj WHERE person = pers-persnr. ... process ... ENDSELECT. ENDSELECT.

vs.

SELECT persnr FROM pers INTO TABLE ipers WHERE cond. . SELECT * FROM persproj FOR ALL ENTRIES IN ipers WHERE person = ipers-persnr ... process . ENDSELECT.

In the lower version the new Open SQL statement FOR ALL ENTRIES is used. Prior to the call, all interesting records from 'pers' are read into an internal table. The second SELECT statement results in a call looking like this (ipers containing: P01, P02, P03): (SELECT * FROM persproj WHERE person = 'P01') UNION (SELECT * FROM persproj WHERE person = 'P02') UNION (SELECT * FROM persproj WHERE person = 'P03')

In case of large statements, the R/3's database interface divides the statement into several parts and recombines the resulting set to one. The advantage here is that the number of transfers is minimized and there is minimal restrictions due to the statement size (compare with range tables).

--------------------------------------------------------------------------------

SELECT * FROM

vs.

SELECT FROM

Use a select list or a view instead of SELECT *, if you are only interested in specific columns of the table. If only certain fields are needed then only those fields should be read from the database. Similarly, the number of columns can also be restricted by using a view defined in ABAP/4 Dictionary. Overall database and network load is considerably less.

--------------------------------------------------------------------------------

SELECT without table buffering support

vs.

SELECT with table buffering support

For all frequently used, read-only(few updates) tables, do attempt to use SAP-buffering for eimproved performance response times. This would reduce the overall Database activity and Network traffic.

--------------------------------------------------------------------------------

Single-line inserts LOOP AT INSERT INTO VALUES ENDLOOP

vs.

Array inserts

Whenever possible, use array operations instead of single-row operations to modify the database tables.

Frequent communication between the application program and database system produces considerable overhead.

--------------------------------------------------------------------------------

Single-line updates SELECT * FROM UPDATE ENDSELECT

vs.

Column updates UPDATE SET

Wherever possible, use column updates instead of single row updates to update your database tables

--------------------------------------------------------------------------------

DO....ENDDO loop with Field-Symbol

vs.

Using CA operator

Use the special operators CO, CA, CS instead of programming the operations yourself If ABAP/4 statements are executed per character on long strings, CPU consumprion can rise substantially

--------------------------------------------------------------------------------

Use of a CONCATENATE function module

vs.

Use of a CONCATENATE statement

Some function modules for string manipulation have become obsolete, and should be replaced by ABAP statements or functions

STRING_CONCATENATE... ---> CONCATENATE STRING_SPLIT... ---> SPLIT STRING_LENGTH... ---> strlen() STRING_CENTER... ---> WRITE..TO. ..CENTERED STRING_MOVE_RIGHT ---> WRITE...TO...RIGHT-JUSTIFIED

--------------------------------------------------------------------------------

Moving with offset

vs.

Use of the CONCATENATE statement

Use the CONCATENATE statement instead of programming a string concatenation of your own

--------------------------------------------------------------------------------

Use of SEARCH and MOVE with offset

vs.

Use of SPLIT statement

Use the SPLIT statement instead of programming a string split yourself

--------------------------------------------------------------------------------

Shifting by SY-FDPOS places

vs

Using SHIFT...LEFT DELETING LEADING...

If you want ot delete the leading spaces in a string use the ABAP/4 statements SHIFT...LEFT DELETING LEADING... Other constructions (with CN and SHIFT... BY SY-FDPOS PLACES, with CONDENSE if possible, with CN and ASSIGN CLA+SY-FDPOS(LEN) ...) are not as fast

--------------------------------------------------------------------------------

Get a check-sum with field length

vs

Get a check-sum with strlen ()

Use the strlen () function to restrict the DO loop to the relevant part of the field, eg. when determinating a check-sum

ABAP Debugger

Activate the Debugger before executing your ABAP program

System -> Utilities -> Debug ABAP/4

The purpose of the debugger is to allow you to execute your program line by line. It also allow you display the data as you execute the program. (double click on the varaible field name and it will be display)

or after program have been executed,

Run transaction SM66 and find your work process. Select the line of your work process and double click on it Click the debugging option. If this is a custom program, you can put a wait statement in the code to buy yourself some time.

ABAP program calling another ABAP program

* and return - returns to the calling program submit zxxxx via selection-screen and return.

* ZX refers to the variant. submit zxxxx via selection-screen using selection-set 'ZX' and return.

ABAP Program Authorization

In your editor program, click Goto -> Attributes

Key in the authorization in the Authorization Group.

ABAP Program run in background

At transaction SE38 click Program -> Execute -> Background.

In order to execute your program in the background, you need to specify a variant.

You can schedule the program to run once at a certain time or periodically every month, week, days, hours or minutes.

To define the print parameters, click Goto -> Print parameters.

ABAP Text String Finder in program source code

RSRSCAN1 - ABAP/4 Find String in Program Source Code

Transaction SE38 -> Utilities -> Find in source code

ABAP Report Page Number

The code below shows how to display the total number of pages in a report like "Page 1 of 8." However, it doesn't work if you execute the program as a background jobs.

* Declare a variable DATA L_PAGE_COUNT(5) TYPE C.

* Copy this code to the end of program * Page count will be printed on each page here WRITE SY-PAGNO TO L_PAGE_COUNT LEFT-JUSTIFIED. DO SY-PAGNO TIMES. READ LINE 1 OF PAGE SY-INDEX. REPLACE '-----' WITH L_PAGE_COUNT INTO SY-LISEL. MODIFY CURRENT LINE. ENDDO.

TOP-OF-PAGE. WRITE: /(70) 'Heading' CENTERED, 70 SY-PAGNO,'of ', '-----'.

Comparing two ABAP Program

To compare two ABAP and show you the differences in both ABAP.

Transaction SE39 will do this.

Internal Tables

* Check Whether Table is Empty IF ITAB[] is initial. WRITE: / 'TABLE EMPTY'. ENDIF.

* Assuming that the data have been uploaded into internal table ITAB. You then can ignore the first line of the internal table Delete ITAB index 1. ( before you do your operation such as batch input or others )

* To know the last record insert in a table DESCRIBE TABLE ITAB LINES SY-TFILL. READ TABLE ITAB INDEX SY-TFILL.

Question : Subject : Dynamic structure

hello everyone,

does anyone know if it's possible to declare a dynamic structure? my program receives a record-field of 1000, and I need to overlay this record with a structure that needs to be dynamic. any advice is welcome.

Kind regards,

Reply : Subject : Dynamic structure

Hi,

if your structure changes from one defined structure to another one, you can try this: ASSIGN yourfield CASTING TYPE yourstructure or CREATE DATA yourdata TYPE yourstructure. If your structure has to be really dynamic - like ALV - you can use the class CL_ALV_TABLE_CREATE.

Hope this helps,

Reply : Subject : Dynamic structure

It has to be really dynamic.

can you tell me how to use this class? I've never programmed object-oriented ABAP before, and don't know much about it...

Is there documentation, help files?

thx in advance,

Reply : Subject : Dynamic structure

Hi,

try this example:

=====================================

REPORT zmaschl_create_data_dynamic .

TYPE-POOLS: slis.

DATA: it_fcat TYPE slis_t_fieldcat_alv, is_fcat LIKE LINE OF it_fcat. DATA: it_fieldcat TYPE lvc_t_fcat, is_fieldcat LIKE LINE OF it_fieldcat. DATA: new_table TYPE REF TO data. DATA: new_line TYPE REF TO data. FIELD-SYMBOLS: TYPE ANY TABLE, TYPE ANY, TYPE ANY.

* Build fieldcat CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE' EXPORTING i_structure_name = 'SYST' CHANGING ct_fieldcat = it_fcat[]. LOOP AT it_fcat INTO is_fcat WHERE NOT reptext_ddic IS initial. MOVE-CORRESPONDING is_fcat TO is_fieldcat. is_fieldcat-fieldname = is_fcat-fieldname. is_fieldcat-ref_field = is_fcat-fieldname. is_fieldcat-ref_table = is_fcat-ref_tabname. APPEND is_fieldcat TO it_fieldcat. ENDLOOP.

* Create a new Table CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = it_fieldcat IMPORTING ep_table = new_table.

* Create a new Line with the same structure of the table. ASSIGN new_table->* TO . CREATE DATA new_line LIKE LINE OF . ASSIGN new_line->* TO .

* Test it... DO 30 TIMES. ASSIGN COMPONENT 'SUBRC' OF STRUCTURE TO . = sy-index. INSERT INTO TABLE . ENDDO.

LOOP AT ASSIGNING . ASSIGN COMPONENT 'SUBRC' OF STRUCTURE TO . WRITE . ENDLOOP.

Reply : Subject : Dynamic structure

perfect,

thank you,

Download Structure from SAP to MS-ACCESS

Use the program RIACCESS. It's a PM program. You need to parameter a RFC.

Look at OSS Notes using "RIACCESS".

Note : Date variable are created with a lengh equal to 10 (External length), as well as the Time variable.

Other than the DATS and TIME variable, you'll get a perfect structure.

Prevent user from submitting the same jobname ZXXX twice

tables: tbtco.

data: t_jobcnt(1) type n, t_sdluname like tbtco-sdluname, t_strtdate like tbtco-strtdate, t_strttime like tbtco-strttime.

select * from tbtco where jobname = 'ZXXX' and strtdate = sy-datum and status = 'R'. t_jobcnt = t_jobcnt + 1. if t_jobcnt = 1. t_sdluname = tbtco-sdluname. t_strtdate = tbtco-strtdate. t_strttime = tbtco-strttime. endif. endselect. if sy-subrc = 0. if t_jobcnt < 1. message e123 with t_sdluname 'have execute the program on' t_strtdate t_strttime. endif. endif.

Force user to run program in Background

You can stop users from submitting a report online by inserting a few lines on abap checking codes. If there a quite a number of abap program that need this function, you can create it as an include statement.

* Insert this statement at the start of the program.

IF SY-BATCH 'X '. MESSAGE E999 WITH 'EXECUTE IN BACKGROUND ONLY'. ENDIF.

Using Message-ID to provide using job logs during program processing

You can used the message command to get feedback from your background programs. The message will be display on the Job Log Entries. With the message command you can display the routinue and the variable data field the program is processing.

Transaction SM37 and hit Enter

Double click on your program name and the job entries log is shown

Using the message command:-

* double click on z1 to check whether is it created. * create a message number in z1 e.g. 001 & & & & report zxxxx message-id z1.

message i001 with 'Start of loop'.

loop at .... message i001 with mara-matnr. endloop.

SAP User Exits Routine

User exits are routine which SAP allows you to add in additional customized programs process without affecting the standard SAP programs.

SAP user exit are usually declare as a form routine :-

form userexit_xxxxx ........................ endform

In VL01 - Create Delivery Order, standard program SAPMV50A, the standard program did not check for storage location equal to space, and delivery quantity less than one when the user click the save button. Therefore I have to insert the additional checking into the userexit routine.

Steps:-

Goto transaction VL01 to pick a Sales Order for delivery (you don't have to save the data)

In the initial screen, click System -> Status -> Double click on Program (Screen)

In the dialog program SAPMV50A, click Edit -> Search/replace

Type userexit in the Find field, then click the In program radio button and hit Enter

A number of userexit routine will be display. You'll have to roughly decide which is the correct userexit routine to used.

form userexit_save_document_prepare. case xlips-pstyv. when 'TAX' or 'REX'. * Accept this two Delivery item category

when 'REN'. if xlips-lgort = space. * Reject this Delivery item category message e001. endif.

when others. if xlips-matnr space. * Check storage location not space if xlips-lgort = space. message e002. endif. * Check delivery quantity not zero if xlips-pikmg < 1. message e003. endif. endif. endcase. endform.

SAP Field Exits

From 4.6c onwards, Field exits will no more be supported by SAP. They removed the function of field exit but they had given lot of flexibility through userexit.

However, if you still required it, here is how to activate it :-

First called up transaction CMOD. Then called up transaction PRFB.

or

Activation of the field exits and assignment of the dynpros can also be carried out using program RSMODPRF. For this purpose, the program must be started without parameters (input fields remain blank). If required, new field exits can be created using program RSMODPRF (see the program documentation).

* * Author by : SAP ABAP/4 Programming, Basis Administration, Configuration Hints and Tips * http://www.sap-basis-abap.com * * Executing Unix command from ABAP * REPORT ZUNIX.

data: unix_command(50) type c value 'ls -ls /usr/sap/trans/data'.

data: begin of internal_table occurs 0, line(200), end of internal_table.

PARAMETERS UNIXCOMM LIKE unix_command DEFAULT 'ls -ls /usr/sap/trans/data' LOWER CASE.

call 'SYSTEM' id 'COMMAND' field UNIXCOMM id 'TAB' field internal_table-*SYS*.

EDITOR-CALL FOR INTERNAL_TABLE DISPLAY-MODE.

*--- End of Program

Calculate begining of previous to end of previous month

ldate = sy-datum. ldate+6(2) = '01'. ldate = ldate - 1. fdate = ldate. fdate+6(2) = '01'.

move: fdate to date-low, ldate to date-high.

append date.

OY05 - Maintain the SAP Factory Calendar

SAP Factory Calendar allows companies to key in their own factory work days. Individual SAP application such as MRP will take into consideration these individual factory customizing.

For alternate Saturday, you set Saturday as a normal working day and key in all the off-days in the Special rules button.

In your abap program, you can calculate whether a particular day is a non-working day, with reference to the Factory Calendar.

ABAP Program to check for holidays using the factory calendar * include zday . * substitute tdate = 'yyyymmdd'. * tholiday_found = 'X' -> Holiday TABLES THOCS. DATA: BEGIN OF INT_THOCS OCCURS 100, THOCS LIKE THOCS. DATA: END OF INT_THOCS.

DATA: TDAY(1), TDATE LIKE SY-DATUM, THOLIDAY_ATTRIBUTES, THOLIDAY_FOUND(1).

FORM HOLIDAY. CALL FUNCTION 'HOLIDAY_CHECK_AND_GET_INFO' EXPORTING DATE = TDATE HOLIDAY_CALENDAR_ID = 'XX' * WITH_HOLIDAY_ATTRIBUTES = ' ' IMPORTING HOLIDAY_FOUND = THOLIDAY_FOUND TABLES HOLIDAY_ATTRIBUTES = INT_THOCS EXCEPTIONS CALENDAR_BUFFER_NOT_LOADABLE = 1 DATE_AFTER_RANGE = 2 DATE_BEFORE_RANGE = 3 DATE_INVALID = 4 HOLIDAY_CALENDAR_ID_MISSING = 5 HOLIDAY_CALENDAR_NOT_FOUND = 6 OTHERS = 7.

CALL FUNCTION 'DATE_COMPUTE_DAY' EXPORTING DATE = TDATE IMPORTING DAY = TDAY EXCEPTIONS OTHERS = 1. * For checking. *if tholiday_found = 'X'. * write: /1 'Holiday ', tdate. *else. * write: /1 'Not Holiday ', tdate. *endif. * *case sy-subrc. * when 0. write: /1 tdate, tday. * when others. write: /1 'Unknown day ', tdate. *endcase. ENDFORM.

Return to :-

To find out the Previous Saturday for a given date

REPORT ZPREVIOUS.

* To find out the Previous Saturday for a given date

DATA: L_DATE LIKE SY-DATUM.

PARAMETERS: PREVDAY(2) TYPE N DEFAULT 7.

L_DATE = SY-DATUM. L_DATE = L_DATE - ( ( ( L_DATE MOD 7 ) + PREVDAY ) MOD 7 ).

CASE PREVDAY. WHEN 7. WRITE:/ 'Previous Saturday ', L_DATE. WHEN 6. WRITE:/ 'Previous Sunday ', L_DATE. WHEN 5. WRITE:/ 'Previous Monday ', L_DATE. WHEN 4. WRITE:/ 'Previous Tuesday ', L_DATE. WHEN 3. WRITE:/ 'Previous Wednesday', L_DATE. WHEN 2. WRITE:/ 'Previous Thursday ', L_DATE. WHEN 1. WRITE:/ 'Previous Friday ', L_DATE. ENDCASE.

Question : Subject : BDC FAQ

Dear Friends:

1.How to handle errors in call transaction method and session method.

2.where can i get good examples of call transaction & session method in sap r/3 system,on internet or in books?

3. What is the criteria to select call transaction method or session method for data upload?

All your answers will be greatly appreciated.

Regards

Reply : Subject : BDC FAQ

You can try this code to handle your BDC errors and display the corresponding error messages:

if session ne 'X'. call transaction tcode using itab_bdc mode 'N' UPDATE 'S' MESSAGES INTO i_errors.

* N - no display * E - errors only * A - display ALL screens elseif session = 'X'. call function 'BDC_INSERT' exporting tcode = tcode tables dynprotab = itab_bdc exceptions internal_error = 1 not_open = 2 queue_error = 3 tcode_invalid = 4 printing_invalid = 5 posting_invalid = 6 others = 7

*Check SY-SUBRC if sy-subrc 0. "Unsuccessful loop at i_errors. MESSAGE ID i_errors-msgid TYPE i_errors-msgtyp NUMBER i_errors-msgnr WITH i_errors-msgv1 i_errors-msgv2 i_errors-msgv3 i_errors-msgv4 INTO i_error_messages-message.

append i_error_messages. endloop. endif. endif.

Search data in Select-Options

select-options s_budat for mkpf-budat.

loop at s_budat write: 'Date from ', s_budat-low, ' to ', s_budat-high. endloop.

The default select-options search is Include.

e.g. Material Document 12345678 to

To Exclude the record 12345678

Place your cursor at the Material Document field.

Click the Selection options button

Click the Radio button Exclude from selection and hit Enter

A red color sign will appear indicating that this is a exclude selection options

If you click the Multiple Selection arrow on the right, scroll down the pop-up screen and you can see an additonal selection ...but not

Pattern selection

When you want to select data based on a certain characters.

At the selection screen field, key in the characters and hit enter. e.g. ZXX* or *ZXX* then hit enter, the pattern sign will appear.

Write - To Bold or not to bold for laser printer

format color col_group. write: / 'not bold'.

format color col_total. write: / 'Bold'.

write: / z_variable color col_total under 'Only this variable Bold'.

* * Writing Left Column Scroll Lock in ABAP just like Excel * * Author by : SAP ABAP/4 Programming, Basis Administration, Configuration Hints and Tips * http://www.sap-basis-abap.com * REPORT ZSCROLL NO STANDARD PAGE HEADING LINE-COUNT 4 LINE-SIZE 140.

START-OF-SELECTION. DO 3 TIMES. WRITE: / '01234567890123456789'.

DO 10 TIMES. WRITE sy-index. ENDDO. ENDDO.

SET LEFT SCROLL-BOUNDARY COLUMN 21.

DO 3 TIMES. WRITE: / '0123456789'. DO 10 TIMES. WRITE sy-index. ENDDO. ENDDO.

SET LEFT SCROLL-BOUNDARY COLUMN 11.

TOP-OF-PAGE. SY-TITLE = 'Column Locking'. WRITE: / SY-TITLE.

*--- End of Program

Return to :-

End of page Routine

If you have this routine, the program will print whatever information you specify at the end of the report. For end-of-page routine to work, you have to specify the number of line-count for the end-of-page. The other problems is at the last page. If the line count did not hit the specify number, the last page will not be printed. To overcome this, you have to let the program make a full count for the total number of print lines using the skip command.

report zxxx line-size 190 no standard page heading line-count 060(004). "indicate 4 lines for end-of-page

data: tline like sy-linno.

start-of-selection. .............................. end-of-selection.

tline = 60 - sy-linno. skip tline.

end-of-page. write: / ..........................

ABAP Program to Lock/Unlock the ABAP Editor Lock Field

REPORT ZEDITOR.

TABLES: TRDIR. "System table TRDIR

PARAMETERS: PROGRAM LIKE TRDIR-NAME. PARAMETERS: EDITOR LIKE TRDIR-EDTX.

SELECT SINGLE * FROM TRDIR WHERE NAME = PROGRAM.

TRDIR-EDTX = EDITOR. MODIFY TRDIR. IF SY-SUBRC EQ 0. WRITE: / 'Editor Lock update Successful ', TRDIR-NAME. IF TRDIR-EDTX = 'X'. WRITE: ' Lock'. ELSE. WRITE: ' UnLock'. ENDIF. ELSE. WRITE: / 'Editor Lock update Unsuccessful ', TRDIR-NAME. ENDIF.

Return to :-

* * Copy the current Client password to the rest of the Client * * Run this program in the Client where you want all the rest * of the Client password to be copied. * The user you specify will have the same Client password as the * Client where you login and run this program. * For e.g. if you run this program in Client XXX, the rest of the * Client like 123, 456 will have the same password as Client XXX. * * Author by : SAP ABAP/4 Programming, Basis Administration, Configuration Hints and Tips * http://www.sap-basis-abap.com * REPORT ZCOPYPASS .

TABLES: USR02, T000.

DATA: PASSWD LIKE USR02-BCODE.

PARAMETERS: USER LIKE USR02-BNAME.

SELECT SINGLE * FROM USR02 WHERE BNAME = USER.

IF SY-UNAME 'SAP*'. WRITE: / 'Only SAP* is allowed to run this program'. EXIT. ENDIF.

IF SY-SUBRC 0. WRITE: / USER, 'user does not exist!'. EXIT. ENDIF.

PASSWD = USR02-BCODE. CLEAR USR02.

WRITE: / 'The password of', USER, 'updated in client:'.

SELECT * FROM T000 WHERE MANDT '066' AND MANDT SY-MANDT. SELECT * FROM USR02 CLIENT SPECIFIED WHERE MANDT = T000-MANDT AND BNAME = USER.

WRITE: / USR02-MANDT. USR02-BCODE = PASSWD. USR02-LTIME = SY-UZEIT. USR02-BCDA1 = USR02-BCDA2 = USR02-BCDA3 = SY-DATUM. USR02-BCDA4 = USR02-BCDA5 = SY-DATUM.

UPDATE USR02 CLIENT SPECIFIED. ENDSELECT. ENDSELECT.

*--- End of Program

Copy Program Variants from one to another

This code copies variants from one program to another provided that the programs have identical selection screens.

* ------------------------------------------------------

* Copy Variants from one Program to another.

* ------------------------------------------------------

REPORT Z_COPY_VARIANTS_PROG_TO_PROG .

* =====================================================

* Data Declarations Section

* =====================================================

TABLES : VARID , VARIS , VARIT .

* -----------------------------------------------------

DATA : BEGIN OF MYVARID OCCURS 0 .

INCLUDE STRUCTURE VARID .

DATA : END OF MYVARID .

* -----------------------------------------------------

DATA : BEGIN OF MYVARIS OCCURS 0 .

INCLUDE STRUCTURE VARIS .

DATA : END OF MYVARIS .

* -----------------------------------------------------

DATA : BEGIN OF MYVARIT OCCURS 0 .

INCLUDE STRUCTURE VARIT .

DATA : END OF MYVARIT .

* -----------------------------------------------------

DATA : BEGIN OF MYVARI OCCURS 0 .

INCLUDE STRUCTURE VARI .

DATA : END OF MYVARI .

DATA : MANS(1) TYPE C .

DATA : PROGRAMM LIKE RS38M-PROGRAMM .

DATA : BEGIN OF MDYNPFIELDS OCCURS 1 .

INCLUDE STRUCTURE DYNPREAD .

DATA : END OF MDYNPFIELDS .

CONSTANTS BUTTONSELECTED(1) TYPE C VALUE 'X' .

* ======================================================

* Macro for Inputing Filenames

* ======================================================

DEFINE GET_FILENAME .

CALL FUNCTION 'WS_FILENAME_GET'

EXPORTING

* DEF_FILENAME = ' '

DEF_PATH = &1

MASK = ',*.*,*.*.'

MODE = '0'

* TITLE = ' '

IMPORTING

FILENAME = &2

* RC =

EXCEPTIONS

INV_WINSYS = 1

NO_BATCH = 2

SELECTION_CANCEL = 3

SELECTION_ERROR = 4

OTHERS = 5.

END-OF-DEFINITION .

* ======================================================

* Macro for Downloading to ASCII Files

* ======================================================

DEFINE DOWNLOAD_TO_ASCII .

CALL FUNCTION 'WS_DOWNLOAD'

EXPORTING

* BIN_FILESIZE = ' '

* CODEPAGE = ' '

FILENAME = &1

FILETYPE = 'DAT'

* MODE = ' '

* WK1_N_FORMAT = ' '

* WK1_N_SIZE = ' '

* WK1_T_FORMAT = ' '

* WK1_T_SIZE = ' '

* COL_SELECT = ' '

* COL_SELECTMASK = ' '

* NO_AUTH_CHECK = ' '

* IMPORTING

* FILELENGTH =

TABLES

DATA_TAB = &2

* FIELDNAMES =

EXCEPTIONS

FILE_OPEN_ERROR = 1

FILE_WRITE_ERROR = 2

INVALID_FILESIZE = 3

INVALID_TABLE_WIDTH = 4

INVALID_TYPE = 5

NO_BATCH = 6

UNKNOWN_ERROR = 7

GUI_REFUSE_FILETRANSFER = 8

OTHERS = 9.

END-OF-DEFINITION .

* ======================================================

* Macro for uploading Data from ASCII files

* ======================================================

DEFINE UPLOAD_FROM_ASCII .

CALL FUNCTION 'WS_UPLOAD'

EXPORTING

* CODEPAGE = ' '

FILENAME = &1

FILETYPE = 'DAT'

* HEADLEN = ' '

* LINE_EXIT = ' '

* TRUNCLEN = ' '

* USER_FORM = ' '

* USER_PROG = ' '

* IMPORTING

* FILELENGTH =

TABLES

DATA_TAB = &2

EXCEPTIONS

CONVERSION_ERROR = 1

FILE_OPEN_ERROR = 2

FILE_READ_ERROR = 3

INVALID_TABLE_WIDTH = 4

INVALID_TYPE = 5

NO_BATCH = 6

UNKNOWN_ERROR = 7

GUI_REFUSE_FILETRANSFER = 8

CUSTOMER_ERROR = 9

OTHERS = 10.

END-OF-DEFINITION .

* ======================================================

* Selection Screen Default

* ======================================================

PARAMETERS : P_FROM_P LIKE RS38M-PROGRAMM OBLIGATORY .

PARAMETERS : P_TO_P LIKE RS38M-PROGRAMM OBLIGATORY .

PARAMETERS : P_SAME_S RADIOBUTTON GROUP GRP1 DEFAULT 'X' .

PARAMETERS : P_DOWNLD RADIOBUTTON GROUP GRP1 .

PARAMETERS : P_UPLOAD RADIOBUTTON GROUP GRP1 .

PARAMETERS : P_FILE_D LIKE RLGRAP-FILENAME DEFAULT 'c:\varid.txt' .

PARAMETERS : P_FILE_S LIKE RLGRAP-FILENAME DEFAULT 'c:\varis.txt' .

PARAMETERS : P_FILE_T LIKE RLGRAP-FILENAME DEFAULT 'c:\varit.txt' .

PARAMETERS : P_FILE LIKE RLGRAP-FILENAME DEFAULT 'c:\vari.txt' .

* =====================================================

* At Selection Screen Events

* =====================================================

AT SELECTION-SCREEN .

PROGRAMM = P_FROM_P .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE_D .

GET_FILENAME 'c:\varid.txt' P_FILE_D .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE_S .

GET_FILENAME 'c:\varis.txt' P_FILE_S .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE_T .

GET_FILENAME 'c:\varit.txt' P_FILE_T .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE .

GET_FILENAME 'c:\vari.txt' P_FILE .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FROM_P .

CLEAR MDYNPFIELDS . REFRESH MDYNPFIELDS .

MDYNPFIELDS-FIELDNAME = 'P_FROM_P' .

APPEND MDYNPFIELDS .

CALL FUNCTION 'DYNP_VALUES_READ'

EXPORTING

DYNAME = SY-CPROG

DYNUMB = SY-DYNNR

TABLES

DYNPFIELDS = MDYNPFIELDS

EXCEPTIONS

INVALID_ABAPWORKAREA = 1

INVALID_DYNPROFIELD = 2

INVALID_DYNPRONAME = 3

INVALID_DYNPRONUMMER = 4

INVALID_REQUEST = 5

NO_FIELDDESCRIPTION = 6

INVALID_PARAMETER = 7

UNDEFIND_ERROR = 8

DOUBLE_CONVERSION = 9

STEPL_NOT_FOUND = 10

OTHERS = 11.

READ TABLE MDYNPFIELDS INDEX 1 .

PROGRAMM = MDYNPFIELDS-FIELDVALUE .

CALL FUNCTION 'REPOSITORY_INFO_SYSTEM_F4'

EXPORTING

OBJECT_TYPE = 'PROG'

OBJECT_NAME = PROGRAMM

IMPORTING

OBJECT_NAME_SELECTED = PROGRAMM

EXCEPTIONS

CANCEL = 1

WRONG_TYPE = 2

OTHERS = 3.

P_FROM_P = PROGRAMM .

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_TO_P .

CLEAR MDYNPFIELDS . REFRESH MDYNPFIELDS .

MDYNPFIELDS-FIELDNAME = 'P_TO_P' .

APPEND MDYNPFIELDS .

CALL FUNCTION 'DYNP_VALUES_READ'

EXPORTING

DYNAME = SY-CPROG

DYNUMB = SY-DYNNR

TABLES

DYNPFIELDS = MDYNPFIELDS

EXCEPTIONS

INVALID_ABAPWORKAREA = 1

INVALID_DYNPROFIELD = 2

INVALID_DYNPRONAME = 3

INVALID_DYNPRONUMMER = 4

INVALID_REQUEST = 5

NO_FIELDDESCRIPTION = 6

INVALID_PARAMETER = 7

UNDEFIND_ERROR = 8

DOUBLE_CONVERSION = 9

STEPL_NOT_FOUND = 10

OTHERS = 11.

READ TABLE MDYNPFIELDS INDEX 1 .

PROGRAMM = MDYNPFIELDS-FIELDVALUE .

CALL FUNCTION 'REPOSITORY_INFO_SYSTEM_F4'

EXPORTING

OBJECT_TYPE = 'PROG'

OBJECT_NAME = PROGRAMM

IMPORTING

OBJECT_NAME_SELECTED = PROGRAMM

EXCEPTIONS

CANCEL = 1

WRONG_TYPE = 2

OTHERS = 3.

P_TO_P = PROGRAMM .

* ======================================================

* Start of Selection

* ======================================================

START-OF-SELECTION .

CASE BUTTONSELECTED.

WHEN P_SAME_S .

PERFORM COPY_FROM_PROG_TO_PROG .

WHEN P_DOWNLD .

PERFORM VDOWNLOAD .

WHEN P_UPLOAD .

PERFORM VUPLOAD .

ENDCASE .

*&---------------------------------------------------*

*& Form COPY_FROM_PROG_TO_PROG

*&---------------------------------------------------*

* text

*----------------------------------------------------*

* --> p1 text

* p1 text

* p_datum. "valid from date

if konh-vakey = int_konp. "Conditions (Item) select single * from konp where knumh = konh-knumh. continue. endif.

endselect.

Return to :-

Hiding ABAP Source code

PROGRAM ZHIDE NO STANDARD PAGE HEADING. ************************************************************************ * This program hides any ABAP's source code and protects it with a * password in this source code. So the first candidate to be hidden * should be ZHIDE itself. * * After hiding, you can still run the abap (the load version is intact) * but it cannot be displayed, edited, traced, transported or generated. * * If the ABAP is not hidden, the program hides it, if it is hidden, it * unhides it. * * To execute this program, change the user name and password in this * source code first. ************************************************************************ SELECTION-SCREEN BEGIN OF BLOCK BLOCK. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(8) PWD. SELECTION-SCREEN POSITION 35. PARAMETERS: PASSWORD(8) MODIF ID AAA. SELECTION-SCREEN END OF LINE. PARAMETERS: PROGRAM(8). SELECTION-SCREEN END OF BLOCK BLOCK. * AT SELECTION-SCREEN OUTPUT. LOOP AT SCREEN. IF SCREEN-GROUP1 = 'AAA'. SCREEN-INVISIBLE = '1'. MODIFY SCREEN. ENDIF. ENDLOOP. * INITIALIZATION. PWD = 'PASSWORD'. * START-OF-SELECTION. TABLES: TRDIR. * User name and passsword check IF SY-UNAME 'SAP' OR PASSWORD 'PASSWORD'. WRITE: / 'Wrong password'. EXIT. ENDIF. * SAP owned? IF NOT PROGRAM CP 'Z*' AND NOT PROGRAM CP 'Y*'. WRITE: / 'Do not hide original SAP programs!'. EXIT. ENDIF. * Exists? SELECT SINGLE * FROM TRDIR WHERE NAME = PROGRAM. IF SY-SUBRC 0. WRITE: / 'Program does not exists!'. EXIT. ENDIF. * Does it have a current generated version? DATA: F1 TYPE D, F3 TYPE D. DATA: F2 TYPE T, F4 TYPE T. EXEC SQL. SELECT UDAT, UTIME, SDAT, STIME INTO :F1, :F2, :F3, :F4 FROM D010LINF WHERE PROG = :PROGRAM ENDEXEC. IF F1 < F3 OR ( F1 = F3 AND F2 < F4 ). WRITE: / 'The program has no recent generated version!'. EXIT. ENDIF. * Compose a new program name DATA: NEW_NAME(8), I TYPE I, J TYPE I. NEW_NAME = PROGRAM. DO 8 TIMES. I = SY-INDEX - 1. NEW_NAME+I(1) = '_'. * Search for acceptable program name variations J = 0. SELECT * FROM TRDIR WHERE NAME LIKE NEW_NAME. J = J + 1. ENDSELECT. IF J = 1. EXIT. ENDIF. NEW_NAME = PROGRAM. ENDDO. * Cannot generate appropriate program name IF J > 1. WRITE: / 'Cannot generate appropriate program name'. EXIT. ENDIF. * Check if it is already in d010s (already hidden) DATA: F5(8). EXEC SQL. SELECT PROG INTO :F5 FROM D010S WHERE PROG = :NEW_NAME ENDEXEC. IF F5 IS INITIAL. * There is no such hidden program, hide it EXEC SQL. UPDATE D010S SET PROG = :NEW_NAME WHERE PROG = :PROGRAM ENDEXEC. ELSE. * There is already a hidden program there, unhide it EXEC SQL. UPDATE D010S SET PROG = :PROGRAM WHERE PROG = :NEW_NAME ENDEXEC. ENDIF.

*** end of program

Client Strategy for Management of ABAP Projects

I am looking for some feedback regarding usage of multiple clients vs. multiple systems for parallel project development environment. I am constructing a system landscape where I am using multiple clients in the same R/3 server to facilitate development and testing of more than one projects (with same delivery time line). The challenges I am facing are management of ABAP objects (with overlaps) and client refresh from (production system for test data creations).

I would like to know if anybody else has managed similar circumstances and has any suggestion for me.

There are various ways to handle multiple projects within the SAP environment. The first and in my opinion, when possible, the best is to stop thinking of them as different projects and treat them as one implementation. If as you state both of these are working to the same timeline then I would suspect that they should be treated as one. Please remember that the last place that you want to test whether these two projects coexist is the first time that they run together in your production system.

If you do have to keep them separate a way to do this is for any ABAP that you write to check an own (Z or Y) table to determine whether it is relevant. I.e. have a flag per project determining whether in the run environment the project is active. I would do this with a function module / method so that it is very easy to switch off when no longer needed as then you would only have to change the function module rather than all the programs.

Proliferation of clients often leads to confusion, management and space problems. Wherever possible the simpler the landscape the better. Unfortunately simple is not always possible!

As you have mentioned we are already trying to club together all the projects (changes) with same delivery time. This actually leads us to move towards a coordinated integration test and roll out effort. However, the challenge is we have some project which are starting at the same time, but will go-live at different time line. This adds a difficult dimension of managing all the ABAP (especially when there are conflicts due to changes on the same object). I am trying to address this by separating the development and test environment for the projects belonging to two different delivery schedules.

I am still interested to use different clients in the development system to facilitate unit test for different projects (or changes) that has to the common delivery time. As for the unit test (especially data conversion) the programs and configurations may need their own set of data. For integration test I am trying to stage all the CTS on a different environment and then perform the complete test there. We have not used multiple clients a lot in the past and that actually forced us to use multiple systems for different project which has been a administrative headache. We are trying to streamline the system landscape (of course with some clean up of development and testing processes along with).

Please let me know if you have any other thought or come across any material that can be helpful for me.

OK there are a few things that I have done in the past. The first as I mentioned before is to separate the new code using a flag on an own table.

I don't know how many systems there are involved in your landscape. Generally when multiple projects have to be catered for I have used a 4 system landscape. Development, system test, UAT and production. What we then try to do is progress the different projects through the landscape at different times. I.E. projects 1 & 2 start. Project 1's timeline is quicker than project 2's. Both develop and unit test in the development system (using the separating flag). Project 1 when it is reasonably happy with its unit testing will then move into the system testing environment to start serious testing. Project 2 (as it has a different timeline) will still be in development. Once project 1 goes into UAT (moves out of system test) project 2 can then go into the system test environment. The same thing then happens in UAT. I.E. project one goes into live and project 2 then goes into system test.

If you already have SAP in production you also have to cope with the possibility that a live problem will occur necessitating changes to code that could potentially be being changed by both, either or none of the development projects. This does not seem to happen very often although when it does it can be painful. Some people who have a large budget have then gone to a 5 system landscape (2 UAT systems) and have kept the second UAT system in line with production. Others have decided to deal with this problem as it occurs. In my experience it does not occur frequently and can be dealt with within the 4 system landscape. This normally necessitates bringing the productive version back into the development system, correcting it and promoting it back up into the production system. The advantage that the 5 system landscape gives you is that you can then test against a production release level in the second UAT system. Without it you have to be sure what effect the new release level will have. After this you have to reapply the changes for the different project releases.

In a 5 system landscape when project 1 goes live and project 2 goes to UAT what is normally done then is that the UAT server that reflects live is brought up to date via the CTS and all the transports are applied to production via that system. The UAT test system is then completely rebuilt from that server. This ensures that project 2 will start from the right release.

Even within these complicated landscapes I try to ensure that the projects work in the same client. This is not always possible. When it is not possible a regression tasting phase is normally then included in project 2's testing.

Over and above all this when things get this complicated a release strategy is normally required. I.E. predetermined release dates (say 4) in the year at which point major releases can be implemented. This also tends to force co-ordinated testing / regression testing.

Obviously much of this is very expensive and heavily dependent on budget!

On the subject of multiple clients. when absolutely unavoidable I will have the following Client 1 - Master UAT client. This has all transports. No testing is allowed in this client. Minimum master data. Clients 2 & 3 are the different projects clients. Client 4 is a copy of client 1 and can be used for co-ordinated testing. If it gets messed up it can always be recreated from client 1. Client 5 is the user training client.

The numbering is not important. The number of project clients would depend on how many there have to be.

The hardest challenge once you start down the route of multiple clients is stopping! What seems to happen is then that as soon as a new project starts one of the first things you here is "I must have my own client, it won't work without it". Beware this route it can be very very expensive in both administration time and real money.

Return to :-

*

* Finding the user-exits of a SAP transaction code

*

* Enter the transaction code in which you are looking for the user-exit

* and it will list you the list of user-exits in the transaction code.

* Also a drill down is possible which will help you to branch to SMOD.

*

* Written by : SAP Basis, ABAP Programming and Other IMG Stuff

* http://www.sap-img.com

*

report zuserexit no standard page heading.

tables : tstc, tadir, modsapt, modact, trdir, tfdir, enlfdir.

tables : tstct.

data : jtab like tadir occurs 0 with header line.

data : field1(30).

data : v_devclass like tadir-devclass.

parameters : p_tcode like tstc-tcode obligatory.

select single * from tstc where tcode eq p_tcode.

if sy-subrc eq 0.

select single * from tadir where pgmid = 'R3TR'

and object = 'PROG'

and obj_name = tstc-pgmna.

move : tadir-devclass to v_devclass.

if sy-subrc ne 0.

select single * from trdir where name = tstc-pgmna.

if trdir-subc eq 'F'.

select single * from tfdir where pname = tstc-pgmna.

select single * from enlfdir where funcname =

tfdir-funcname.

select single * from tadir where pgmid = 'R3TR'

and object = 'FUGR'

and obj_name eq enlfdir-area.

move : tadir-devclass to v_devclass.

endif.

endif.

select * from tadir into table jtab

where pgmid = 'R3TR'

and object = 'SMOD'

and devclass = v_devclass.

select single * from tstct where sprsl eq sy-langu and

tcode eq p_tcode.

format color col_positive intensified off.

write:/(19) 'Transaction Code - ',

20(20) p_tcode,

45(50) tstct-ttext.

skip.

if not jtab[] is initial.

write:/(95) sy-uline.

format color col_heading intensified on.

write:/1 sy-vline,

2 'Exit Name',

21 sy-vline ,

22 'Description',

95 sy-vline.

write:/(95) sy-uline.

loop at jtab.

select single * from modsapt

where sprsl = sy-langu and

name = jtab-obj_name.

format color col_normal intensified off.

write:/1 sy-vline,

2 jtab-obj_name hotspot on,

21 sy-vline ,

22 modsapt-modtext,

95 sy-vline.

endloop.

write:/(95) sy-uline.

describe table jtab.

skip.

format color col_total intensified on.

write:/ 'No of Exits:' , sy-tfill.

else.

format color col_negative intensified on.

write:/(95) 'No User Exit exists'.

endif.

else.

format color col_negative intensified on.

write:/(95) 'Transaction Code Does Not Exist'.

endif.

at line-selection.

get cursor field field1.

check field1(4) eq 'JTAB'.

set parameter id 'MON' field sy-lisel+1(10).

call transaction 'SMOD' and skip first screen.

*---End of Program