Инлайновая декларация ABAP - DATA()

Важно знать про инлайн декларации:

  • Инлайновые переменные определяются только локально
  • Тип переменной определяется в момент компиляции, 
    а не в момент создания переменной
  • Переменная, определённая инлайн внутри какой-либо конструкции, например, LOOP или CASE, остаётся доступной и вне этой конструкции.

Инлайновая декларация в ABAP стала доступна начиная с версии 7.4, в предыдущих использовались старые варианты записи. Существует множество вариантов использования инлайн декларирования, но они не заменят полностью обычный вид декларирования переменных, а только дадут возможность для некоторых случаев заменить его на новый вид записи.

Создание переменной в любой момент

+ Удобно  при создании переменной, сразу произвести её заполнение нужными данными и она уже готова к использованию без лишних строк.

- В недостаток некоторые указывают снижение читабельности кода, но ,по моему мнению, это спорный вопрос.

" Создаём структуру
DATA(ls_scar) = VALUE scarr( carrid   = 'AA'
                             carrname = 'American Air' ).
" Создаём таблицу
DATA(lt_scar) = VALUE scarr_t( ( carrid   = 'AA'
                              	 carrname = 'American Air' ) ).

Считывание данных во внутреннюю таблицу

+ Удобно  считывать данные из таблицы базы данных во внутреннюю таблицу определённую инлайн. В этом случае программа сама сформирует таблицу со столбцами, указанными после оператора SELECT. При этом, нам не нужно предварительно определять тип внутренней таблицы или считывать лишние данные в неё, используя имеющийся тип.

- Недостаток этого варианта в том, что таблица, которая определена инлайн, всегда стандартная (STANDART TABLE). А работа со стандартными таблицами при большом объёме данных - это не оптимальный вариант. Более оптимально использовать сортированные или хэшированные таблицы, в зависимости от определённого случая.

SELECT carrid, carrname
  INTO TABLE @DATA(lt_scarr)
  FROM scarr
  UP TO 5 ROWS.	

Получение строки или ссылки на строку внутренней таблицы

+ Удобно без определения дополнительных переменных пробежаться по внутренней таблице и, например, изменить значения в строках. Или считать данные с использованием конструкции READ TABLE и поместить ссылку на строку в переменную, определённую инлайн.

- Недостатком этого варианта называют то, что если одну переменную использовать два раза в одинаковых циклах, то не получится поменять их местами без дополнительных правок кода. Также, слышал комментарии о том, что данный вариант определения снижает читабельность кода. По моему мнению, этот вариант удобен и я не вижу у него каких то реальных минусов.

LOOP AT lt_scarr REFERENCE INTO DATA(lr_scarr). "Получаем ссылку
ENDLOOP.
	
LOOP AT lt_scarr INTO DATA(ls_scarr). "Получаем копию строки
ENDLOOP.	

"Аналогично определяется преременная при READ TABLE
READ TABLE lt_data REFERENCE INTO DATA(lr_data).

При вызове методов во входных и выходных параметрах

+ Удобно в момент вызова метода, например, определить таблицу или структуру и сразу передать её в метод, даже не создавая отдельной переменной с наименованием. Например,
таблицу "VALUE #( ( day = '22' year = '2020' ) )" или
структуру "VALUE #( day = '22' year = '2020' )", заполнив только необходимые для нас поля.
Также, мы можем непосредственно при вызове метода поместить результат его выполнения в переменную определённую инлайн.

- Ограничения этого способа в том, что мы не можем передать инлайн переменную в метод или получить её непосредственно, при вызове, если параметр имеет родовой тип DATA (RV_RESULT Returning Type Ref To DATA). Также, мы не можем, по понятным причинам, определить переменные CHANGING инлайн. Важным ограничением является то, что мы не можем использовать инлайновое декларирование непосредственно при вызове ФМ.

cl_salv_table=>factory( 
EXPORTING t_table = VALUE #( ( day = '22' year = 2020 ) )
IMPORTING r_salv_table = DATA(lr_grid) ).

" Ограничения ФМ
DATA:
  lv_new_day TYPE SCAL-INDICATOR.

CALL FUNCTION 'DATE_COMPUTE_DAY'
  EXPORTING
    DATE          = CONV sy-datum( |20200322| )
  IMPORTING
    DAY           = lv_new_day.

" Таким образом получить параметр из ФМ нельзя
CALL FUNCTION 'DATE_COMPUTE_DAY'
  EXPORTING
    DATE          = sy-datum
  IMPORTING
    DAY           = DATA(lv_day).

Данная статья не полностью охватывает всю обширную тему инлайнового декларирования, поэтому в ближайшее время выйдет вторая часть данной статьи.