1

I have a solution that includes a LOOP which I would like to spare. So I wonder, whether you know a better way to do this.

My goal is to loop through an internal, alphabetically sorted standard table. This table has two columns: a name and a table, let's call it subtable. For every subtable I want to do some stuff (open an xml page in my xml framework).

Now, every subtable has a corresponding name. I want to group the subtables according to the first letter of this name (meaning, put the pages of these subtables on one main page -one main page for every character-). By grouping of subtables I mean, while looping through the table, I want to deal with the subtables differently according to the first letter of their name.

So far I came up with the following solution:

TYPES: BEGIN OF l_str_tables_extra,
        first_letter(1) TYPE c,
        name TYPE string,
        subtable TYPE REF TO if_table,
       END OF l_str_tables_extra.

DATA: ls_tables_extra TYPE l_str_tables_extra.
DATA: lt_tables_extra TYPE TABLE OF l_str_tables_extra.

FIELD-SYMBOLS: <ls_tables> TYPE str_table."Like LINE OF lt_tables.
FIELD-SYMBOLS: <ls_tables_extra> TYPE l_str_tables_extra.


*"--- PROCESSING LOGIC ------------------------------------------------
SORT lt_tables ASCENDING BY name.

"Add first letter column in order to use 'at new' later on
"This is the loop I would like to spare
LOOP AT lt_tables ASSIGNING <ls_tables>.
  ls_tables_extra-first_letter = <ls_tables>-name+0(1). "new column
  ls_tables_extra-name = <ls_tables>-name.
  ls_tables_extra-subtable = <ls_tables>-subtable.
 APPEND ls_tables_extra TO lt_tables_extra.
ENDLOOP.

LOOP AT lt_tables_extra ASSIGNING <ls_tables_extra>.
 AT NEW first_letter.
  "Do something with subtables with same first_letter.
 ENDAT.
ENDLOOP.

I wish I could use

 AT NEW name+0(1)

instead of

AT NEW first_letter

, but offsets and lengths are not allowed.

You see, I have to inlcude this first loop to add another column to my table which is kind of unnecessary because there is no new info gained.

In addition, I am interested in other solutions because I get into trouble with the framework later on for different reasons. A different way to do this might help me out there, too.

I am happy to hear any thoughts about this! I could not find anything related to this here on stackoverflow, but I might have used not optimal search terms ;)

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
Ela
  • 325
  • 1
  • 3
  • 13

2 Answers2

7

Maybe the GROUP BY addition on LOOP could help you in this case:

LOOP AT i_tables
  INTO DATA(wa_line)
  " group lines by condition
  GROUP BY (
    " substring() because normal offset would be evaluated immediately
    name = substring( val = wa_line-name len = 1 )
  ) INTO DATA(o_group).

  " begin of loop over all tables starting with o_group-name(1)

  " loop over group object which contains 
  LOOP AT GROUP o_group
    ASSIGNING FIELD-SYMBOL(<fs_table>).
      " <fs_table> contains your table
  ENDLOOP.

  " end of loop

ENDLOOP.
  • 1
    Thanks. Yet, I think the 'group by' works only together with 'select' for data bases. But I am interested in an internal table. Am I wrong? It has the advantage to not to have to declare an additional type. But is another loop nevertheless. – Ela Oct 19 '17 at 09:29
  • 1
    @Ela `GROUP BY` is also valid syntax on `LOOP` and works as I proposed in my answer. At least on NetWeaver >7.4 –  Oct 19 '17 at 12:28
2

why not using a IF comparison?

data: lf_prev_first_letter(1) type c.

loop at lt_table assigning <ls_table>.
    if <ls_table>-name(1) <> lf_prev_first_letter. "=AT NEW
       "do something
       lf_prev_first_letter = <ls_table>-name(1).
    endif.
endloop.
futu
  • 868
  • 6
  • 12