5
votes

I need to find the sy-tabix of a the last entry in an internal table that matches v_key = x. I'm trying to do it with:

read table i_tab with key v_key = x

But since there are multiple entries in the table that match v_key = x, how can I make sure I get the sy-tabix of the last matching entry? I can't search by another key unfortunately.

5
Two possibilities: Either use LOOP AT ... WHERE v_key = x, SY-TABIX inside the loop at the last iteration will give you the line number. Or calculate the next possible value of x at byte level (byte+1), sort your table (with preference to a table with a sorted key), do a READ TABLE with "X+1", which will return SY-TABIX of the next line, so just subtract 1. - Sandra Rossi

5 Answers

7
votes

READ TABLE is for reading single lines, for more lines you have to use LOOP:

LOOP AT itab
     ASSIGNING ...
     WHERE vkey EQ x.
ENDLOOP.

Right after the LOOP sy-tabix will contain the last line, where the condition is true.

As it was pointed (see discussion below), for the best performance there has to exist a NON-UNIQUE SORTED key (either primary or secondary) for this field

2
votes

Another possibility, which is useful if you have many lines with the same v_key value.

First, make sure a line exists for X. If it's not found, then no need to pursue.

Calculate the next possible value (variable x_next_value) of the searched value (variable X). Examples:

  • If X is an integer, simply search X + 1. Example: for value 5, x_next_value will be 6.
  • If X are characters (C or string), then get the number of the last character (cl_abap_conv_**out**_ce=>uccpi), add 1, and update the last character (cl_abap_conv_**in**_ce=>uccpi).
  • Same kind of logic for other types of X.

Make sure your table is sorted (with preference to a table declared sorted table of ... with non-unique key v_key)

Then do READ TABLE itab WITH KEY v_key = x_next_value.

Important : even if no line is found, SY-TABIX will be set to the number of next line after all the lines having v_key = x (cf ABAP documentation of READ TABLE - Possible values for SY-SUBRC and SY-TABIX)

Pseudo code :

READ TABLE ... WITH KEY v_key = x_next_value.
" eventually BINARY SEARCH if itab is STANDARD instead of SORTED

CASE sy-subrc.
  WHEN 0.
    last_tabix_of_x = sy-tabix.
  WHEN 4.
    last_tabix_of_x = sy-tabix - 1.
  WHEN 8.
    last_tabix_of_x = lines( itab ).
ENDCASE.

Note : exactly two READ TABLE are needed to find the last matching result.

1
votes

I think fastest way is

Sort itab by key.
read table itab with key key = v_key
                binary search.
loop at itab assign <fs> from sy-tabix.
   if <fs>-key ne v_key.
      exit.
   endif.
endloop.
0
votes

I am writing a different solution which might be helpful to you.

add one column keyno in table i_tab.

When you are inserting records in table i_tab, and there are multiple records to append in table i_tab for same key, you can add keyno for each records where same key has multiple records.

For Example:

Insertion of records in Table i_tab

i_tab_line-key = 'X'.
i_tab_line-keyno = 1.
APPEND i_tab_line to i_tab.
i_tab_line-key = 'X'.
i_tab_line-keyno = 2.
APPEND i_tab_line to i_tab.
i_tab_line-key = 'X'.
i_tab_line-keyno = 3.
APPEND i_tab_line to i_tab.

Table i_tab Sorting by Key Keyno descending.

   SORT i_tab by key keyno Desc.

Now Read Table will find last matching entry from table i_tab for the key.

   read table i_tab with key = X

regards,

Umar Abdullah

-1
votes
sort i_tab by v_key .
read table i_tab with key v_key = x binary search.

while i_tab-key = x
  lv_tabix = sy-tabix + 1 .
  read table i_tab index = lv_tabix .
endwhile.

result = lv_tabix -1 .