Skip to Content
Technical Articles
Author's profile photo Kallol Chakraborty

Easy ways to create and populate range tables in ABAP 7.4 onwards

Introduction

In certain cases, you need to create and populate range tables in ABAP for different purposes. So, in this blog post, I have explained 3 easy ways to populate range tables.

Solution

The ways are the following.

  1. Using LET with VALUE. Please check the below section for quick reference.
    TYPES lr_bukrs_type TYPE RANGE OF bukrs.
    DATA : lr_bukrs_01 TYPE lr_bukrs_type, "Table 1
           lr_bukrs_02 TYPE lr_bukrs_type. "Table 2
    
    * Using only LET with VALUE
    *--------------------------------------------------------------------*
    lr_bukrs_01 = VALUE lr_bukrs_type(
                                    LET s = 'I'
                                        o = 'EQ'
                                    IN sign   = s
                                       option = o
                                       ( low = '0100' )
                                       ( low = '0200' )
                                       ( low = '0300' )
                                       ( low = '0400' )
                                       ( low = '0500' )
                                       ( low = '0600' )
                                       ( low = '0700' )
                                      ).
    ​
  2. Using MACRO: This is the simplest way. Please check the below section for quick reference.
    TYPES lr_bukrs_type TYPE RANGE OF bukrs.
    DATA : lr_bukrs_01 TYPE lr_bukrs_type, "Table 1
           lr_bukrs_02 TYPE lr_bukrs_type. "Table 2
    
    * Using MACRO
    *--------------------------------------------------------------------*
    DEFINE range_bukrs.
      lr_bukrs_01 = VALUE lr_bukrs_type(
                                          BASE lr_bukrs_01 (
                                                            sign = 'I'
                                                            option = 'EQ'
                                                            low = &1
                                                            )
                                        ).
    END-OF-DEFINITION.
    
    *--------------------------------------------------------------------*
    range_bukrs: '0100', '0200', '0300', '0400', '0500', '0600', '0700'.
    *--------------------------------------------------------------------*​
  3. Using FOR LOOP: By this procedure, one can populate the range table w.r.t another table. Please check the below section for quick reference.
    TYPES lr_bukrs_type TYPE RANGE OF bukrs.
    DATA : lr_bukrs_01 TYPE lr_bukrs_type, "Table 1
           lr_bukrs_02 TYPE lr_bukrs_type. "Table 2
    
    * Using MACRO
    DEFINE range_bukrs.
      lr_bukrs_01 = VALUE lr_bukrs_type(
                                          BASE lr_bukrs_01 (
                                                            sign = 'I'
                                                            option = 'EQ'
                                                            low = &1
                                                            )
                                        ).
    END-OF-DEFINITION.
    
    range_bukrs: '0100', '0200', '0300', '0400', '0500', '0600', '0700'.
    
    * Combining LET with FOR LOOP
    *--------------------------------------------------------------------*
    lr_bukrs_02 = VALUE #( FOR ls_bukrs IN lr_bukrs_01
    *                          ( sign = 'I'      "Alternatively
    *                            option = 'EQ'   "Alternatively
                                 LET s = 'I'
                                     o = 'EQ'
                                 IN sign   = s
                                    option = o
                               ( low = ls_bukrs-low )
                          ).
    ​

That’s it. 🙂

Assigned Tags

      22 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Andre Kuller
      Andre Kuller

      the first example can still be simplified,

      DATA(burks_range) = VALUE lr_bukrs_type( sign = 'I' option = 'EQ'
         ( low = '0100' )
         ( low = '0200' )
         ( low = '0300' )
         ( low = '0400' )
         ( low = '0500' )
         ( low = '0600' )
         ( low = '0700' ) ).

       

      I personally find the other options not elegant and rather complicated.

      Author's profile photo Kallol Chakraborty
      Kallol Chakraborty
      Blog Post Author

      Dear Andre,

       

      Thanks for reviewing the blog post. 🙂

      Yes, the example that you have provided is also right. The 'LET' keyword creates complicacy sometimes.

       

      Regards,

      Kallol

      Author's profile photo Michelle Crapo
      Michelle Crapo

      I actually like all three of the examples.   It drives me crazy to create those range tables.  My personal preference is the macro.  However, someplace around here I read "Macros were bad".  Not sure where...

      My old way of doing it - is a simple loop within a class where the table and the field are dynamically passed.  I know not very elegant - Hence I'm not sharing.  🙂  I like these better.

       

       

      Author's profile photo Mithun Kumar
      Mithun Kumar

      You're right. There're two main reasons that I feel macros are not so good:

      1. You cannot debug through a macro. That's a biggest deal-breaker for me, as it's bad maintainability.
      2. In this sort of example, it might still be considered if the 'filling' in range table is being done many times, but for one time it's an overkill. Moreover, even for many times, I wouldn't mind writing the 1 statement a few times as Andre shows in his comment above.
      Author's profile photo Jörgen Lindqvist
      Jörgen Lindqvist

      Here's where you can also read it: ABAP Programming Guidelines on Macros 🙂

      It basically says "Only use macros in exceptional cases", but also that simple cases (like I would say this one is) are just fine...

      Personally, as one of those "decisions that make other decisions easier", I prefer not to use them at all. For ranges specifically I use the Andre Kuller version without the additional LET...

      Author's profile photo Matthew Billingham
      Matthew Billingham

      There's nothing you can do with a macro that you can't do equally well using methods or VALUE or ASSIGN.

      If you feel there is somewhere where you need it, I'd bet you've got a bad program design! 😀

      TL;DR Don't use macros. They're BAAAAAAAAAAAAAAAAAAAAAAD.

      Author's profile photo Suhas Saha
      Suhas Saha

      My 2 cents...

      data RANGE_OF_COMP_CODES type range of BUKRS.
      
      select 'I', 'EQ', BUKRS from T001 up to 10 rows 
      into table @RANGE_OF_COMP_CODES.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Perhaps:

          SELECT 'I' AS sign, 'EQ' AS option, bukrs AS low, @space AS high 
              FROM t001 UP TO 10 ROWS
              INTO TABLE @DATA(range_of_comp_codes).
      Author's profile photo Suhas Saha
      Suhas Saha

      But i remember having some problem declaring the ranges in-line. Therefore, I do not use this construct.

      High_Low_Diff_Datatype

      High_Low_Diff_Datatype

      I prefer declaring the range explicitly & then using it in the select.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Good point. Maybe

      `    ` AS high

      would work.

      Author's profile photo Aditya Waghmare
      Aditya Waghmare

      Better yet, use cast

      SELECT 'I' AS SIGN, 'EQ' AS OPTION, BUKRS AS LOW, CAST( @SPACE AS CHAR( 4 ) ) AS HIGH
              FROM T001 UP TO 10 ROWS
              INTO TABLE @DATA(RANGE_OF_COMP_CODES).
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Don't use macros - reason given above.

      I use:

      DATA range_of_strings TYPE RANGE OF strings.
      range_of_strings = VALUE #( ( sign = 'I' option = 'EQ' low = `cotton`)
                                  ( sign = 'I' option = 'EQ' low = `rope` )
                                  ( sign = 'I' option = 'EQ' low = `hemp` ) ).
      
      

      I seem to recall you can also use

      DATA range_of_strings TYPE RANGE OF strings.
      range_of_strings = VALUE #( ( sign = 'I' option = 'EQ' low = `cotton`)
                                  (                          low = `rope` )
                                  (                          low = `hemp` ) ).

       

      Author's profile photo Michelle Crapo
      Michelle Crapo

      Well dang - I like these even better.   My loop/end loop might be around a T table.   So I'd have to see how it works - one line at a time.

      I can see I need to think about ranges a bit longer.  

      Author's profile photo Matthew Billingham
      Matthew Billingham

      As far as ranges go, I'd like to see

      ... TYPE LINE OF RANGE OF ...

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Don't you mean this? (like Andre Kuller answer)

      DATA range_of_strings TYPE RANGE OF strings.
      range_of_strings = VALUE #( sign = 'I' option = 'EQ' ( low = `cotton`)
                                                           ( low = `rope` )
                                                           ( low = `hemp` ) ).
      Author's profile photo Matthew Billingham
      Matthew Billingham

      I may well mean that...

      Author's profile photo Michelle Crapo
      Michelle Crapo

      I love this blog.  Just for all the comments it's been generating.  It proves to me - again - it's worth writing a blog sometimes just to read the comments.

      Author's profile photo B. Meijs
      B. Meijs

      Sometimes you need to create a range table from another internal table. I use an SQL Expression for that. In the example below docitems is an internal table containing the BUKRS field.

      SELECT DISTINCT
             'I'                       AS sign,
             'EQ'                      AS option,
             bukrs                     AS low,
             CAST( '    ' AS CHAR )    AS high
             FROM @docitems AS docitems
             INTO TABLE @DATA(bukrs_range).
      Author's profile photo Aditya Waghmare
      Aditya Waghmare

      Instead of blank spaces, can specify exact number

      SELECT 'I' AS SIGN, 'EQ' AS OPTION, BUKRS AS LOW, CAST( @SPACE AS CHAR( 4 ) ) AS HIGH
              FROM T001 UP TO 10 ROWS
              INTO TABLE @DATA(RANGE_OF_COMP_CODES).
      Author's profile photo Alberto RADICATI
      Alberto RADICATI

      Can I ask you please on what release you are? This does not work on ABAP 7.50. Perhaps you are beyond this version?

      Author's profile photo Alira Faleiro
      Alira Faleiro

      This is really a helpful blog I am really impressed with your work, keep it up the good work

      Author's profile photo Namasivayam Naveen G
      Namasivayam Naveen G

      We can also convert any column in internal table to a Rangle table in a single line of code like below.

      DATA(RT_PERNR)  VALUE RSDSSELOPT_TFOR WA_EMP1 IN IT_EMP SIGN IF_FSBP_CONST_RANGE=>SIGN_INCLUDE OPTION IF_FSBP_CONST_RANGE=>OPTION_EQUAL LOW WA_EMP1-PERNR ).