Incompatible type of Field-Symbol in FOR loop

Viewed 169

I wonder is there any solution for this.

TYPES: BEGIN OF ty_table1,
         field1 TYPE string,
       END OF ty_table1,
       tt_table1 type STANDARD TABLE OF ty_table1 with EMPTY KEY,
       BEGIN OF ty_table2,
         field1 TYPE string,
       END OF ty_table2,
       tt_table2 type STANDARD TABLE OF ty_table2 with EMPTY KEY.
DATA: lt_table TYPE table OF ty_table1,
      lt_final TYPE table OF ty_table2.

DATA(lt_table1) = VALUE tt_table1( FOR <fs_struct> IN lt_table WHERE ( field1 EQ 'TEST' )
                  ( CORRESPONDING #( <fs_struct> ) )  ).

DATA(lt_table2) = VALUE tt_table2( FOR <fs_struct> IN lt_final WHERE ( field1 EQ 'TEST1' )
                  ( CORRESPONDING #( <fs_struct> ) )  ).

Here, we will be getting a syntax error in the 2nd constructor expression stating:

"<FS_STRUCT>" was already declared with the type "TY_TABLE1" and cannot be used with the type "TY_TABLE2" here.

Is there any way to "unassign" <FS_STRUCT> after the 1st statement? So that, it can be used in the next forthcoming FOR statements for different tables.

The normal UNASSIGN statement can't be used to unassign <fs_struct> since it won't have scope outside the FOR loop.

1 Answers

The target field of a FOR statement has the same semantics as LET expressions:

A helper field specified in a LET expression is valid in the context in which the LET expression is specified. This can be a full expression or just part of an expression. All helper fields of a full expression are in the same namespace. A previously specified helper field cannot be specified in a further LET expression of the same expression. Furthermore, the helper fields are in the same namespace as the data objects or field symbols of the current procedure or program. Helper fields cannot be defined in a LET expression if a data object or field symbol with the same name already exists in the procedure or program of the expression. Conversely, no data objects or field symbols with names assigned to helper fields can be declared after an expression with a LET expression. When reusing helper fields in different expressions, the following applies:

  • If a helper field is defined for the first time in the current procedure or program, it is declared inline.
  • If a helper field in the current procedure or program is defined again in a LET expression of a different expression and the derived data type matches, the helper field is bound to this expression and can be used there.
  • If a helper field in the current procedure or program is defined again in a LET expression of a different expression and the derived data type does not match, the helper field cannot be used there and a syntax error occurs.

Thus in fact there are two different declarations in your code (which in theory could hold different types). However the ABAP language enforces that the types match, probably to avoid confusing situations where variables with the same name suddenly hold different types (also this might be needed to prevent collisions at runtime).

There is also no way to influence the type inferred for a a local variable declared with LET².

From that I'd say the answer is clearly no, and you really should use different names for different types. Also using CORRESPONDING on a generic field symbol sounds quite dangerous to me, I'd avoid that.


²Except you change the value from which the type is derived, eg. by CONVerting one table to the other (though that probably won't work for your case):

DATA(second_result) = VALUE second_table_type( 
  FOR <entry> IN CONV first_table_type( second_source ) 
    WHERE ( field1 EQ 'TEST1' ) 
    ( CORRESPONDING #( <entry> ) )  
).
Related