Привет,в прошлой статье мы разобрали декларацию внутренних таблиц. Сегодня поговорим об использовании внутренних таблиц: добавление удаление и выборка данных, агрегатные функции и т.д.

Начнем с простейшего заполнения таблицы, для начала заполним таблицу прямо в коде программы:

REPORT  ZFM_ART_TEST.

*Объявляем таблицу
data: begin of itab occurs 0,
field1(50type c,
field2(50type c,
end of itab.

* Заполняем таблицу

itabfield1 ‘Запись 1 поле 1′.
itabfield2 ‘Запись 1 поле 2′.
append itab.

itabfield1 ‘Запись 2 поле 1′.
itabfield2 ‘Запись 2 поле 2′.
append itab.

break-point.

Запускаем программу (не забыв активировать). Пока не будем обрабатывать таблицу, посмотрим в отладчике на результат труда.

Давайте разберем программу. Все предельно просто – мы объявили таблицу, и т.к. указали occurs 0, то таблица у нас с рабочей областью. Мы присваиваем полям из рабочей области значения, а потом оператором append помещаем эти значения в записи таблицы.

Теперь давайте все-таки сделаем по данной таблице цикл и выведем значения на экран.

loop at itab.

write:/ itabfield1, itabfield2.

endloop.

Получаем результат:

Цикл можно организовать и с определенным условием:

loop at itab where field1+7(1) = ‘2’.

write:/ itabfield1, itabfield2.

endloop.

Мы задали условие, что цикл должен проходить только по записям, в который у поля field1 8-й символ равен 2. Получаем результат:

Вывести данные из таблицы (в данном конкретном случае будем считать, что это значит поместить их в заголовок/рабочую область) можно также оператором read.

Напишем следующий код:

*Объявляем таблицу
data: begin of itab occurs 0,
field1(50type c,
field2(50type c,
end of itab.

* Заполняем таблицу

itabfield1 ‘Запись 1 поле 1′.
itabfield2 ‘Запись 1 поле 2′.
append itab.

itabfield1 ‘Запись 2 поле 1′.
itabfield2 ‘Запись 2 поле 2′.
append itab.

write:‘До оператора read’.
write:/ itabfield1, itabfield2.

read table itab with key field1 ‘Запись 1 поле 1′.

if sysubrc 0.
write:‘После оператора read’.
write:/ itabfield1, itabfield2.
endif.

Результат:

Давайте разберем, что делает программа. Сначала, как и прошлый раз, мы объявили и заполнили таблицу. А затем я для наглядности вывел на экран текущее содержимое заголовка таблицы:

write:‘До оператора read’.
write:/ itabfield1, itabfield2.

Т.к. последние значения, которые мы помещали в заголовок, были:

itabfield1 ‘Запись 2 поле 1′.
itabfield2 ‘Запись 2 поле 2′.

То данный оператор вывел нам на экран текст:

Далее мы оператором read прочитали запись таблицы, у которой значение поля field1 равно ‘Запись 1 поле 1′. Поэтому после чтения write
нам выдал текст:

Перед тем как выводить текст на экран, я проверил, был ли успешным запрос к таблице при помощи условия if sysubrc 0, если бы я этого не сделал, то в случае неудачного запроса, я бы получил опять текст:

Вы, наверное, уже догадались, что оператор read всегда читает из таблицы только одну запись.

Для того, чтобы избежать сохранения устаревших данных после оператора read, в случае неудачного запроса, очень удобно использовать проверку кода возврата sy-subrc, но не всегда это возможно, т.к. код возврата может поменяться после других операторов (например, если вы читаете сразу из нескольких таблиц), поэтому я рекомендую, перед тем как читать таблицу, очистить её заголовок оператором clear (clear itab).

Удаление данных из таблицы производится оператором refresh – этот оператор чистит всю таблицу, кроме его заголовка.

В данном примере, мы рассматривали случай, когда рабочая область является частью таблицы, но, как правило, создается отдельная рабочая область с которой идет работа. Давайте рассмотрим аналогичные примеры, но уже с отдельной рабочей областью:

REPORT  ZFM_ART_TEST.

TYPES: begin of s_itab,
field1(50type c,
field2(50type c,
field3(16type decimals 2,
end of s_itab.
data: itab type table of s_itab.
data: wa_itab type s_itab.

data:
intern type table of alsmex_tabline,
wa_intern type alsmex_tabline,
l_index type i,
l_start_col type i value ‘1’,
l_start_row type i value ‘1’,
l_end_col type i value ‘3’,
l_end_row type i value ‘65536’.

parameter: f_name type rlgrapfilename obligatory.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR f_name.
CALL FUNCTION ‘F4_FILENAME’
EXPORTING
program_name  systcprog
dynpro_number systdynnr
field_name    ‘FILE_NM’
IMPORTING
file_name     f_name.

start-of-selection.
* Заполняем таблицу

call function ‘ALSM_EXCEL_TO_INTERNAL_TABLE’
exporting
filename                f_name
i_begin_col             l_start_col
i_begin_row             l_start_row
i_end_col               l_end_col
i_end_row               l_end_row
tables
intern                  intern
exceptions
inconsistent_parameters 1
upload_ole              2
others                  3.

if sysubrc > 0.
Write:‘Ошибка при открытии файла’.
else.
if intern[] is initial.
write:‘Данные не загружены!’.
else.
sort intern by row col.
loop at intern into wa_intern.
CASE wa_interncol.
WHEN ‘0001’.
wa_itabfield1   wa_internvalue.
WHEN ‘0002’.
wa_itabfield2   wa_internvalue.
WHEN ‘0003’.
wa_itabfield3   wa_internvalue.
APPEND wa_itab TO itab.
endcase.
endloop.
endif.
endif.

clear wa_itab.
loop at itab into wa_itab.

write:/ wa_itabfield1, wa_itabfield2, wa_itabfield3.

endloop.

Результат работы программы:

Теперь давайте разберем данную программу по косточкам, тем более я немного усложнил программу. Для интереса я не стал заполнять таблицу в коде программы, а заранее подготовил файл MS Excel, в которой ввел массив записей (см. ниже). Эти записи программа загрузит из файла и разместит во внутренней таблице.

Для загрузки данных будет использована функция ALSM_EXCEL_TO_INTERNAL_TABLE.

Итак…

  1. Объявляем переменные и внутренние таблицы.

TYPES: begin of s_itab,            » тип для таблицы itab и рабочей области
field1(50type c,
field2(50type c,
field3(16type decimals 2,
end of s_itab.
data: itab type table of s_itab.     » целевая таблица данных
data: wa_itab type s_itab.         » рабочая область для таблицы itab

data:
intern type table of alsmex_tabline,
wa_intern type alsmex_tabline,
l_start_col type i value ‘1’,
l_start_row type i value ‘1’,
l_end_col type i value ‘3’,
l_end_row type i value ‘65536’.

parameter: f_name type rlgrapfilename obligatory.

Здесь: s_itab – тип для таблицы itab (нашей таблицы данных),

itab – таблица данный,

wa_itab – рабочая область таблицы данных.

Для загрузки из Excel мы должны приготовить некоторые вспомогательные переменные и таблицы:

Intern – таблица, в которую функция ALSM_EXCEL_TO_INTERNAL_TABLE вернет данные из файла,

wa_intern – рабочая область таблицы intern,

l_start_col – начальный столбец Excel с которого будут загружаться данные,

l_start_row – начальная строка Excel с которой будут загружаться данные,
l_end_col –
конечный столбец, т.к. в нашем массиве данных три столбца, то значение этой переменной равно 3,
l_end_row 
конечная строка загрузки, сделаем её равной 65536.

Для того, чтобы ввести в программу путь к файлу, задам параметр (при его объявлении при запуске в программе, автоматически создается экран 1000 с параметрами запуска программы-отчета).

parameter: f_name type rlgrapfilename obligatory.

Т.к. удобнее вводить путь не руками, а выбирать через специальный сервис, то я обрабатываю событие кнопки F4 (или нажатие на кнопку вызова справочника справа от поля) для параметра f_name.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR f_name.
CALL FUNCTION ‘F4_FILENAME’
EXPORTING
program_name  systcprog
dynpro_number systdynnr
field_name    ‘FILE_NM’
IMPORTING
file_name     f_name.

  1. Запускаем функцию считывания данных из Excel

  call function ‘ALSM_EXCEL_TO_INTERNAL_TABLE’
exporting
filename                f_name
i_begin_col             l_start_col
i_begin_row             l_start_row
i_end_col               l_end_col
i_end_row               l_end_row
tables
intern                  intern
exceptions
inconsistent_parameters 1
upload_ole              2
others                  3.

Функция возвращает нам массив данных в таблицу intern в следующем виде:


Т.е. все значения ячеек прописываются в поле value, при этом в полях ROW и COL прописаны значения номера столбца и строки Excel.

  1. Обрабатываем полученные данные:

Проверяем отклик функции, если он больше нуля (ну или не равен) значит, данные не загрузились.

  if sysubrc > 0.
Write:‘Ошибка при открытии файла’.
else.

Если таблица
intern
пустая
,
а пустые квадратные скобки говорят о том, что мы в условии подразумеваем тело внутренней таблицы (например, intern[34] говорила бы о том, что мы работаем с записью 34 таблицы).


if intern[] is initial.
write:‘Данные не загружены!’.
else.

На всякий случай сортируем таблицу
intern
по записям и
столбцам и делаем по ней цикл, помещая значения полей в рабочую область wa_intern.


sort intern by row col.
loop at intern into wa_intern.

Оператор
CASE
помогает нам распределить данные по полям рабочей области wa_itab
таблицы itab в зависимости от значения поля wa_interncol (мы знаем, что первая колонка соответствует полю field1 и т.д.).
CASE wa_interncol.
WHEN ‘0001’.
wa_itabfield1   wa_internvalue.
WHEN ‘0002’.
wa_itabfield2   wa_internvalue.
WHEN ‘0003’.
wa_itabfield3   wa_internvalue.

Помещаем значение рабочей области в таблицу, после того, как заполнена вся запись, т.е. на каждом третьем цикле.


APPEND wa_itab TO itab.
endcase.
endloop.
endif.
endif.

clear wa_itab.
loop at itab into wa_itab.

write:/ wa_itabfield1, wa_itabfield2, wa_itabfield3.

endloop.

Мы рассмотрели возможность заполнения внутренней таблицы при помощи оператора append, это, наверное, один из наиболее используемых операторов. Но операторов, способных чего-нибудь вставить во внутреннюю таблицу несколько. Рассмотрим их. Первый, не менее полезный чем append, оператор collect. Суть этого оператора – добавлять в таблицу запись, если в таблице уже нет с такими же нечисловыми полями, а если такая запись находится, то данный оператор складывает (арифметически) все числовые поля. Давайте рассмотрим пример: перепишем нашу таблицу Excel, а в коде последней программы заменим «APPEND wa_itab TO itab.» на «COLLECT wa_itab INTO itab.».

Так у нас будут выглядеть загружаемые данные:


А вот наш цикл с заполнением таблицы
itab.

       loop at intern into wa_intern.
CASE wa_interncol.
WHEN ‘0001’.
wa_itabfield1   wa_internvalue.
WHEN ‘0002’.
wa_itabfield2   wa_internvalue.
WHEN ‘0003’.
wa_itabfield3   wa_internvalue.
*          APPEND wa_itab TO itab.
Collect wa_itab INTO itab.
endcase.
endloop.

При запуске программы получаем:


Также для работы с внутренними таблицами используются операторы:

Insert – добавляет запись во внутреннюю таблицу (возможно указание определенной позиции вставляемой записи в таблице);

Modify – изменяет запись в таблице по определенному условию, если такой записи нет, то она добавляется;

Delete – удаляет запись из таблицы по определенному условию.

[/paid_content]

  2 Ответов в “Работа с внутренними таблицами. Часть 2 — Работа с данными”

  1. Отличная статья, написанная простым и понятным языком. Кстати, отличный ресурс по SAP в век дефицита информации. Рекомендую, саперы;) А можно ли как то получить консультацию по классам?

  2. Привет! Сейчас у меня в работе несколько статей, в части ABAP пока продолжаю работать по внутренним таблицам, пишу про эволюцию систем управления, а также статья по проектному управлению.
    После них обещаю заняться классами в ABAP, видимо выведу в отдельную рубрику.

 
© 2013 sap-blog.ru
Яндекс.Метрика