2015 Aug 14 10:18 AM
Hi everybody,
I am trying to use a table comprehension to find all elements in a list of integers that are greater or equal to the first element.
My idea was to use a table comprehension as follows:
data(lt_great) = value t_int(
for wa in lt_data from 2
where ( TABLE_LINE >= lt_data[ 1 ] )
( wa ) ).
However this doesn't seem to work. Here's my demo report
REPORT ZPORT_COMP2.
types t_int TYPE TABLE OF i with EMPTY KEY.
data(lt_data) = value t_int( ( 1 ) ( 2 ) ( 3 ) ).
data(lt_from2) = value t_int(
for wa in lt_data from 2
( wa ) ).
data(lt_tmp) = value t_int(
for wa in lt_data from 2
where ( TABLE_LINE >= 1 )
( wa ) ).
data(lt_great) = value t_int(
for wa in lt_data from 2
where ( TABLE_LINE >= lt_data[ 1 ] )
( wa ) ).
perform print USING `lt_data ` lt_data.
perform print USING `lt_from2` lt_from2.
perform print USING `lt_tmp ` lt_tmp.
perform print USING `lt_great` lt_great.
form print using name type string list type t_int.
write: name.
LOOP AT list ASSIGNING FIELD-SYMBOL().
write: .
ENDLOOP.
write /.
ENDFORM.
The output is
Programm ZPORT_COMP
lt_data 1 2 3
lt_from2 2 3
lt_tmp 2 3
lt_great 1 2 3
I don't understand why the last table comprehension results in 1, 2, 3. Why is 1 part of the result? The "from" clause should make the comprehension to start looking at line 2, right?
2015 Aug 15 10:46 AM
Quite interesting.
If you do it this way you get the expected result.
LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<data>)
FROM 2
WHERE table_line >= lt_data[ 1 ].
WRITE: <data>.
ENDLOOP.
" Output: 2 ,3
And if i get the documentation right
the result should be equivalent to your expression.
DATA(lt_great) = VALUE t_int(
FOR wa IN lt_data FROM 2
WHERE ( table_line >= lt_data[ 1 ] )
( wa ) ).
Maybe Horst Keller can bring some light into the dark.
2015 Aug 14 8:08 PM
Dear lord... This is some kind of advanced 7.4 stuff, but just a quick guess - maybe the issue is with this statement?
TABLE_LINE >= lt_data[ 1 ]
Shouldn't it be > instead of >= ?
2015 Aug 17 1:08 AM
It "works" if we change the signal to > but he wants "greater or equal than first element".
2015 Aug 17 4:14 PM
Thanks, Custodio! I guess I was mislead by the name lt_great. (One more point in favor of "self-documenting code".)
Bug in the ABAP itself?! Oh my... If only there were some testing tools SAP could use...
2015 Aug 15 10:46 AM
Quite interesting.
If you do it this way you get the expected result.
LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<data>)
FROM 2
WHERE table_line >= lt_data[ 1 ].
WRITE: <data>.
ENDLOOP.
" Output: 2 ,3
And if i get the documentation right
the result should be equivalent to your expression.
DATA(lt_great) = VALUE t_int(
FOR wa IN lt_data FROM 2
WHERE ( table_line >= lt_data[ 1 ] )
( wa ) ).
Maybe Horst Keller can bring some light into the dark.
2015 Aug 17 7:36 AM
For me it looks like another bug
TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY.
CLASS cls DEFINITION.
PUBLIC SECTION.
CLASS-METHODS
meth IMPORTING p TYPE t_itab
RETURNING VALUE(r) TYPE LINE OF t_itab.
ENDCLASS.
CLASS cls IMPLEMENTATION.
METHOD meth.
r = p[ 1 ].
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(itab) = VALUE t_itab( ( 1 ) ( 2 ) ( 3 ) ).
DATA(result1) = VALUE t_itab(
FOR wa IN itab FROM 2
WHERE ( table_line >= itab[ 1 ] )
( wa ) ).
cl_demo_output=>write( result1 ).
DATA(result2) = VALUE t_itab(
FOR wa IN itab FROM 2
WHERE ( table_line >= cls=>meth( itab ) )
( wa ) ).
cl_demo_output=>write( result2 ).
DATA(result3) = VALUE t_itab(
FOR wa IN itab FROM 2
WHERE ( table_line >= 1 )
( wa ) ).
cl_demo_output=>write( result3 ).
DATA result4 TYPE t_itab.
LOOP AT itab INTO DATA(line)
FROM 2
WHERE ( table_line >= itab[ 1 ] ).
result4 = VALUE #( BASE result4 ( line ) ).
ENDLOOP.
cl_demo_output=>write( result4 ).
cl_demo_output=>display( ).
For whatsover reason FROM 2 is disregarded in the FOR expression when itab is used in the WHERE-Clause.
Forwarded to development (in vacation, answer will take some time ...).
Thanks for notifying!
Horst
2015 Aug 17 7:33 AM
Thanks for your replies!
I am starting to think that this is a bug.
It gives the expected result when you pull out lt_data[1] into a separate variable like this:
DATA(l_1st) = lt_data[ 1 ].
data(lt_great) = value t_int(
for wa in lt_data from 2
where ( TABLE_LINE >= l_1st )
( wa ) )I will open a ticket.
Thanks, Thomas
2015 Sep 10 6:59 AM
Development is back from vacation, and yes it is a bug.
Kernel patch is in preparation ....
2015 Sep 10 8:47 AM
I tried it by creating a TYPE and then creating a TABLE Type for it and it works then BUT for not inbuilt declaration
TYPES : BEGIN OF t_int1,
num type i,
end of t_int1.
TYPES : t_int TYPE TABLE OF t_int1 with empty key.
data(lt_data) = value t_int( ( num = 1 ) ( num = 2 ) ( num = 3 ) ).
data(lt_from2) = value t_int(
for wa in lt_data from 2
( wa ) ).
data(lt_tmp) = value t_int(
for wa in lt_data from 2
where ( num >= 1 )
( wa ) ).
data(lt_great) = value t_int(
for wa in lt_data from 2
where ( num >= lt_data[ 1 ]-num )
( wa ) ).
perform print USING `lt_data ` lt_data.
perform print USING `lt_from2` lt_from2.
perform print USING `lt_tmp ` lt_tmp.
perform print USING `lt_great` lt_great.
form print using name type string list type t_int.
write: name.
LOOP AT list ASSIGNING FIELD-SYMBOL(<ls_list>).
write: <ls_list>-num.
ENDLOOP.
write /.
ENDFORM.
2015 Sep 10 9:16 AM
Hi Amit,
you are right. In your example everything works fine.
Seems to be a quite specific situation in which this bug causes the problems mentioned above.
Thanks,
Thomas