Anda di halaman 1dari 45

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
o Basic Lists are details reports. Every records in the table are printed.
o Statistic are summary reports. The records with the same keys are group
together.
o 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 "eventdriven", "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 <TABLE>
CHECK: <CONDITION>
ENDSELECT

vs.
SELECT * FROM <TABLE>
WHERE <CONDITION>
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 <TABLE> INTO <INT-TAB>
APPEND <INT-TAB>
ENDSELECT
vs.
SELECT * FROM <TABLE> INTO TABLE <INT-TAB>

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 <INT-TAB> + LOOP AT T

SELECT * FROM <TABLE> INTO TABLE <INT-TAB>.


LOOP AT <INT-TAB>.
ENDLOOP.
vs.
SELECT * FROM <TABLE>
.
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 <TABLE-A>
SELECT * FROM <TABLE-B>
..
ENDSELECT.
ENDSELECT
vs.

Select with view


SELECT * FROM <VIEW>
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 <TABLE>


vs.
SELECT <column(s)> FROM <TABLE>
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 <INT-TAB>
INSERT INTO <TABLE> VALUES <INT-TAB>
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 <TABLE>

<COLUMN-UPDATE STATEMENT>
UPDATE <TABLE>
ENDSELECT
vs.
Column updates
UPDATE <TABLE> SET <COLUMN-UPDATE STATEMENT>
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+SYFDPOS(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: <l_table> TYPE ANY TABLE,
<l_line> TYPE ANY,
<l_field> 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 <l_table>.
CREATE DATA new_line LIKE LINE OF <l_table>.
ASSIGN new_line->* TO <l_line>.
* Test it...
DO 30 TIMES.
ASSIGN COMPONENT 'SUBRC' OF STRUCTURE <l_line> TO <l_field>.
<l_field> = sy-index.
INSERT <l_line> INTO TABLE <l_table>.
ENDDO.
LOOP AT <l_table> ASSIGNING <l_line>.
ASSIGN COMPONENT 'SUBRC' OF STRUCTURE <l_line> TO <l_field>.
WRITE <l_field>.

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
ldate

to date-low,
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 offdays 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
DOUBLE_CONVERSION
STEPL_NOT_FOUND
OTHERS

=
=
=
=

8
9
10
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
* <-- p2
text
*----------------------------------------------------*
FORM COPY_FROM_PROG_TO_PROG.

*
*
*
*
*

CALL FUNCTION 'POPUP_TO_CONFIRM_STEP'


EXPORTING
DEFAULTOPTION = 'Y'
TEXTLINE1
= 'Are you sure you want to copy Variants ? '
TEXTLINE2
= ' '
TITEL
= 'Confirmation '
START_COLUMN
= 25
START_ROW
= 6
CANCEL_DISPLAY = 'X'
IMPORTING
ANSWER
= MANS
EXCEPTIONS
OTHERS
= 1.
IF MANS = 'J' .

* -----------------------------------------------------REFRESH MYVARID . CLEAR MYVARID .


SELECT * FROM VARID INTO TABLE MYVARID
WHERE REPORT = P_FROM_P.
LOOP AT MYVARID .
MYVARID-REPORT = P_TO_P .
MODIFY MYVARID .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARID WHERE REPORT = P_TO_P .
INSERT VARID FROM TABLE MYVARID .
ENDIF .
* ---------------------------------------------------REFRESH MYVARIS . CLEAR MYVARIS .
SELECT * FROM VARIS INTO TABLE MYVARIS
WHERE REPORT = P_FROM_P.
LOOP AT MYVARIS .
MYVARIS-REPORT = P_TO_P .
MODIFY MYVARIS .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARIS WHERE REPORT = P_TO_P .
INSERT VARIS FROM TABLE MYVARIS .
ENDIF .
* ----------------------------------------------------REFRESH MYVARIT . CLEAR MYVARIT .
SELECT * FROM VARIT INTO TABLE MYVARIT
WHERE REPORT = P_FROM_P.
LOOP AT MYVARIT .
MYVARIT-REPORT = P_TO_P .
MODIFY MYVARIT .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARIT WHERE REPORT = P_TO_P .
INSERT VARIT FROM TABLE MYVARIT .
ENDIF .
* ----------------------------------------------------REFRESH MYVARI . CLEAR MYVARI .
SELECT * FROM VARI
INTO TABLE MYVARI
WHERE REPORT = P_FROM_P.
LOOP AT MYVARI .
MYVARI-REPORT = P_TO_P .
MODIFY MYVARI .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARI WHERE REPORT = P_TO_P .
INSERT VARI FROM TABLE MYVARI .
ENDIF .
ENDIF .
ENDFORM.

" COPY_FROM_PROG_TO_PROG

*&-----------------------------------------------------*
*&
Form VDOWNLOAD
*&-----------------------------------------------------*
*
text

*------------------------------------------------------*
* --> p1
text
* <-- p2
text
*------------------------------------------------------*
FORM VDOWNLOAD.
REFRESH MYVARID . CLEAR MYVARID .
SELECT * FROM VARID INTO TABLE MYVARID
WHERE REPORT = P_FROM_P.
DOWNLOAD_TO_ASCII P_FILE_D MYVARID .
* ----------------------------------------------------REFRESH MYVARIS . CLEAR MYVARIS .
SELECT * FROM VARIS INTO TABLE MYVARIS
WHERE REPORT = P_FROM_P.
DOWNLOAD_TO_ASCII P_FILE_S MYVARIS .
* ----------------------------------------------------REFRESH MYVARIT . CLEAR MYVARIT .
SELECT * FROM VARIT INTO TABLE MYVARIT
WHERE REPORT = P_FROM_P.
DOWNLOAD_TO_ASCII P_FILE_T MYVARIT .
* ---------------------------------------------------REFRESH MYVARI . CLEAR MYVARI .
SELECT * FROM VARI
INTO TABLE MYVARI
WHERE REPORT = P_FROM_P.
DOWNLOAD_TO_ASCII P_FILE MYVARI .
ENDFORM.

" VDOWNLOAD

*&-----------------------------------------------------*
*&
Form VUPLOAD
*&-----------------------------------------------------*
*
text
*------------------------------------------------------*
* --> p1
text
* <-- p2
text
*------------------------------------------------------*
FORM VUPLOAD.
CALL FUNCTION 'POPUP_TO_CONFIRM_STEP'
EXPORTING
*
DEFAULTOPTION = 'Y'
TEXTLINE1
=
'Are you sure you want to upload Variants ? '
*
TEXTLINE2
= ' '
TITEL
= 'Confirmation '
*
START_COLUMN
= 25
*
START_ROW
= 6
*
CANCEL_DISPLAY = 'X'
IMPORTING
ANSWER
= MANS
EXCEPTIONS
OTHERS
= 1.
IF MANS = 'J' .
* ----------------------------------------------------REFRESH MYVARID . CLEAR MYVARID .

UPLOAD_FROM_ASCII P_FILE_D MYVARID .


LOOP AT MYVARID .
MYVARID-REPORT = P_TO_P .
MODIFY MYVARID .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARID WHERE REPORT = P_TO_P .
INSERT VARID FROM TABLE MYVARID .
ENDIF .
* ----------------------------------------------------REFRESH MYVARIS . CLEAR MYVARIS .
UPLOAD_FROM_ASCII P_FILE_S MYVARIS .
LOOP AT MYVARIS .
MYVARIS-REPORT = P_TO_P .
MODIFY MYVARIS .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARIS WHERE REPORT = P_TO_P .
INSERT VARIS FROM TABLE MYVARIS .
ENDIF .
* ----------------------------------------------------REFRESH MYVARIT . CLEAR MYVARIT .
UPLOAD_FROM_ASCII P_FILE_T MYVARIT .
LOOP AT MYVARIT .
MYVARIT-REPORT = P_TO_P .
MODIFY MYVARIT .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARIT WHERE REPORT = P_TO_P .
INSERT VARIT FROM TABLE MYVARIT .
ENDIF .
* -----------------------------------------------------REFRESH MYVARI . CLEAR MYVARI .
UPLOAD_FROM_ASCII P_FILE MYVARI
.
LOOP AT MYVARI .
MYVARI-REPORT = P_TO_P .
MODIFY MYVARI .
ENDLOOP .
IF SY-SUBRC = 0 .
DELETE FROM VARI WHERE REPORT = P_TO_P .
INSERT VARI FROM TABLE MYVARI .
ENDIF .
ENDIF .
ENDFORM.

" VUPLOAD

Creation and download an XML file


REPORT z_down_xml LINE-SIZE 132 NO STANDARD PAGE HEADING.
**********************************************************************
* REPORT Z_DOWN_XML - Using an internal table (gt_marc)
*
* and downloading the report data as an xml file
*
* The xml indentation is hard coded into the file
*
**********************************************************************
* Databases
TABLES:
makt,
"Mat description

marc,
t001w,
bhdgd.

"Material / plant
"plant name
"Batch heading

* Internal tables
DATA:
BEGIN OF gt_marc OCCURS 0,
werks LIKE marc-werks,
matnr LIKE marc-matnr,
END OF gt_marc,
* Table to be downloaded as xml. Each line stores start and end tags
* and the value
BEGIN OF gt_xml OCCURS 0,
line(120),
END OF gt_xml,
g_maktx(120).
* User-input
SELECT-OPTIONS:
s_werks FOR marc-werks,
s_matnr FOR marc-matnr.
**********************************************************************
START-OF-SELECTION.
* Extract all required data
PERFORM main_processing.
**********************************************************************
END-OF-SELECTION.
SORT gt_marc BY werks matnr.
LOOP AT gt_marc.
AT FIRST.
CLEAR gt_xml.
gt_xml-line = '<LOCATIONS>'.
APPEND gt_xml.
CLEAR gt_xml.
ENDAT.

"First tag must be root

AT NEW werks.
"At new plant
PERFORM read_plant.
FORMAT COLOR 4 ON.
SKIP 1.
WRITE :/ gt_marc-werks, t001w-name1.
FORMAT COLOR 4 OFF.
CLEAR gt_xml.
gt_xml-line = ' <PLANT>'.
APPEND gt_xml.
CLEAR gt_xml.
CONCATENATE ' <NUMBER>' gt_marc-werks '</NUMBER>'
INTO gt_xml-line.
APPEND gt_xml.

CLEAR gt_xml.
CONCATENATE ' <NAME>' t001w-name1 '</NAME>' INTO gt_xml-line.
APPEND gt_xml.
CLEAR gt_xml.
gt_xml-line = ' </PLANT>'.
APPEND gt_xml.
CLEAR gt_xml.
ENDAT.
PERFORM read_description.
CLEAR gt_xml.
gt_xml-line = ' <MATERIAL>'.
APPEND gt_xml.
CLEAR gt_xml.
CONCATENATE ' <NAME>' g_maktx '</NAME>'
INTO gt_xml-line.
APPEND gt_xml.
CLEAR gt_xml.
CONCATENATE ' <NUMBER>' gt_marc-matnr '</NUMBER>'
INTO gt_xml-line.
APPEND gt_xml.
CLEAR gt_xml.
gt_xml-line = ' </MATERIAL>'.
APPEND gt_xml.
CLEAR gt_xml.
* display data
FORMAT COLOR 2 ON.
WRITE :/ gt_marc-matnr, makt-maktx.
FORMAT COLOR 2 OFF.
ENDLOOP.
* The last tag must be the root closing tag --*
gt_xml-line = '</LOCATIONS>'.
APPEND gt_xml.
CLEAR gt_xml.
CALL FUNCTION 'DOWNLOAD'
EXPORTING
filename = 'C:\PLANT1.XML'
filetype = 'ASC'
TABLES
data_tab = gt_xml.
**********************************************************************
TOP-OF-PAGE.
MOVE sy-title TO bhdgd-line1.
MOVE sy-repid TO bhdgd-repid.
MOVE sy-uname TO bhdgd-uname.
MOVE sy-datum TO bhdgd-datum.
MOVE '0' TO bhdgd-inifl.
MOVE '132' TO bhdgd-lines.
FORMAT INTENSIFIED ON COLOR COL_HEADING.
PERFORM batch-heading(rsbtchh0).
"report header

*---------------------------------------------------------------------*
* Form READ_PLANT
*---------------------------------------------------------------------*
FORM read_plant.
* Get plant name
CLEAR t001w.
SELECT SINGLE name1
INTO t001w-name1
FROM t001w
WHERE werks EQ gt_marc-werks.
ENDFORM.
" READ_PLANT
*---------------------------------------------------------------------*
* Form MAIN_PROCESSING
*---------------------------------------------------------------------*
FORM main_processing.
* Material and
SELECT werks
INTO TABLE
FROM marc
WHERE werks
AND matnr

plant basic data


matnr
gt_marc
IN s_werks
IN s_matnr.

ENDFORM.
" MAIN_PROCESSING
*---------------------------------------------------------------------*
* Form READ_DESCRIPTION
*---------------------------------------------------------------------*
FORM read_description.
* Material name
CLEAR g_maktx.
SELECT SINGLE maktx
INTO g_maktx
FROM makt
WHERE matnr EQ gt_marc-matnr
AND spras EQ 'E'.
* Replace special character
DO.
REPLACE '&' WITH '*%;' INTO g_maktx.
IF NOT sy-subrc IS INITIAL. EXIT.ENDIF.
ENDDO.
DO.
REPLACE '*%;' WITH '&amp;' INTO g_maktx.
IF NOT sy-subrc IS INITIAL. EXIT.ENDIF.
ENDDO.
DO.
REPLACE '/' WITH '&#47;' INTO g_maktx.
IF NOT sy-subrc IS INITIAL. EXIT.ENDIF.
ENDDO.
ENDFORM.
" READ_DESCRIPTION
******************** END OF PROGRAM Z_DOWN_XML ************************

Write the SAP ICONS on your reports

This program list for you all the SAP ICONS that can be used in your reports. Take note
that the SAP ICONS are used for interative reports. It can be display on screens. You
will only see the icon names when you do a print out.
REPORT ZICONS .
TABLES: ICON.
INCLUDE <ICON>.
FIELD-SYMBOLS: <F>.
* When displaying ICON, specify the maximum length of 4
WRITE: / 'ICON IN WRITE STATEMENT ', (4) ICON_ALARM.
SKIP.
WRITE: / 'List of SAP ICONS, minimum length 2, maximum length 4.'.
SKIP.
SELECT * FROM ICON.
ASSIGN (ICON-NAME) TO <F>.
WRITE: /(5) <F>, 20 '@',21 ICON-ID+1(2),23 '@',ICON-OLENG,
ICON-BUTTON,ICON-STATUS,ICON-MESSAGE,ICON-FUNCTION,
ICON-NAME.
ENDSELECT.
Return to :Extract the Producton Order System Status Table
tables: aufk
jest,
tj02t.

"Order master data


"Object status
"Status Description

* Order Status - To Retrieve & Filter


select stat from jest
where objnr = aufk-objnr " objnr means object no
and stat in ('I0012', 'I0045', 'I0074', 'I0076')
and inact ne 'X'
"Flag: Status inactive
order by stat.
select single * from tj02t
where istat = jest-stat
and spras = 'E'.
Retrieve the Purchase Order Condition Records Table
select * from ekko.
select * from konv where knumv = ekko-knumv
"Get all the condition records for the purchase order

endselect.
endselect.
* Get the info record conditions record
* First declare the record structure for the key
data: begin of int_konp,
txt1(5),
lifnr(5),
matnr(18),
txt2(4),
txt3(1),
end of int_konp.
clear: konh, konp, int_konp.
* data for the record key konh-vakey
int_konp-txt1 = '00000'.
int_konp-lifnr = ekko-lifnr+5(5).
int_konp-matnr = ekpo-matnr(18).
int_konp-txt2 = 'ALL'.
int_konp-werks = ekpo-werks.
int_konp-txt3 = '0'.
select * from konh where
kschl = 'PB00'
and datab => p_datum.

"Conditions (Header)
"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