更新的记录不显示在子屏幕 ALV 中

Updated records are not displayed in subscreen 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( ).,但没有任何反应。第一次调用数据正常,再次调用subscreen,数据有变化,更新记录不显示。我可以在调试期间在 table 中看到更新的记录。

这是一个众所周知的控件问题。如果您在容器内实例化任何 GUI 控件(在您的情况下,它是 ALV 网格),其中已经有一个尚未 释放 的控件(在您的情况下,ALV 网格首先使用 cl_salv_table=>factory) 实例化,然后旧控件仍然显示,新控件未显示。

两种解决方案:

  • 要么你继续实例化控件,但是你必须释放之前的控件。为此,您必须调用 control->FREE( ),然后调用语句 FREE control。该方法对所有控件都有效(连容器本身也可以释​​放,其内部的所有控件都被释放)。

  • 或者您通过仅实例化控件一次来更改逻辑,然后刷新其内容。

特殊情况:一些控件可能被某些包装器 类 包装,这些包装器不允许访问控件(例如 SALV 类),所以最简单的方法是释放容器控件附加到的。

您很可能遇到 CX_SALV_NO_NEW_DATA_ALLOWED 异常,该异常在您实例化的第二次调用期间被 TRY 子句捕获。这就是 display() 方法没有被执行的原因。

SET_DATA方法文档中有注释:

You are not able to call these methods in an event handler. If you
do you will get an error.

...

Exceptions
CX_SALV_NO_NEW_DATA_ALLOWED
You have called SET_DATA in an event handler.

在您的上下文中,屏幕退出与事件处理程序相同,因为它由同一事件调用。

OP 确认了解决方案:“完美无缺”

已添加到顶部包含的声明中。

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 ).

只是对@suncatcher 的回答的补充。 首先检查引用变量是否包含有效引用:'IF go_alv_grid IS BOUND'.

示例:

SELECT * 从 zemployees 绕过缓冲区进入 TABLE 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.