The difference between a normal programmer and a good programmer is, the latter keeps his/her basics right. Good programmers are distinguished by the quality of their deliverables. They provide enough documentation in their object so that the future practitioners supporting their product do not curse them. One of my Team Lead once told me, “your code should not only meet the functionalities, it should also be asthetically pleasing if someone happens to peep into it“.
Today, in this post I do not want to bore you with the “Gyan” (Sanskrit word that roughly translates to “sermons/preachings”). But, I would like to provide a list of simple checks which every programmer should remember even in their sleep… 🙂
Note: Numbers are only for bullet marker. It does not rate one higher to next. Every point has different weightage in different scenarios.
1) Define your variables with meaningful names (eg: instead of v_var1; v_material is more meaningful). Provide as much documentations/halfline comments as possible. Align your code and demarcate your blocks. Provide uniform spacing in between different units and remove dead codes. Clean code would reflect your personality.. 😉
2) In the AT SELECTION-SCREEN event, use UP TO 1 ROWS (or count( * ) UP TO 1 ROWS) in the SELECT statement used for validating the data since the idea is just to ensure that at least 1 row will be considered for processing in the main selection event.
3) Internal table is defined with “TYPE STANDARD/SORTED/HASHED TABLE OF” “INITIAL SIZE 0” and work area is used instead of tables with HEADER LINES. If you have multiple internal tables of same type, you need not always define as many work areas. Same work area should be used across multiple internal tables, if they are of same type.
4) Declare global internal tables only if they are expected to be used globally (across multiple subroutines) in the program. This is to avoid unnecessary memory usage as local internal tables are cleared from the memory on exiting the subroutine.
5) Wild cards like ‘A%’ should be avoided as much as possible.
6) Always SELECT INTO internal table, except when the table will be very large, use “UP TO N Rows” when the number of records needed is known.
7) Use “JIT”, Just In Time concept to select data when needed, use them and free them. Most programmers have the habit of selecting all the tables one by one first and then processing/massaging them later at the end. This practice burdens the system by unnecessary memory consumption by holding the data when they are not needed. SELECTs should be done when needed and FREE/REFRESH the tables as soon as it is used and not needed afterwards.
8) SORT fields and SORT Order on the SORT statement should be mentioned explicitly (e.g. SORT ITAB BY FLD1 ASCENDING FLD2 DESCENDING).
9) HASHED table is used for processing large amount of data (provided that you access single records only, and all with a fully specified key).
10) DELETE or SORT is not used on a HASHED table since it increases memory consumption.
11) Fields specified in the WHERE condition with the critical operators NOT and <> (negative SQL statements) cannot be used for a search using database indexes. Whenever possible formulate SQL statements positively. Avoid negation statements.
12) When IF or CASE, testing conditions are nested so that the most frequently true conditions are processed first. Also CASE is used instead of IF when testing multiple fields “equal to” something.
13) READ TABLE INTO WORKAREA should be used instead of only READ TABLE. If INTO work area is not needed then, use the addition TRANSPORTING NO FIELDS if the purpose of the read statement is only to check the existence of the record in that table.
14) For copying internal tables use ‘=’ operator instead of LOOPing and appending. SORT inside a LOOP should be avoided.
15) Do not delete the records of internal table inside the LOOP — ENDLOOP. Instead mark the rows to be deleted by passing some identifier to the row field(s) and delete all those identified after the end of LOOP. Use Field Symbol, if you want to modify the fields of a table in the LOOP. Usage of field symbol would avoid modify statement inside the LOOP.
16) Use CONTROL BREAKS in the LOOP — ENDLOOP syntax to avoid repeated reading of other internal tables and for summarizing / updating the internal tables.
17) DELETE ADJACENT DUPLICATES entries from internal table before selection from database table using “ FOR ALL ENTRIES” statement. Applicable only in those cases where the table can possibly have duplicate entries.
18) Nested SELECT should not be used instead, “INNER JOIN” and/or “FAE” should be used. “FAE” is to be used over “LOOP at ITAB / SELECT / ENDLOOP”.
19) In SELECT statement, only the required fields should be selected from the database table/structure/view. While using FOR ALL ENTRIES, make sure to SELECT all the primary keys even if you do not need some of them later as FAE retrieves unique result set. For selecting single row from a database table, “SELECT UP TO 1 ROWS” is used (when you do not have full primary key for your WHERE clause). Always CHECK that the internal table used in FOR ALL ENTRIES is NOT empty. “SELECT SINGLE” is used only when full primary key combination is known. Avoid SELECT * as much as possible.
20) When creating JOINs over database tables there should be an index at least on the inner table for the fields in the JOIN condition else use “ FOR ALL ENTRIES” SELECT statement. Ensure that the inner join uses the correct indexes.
21) SORT internal table by fields in the correct order, which are used in a READ TABLE statement using BINARY SEARCH. If the order of SORTING is invalid, the BINARY SEARCH will never work. And you would be scratching your head for a long time to find the root cause if you need to do dry run where issues could be replicated.. 😛
22) Avoid MODIFY, use explicit INSERT or UPDATE; it is better for performance and support. MODIFY statement is more attractive to programmers because of the ease of usage. But, believe me, splitting your table entries to INSERT and UPDATE is still better, even though it might need one more select statements. Tried and Tested in real projects. 😛
23) For large internal tables where only some rows are to be processed, use SORT and then the READ TABLE command is used to set index to first relevant row before LOOPing from that index. Use CHECK or IF…EXIT…ENDIF as appropriate to exit from the loop. Also called, Parallel Cursor technique.
24) SORTed table is used for range accesses involving table key or index accesses. SORTed tables are particularly useful in nested loop processing. LOOP AT ITAB with a WHERE condition is preferred where ITAB is a SORTED table (instead of STANDARD or HASHED internal table) and the fields used in the WHERE condition are the non-unique key fields of the sorted table.
25) Use indexed table like VAPMA instead of VBAP to identify sales orders for a particular MATNR (i.e in situations when you have material and you do not have VBELN (sales order number) in hand). Similarly VAKPA etc. VBFA is used for forward search i.e. preceding to subsequent. For subsequent to preceding we should use alternate tables such as LIPS or VBRP (VBGEL, VGPOS). Try to use Views instead of joining multiple tables.
26) Run Code Inspector and Extended syntax checks with character literals checkbox switched on to rectify all relevant errors and warnings. SAP has provided this cool feature, please use it. Proudly flaunt the results with zero/ignorable warnings. 😉
27) Use transaction code SCI/SCII to do the sanity check of your deliverables before passing it to the quality reviewers. Easy way to impress your reviewer. 😛
28) Use transaction code ST05/ST12 to trace your code. Make sure to check what indices your database accesses are using. Check these indices against your “WHERE” clause to assure they are significant. Check other indices for this table and where you have to change your “WHERE” clause to use it. Create new indices if necessary after consulting your Basis team. For client dependant tables, use MANDT as the first field in the secondary index since it is internally considered by SAP when retrieving the data from the database tables.
Please note, this article is not intended for Performance Tuning. This is an effort to remind the programmers about the simple checks which we should take care as part of good programming practice. Please feel free to suggest if you think something is missing. We would be happy to add them in this list.