Skip to Content
Personal Insights
Author's profile photo Vimal Sharma

My learnings with AMDP

In this blog, we will be covering some of the learnings of AMDP. We are covering different scenarios and errors related to it.

This is an attempt to help anyone who is starting with AMDP’s and need help with issues faced.

Further scenarios will be added in up-coming blogs or updated in this blog only.

 

Scenario 1) Add colon(:) sign as and when you are going to use a local variable in a method. Below error will come if there’s no colon added:

“LT_ABAP_DATA” is unknown. ABAP objects and DDIC objects must be declared in the METHOD statement. Local names must start with “:” here.

 

SELECT COUNT( * ) INTO LV_DSO_COUNT FROM :LT_ABAP_DATA WHERE LOW = 'XYZ';

In above code, we are using colons(:) before variable lt_abap_data. Lt_abap_data is created in method itself and need colon to be identified as local variable.

 

Scenario 2) If you are using any method of same AMDP class or other class or DDIC object, then that object must be declared in USING clause. If not, then you will encounter the below error:

“ZPCMCL_XYZ=>GET_ DATA” is unknown. ABAP objects and DDIC objects must be declared in the METHOD statement. Local names must start with “:” here.

 

Scenario 3) If you must pass value of a variable in all records, then following is the way to do:

E_view3 = SELECT	ZP_PROGRM
			:S_T_SCNR as ZP_SCNR
			FROM: lt_all;

In above statement, we are selecting all records and putting the value of variable :S_T_SCNR into field ZP_SCNR.

 

Scenario 4) Using BETWEEN keyword from a range table.

FROM :lt_pbs_p102_tmp
                     WHERE
                        ZP_PRFTCR  IN ( SELECT LOW FROM :I_T_ABAP_DATA WHERE IOBJNM = 'ZP_PRFTCR' )
                        AND ZP_SCNR    = S_S_SCNR
                        AND ZP_VERSN   IN ( SELECT LOW FROM :I_T_ABAP_DATA WHERE IOBJNM = 'ZP_VERSN' )
                        "0FISCPER" BETWEEN ( SELECT LOW FROM :I_T_ABAP_DATA WHERE IOBJNM = '0FISCPER' )
                          AND ( SELECT high FROM :i_t_abap_data WHERE iobjnm = '0FISCPER' )

In above code , we are using BETWEEN keyword for field “0FISCPER” using Low and High.

 

Scenario 5) If you must pass default values, then below is the code.

e_view_temp = SELECT
                     CONCAT( lv_target_year ,'012') AS FISCPER,
                     '012' fiscper3,

In above code , we are putting default value ‘012’ in field FISCPER3.

 

Scenario 6) You can add arithmetic calculations while querying in where clause:Code

Source : code snippet from personal development

In above query, we are doing calculations on FISCYEAR field by reducing one year.

 

Scenario 7)  If the value is NULL and you want to pass a default, then you can use IFNULL method                       in select statement as shown below.

 et_out = select IFNULL(kurst,'2002') as kurst ,fcurr,tcurr,
                gdatu,
                ukurs
               from tcurr where tcurr = 'GBP';

In above code , if value of KURST is NULL then we are passing default value of ‘2002’.

 

Scenario 8) You can use keyword ::ROWCOUNT to count the number of rows found after a select statement.

SELECT low INTO e_t_versn FROM :i_t_abap_data WHERE iobjnm = 'T_ZP_VERSN';
IF ::ROWCOUNT = 0 THEN

END IF;

In above statement, we will have count of records after execution of select statement in variable ::ROWCOUNT. It’s similar to DESCRIBE TABLE in ABAP but be very careful of using this keyword, if you are using it for multiple times then it’s better to use COUNT(*) as we faced number of issues with this keyword when using multiple times. If it’s only one time, then we can use it without any issue.

Scenario 9)  Use of CASE statement in Select query:

CASE
  WHEN s_t_scnr IS NOT NULL OR s_t_scnr <> '' THEN
    s_t_scnr
  ELSE
    ZP_SCNR
END AS ZP_SCNR,

 

Scenario 10) Dynamic WHERE clause in AMDP: There might be instances where you need to create dynamic where clause in AMDP(Dynamic queries are not recommended). So trying to cover one of the scenarios as shown below:

Step i):

lt_concat1 = SELECT '''' || LOW || '''' AS CONCAT_LOW
                                          FROM :I_S_ABAP_DATA
                                              WHERE IOBJNM = 'ZP_VERSN';

In above query, we are trying to select all data of LOW field from importing parameter I_S_ABAP_DATA and adding colons to the value. Below are the values of internal tables for better understanding:

 

:I_S_ABAP_DATA : This is the table we are querying. It’s a range table as you can see having ZP_VERSN with multiple values (not visible in pic).

code

Source : code snippet from personal development

Once the query is executed, below will be result in internal table lt_concat1(Values with colons). code

Source : code snippet from personal development

 

Step ii) 

lt_concat = SELECT STRING_AGG(CONCAT_LOW,',') AS concat_low
                                            FROM :lt_concat1;

In above query, we are using STRING_AGG function to segregate the data into rows from internal table LT_CONCAT1. In this way, you will have data in LT_CONCAT as shown below(In single row):

code

Source : code snippet from personal development

 

Step iii):

SELECT CONCAT_LOW INTO lv_concat_versn FROM :lt_concat;
IF ::ROWCOUNT > 0 THEN
  lv_s_versn := ' AND ZP_VERSN IN (' || (lv_concat_versn) || ')';
END IF;

 

In above query, we selecting converted values in variable lv_concat_Versn and creating WHERE clause. Below will be the value for variable lv_s_versn:

code

Source : code snippet from personal development

 

In above code as you can see in highlighted text, field ZP_VERSN is ready to be filtered with two values. You can use the same logic for rest of your fields. We are adding AND operator because of there’s other fields before this field(you can change it according to your requirement).

Once all fields are done this way , you can use APPLYFILTER to filter the records.

 

Scenario 11) How to remove decimals from currency values in AMDP:

You can use below code to pass the internal table(:lt_local_curr) and the field(Amount) from where you want to remove the decimal values. Basicall it’s a kind of padding we are doing by adding to STEPS parameter as ‘shift_back’.

E_local_CURR_DATA  = CE_CONVERSION (
                            :LT_LOCAL_CURR,
                            [ FAMILY             = 'currency',
                              METHOD             = 'ERP',
                              STEPS              = 'shift_back',
                              TARGET_UNIT_COLUMN   = "CURRENCY",
                              SOURCE_UNIT_COLUMN = "CURRENCY",
                              OUTPUT_UNIT_COLUMN = "CURRENCY",
                              ERROR_HANDLING     = 'keep unconverted' ],
                            [ AMOUNT AS AMOUNT ]
                             );

 

 

These are the 11 scenarios we have covered till now, we will be updating this blog as we move ahead or we will be adding other relevant links of AMDP related blogs in comment section.

Also , if you have any scenario which you would like to cover in AMDP or if you have any question for above scenarios , please comment on blog and we will get back.

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing, Vimal! Your analysis of error messages will definitely be helpful to those who search. I frequently just google error message text when I'm having trouble understanding it.

      I did find your example of BETWEEN a bit odd though. Technically, you don't use BETWEEN at all because the respective line is commented out. 🙂 But that's not the main issue. I feel the idea of having everything, including "between" operator, in the selection table but using just LOW / HIGH fields is fundamentally flawed. I've seen this many times in classic ABAP programs: an assumption is made that low/high is always "from-to" but range tables can also have "not equals" or "less than" conditions and such. So properly handling these possibilities is usually a better option.

      I'm not an AMDP expert, so I googled "AMDP and range tables" and immediately found this blog from 2015 that explains a better option for handling range / SELECT-OPTIONS tables. That approach should work for any data in the range tables and would be more resilient / easier to maintain.

      Thank you.

      Author's profile photo Vimal Sharma
      Vimal Sharma
      Blog Post Author

      Thanks Jelena for your feedback. Would like to address some of your points.

      The respective line is not commented out , it's part of active code(it's in gray color here but it's not commented). Secondly, here i'm trying to depict how if needed we can use BETWEEN operator and in this example we are trying to work on Fiscal Period field , so we need data between the two fiscal periods e.g. between 01 to 04 and when we are sending range table there will be keyword BT(denotes between) will come in range table.

      The blog which you are referencing for handling select-options with dynamic where clause is more or less same thing. It will still be filtering records with BETWEEN in the back-end, it's just that we are creating a dynamic query based on filters and using APPLYFILTERS. So i don't see much of a difference.

       

       

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for a reply!

      Double quotation mark (") is an in-line comment sign in ABAP, that's why it shows here as a commented-out code. I see that a single quote mark (') is used in all other places. Was this a typo or an odd syntax? I'm curious.

      Sorry to be a stickler but the difference between the other blog and the code here is that the latter is not evaluating the range table content. It just takes low/high value and assumes we need to look for the date between these. However, range tables could have information in other fields that would make this assumption invalid. E.g. it might have "excluding interval". Or HIGH might as well be blank. There is no assumption made in other blog, it would work with whatever is in the table. That's the major difference, in my opinion.

      Author's profile photo Vimal Sharma
      Vimal Sharma
      Blog Post Author

      Hi Jelena,

      Thanks for your resonse.

      Double quotation mark is added due to field starting with 0 . If you see the field it's 0FISCPER and AMDP will not accept this field without double quotation mark. So if you have a field starting with numeric's , you need to add double quotation mark in AMDP.

      Regarding 2nd point , You are correct referenced blog is the ideal way for handling range option .

       

      Thanks,

      Vimal