We can help. Together we learn....

CL_GUI_ALV_GRID

by Voice | Wednesday, December 24, 2008 in | comments (5)

I was writing a program for ALV Grid after a long time. I was using CL_GUI_ALV_GRID class for the required ALV display and I encountered some problems. I tried to consult with my friends and finally we did it but it took a lot of experimentation and time and also I came to know a lot of things about CL_GUI_ALV_GRID and thought it is worth sharing.

First and foremost, never make unnecessary custom screens and containers it is not totally unavoidable. Custom screens with containers look pretty but it causes a unique problem which is hard to conceive. Have a look.. 


This is normal display. I used a custom screen with container to show the ALV Grid. Click on Customize Local Layout (Alt+F12) and then Font and increase the font size.

Depending on your monitor size and resolution at some point you will see that scroll bars are gone. Something like this will happen

Actually the custom window has got magnified and the scroll bars are out of monitor size. This problem will not happen if you use the default screen for report display.

 

Now if you want to add a header you can use TOP-OF-PAGE event which I am sure most of you use. Now if you try printing the ALV grid display, all you will get is the ALV display only and no header in the print out.

If you want print out you have to add another Event, PRINT_TOP_OF_PAGE. What ever you will write here will get printed.

 

Then also you will face problems for printing the page number. Please write to me in the comment section if you want to know how, I don’t want to make this post any longer

Please let me know if any of you want the code or some other information. Reason is same… I don’t want to increase the size of the post.



In very few developments we need Dynamic Where Condition for data base (DB) queries. Meaning; during runtime your program may decide which all fields of the data base table to be used for the DB query. We can very well write our custom code for developing those Dynamic Where Condition. But we know the effort and pain it takes to write such a code or else we can use a Standard SAP function module CRS_CREATE_WHERE_CONDITION to achieve the requirement.


Sample Example:

Lets consider, we have a program which will follow some logic and finally it comes to the conclusion that it will have to do a query on Data Base table MARA based on the fields MATNR (Material Number) and MTART (Material Type). There could be some other possible fields based on which the query can be made and this will be decided at run time. The table fields and their corresponding values can not be know until run time . So we need a Dynamic Where Condition for the Data Base Query. In such a condition you may choose to explore all possible combinations of fields to be used in the where condition and write your custom code to manufacture a Dynamic Where Condition or you can just use a Function Module (FM) which will do the job you.

We will discuss the above situation considering a program, with a selection screen having both the fields MATNR and MTART. (Let us assume these two fields and their corresponding values will be not be available until runtime).


REPORT z_dynamic_where_condition.

* Types
TYPES: BEGIN OF x_mara,
matnr TYPE matnr, "Material Number
mtart TYPE mtart, "Material Type
END OF x_mara.

DATA:
* Internal table
l_i_range TYPE STANDARD TABLE OF crmselstr,
l_i_output TYPE STANDARD TABLE OF mcondition,
l_i_mara TYPE STANDARD TABLE OF x_mara,

* Work area
l_wa_range TYPE crmselstr,

* Variable
v_matnr TYPE mara-matnr,
v_mtart TYPE mara-mtart.


* Selection Screen
SELECT-OPTIONS: s_matnr FOR v_matnr,
s_mtart FOR v_mtart.

* For Select Option 1
LOOP AT s_matnr. "Looping to get multiple (single) values
l_wa_range-table = 'MARA'. "Name of the DB table
l_wa_range-field = 'MATNR'. "Field name the user has selected
l_wa_range-sign = s_matnr-sign. "Sign
l_wa_range-option = s_matnr-option."option
l_wa_range-low = s_matnr-low. "Lower Value
l_wa_range-high = s_matnr-high. "Higher Value
APPEND l_wa_range TO l_i_range.
ENDLOOP..

* For Select Option 2
LOOP AT s_mtart. "Looping to get multiple (single) values
CLEAR l_wa_range.
l_wa_range-table = 'MARA'. "Name of the DB table
l_wa_range-field = 'MTART'. "Field name the user has selected
l_wa_range-sign = s_mtart-sign. "Sign
l_wa_range-option = s_mtart-option. "option
l_wa_range-low = s_mtart-low. "Lower Value
l_wa_range-high = s_mtart-high. "Higher Value
APPEND l_wa_range TO l_i_range.
ENDLOOP.


IF NOT l_i_range[] IS INITIAL.

* Call the FM to create the Dynamic Where condition
CALL FUNCTION 'CRS_CREATE_WHERE_CONDITION'
TABLES
ti_range = l_i_range
to_cond = l_i_output
EXCEPTIONS
invalid_input = 1
OTHERS = 2.

IF sy-subrc = 0.

* Special way to write the query
SELECT matnr "Material Number
mtart "Material Type
FROM mara
INTO TABLE l_i_mara
WHERE (l_i_output).

IF sy-subrc = 0.

ENDIF.

ENDIF. "IF sy-subrc = 0: SELECT matnr mtart

ENDIF. "IF NOT l_i_range[] IS INITIAL.

******************************************************************
** You may need an Dynamic Internal table in such a scenario.
So find here the link for the same **

http://help-sap.blogspot.com/search/label/Internal%20table
******************************************************************

Ever tried it. It is not so simple :)


Method 1
--------------
a) Create a subscreen area in your screen layout where you want to create the select options.
b) In the top include of  your module pool program declare a selection screen as a subscreen e.g.
       SELECTION-SCREEN BEGIN OF SCREEN 100 AS SUBSCREEN.
             select-options s_matnr for mara-matnr.
       SELECTION-SCREEN END OF SCREEN.
c) In the PBO and PAI of the main screen where the select options needs to be created do a call subscreen of the above screen (100).
       CALL SUBCREEN sub_area INCLUDING    
  This call subscreen statement is necessary for transport of values between screen and program.

Note: All validations of the selection screen fields e.g. the s_matnr field created above should be done in selection screen events like AT SELECTION-SCREEN etc and not in PAI. These selection screen validations etc should be done in the top include only.

Method 2
---------------
a) Create 2 separate fields in your screen layout - one for the low value and one for the high value. Insert an icon beside the high value which will call the multiple selections popup screen on user command. Use function module COMPLEX_SELECTIONS_DIALOG to achieve this. 

struc_tab_and_field-fieldname   = con_cust.      " 'KUNNR'
struc_tab_and_field-tablename = con_kna1.     " 'KNA1'.

CALL FUNCTION 'COMPLEX_SELECTIONS_DIALOG'
          EXPORTING
*           TITLE                   = ' '
            text                         = g_titl1                                " 'Customers'
            tab_and_field     = struc_tab_and_field
          TABLES
            RANGE                   = rng_kunnr
          EXCEPTIONS
            NO_RANGE_TAB          = 1
            CANCELLED                    = 2
            INTERNAL_ERROR     = 3
            INVALID_FIELDNAME = 4
            OTHERS                           = 5.

IF NOT rng_kunnr[] IS INITIAL.
*          Read the very first entry of the range table and pass it to
*          dynpro screen field
           READ TABLE rng_kunnr INDEX 1.
           IF sy-subrc = 0.
              g_cust = rng_kunnr-low.
           ENDIF.

You can use the return table rng_kunnr to populate your own internal range table with the values entered by the user. Basically here you are just simulating the work of a select-options parameter by module pool screen elements.

Sometimes we have specific requirements while designing a selection screen. We may have to place more than one Parameter (or Select Option or Radio Button). This can be easily done by using the selection screen BEGIN OF LINE / END OF LINE statements.

The following code extract will help you in designing such a selection screen.

*** Start of Code ***
DATA: l_field TYPE char10,
l_pos TYPE char4.

SELECTION-SCREEN BEGIN OF BLOCK out WITH FRAME TITLE text-s01.
* Line 1
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 5(15) text-010 FOR FIELD p_field1.
PARAMETERS: p_field1 LIKE l_field.
SELECTION-SCREEN COMMENT 45(15) text-011 FOR FIELD p_pos11.
PARAMETERS: p_pos11 LIKE l_pos.
SELECTION-SCREEN COMMENT 75(15) text-012 FOR FIELD p_pos12.
PARAMETERS: p_pos12 LIKE l_pos.
SELECTION-SCREEN END OF LINE.

*** End of Code ***

Output:


Instead of Parameters, you can easily have other elements like Radio Buttons or Select Options. The important thing here is that you need to keep the correct spacing and position or else you can get a selection screen generation error during activating the code, even if your code is syntactically correct.

Value entered in the selection screen, displayed automatically by the function module is nice tabular fashion. Very helpful when the selection screen is huge having a lot of parameters and select options.

 

*----------------------------------------------------------------------*
* T A B L E S *
*----------------------------------------------------------------------*
TABLES: mara.
*----------------------------------------------------------------------*
* S E L E C T I O N S C R E E N *
*----------------------------------------------------------------------*
SELECTION-
SCREENBEGIN OF BLOCK b2 WITH FRAME.
SELECT-OPTIONS: mat FOR mara-matnr NO INTERVALS.
SELECT-OPTIONS: mtype FOR mara-mtart NO INTERVALS.
SELECTION-
SCREENEND OF BLOCK b2.

END-OF-SELECTION.
WRITE:/ 'Thank you'.

TOP-
OF-PAGE.
DATA: i_sel TYPE STANDARD TABLE OF rsparams INITIAL SIZE 0.
  
IF sy-pagno EQ 1.
* Call function for getting selection screen details
    
CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS'
      
EXPORTING
        curr_report     = sy-cprog
      
TABLES
        selection_table = i_sel
      
EXCEPTIONS
        not_found       = 
1
        no_report       = 
2
        
OTHERS          = 3.
    
IF sy-subrc <> 0.
      
WRITE:/ 'Fails to get the selection screen details'(201).
    
ENDIF.

* Displaying selection screen details
    
CALL FUNCTION 'RS_LIST_SELECTION_TABLE'
      
EXPORTING
        
report        = sy-cprog
        seltext       = 
'X'
        screennr      = 
' '
      
TABLES
        sel_tab       = i_sel
      
EXCEPTIONS
        sel_tab_empty = 
1
        
OTHERS        = 2.
    
IF sy-subrc <> 0.
      
WRITE:/ 'Fails to display the selection screen details'(202).
    
ENDIF.
  
ENDIF.




Restricting range entry for select-option.

by Voice | Thursday, November 06, 2008 in | comments (2)

Sometime it is required to restrict range input for a select option.  SAP provides an extension which is generally used for this is NO INTERVALS.

 Code:SELECT-OPTIONS: mat FOR mara-matnr NO INTERVALS.

 Apparently it seem that requirement is met but if someone presses multiple selection tab, a pop screen will open and there user can enter the range. This can also be restricted by using a function module SELECT_OPTIONS_RESTRICT.

 Example code:

**********************************************************************
* TYPE-POOLS:
**********************************************************************
TYPE-POOLS: sscr.
*----------------------------------------------------------------------*
* T A B L E S *
*----------------------------------------------------------------------*
TABLES: mara.
*----------------------------------------------------------------------*
* S E L E C T I O N S C R E E N *
*----------------------------------------------------------------------*
SELECTION-
SCREENBEGIN OF BLOCK b2 WITH FRAME.
SELECT-OPTIONS: mat FOR mara-matnr NO INTERVALS.
SELECT-OPTIONS: mtype FOR mara-mtart NO INTERVALS.
SELECTION-
SCREENEND OF BLOCK b2.

*---------------------------------------------------------------------*
* Initialization Event
*---------------------------------------------------------------------*
INITIALIZATION.

  
CONSTANTS: lc_opt_list TYPE rsrest_opl VALUE 'OPT_LIST',
             lc_s        
TYPE rsscr_kind VALUE 'S',
             lc_mat      
TYPE blockname  VALUE 'MAT',
             lc_inc      
TYPE c          VALUE 'I'.

  
DATA: lw_opt_list TYPE sscr_opt_list,
         lw_restrict 
TYPE sscr_restrict,
         lw_ass      
TYPE sscr_ass.

  lw_opt_list-name       = lc_opt_list.
  lw_opt_list-options-bt = space.
  lw_opt_list-options-
eq = 'X'.
  
APPEND lw_opt_list TO lw_restrict-opt_list_tab.

  lw_ass-kind    = lc_s.
  lw_ass-name    = lc_mat.
  lw_ass-sg_main = lc_inc.
  lw_ass-op_main = lc_opt_list.
  
APPEND lw_ass TO lw_restrict-ass_tab.

  
CALL FUNCTION 'SELECT_OPTIONS_RESTRICT'
    
EXPORTING
      restriction            = lw_restrict
    
EXCEPTIONS
      too_late               = 
1
      repeated               = 
2
      selopt_without_options = 
3
      selopt_without_signs   = 
4
      invalid_sign           = 
5
      empty_option_list      = 
6
      invalid_kind           = 
7
      repeated_kind_a        = 
8
      
OTHERS                 = 9.




   With NO INTERVALS command. After pressing multiple selection tab you can enter range value.









After restricting with the function module you can not enter range value now.

There are other option available in this function module. Explore and enjoy :)

Dynamic selection screen

by Voice | Thursday, November 06, 2008 in | comments (0)

Selection screen is the first thing which user can see when he/she executes a program or transaction. For basic need, we can create a selection screen only by using ABAP commands and we do not have to go for a module pool programming.

 

There are some extensions which can be used with select option to meet the requirement.

Please check F1 for the extensions and their effects.

Some it is required to populate a default value in the selection screen. There is an ABAP command which can be used for this.

Eg. SELECT-OPTIONS: matn FOR mara-matnr DEFAULT 'AA'.

 

# Sometime the default value needs to be calculated at run-time. Use Initialization Event or At Selection-screen output Event.

 

Dynamic Selection Screen: You can active a field or can disable input to a certain field depending on some criteria at your will. The following code may help you to make a dynamic screen. There are several other option in SCREEN structure. Explore and you can impress some user by producing a flashy selection screen. Remember selection screen is the first impression of your program.

 

TABLES: mara.

*----------------------------------------------------------------------*
* S E L E C T I O N S C R E E N *
*----------------------------------------------------------------------
SELECTION-
SCREENBEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS : mat RADIOBUTTON GROUP opt1 DEFAULT 'X' USER-COMMAND aa.
PARAMETERS : mtype RADIOBUTTON GROUP opt1.
SELECTION-
SCREENEND OF BLOCK b1.
SELECTION-
SCREENBEGIN OF BLOCK b2.
SELECT-OPTIONS: matn FOR mara-matnr DEFAULT 'AA'
                MODIF 
ID a.
SELECT-OPTIONS: mtypen FOR mara-mtart MODIF ID b.
SELECTION-
SCREENEND OF BLOCK b2.
*----------------------------------------------------------------------*
* AT S E L E C T I O N S C R E E N O U T P U T *
*----------------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT.
  
LOOP AT SCREEN.
    
IF mat = 'X'.
      
IF screen-group1 = 'B'.
        
screen-input = 0.
      
ENDIF.
    
ELSE.
      
IF screen-group1 = 'A'.
        
screen-active = 0.
      
ENDIF.
    
ENDIF.
    
MODIFY SCREEN.
  
ENDLOOP.

Transport ABAP Report Variants

Some times it is required to transport the selection variants (created for a report program) from one environment to another. We will discuss this requirement with a sample scenario.


Steps to be followed.

Step 1) Execute transaction SE38 and give the name of the program as:


Step 2) In the same screen check the radio button “Variants” and click on Display
pushbutton or follow menu path Goto -> Variants as:


Step 3) In the next screen thus appears; follow the menu path Utilities -> Transport
request.. as:


Step 4) Execute (F8) the program thus appears in the next screen as:


Step 5) Up on execution a pop up would appear asking for selecting the variants
(saved against that report program) to be transported as:

(We can select the variants we need and exclude the others)


Step 6) Up on pressing Continue, a next pop up appears; asking for the transport
details as:

Here we can choose our own transport to move the selection
variants for the report program from one environment to another.

ABAP CRM Tips

by Biswa | Tuesday, November 04, 2008 in , | comments (3)

Tip 1: Opening CRM Order in a new window

When there is a requirement to open a CRM Order (Customer Order. Service Order. etc.) from a program, the normal process is to populate the Business Object Parameter (CRM_OBJECT_ID) with the Transaction Number (OBJECT_ID) and then doing a CALL TRANSACTION to CRMD_ORDER. But this method does not seem to work.

SET PARAMETER ID 'CRM_OBJECT_ID' FIELD .
CALL TRANSACTION 'CRMD_ORDER' AND SKIP FIRST SCREEN.

It will not get into the transaction (CRM Order) , but stop at the search screen

The way around could be using the BAPI BAPI_BUSPROCESSND_DISPLAY to display the CRM Order. You can use it to display the CRM Order screen directly. Just pass your Order Header GUID ID to the business process and the CRMD_ORDER screen will be displayed.

CALL FUNCTION 'BAPI_BUSPROCESSND_DISPLAY'
EXPORTING
business_process = <order_header_guid>

Tip 2: Inserting or Deleting Standard / Custom messages in CRM GUI.

If possible, you can follow the following steps.

a) First delete message, for example


* Deleting the messages from stack

CALL FUNCTION 'CRM_MESSAGES_DELETE'
EXPORTING
iv_caller_name = gc_object_name-order
iv_ref_object = iv_item
it_r_msgidno = lt_idno
EXCEPTIONS
OTHERS = 1.


b) Check for corresponding message text already exists or not, for example


CALL FUNCTION 'CRM_TEXT_READ_API'
EXPORTING
it_guid = lt_object_guids
iv_object_kind = gc_object_kind-orderadm_i
IMPORTING
et_text = lt_text.

OR,

Search the corresponding messages, for example,

ls_idno-sign = 'I'.
ls_idno-option = 'EQ'.
ls_idno-low-msgid = 'Z_ZZZ_CA_MESSAGES'.
ls_idno-low-msgno = '126'.

APPEND ls_idno TO lt_idno.

CALL FUNCTION 'CRM_MESSAGES_SEARCH'
EXPORTING
it_r_msgidno = lt_idno
iv_ref_object = iv_header_guid
iv_ref_kind = gc_object_kind-orderadm_h
iv_only_errors_on_object = true
IMPORTING
et_msg_info = lt_msg_info
EXCEPTIONS
appl_log_error = 1
error_occurred = 2
OTHERS = 3.


c) If message does not exist .Then raise message. for example


CALL FUNCTION 'CRM_MESSAGE_COLLECT'
EXPORTING
iv_caller_name = gc_object_name-order
iv_ref_object = iv_item
iv_ref_kind = gc_object_kind-orderadm_i
iv_logical_key = 'MAINTAIN'
iv_msgno = lv_msgno
iv_msgid = 'CRM_ORDERADM_I'
iv_msgty = lv_msgty
EXCEPTIONS
not_found = 1
appl_log_error = 2
OTHERS = 3.


Sending Inbound IDocs from a SAP Program

by Biswa | Tuesday, November 04, 2008 in , | comments (3)

In most cases, the inbound IDoc to SAP is generated by an external system (say XI) and passed on to SAP. The inbound IDoc is then processed using the process code / corresponding function module. But in certain cases, due to the client requirements, the interface program needs to be designed in such a way that the Inbound IDoc originates from within the same SAP system i.e. both the sending and receiving system are the same.

Now mostly in such requirements, we generally generate the IDoc after reading data from a flat file. The file is passed to the application server by a middleware (say XI). The SAP interface program reads the file from the application server and then starts processing the data. To create the inbound IDoc, we need to use the Function Module ‘IDOC_INBOUND_WRITE_TO_DB’. This creates and saves the IDoc to the database.

The control record information for the inbound IDoc is passed to pc_control_record (Similar to EDIDC – IDoc control record). In the control records, all relevant information like status (53); receiver port, receiver partner no.; sender port; sender partner no etc are populated. All the IDoc data is passed to internal table t_data_records (Similar to EDIDD – IDoc control record). The IDoc data is read from the incoming file and processed and then populated to internal table itab_data_records_db with segment name etc.

The inbound process data is passed to the function module.

CALL FUNCTION 'IDOC_INBOUND_WRITE_TO_DB'
exporting
pi_do_handle_error = 'X'
pi_return_data_flag = ' '

importing
pe_idoc_number = control_record_db_in-docnum
pe_inbound_process_data = wa_inbound_process_data_in

tables
t_data_records = itab_data_records_db
changing
pc_control_record = control_record_db_in
exceptions
idoc_not_saved = 1
others = 2.


Now if the inbound IDoc has been successfully created and we want to process the same, the function module ‘IDOC_START_INBOUND’ can be used. Here we pass the inbound process data containing the IDoc process code and event code to wa_inbound_process_data_in. The status and release are added to the control records internal table i_control_records.

CALL FUNCTION 'IDOC_START_INBOUND'
exporting
pi_inbound_process_data = wa_inbound_process_data_in
pi_called_online = 'X'
succ_show_flag = 'X'

tables
t_control_records = i_control_records
exceptions
others = 1.

If we have no exception, then the IDoc will be successfully processed and have status ‘53’.


Link to this post on our new blog : http://www.sapyard.com/sending-inbound-idocs-from-a-sap-program/

How to find BAdis

by Voice | Wednesday, October 29, 2008 in , | comments (0)

Business Add-Ins (BAdis) are a  SAP enhancement technique based on ABAP Objects. Two parts - Definition and its Implementation - definition can either be SAP provided or user may also create it.


How to find BAdi
You can look for BAdi definition in IMG and in component hierarchy. But there are some easier methods to find a BAdi. They are follows:

Method 1
These steps should enable you to find a BAdi related to any transaction in a matter of minutes.
1) Go to the transaction SE37 to find your function module.
2) Locate the function SXV_GET_CLIF_BY_NAME.
3) Put a breakpoint there.
4) Now open a new session.
5) Go to your transaction.
6) At that time, it will stop this function.
7) Double click on the function field NAME.
8) That will give you name of the BAdi that is provided in your transaction.

Method 2
1. Goto SE80,  open CL_EXITHANDLER (Class)
2. Goto Method, GET_INSTANCE
3. Set a break point at 
CALL METHOD cl_exithandler=>get_class_name_by_interface
    EXPORTING
      instance                      = instance
    IMPORTING
      class_name                    = class_name
    CHANGING
      exit_name                     = exit_name
    EXCEPTIONS
      no_reference                  = 1
      no_interface_reference        = 2
      no_exit_interface             = 3
      data_incons_in_exit_managem   = 4
      class_not_implement_interface = 5
      OTHERS                        = 6.
  CASE sy-subrc.
    WHEN 1.
      RAISE no_reference.
    WHEN 2.
      RAISE no_interface_reference.
    WHEN 3.
      RAISE no_exit_interface.
    WHEN 4.
      RAISE data_incons_in_exit_managem.
    WHEN 5.
      RAISE class_not_implement_interface.
  ENDCASE.

4) Now open a new session.
5) Go to your transaction.
6) At that time, it will stop this function.
7) Double click on the function field EXIT_NAME.
8) That will give you name of the BAdi that is provided in your transaction.


Method 3:
1. Goto ST05
2. Select SQL trace and buffer trace
3. Activate trace
4. Now run your transaction
5. Deactivate trace
6. Display trace
7. A pop will come



















8. Select following objects (Views)












9. Now display the trace results. It will return all the BAPI and enhancement list in order of their execution.














Some tips

by Voice | Monday, October 27, 2008 in , | comments (0)

Here are some tips which may save some time for you. And it is always fun experimenting with the things you know.

 Problem: Suppose you are dividing two numbers (in real project scenario it is used while converting amount from one currency to another currency) and there is a requirement to round off the result.

Easy solution: Suppose you need to round it off to 1 decimal position, just use a variable having data element having one decimal position while storing the result. It will be rounded off automatically.

 

Problem: When you try to assign value from character to amount variable or quantity variable, it gives short dump.

Easy solution: Before assigning value, just assign any number to the required amount variable or quantity variable. Then use the assign the character value to amount variable. It will take the value.

Keep it in mind that value in the character field should be in the same format as the variable.

 

Problem: In Sap script, sometime it is required to print values only in the last page or first page. For this we use variables like “SAPSCRIPT-FORMPAGES” or “NEXT-PAGE”. It works fine but yet people find that their script is not printing properly.

For this I don’t have any easy solution. You can only use some text element which is either called in the beginning or in the end. But I will tell you the reason why it does not work. This problem arises when you try to use these variables in MAIN window and sadly in main window these variables do not work. So even you check your form and it seems logically foolproof, you will not get desired result. It is pain taking to debug a SAP Script so we do not even check it in debug mode and keep banging our heads. This tip can be useful for them. :)

I can give you another tip like, if you want to print any line or box something like that in the end page only and that has to be a part of main window, then I will suggest, use a pseudo window, over lapping the main window. You can use the variable in that window and can use to print something like box or line at the page you desire.

Anyways if such requirement is needed, then do let me know in the comment section; will try my best to give you some alternative logic to do so.

 

Problem: In Sap script, when we do amount calculation in sub routine pool program (a z program which is called from the Sap script to do data manipulation), even we use ‘(<)’ operator to shift the negative sign to the left of the amount, it does not work.

Solution: This is again one problem which makes developers bang their heads. The problem occurs because the variable which returns the value from the Z program is type “char”.  So command like ‘(<)’ does not work. For this you have to whether the value is negative or not in the sub routine pool itself and then if it negative, then you have to remove negative sign from the right and have to concatenate minus sign in left of the value.

 

There are many tips like this which look small but are very effective. May be sometime later… and if you want to share something, please do in the comment section.

 

Expensive SQL statements

by vinaysingh | Wednesday, October 22, 2008 in | comments (0)

Expensive SQL statements:-

These are defined as sql statements that cause database to read many blocks from disk or buffer.

User point of view: when transactions using these statements are executed, the response time is large.

Systems point of view: A large number of Data Blocks are scanned to find the selected records.

Why checking Expensive SQL statements:

a. Work processes are blocked by reports, thereby increasing the wait time for other processes.

b. a.High CPU load on database server.

c. b.Many blocks are moved from database buffer which results into bad

cache hit rate for other SQL statement.

d. c.Data base busy reading large number of blocks.



so an Expensive SQL statement reduces the performance of SAP system

Finding out the culprits:-

1. SQL statements with higher number of buffer gets.

2. reports/transaction where t he database request time

of response time.

Once we are able to find out the statements, we need to find out following for each statement:-

a.Table name.

b.WHERE cluase

c.Index used

d. Name of transaction and report containing the statement.

To get the above details:-

  • Goto DBACOCKPIT ->performance->SQL statement Analysis->shared cursor cache [sap net weaver]
  • Goto ST04 -> Detailed Analysis Menu -> SQl Request -> Sort by disk reads/ buffer gets / executions.[for others]


SM 50/66, ST05 and ST03/STAD can also be used to find expensive SQL statement.

Expensive SQL statements can be categories under following heads:-

a) SQL statements which are used by ABAP programs. - These statements can be tuned.

b) SQL Statements used by database – cannot be tuned by us.

c) SQL statements selected from SAP Basis tables –can’ t be tuned by us

d) Recursive SQL statement - can’ t be tuned by us

Tuning the tunable statements

It is done under two heads, depending on the scenarios:-

a) Case 1:- you see many buffer gets * but only few records per execution.

We can speed up the execution of SQL statements in such case by:-

- Updating the optimizer statistics.

- Creating/extending/dropping existing indexes.

- Optimizing the user input.

a) Case 2:- you see many buffer gets* and many records per execution.

In such cases, we can speed up the execution by:-

- Adapting the ABAP code, replacing “* “from the statements [“SELECT* FROM…..”]

With list of fields that are actually used by the program.

- Optimizing the user input.

- Tuning the business process.

· * you can see the buffer get @ DBACOCKPIT->performance->SQL statement Analysis->shared cursor cache (double click here)->new screen for selection criteria, put your value in buffer gets field.


Categories