更新的记录不显示在子屏幕 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.
我正在尝试在 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.