DATA lo_alv TYPE REF TO cl_salv_table READ-ONLY.
...
DATA(lo_funcs) = lo_alv->get_functions( ).
lo_funcs->add_function(
EXPORTING
name = 'ZREFRESH'
icon = CONV #( ICON_REFRESH )
text = 'Обновить'
tooltip = 'Обновить'
position = if_salv_c_function_position=>left_of_salv_functions
).
...
DATA(lo_event) = lo_alv->get_event( ).
SET HANDLER on_alv_function FOR lo_event ACTIVATION abap_true.
...
METHODS on_alv_function FOR EVENT added_function OF cl_salv_events IMPORTING sender e_salv_function.
...
METHOD on_alv_function.
CASE e_salv_function.
WHEN 'ZREFRESH'.
...
WHEN OTHERS.
ENDCASE.
ENDMETHOD.
Но данный способ не подойдет, если вы хотите добавить не простую кнопку, а
кнопку с выпадающими действиями типа такой:
понедельник, 8 февраля 2021 г.
SALV с DropDown кнопками в панели инструментов
понедельник, 2 ноября 2020 г.
Странное поведение приведения классов
Код притянут за уши, но смысл его примерно такой. Есть некий базовый класс данных (LCL_ABSTRACT_DATA). От него наследуется конкретный класс с конкретными данными (LCL_DATA).Данные тут таблица целых чисел. Для простоты она сделана публичной. Также есть метод PRINT, который выводит содержимое таблицы на экран.
Также есть некий абстрактный обработчик данных (LCL_ABSTRACT_PROCESSOR), который при создании на вход получает ссылку на инстанцию класса с данными и сохраняет ее у себя в атрибуте (MO_DATA). От него наследуется обработчик для конкретных данных (LCL_PROCESSOR), который работает именно с LCL_DATA. Для этого внутри своих методов он приводит ссылку на LCL_ABSTRACT_DATA к ссылке на LCL_DATA и работает именно с ней. У него есть 3 разных метода (PROCESS,PROCESS2,PROCESS3), где приведение происходит разными способами. И это, как говорится, влияет! В остальном методы делают одно и тоже - прибавляют 1 к каждому числу в таблице
В начале программы создается класс с данными и заполняется двумя числами 1 и 2.
Далее создается класс процессора, куда передается ссылка на созданный класс с данными, после чего выводится начальное содежимое таблицы класса с данными.
Далее последовательно вызываются методы PROCESS,PROCESS2,PROCESS3 у процессора и после каждого вызова происходит вывод текущего состояния таблицы с данными на экран.
Рассмотрим первый метод:
METHOD process.
DATA(lo_data) = lcl_data=>cast( mo_data ).
LOOP AT lo_data->mt_data ASSIGNING FIELD-SYMBOL(<v_value>).
ADD 1 TO <v_value>.
ENDLOOP.
ENDMETHOD.
Здесь вначале вызывается метод lcl_data=>cast для приведения ссылки на LCL_ABSTRACT_DATA к ссылке на LCL_DATA. Полученная ссылка запоминается в переменной LO_DATA. После чего идет цикл по LO_DATA->MT_DATA и к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 2 и 3: (1,2) + 1 -> (2,3). Забегая вперед - так и есть. Тут все работает.
Рассмотрим второй метод:
METHOD process2.
LOOP AT CAST lcl_data( mo_data )->mt_data ASSIGNING FIELD-SYMBOL(<v_value>).
ADD 1 TO <v_value>.
ENDLOOP.
ENDMETHOD.
Здесь вначале для приведения ссылки используется конструкция CAST lcl_data( mo_data ) непосредственно в теле цикла. В логике все то же самое - к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 3 и 4: (2,3) + 1 -> (3,4). Забегая вперед - так и есть. Тут тоже все работает.
И, наконец, третий метод:
METHOD process3.
LOOP AT lcl_data=>cast( mo_data )->mt_data ASSIGNING FIELD-SYMBOL(<v_value>).
ADD 1 TO <v_value>.
ENDLOOP.
ENDMETHOD.
Здесь вначале для приведения ссылки используется конструкция lcl_data=>cast( mo_data ) как и в первом методе, но ссылка предварительно не запоминается, а результат вызова метода CAST используется непосредственно в теле цикла. В логике все то же самое - к каждом числу в таблице добавляется 1. В итоге значения в таблице должны стать 4 и 5: (3,4) + 1 -> (4,5). И вот тут все не так.
Вот как выглядит вывод программы:Как видите, последний метод почему-то не меняет данные в таблице, хотя в отладке все вроде происходит: 3 становится 4, а 4 становится 5. Но после выхода из цикла эти изменения испаряются. Такое чувство, что в этом случае создается какая-то локальная копия класса именно для цикла и изменения происходят в ней. После чего она благополучно поглощается сборщиком мусора. И главное не понятно по какой причине. Да, returning возращает value, то есть, значение, а не ссылку, но это значение и содержит ссылку. Ну, то есть, даже если это копия оригинальной ссылки, то указывать-то она все равно должна на то же самое!
В общем толи я чего-то не понимаю, толи это баг в SAP.
SELECT * и CORRESPONDING
Часто в регламентах на разработку или в BestPracties нас пугают тем, что писать SELECT * - это плохо. Аргументируется это тем, что не надо выбирать лишнии данные чтобы избегать проблем с производительностью (передача большего числа полей из БД понятно приводит к замедлению этого процесса) и занимаемой памятью (понятно что переденное где то в итоге хранится). И аргументация правильная, но не многие знают, что SELECT * не всегда выбирает все поля.