Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

VALUE operator

Former Member

Need some clarity on the VALUE operator.

The following lines of code work as expected.

data it TYPE STANDARD TABLE OF i with EMPTY KEY.
it = value #( ( 1 ) ( 2 ) ( 3 ) ).

But with the below code, I get an error.

data lt type IF_SALV_GUI_TYPES_IDA=>YTS_FIELD_NAME.
lt = VALUE #( ( 'VBELN' ) ( 'POSNR' ) ).

Error message -> "'VBELN'" and the row type of "LT" are incompatible.

The type mentioned above has a domain of type CHAR 30.

Can some please shed some light.

Thanks,

Vikram.M

1 ACCEPTED SOLUTION

fabianlupa
Contributor
0 Kudos

Try CONV maybe?

lt = VALUE #( ( CONV #( 'VBELN' ) ) ( CONV #( 'POSNR' ) ) ).
12 REPLIES 12

fabianlupa
Contributor
0 Kudos

Try CONV maybe?

lt = VALUE #( ( CONV #( 'VBELN' ) ) ( CONV #( 'POSNR' ) ) ).

0 Kudos

Thanks that seems to do the trick. But I still dont understand why a conversion is required here though.

0 Kudos

Type inference for the literals probably builds C LENGTH 5 in both cases which is not strictly compatible with CHAR 30.

pokrakam
Active Contributor
0 Kudos

if a table consists of multiple named components you need to specify them by name. I suspect this will also trigger implicit conversion, whereas unnamed fields might not. A bug maybe?

itab = value #( ( myfield = 'foo' ) ( myfield = 'bar' ) ). 

Another small comment: the # is an inference operator, telling the compiler to work out the data type.

If you ar declaring it right before the assignment, you may as well do both in the same line of code:

data(itab) = value mytabletype( ( field1 = 'a' field2 = 1 )
                                ( field1 = 'b' field2 = 2 ) ).

pokrakam
Active Contributor

OK, this bothered me so I did some testing. It definitely doesn't do implicit conversion on single-field tables, but if you put it inside a structure it works with a fully-specified field.

    TYPES t_itab TYPE SORTED TABLE OF fieldname WITH UNIQUE KEY table_line.
    DATA(test1) = VALUE t_itab( ( 'ID' ) ).                              "==> Not OK
    DATA(test2) = VALUE t_itab( ( 'ID                            ' ) ).  "==> OK
TYPES: BEGIN OF t_field, fieldname TYPE fieldname, END OF t_field. TYPES t_fields TYPE SORTED TABLE OF t_field WITH UNIQUE KEY fieldname.
DATA(fields1) = VALUE t_fields( ( 'ID' ) ). "==> Not OK DATA(fields2) = VALUE t_fields( ( 'ID ' ) ). "==> Not OK DATA(fields3) = VALUE t_fields( ( fieldname = 'ID' ) ). "==> OK

So implicit conversion only happens on fully-specified components, even though the compiler is able to figure it out in order to provide the error message 🙂

I would be very interested if horst.keller could share some insight? I kindof expected the second failure but was a bit surprised by the first case.

horst_keller
Product and Topic Expert
Product and Topic Expert

The behavior is not as documented.

DATA dref TYPE REF TO string.
dref = NEW #( 'X' ). "No Error

DATA itab TYPE TABLE OF string.
itab = VALUE #( ( 'X' ) ). "Error

DATA tref LIKE REF TO itab.
tref = NEW #( ( 'X' ) ). "Error

According to documentation the second and third should behave as the first.

Let's see whether the behavior or the documentation will be adjusted.

pokrakam
Active Contributor

OK, after discussing with a colleague, we tried string templates, and they work fine. Methinks something in ABAP is not consistent from a user point of view. The latest code / result set:

    TYPES t_itab TYPE SORTED TABLE OF fieldname WITH UNIQUE KEY table_line.
    DATA itab TYPE t_itab.
itab = VALUE #( ( 'ID' ) ). "==> Not OK itab = VALUE #( ( `ID` ) ). "==> Not OK itab = VALUE #( ( |ID| ) ). "==> OK itab = VALUE #( ( 'ID ' ) ). "==> OK TYPES: BEGIN OF t_field, fieldname TYPE fieldname, END OF t_field. TYPES t_fields TYPE SORTED TABLE OF t_field WITH UNIQUE KEY fieldname. DATA fields TYPE t_fields. fields = VALUE #( ( 'ID' ) ). "==> Not OK fields = VALUE #( ( 'ID ' ) ). "==> Not OK fields = VALUE #( ( |ID| ) ). "==> OK fields = VALUE #( ( fieldname = 'ID' ) ). "==> OK

horst_keller
Product and Topic Expert
Product and Topic Expert

As in my comment above.

TYPES text TYPE c LENGTH 1.
DATA dref TYPE REF TO text.
dref = NEW #(  `X`  ). "No Error
dref = NEW #(  |X|  ). "No Error

DATA itab TYPE TABLE OF text.
itab = VALUE #( ( |X| ) ). "No Error
itab = VALUE #( ( `X` ) ). "Error

Works different than documented.

According to documentation for elementary line types the same should hold as for elementary types with NEW.

This example shows that rather the behavior must be corrected and not the documentation.

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

Seems that you found an error. Either in behavior or in documentation.

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

It is all about inserting lines into internal tables.

Here we go,

CLASS cls DEFINITION.
  PUBLIC SECTION.
    METHODS main.
    METHODS meth RETURNING VALUE(r) TYPE string.
ENDCLASS.
CLASS cls IMPLEMENTATION.
  METHOD main.

    TYPES c1 TYPE c LENGTH 1.
    DATA itab TYPE TABLE OF c1.

    DATA(txt) = `X`.

    DATA jtab TYPE TABLE OF string.
    TYPES:
      BEGIN OF tst,
        col TYPE string,
      END OF tst.
    DATA ktab TYPE TABLE OF tst.

    "itab = VALUE #( ( txt ) ).                                 "Error
    "INSERT txt INTO TABLE itab.                                "Error
    itab = VALUE #( ( CONV string( 'X' ) ) ).                   "No error
    INSERT CONV string( 'X' ) INTO TABLE itab.                  "No Error
    itab = VALUE #( ( substring( val = 'X' off = 1 ) ) ).       "No error
    "INSERT substring( val = 'X' off = 1 ) INTO TABLE itab.     "Error
    itab = VALUE #( ( |X| )  ).                                 "No error
    "INSERT |X| INTO TABLE itab.                                "Error
    itab = VALUE #( ( 'X' && 'X' )  ).                          "No error
    "INSERT 'X' && 'X' INTO TABLE itab.                         "Error
    itab = VALUE #( ( COND string(  WHEN 1 = 1 THEN `X`) )  ).  "No error
    INSERT COND string(  WHEN 1 = 1 THEN `X`) INTO TABLE itab.  "No Error
    itab = VALUE #( ( meth( ) )  ).                             "No error
    "INSERT meth( ) INTO TABLE itab.                            "Error
    itab = VALUE #( ( jtab[ 1 ] ) ).                            "No Error
    "INSERT jtab[ 1 ] INTO TABLE itab.                          "Error
    itab = VALUE #( ( ktab[ 1 ]-col ) ).                        "No Error
    "INSERT ktab[ 1 ]-col INTO TABLE itab.                      "Error

  ENDMETHOD.
  METHOD meth.
  ENDMETHOD.
ENDCLASS.

(same results for structured line types).

From that, the current behavior for inserting lines in tables can be summarized as follows:

  • The VALUE operator requires compatibility for data objects (fields). Convertibility is sufficient for expressions (built-in funktions, functional methods, calculation expressions, constructor expressions, table expressions).
  • The INSERT statement always requires compatibility except for arbitrary constructor expressions.

Note that the CONV operator in INSERT in the above example creates type string that is not compatible to the line type c lengh 1.

Let's say, it is ABAPesk.

Note:

Here we are dealing with the insertion of whole lines into internal tables.The discussion about assigning structure components with ( col = ... ) is orthogonal to this. For these assignments the normal assignment rules are followed. For inserting into internal tables we have to regard the net result of the expression in the brackets.

0 Kudos

Bug or a feature?

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

For the time being it is a feature.