Обновленные записи не отображаются в подэкране ALV

Я пытаюсь отобразить обновленные записи в ALV, но отображаются старые записи.

Вот код, написанный на экране выхода из рабочего задания.

  TRY.
      cl_salv_table=>factory(
        EXPORTING
          r_container    = lo_cust_container
        IMPORTING
          r_salv_table   = lo_alv_table
        CHANGING
          t_table        = gt_wflog ).

**// Functions
      DATA(lo_alv_functions) = lo_alv_table->get_functions( ).
      lo_alv_functions->set_all( abap_true ).

**// Display Settings
      DATA(lo_alv_display) = lo_alv_table->get_display_settings( ).
      lo_alv_display->set_striped_pattern( abap_true ).

**// Layout Settings
      DATA: ls_layout_key TYPE salv_s_layout_key.
      DATA(lo_alv_layout) = lo_alv_table->get_layout( ).
      ls_layout_key-report = sy-repid.
      lo_alv_layout->set_key( ls_layout_key ).
      lo_alv_layout->set_save_restriction( cl_salv_layout=>restrict_user_independant ).

      lo_alv_columns->set_optimize( abap_true ).
      lo_alv_table->set_data( CHANGING t_table = gt_wflog[] ).
      lo_alv_table->display( ).

    CATCH cx_salv_msg cx_salv_error INTO DATA(lx_salv_msg).
      MESSAGE lx_salv_msg->get_text( ) TYPE 'I'.
  ENDTRY.

Я попытался использовать метод обновления lo_alv_table->resfresh( ). с опцией мягкого или полного обновления, но ничего не вышло. Данные о первом вызове в порядке, когда подэкран вызывается снова и данные изменяются, тогда обновленные записи не отображаются. Я вижу обновленные записи в таблице во время отладки.


person Umar Abdullah    schedule 16.01.2020    source источник


Ответы (3)


Скорее всего, у вас CX_SALV_NO_NEW_DATA_ALLOWED исключение, которое перехватывается предложением TRY во время второго вызова вашего экземпляра. Поэтому метод display() не выполняется.

В документации метода SET_DATA есть примечание:

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

...

Исключения
CX_SALV_NO_NEW_DATA_ALLOWED
Вы вызвали SET_DATA в обработчике событий.

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

Решение подтверждено OP: работает отлично

Добавлены объявления в топ include.

DATA go_alv_table TYPE REF TO cl_salv_table.

Добавлен в код

IF go_alv_table IS NOT BOUND.
  cl_salv_table=>factory( )
  ...
ENDIF.

Добавлено после вызова метода set_data

go_alv_table->refresh( refresh_mode = if_salv_c_refresh=>soft ).
person Suncatcher    schedule 16.01.2020

Это хорошо известная проблема с элементами управления. Если вы создаете экземпляр любого элемента управления GUI (в вашем случае это сетка ALV) внутри контейнера, в котором уже был элемент управления, который не был освобожден (в вашем случае, сетка ALV сначала была создана с использованием cl_salv_table=>factory), то старый элемент управления все еще отображается, новый не отображается.

Два решения:

  • Либо вы продолжаете создавать экземпляр элемента управления, но затем вы должны освободить предыдущий элемент управления. Для этого необходимо вызвать control->FREE( ), за которым следует оператор FREE control. Этот метод доступен для всех элементов управления (можно освободить даже сам контейнер, после чего будут освобождены все его внутренние элементы управления).

  • Или вы меняете логику, создавая экземпляр элемента управления только один раз и обновляя его содержимое.

Особый случай: некоторые элементы управления могут быть обернуты некоторыми классами-оболочками, которые не предоставляют доступ к элементу управления (например, классы SALV), поэтому простой способ - освободить контейнер, к которому прикреплен элемент управления.

person Sandra Rossi    schedule 16.01.2020

Просто дополнение к ответу @suncatcher. Сначала проверяет, содержит ли ссылочная переменная действительную ссылку: «ЕСЛИ go_alv_grid IS BOUND».

Пример:

ВЫБРАТЬ * ИЗ zemployees ОБХОД БУФЕРА В ТАБЛИЦУ it_zemployees.

IF go_alv_grid IS BOUND. 
  go_alv_grid->refresh( ).

ELSE.
  cl_salv_table=>factory(
EXPORTING
  r_container    = NEW cl_gui_custom_container( 'CONTAINER_NAME' ) 
  container_name = 'CONTAINER_NAME'
IMPORTING
  r_salv_table   = go_alv_grid
CHANGING
  t_table        = it_zemployees
  ).

  "Style the table
  go_alv_grid->get_functions( )->set_all( ).
  go_alv_grid->get_columns( )->set_optimize( ).
  go_alv_grid->get_display_settings( )->set_striped_pattern( abap_true ).


  go_alv_grid->display( ).
ENDIF.
person Shreyder    schedule 03.06.2020