VALUE, FOR и TABLE EXPRTESSIONS – ABAP 740
Разработчики SAP постоянно нас радуют новыми апгрейдами, в том числе и в ABAP; сегодня я хотел бы рассмотреть новые конструкции языка, которые упрощают нам с вами жизнь.
Содержание
Пример №1. Несколько способов инициализации структур
Пример №2. Инициализации внутренних таблиц
Пример №3. Инициализация сложных типов таблиц с глубокой структурой
Пример №4. Копирование данных при создании таблицы из другой внутренней таблицы
Пример №5. Использование WHERE условий в операторе FOR
Пример №6. Использование вложенных FOR
Пример №7. Чтение таблицы по индексу
Пример №8. Запись значений компонента в таблицу по индексу
Пример №9. Поиск и выдача данных из таблицы с использованием ключа, без какой-либо рабочей области
Аннотация
Разработчики SAP постоянно нас радуют новыми апгрейдами, в том числе и в ABAP; сегодня я хотел бы рассмотреть новые конструкции языка, которые упрощают нам с вами жизнь. Я использовал как материалы с официальных блогов SAP, так и некоторые заметки из иностранных обзоров. Цель же моя проста: познакомить тех, кто еще не знает этого, с новыми операторами и конструкциями языка, а может, и напомнить, о том, что иногда стоит привыкать делать что-то «по-новому», оставляя старые привычки позади!
Итак, рассмотрим два новых оператора и синтаксис работы с внутренними таблицами:
- Оператор VALUE
- Оператор FOR
- Выражения для внутренних таблиц (TABLE EXPRESSIONS)
Работа с операторами
Оператор VALUE
Для начала обратимся к официальной информации и почитаем, что пишут о новом операторе:
1. VDLUE – это по сути конструктор, который определяет данные с указанным типом
… VALUE dtype|#( ) …
2. Он может установить начальные значения для любого типа данных
… VALUE dtype|#( comp1 = a1 comp2 = a2 … ) …
3. Он может установить значение сразу для нескольких записей
… VALUE dtype|#( ( … ) ( … ) … ) …
4. Он не работает с простыми типами
Давайте посмотрим синтаксис определения таблиц с вложенными структурами:
VALUE dtype|#( col1 = dobj11 … ( col2 = dobj12 col3 = dobj13 … ) ( col2 = dobj22 col3 = dobj23 … ) … col1 = dobj31 col2 = dobj32 … ( col3 = dobj33 … ) ( col3 = dobj43 … ) … ).
Как видно, синтаксис имеет гибкую структуру и чем-то походит на объявления массивов в современных языках программирования.
Примеры использования
Пример №1. Несколько способов инициализации структур
TYPES: BEGIN OF t_col2, col1 TYPE i, col2 TYPE i, END OF t_col2. TYPES: BEGIN OF t_struct, col1 TYPE i, col2 TYPE t_col2, END OF t_struct. DATA: struct TYPE t_struct, col2 TYPE t_col2. “1 struct = VALUE t_struct( col1 = 1 col2-col1 = 1 col2-col2 = 2 ). “2 col2 = VALUE t_col2( col1 = 1 col2 = 2 ). struct = VALUE t_struct( col1 = 1 col2 = col2 ). “3 struct = VALUE t_struct( col1 = 1 col2 = VALUE #( col1 = 1 col2 = 2 ) ).
Пример №2. Инициализации внутренних таблиц
TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY. DATA itab TYPE t_itab. itab = VALUE #( ( ) ( 1 ) ( 2 ) ). DATA itab TYPE RANGE OF i. itab = VALUE #( sign = ‘I’ option = ‘BT’ ( low = 1 high = 10 ) ( low = 21 high = 30 ) ( low = 41 high = 50 ) option = ‘GE’ ( low = 61 ) ).
Пример №3. Инициализация сложных типов таблиц с глубокой структурой
TYPES: BEGIN OF ty_alv_data, kunnr TYPE kunnr, name1 TYPE name1, ort01 TYPE ort01, land1 TYPE land1, t_color TYPE lvc_t_scol, END OF ty_alv_data. TYPES: tt_alv_data TYPE STANDARD TABLE OF ty_alv_data WITH DEFAULT KEY. * classical DATA: itab_alv_c TYPE tt_alv_data. FIELD-SYMBOLS: <fs_a> LIKE LINE OF itab_alv_c, <fs_col> LIKE LINE OF <fs_a>-t_color. APPEND INITIAL LINE TO itab_alv_c ASSIGNING <fs_a>. <fs_a>-kunnr = '123'. <fs_a>-name1 = 'ABCD'. <fs_a>-ort01 = 'LV'. <fs_a>-land1 = 'NV'. APPEND INITIAL LINE TO <fs_a>-t_color ASSIGNING <fs_col>. <fs_col>-fname = 'KUNNR'. <fs_col>-color-col = COL_NEGATIVE. <fs_col>-color-int = 0. <fs_col>-color-inv = 0. APPEND INITIAL LINE TO <fs_a>-t_color ASSIGNING <fs_col>. <fs_col>-fname = 'ORT01'. <fs_col>-color-col = COL_TOTAL. <fs_col>-color-int = 1. <fs_col>-color-inv = 1. APPEND INITIAL LINE TO itab_alv_c ASSIGNING <fs_a>. <fs_a>-kunnr = '456'. <fs_a>-name1 = 'XYZ'. <fs_a>-ort01 = 'LA'. <fs_a>-land1 = 'CA'. * Using VALUE DATA(itab_alv) = VALUE tt_alv_data( "First Row ( kunnr = '123' name1 = 'ABCD' ort01 = 'LV' land1 = 'NV' " color table t_color = VALUE #( " Color table - First Row ( fname = 'KUNNR' color-col = COL_NEGATIVE color-int = 0 color-inv = 0 ) " Color Table - 2nd Row ( fname = 'ORT01' color-col = COL_TOTAL color-int = 1 color-inv = 1 ) ) ) "Second row ( kunnr = '456' name1 = 'XYZ' ort01 = 'LA' land1 = 'CA' ) ).
Тесно с этим оператором может сотрудничать еще один новенький оператор, оператор FOR!
Оператор FOR
Этот оператор предоставляет возможность пройтись по таблице (почти как старый добрый LOOP), и по своей природе является итератором, его особенность в удобном синтаксисе и достаточно широких возможностях использования.
Рассмотрим мини-пример:
DATA(t_city) =
VALUE tt_citys(
FOR ls_cust IN t_customres
INDEX INTO cust_index
( ls_cust-city )
).
Мы определяем таблицу t_city, записи в которую добавляются одновременно с созданием. В таблицу t_ заносятся все города из таблицы ls_cust, одновременно с каждой итерацией переключается индекс строки в переменной cust_index.
Примеры использования
Посмотрим полные примеры использования…
Пример №4. Копирование данных при создании таблицы из другой внутренней таблицы
TYPES:
BEGIN OF ty_customer,
customer TYPE char10,
NAME TYPE char30,
city TYPE char30,
route TYPE char10,
END OF ty_customer.
TYPES: tt_customers TYPE SORTED TABLE OF ty_customer
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 17
Комментарий от
Олег Башкатов
| 04 июля 2017, 08:02
zevolving.com/2014/09
zevolving.com/2015/05
Комментарий от
Леонид Мартынов
| 04 июля 2017, 09:34
Олег Башкатов 04 июля 2017, 08:02
Леонид, я правильно понимаю, что реально Вы не используете эти конструкции и не применяете? иначе, зачем Вы копируете "один-в-один" из статьи 2015года в том числе и примеры:
zevolving.com/2014/09
zevolving.com/2015/05
Комментарий от
Олег Точенюк
| 04 июля 2017, 21:43
Леонид Мартынов 04 июля 2017, 09:34
Реально я с ними не так давно познакомился, примеры в общем доступе из интернета в том числе сап блогов , не хотел тратить время на измышления своих,теперь пытаюсь их применять, и по своим коллегам вижу , что они тоже не часто не то что не используют, не знаю что такие конструкции появились. Цель статьи рассказать, ознакомить =)
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
а потом плакать будут, окружающие, ну зато мне работы может подкинут :-) в перспективе, так как суть старого и нового методов различна и сравнивать их в таком виде очень не рекомендуется, а вы вот сравниваете и не понимаете в чем существенная разница.
Комментарий от
Леонид Мартынов
| 05 июля 2017, 05:44
Олег Точенюк 04 июля 2017, 21:43
Ознакомить то оно конечно полезно, только в таком виде лучше бы не делать этого. А то ведь послушают вас и возьмут на вооружение, например предложенный вами последний пример:
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
а потом плакать будут, окружающие, ну зато мне работы может подкинут :-) в перспективе, так как суть старого и нового методов различна и сравнивать их в таком виде очень не рекомендуется, а вы вот сравниваете и не понимаете в чем существенная разница.
Тем не менее спасибо за комментарий =)
Комментарий от
Леонид Мартынов
| 05 июля 2017, 06:00
Олег Точенюк 04 июля 2017, 21:43
Ознакомить то оно конечно полезно, только в таком виде лучше бы не делать этого. А то ведь послушают вас и возьмут на вооружение, например предложенный вами последний пример:
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
а потом плакать будут, окружающие, ну зато мне работы может подкинут :-) в перспективе, так как суть старого и нового методов различна и сравнивать их в таком виде очень не рекомендуется, а вы вот сравниваете и не понимаете в чем существенная разница.
Комментарий от
Леонид Мартынов
| 05 июля 2017, 08:32
Комментарий от
Олег Точенюк
| 05 июля 2017, 15:40
Леонид Мартынов 05 июля 2017, 05:44
я лишь показал примеры использования новых моделей, как их лучше применять решит каждый в зависимости от задачи, не правда ли? Использовать ли первую (скажем с лог. поиском) или простую вторую конструкцию - решит программист,не было целью обучать программированию, целью было продемонстрировать. Если вы готовы судить о том, чтО я понимаю , а что нет то мне жаль, что вы готовы это делать заочно. Еще раз повторюсь - цель показать примеры!
Тем не менее спасибо за комментарий =)
По поводу решил программист, согласитесь для того, чтобы что-то решить, нужно представлять последствия своих решений (например использовать BAPI или вкатить прямой апдейт таблиц). Из написанного вами получается, что последствий никаких, это просто новый, более компактный метод записи кода. Я правильно понял донесенную вами мысль?
Комментарий от
Олег Точенюк
| 05 июля 2017, 15:43
Леонид Мартынов 05 июля 2017, 06:00
Удивляюсь только одному, сколь много людей готовы выразить многозначность своего ЭГО и показать свой великолепный ум, на таком мелком материале....без зазрения совести уверенные, что у других нет возможности отличить черное от белое, или скажем доступ к одному полю и чтение в структуру....беда!
Комментарий от
Леонид Мартынов
| 05 июля 2017, 16:14
Олег Точенюк 05 июля 2017, 15:43
Вы даже не представляете какая беда... уже попал на любителей нового синтаксиса, оказывается, таки не понимают.
Комментарий от
Леонид Мартынов
| 05 июля 2017, 16:15
Олег Точенюк 05 июля 2017, 15:40
А очно вы себе это как представляете, я к вам в гости или вы ко мне? Комментарии к статье как бы и предназначены для общения и высказывания своего мнения по прочитанному. Не очень понимаю в чем была проблема? Ну добавьте в следующий раз в конце статьи, что просьба по статье не высказываться, раз это сильно почему-то задевает.
По поводу решил программист, согласитесь для того, чтобы что-то решить, нужно представлять последствия своих решений (например использовать BAPI или вкатить прямой апдейт таблиц). Из написанного вами получается, что последствий никаких, это просто новый, более компактный метод записи кода. Я правильно понял донесенную вами мысль?
Спасибо за ваше мнение!
Комментарий от
Сергей Левченко
| 13 июля 2017, 11:31
Олег Точенюк 04 июля 2017, 21:43
Ознакомить то оно конечно полезно, только в таком виде лучше бы не делать этого. А то ведь послушают вас и возьмут на вооружение, например предложенный вами последний пример:
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
а потом плакать будут, окружающие, ну зато мне работы может подкинут :-) в перспективе, так как суть старого и нового методов различна и сравнивать их в таком виде очень не рекомендуется, а вы вот сравниваете и не понимаете в чем существенная разница.
Вообше непонятно, зачем АБАПу новые операторы, если все "старые" языки пошли в библиотеки.
С уважением
Сергей
Комментарий от
Иван Рыбкин
| 13 июля 2017, 12:46
Олег Точенюк 05 июля 2017, 15:43
Вы даже не представляете какая беда... уже попал на любителей нового синтаксиса, оказывается, таки не понимают.
Комментарий от
Олег Точенюк
| 13 июля 2017, 19:45
Иван Рыбкин 13 июля 2017, 12:46
Олег, добрый день. Если не трудно, напишите плз, какие возникают проблемы при использовании нового синтаксиса? ( не считая того , что надо использовать TRY.. ENTRY ). Чисто практический интерес..
Хорошо, буквально один пример, из приведенного выше, который я использовал в самом начале.
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
На самом деле старый метод написан не правильно, эквивалент нового метода должен быть таким:
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123' TRANSPORTING ort01.
т.е. вы фактически читаете значение одного поля. К чему это ведет с точки зрения производительности. В старой конструкции обычно читали всю запись, а дальше фактически вы могли работать со всеми полями считанной записи. В новой методике многие начинать писать так:
WRITE: /
itab_multi_comp[ kunnr = '123' ]-ort01,
itab_multi_comp[ kunnr = '123' ]-ort02,
itab_multi_comp[ kunnr = '123' ]-ort03,
itab_multi_comp[ kunnr = '123' ]-ort04.
Абап не умеет оптимизировать такие конструкцию, фактически это приводит к 4 последовательными чтениям т.е. в старых терминах можно считать что будет выполняь следующий код:
READ TABLE itab_multi_comp INTO:
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort01,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort02,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort03,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort04.
Как можно понять производительность при этом проседает, хотя написание кода более короткое и визуально воспринимается проще.
Комментарий от
Сергей Плаксин
| 21 июля 2017, 11:47
Олег Точенюк 13 июля 2017, 19:45
Да я просто не знаю, как бы статья не моя, наверное лучше чтобы автор продолжил раскрывать данную тему, ну как мне кажется.
Хорошо, буквально один пример, из приведенного выше, который я использовал в самом начале.
* Старый метод доступа
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123'.
WRITE: / ls_comp-ort01.
* Новый метод доступа
WRITE: / itab_multi_comp[ kunnr = '123' ]-ort01.
На самом деле старый метод написан не правильно, эквивалент нового метода должен быть таким:
READ TABLE itab_multi_comp INTO ls_comp WITH KEY kunnr = '123' TRANSPORTING ort01.
т.е. вы фактически читаете значение одного поля. К чему это ведет с точки зрения производительности. В старой конструкции обычно читали всю запись, а дальше фактически вы могли работать со всеми полями считанной записи. В новой методике многие начинать писать так:
WRITE: /
itab_multi_comp[ kunnr = '123' ]-ort01,
itab_multi_comp[ kunnr = '123' ]-ort02,
itab_multi_comp[ kunnr = '123' ]-ort03,
itab_multi_comp[ kunnr = '123' ]-ort04.
Абап не умеет оптимизировать такие конструкцию, фактически это приводит к 4 последовательными чтениям т.е. в старых терминах можно считать что будет выполняь следующий код:
READ TABLE itab_multi_comp INTO:
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort01,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort02,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort03,
ls_comp WITH KEY kunnr = '123' TRANSPORTING ort04.
Как можно понять производительность при этом проседает, хотя написание кода более короткое и визуально воспринимается проще.
WRITE: /
itab_multi_comp[ kunnr = '123' ]-ort01.
нельзя будет забывать писать
TRY.
CATCH CX_SY_ITAB_LINE_NOT_FOUND.
ENDTRY.
Иначе, приведет к неминуемому дампу, если такой записи во внутренней таблице нет.
Комментарий от
Олег Точенюк
| 26 июля 2017, 12:09
Сергей Плаксин 21 июля 2017, 11:47
К тому же для конструкции:
WRITE: /
itab_multi_comp[ kunnr = '123' ]-ort01.
нельзя будет забывать писать
TRY.
CATCH CX_SY_ITAB_LINE_NOT_FOUND.
ENDTRY.
Иначе, приведет к неминуемому дампу, если такой записи во внутренней таблице нет.
Комментарий от
Олег Башкатов
| 06 декабря 2019, 06:20
Сергей Плаксин 21 июля 2017, 11:47
К тому же для конструкции:
WRITE: /
itab_multi_comp[ kunnr = '123' ]-ort01.
нельзя будет забывать писать
TRY.
CATCH CX_SY_ITAB_LINE_NOT_FOUND.
ENDTRY.
Иначе, приведет к неминуемому дампу, если такой записи во внутренней таблице нет.
ls_line = VALUE #( lt_tab[ f1 = 'NOT_EXIST' ] OPTIONAL ).
тогда не нужны проверки на исключение.
Комментарий от
Олег Точенюк
| 12 декабря 2019, 15:05
Сергей Левченко 13 июля 2017, 11:31
Олег, лучше напиши какие могут быть проблемы. Воспитание учителей неблагодарный труд. :)
Вообше непонятно, зачем АБАПу новые операторы, если все "старые" языки пошли в библиотеки.
С уважением
Сергей
LOOP AT <таблица> INTO data(<строка>).
ENDLOOP.
намного удобнее и проще чем отдельно объявление строки заголовка.
Или заполнение таблицы через VALUE тоже как мне кажется удобнее и проще. Так что смысл есть.