ABAP--如何使用REUSE_ALV_GRID_DISPLAY函数删除内表数据(样例代码,感谢依风提供)

这篇博客介绍了如何在ABAP中利用REUSE_ALV_GRID_DISPLAY函数显示并删除内表数据。通过示例代码,展示了如何设置ALV表格的列属性、回调函数以及处理用户命令来实现内表数据的选择和删除功能。

请注意程序中的五处红色标记的代码,其他代码请用户自己按自己的需要进行修改

*&---------------------------------------------------------*
*& REPORT CREATE TRANSFER                                  *
*&---------------------------------------------------------*
*& Create date       : 2007/06/21                          *
*& Program type      : Report                              *
*&---------------------------------------------------------*
*& Modifications :                                         *
*& Date      | Programmer |Change request | Description    *
*&                                                         *
*&-------------------------------------------------------- *
REPORT zsdpr_yfdj MESSAGE-ID zmc01 NO STANDARD PAGE HEADING LINE-SIZE 500.
************************************************************
*  TABLES
************************************************************
TABLES : zadtb_yf.

TYPE-POOLS: slis.
************************************************************
*INTERNAL TABLE DEFINITION
************************************************************
DATA: BEGIN OF gs_it,
        lfdat(10),
        vbeln(50),
        zstation(20),
      END OF gs_it.
DATA : gt_it  LIKE gs_it   OCCURS 0 WITH HEADER LINE.
DATA : gt_itab LIKE zadtb_yf OCCURS 0 WITH HEADER LINE.
DATA: BEGIN OF gs_yf  OCCURS 0 .
*1内表增加一个选中字段
DATA:  gv_check TYPE c.
       INCLUDE TYPE zadtb_yf.
DATA: END OF gs_yf.

DATA : gt_yf   LIKE gs_yf OCCURS 0 WITH HEADER LINE.
************************************************************
* Variable  DEFINITION
***********************************************************
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE,
      gs_layout   TYPE slis_layout_alv,
      usercommand TYPE slis_fieldname VALUE 'USERCOMMAND',
      gt_sort     TYPE slis_t_sortinfo_alv.
DATA: progname    LIKE sy-repid,
      title(70).
DATA : gv_cancel(1) TYPE c,
       gv_flag TYPE i.
************************************************************
* SELECTION-SCREEN
************************************************************
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-bl1.
SELECTION-SCREEN SKIP 1.
SELECT-OPTIONS:
           so_lfdat     FOR zadtb_yf-lfdat,"提货日期
           so_vbeln     FOR zadtb_yf-vbeln,"销售凭证
           so_erdat     FOR zadtb_yf-erdat."录入日期
SELECTION-SCREEN END OF BLOCK bl1.
SELECTION-SCREEN BEGIN OF BLOCK bl3 WITH FRAME TITLE text-bl3.
PARAMETERS: pa_z2 RADIOBUTTON GROUP pa2 ."删除
SELECTION-SCREEN SKIP 1 .
SELECTION-SCREEN END OF BLOCK bl3.
***********************************************************
* START OF  SELECTION
***********************************************************
START-OF-SELECTION.
    PERFORM get_date.
END-OF-SELECTION.
    PERFORM output_date.
*&---------------------------------------------------------------------*
*&      Form  GET_DATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_date .
  SELECT *
       INTO CORRESPONDING FIELDS OF TABLE gt_yf
       FROM zadtb_yf
       WHERE  lfdat IN   so_lfdat  "提货日期
       AND    vbeln IN   so_vbeln  "销售凭证
       AND    erdat IN  so_erdat.  "录入日期
ENDFORM.                    " GET_DATE
*&---------------------------------------------------------------------*
*&      Form  OUTPUT_DATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM output_date .
  REFRESH  gt_fieldcat.
  progname = sy-repid.
  title = '运费查询及信息删除'.

  gs_layout-zebra  = 'X'.            "设置每行的背景颜色交错 显示。
  gs_layout-colwidth_optimize = 'X'.  "ALV输出时候自动优化宽 度
  gs_layout-detail_popup    = 'X'.

*2此处代码设置屏幕的chekbox选中字段
 gt_fieldcat-fieldname = 'GV_CHECK'.
  gt_fieldcat-seltext_m  = '选择'.
  gt_fieldcat-outputlen = 1.
  gt_fieldcat-checkbox = 'X'.
  gt_fieldcat-input = 'X'.
  gt_fieldcat-edit = 'X'.
  APPEND gt_fieldcat.
  CLEAR gt_fieldcat.

 gt_fieldcat-fieldname = 'LFDAT'.
  gt_fieldcat-seltext_m  = '提货日期'.
  gt_fieldcat-outputlen = 10.
  APPEND gt_fieldcat.
  CLEAR gt_fieldcat.

  gt_fieldcat-fieldname = 'VBELN'.
  gt_fieldcat-seltext_m  = '销售凭证'.
  gt_fieldcat-outputlen = 50.
  APPEND gt_fieldcat.
  CLEAR gt_fieldcat.

  gt_fieldcat-fieldname = 'ZSTATION'.
  gt_fieldcat-seltext_m  = '到站'.
  gt_fieldcat-outputlen = 20.
  APPEND gt_fieldcat.
  CLEAR gt_fieldcat.

*3设置处理代码
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = progname
      is_layout                = gs_layout
      it_fieldcat              = gt_fieldcat[]
     i_grid_title             = title
      i_callback_pf_status_set = 'PF_STATUS_SET'
      i_callback_user_command  =  usercommand
*      i_save                  = 'A'
    TABLES
      t_outtab                 = gt_yf
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
       WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    " OUTPUT_DATE
*&---------------------------------------------------------------------*
*&      FORM user_command
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM usercommand USING ucomm TYPE sy-ucomm
                    selfield TYPE slis_selfield.
  DATA: lr_grid TYPE REF TO cl_gui_alv_grid.

*4此处代码将用户输入读入内表(这一步不可少)
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lr_grid.
  CALL METHOD lr_grid->check_changed_data.

*5此处代码阻止'REUSE_ALV_GRID_DISPLAY创建新的屏幕,造成屏幕多层
  selfield-refresh = 'X'.
  CASE sy-ucomm.
    WHEN 'DELE'.
      CLEAR  sy-ucomm.
      LOOP AT gt_yf.
        IF gt_yf-gv_check = 'X'.
*请填写删除操作
           DELETE gt_yf.
        ENDIF.
      ENDLOOP.
  ENDCASE.
ENDFORM.                    "USER_COMMAND
*&---------------------------------------------------------------------*
*&      FORM PF_STATUS_SET
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM pf_status_set USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'YFDJ'  .
ENDFORM.                    "frm_PF_STATUS_SET 

<think>我们正在讨论ABAP中的ALV网格控件,特别是REUSE_ALV_GRID_DISPLAY_LVC函数模块。用户想要在修改单元格数据后刷新网格,同时保持当前的滚动位置(即用户正在查看的行和列不会因为刷新而改变)。 根据引用[^1],我们知道REUSE_ALV_GRID_DISPLAY_LVC是REUSE_ALV_GRID_DISPLAY的升级版,支持单元格级别的编辑。引用[^2]和[^3]提到了如何实现单元格编辑以及如何设置回调(通过设置`ls_setting-edt_cll_cb = 'X'`来启用单元格更改事件)。 但是,用户的问题是关于刷新网格并保持位置。在ALV中,当我们刷新网格时,默认情况下会回到初始位置(即第一行第一列)。为了保持位置,我们需要在刷新前保存当前的滚动位置,然后在刷新后恢复这个位置。 具体步骤: 1. 在刷新前获取当前的滚动位置(行和列)。 2. 刷新网格(重新显示ALV)。 3. 在刷新后设置之前保存的滚动位置。 在ABAP中,我们可以使用类`CL_GUI_ALV_GRID`的方法来获取和设置滚动位置。 实现思路: - 在定义ALV网格时,我们需要声明一个引用变量指向ALV网格对象(如`gr_alv`)。 - 在刷新网格之前,调用`gr_alv->get_scroll_info()`方法获取当前的滚动信息(包括行和列)。 - 刷新网格(通常是通过调用函数重新显示ALV,但注意刷新时不能重新创建ALV控件,而应该使用`gr_alv->refresh_table_display()`方法)。 - 刷新之后,调用`gr_alv->set_scroll_info()`方法将之前保存的滚动位置设置回去。 但是,这里需要注意的是,用户使用的是`REUSE_ALV_GRID_DISPLAY_LVC`函数,这个函数在内部创建了ALV网格控件,并且我们通常不会直接持有该控件的引用。所以,我们需要在调用函数时获取这个引用,并保存起来。 具体步骤: 1. 在调用`REUSE_ALV_GRID_DISPLAY_LVC`时,通过参数`I_CALLBACK_PROGRAM`指定回调程序,同时使用`I_CALLBACK_TOP_OF_PAGE`或`I_CALLBACK_HTML_TOP_OF_PAGE`等参数并不是必须的。但是,为了获取ALV对象的引用,我们需要使用`I_CALLBACK_USER_COMMAND`或类似回调,或者使用`ES_EXIT_CAUSED_BY_USER`参数获取信息,但这些都不直接提供对象引用。 另一种方法:使用`cl_gui_alv_grid`的静态方法`get_instance_by_sub_id`或`get_instance_by_dynnr`来获取实,但这种方法需要知道子容器ID或屏幕号,在函数模块内部创建的情况下可能比较困难。 实际上,在调用`REUSE_ALV_GRID_DISPLAY_LVC`时,我们可以通过参数`I_GRID`传递一个容器对象(自定义容器),这我们就可以通过容器来获取ALV网格实。但是,如果我们没有使用自定义容器(即使用函数默认创建的容器),那么我们就需要在回调中获取实。 在ABAP中,有一个标准的做法:在`REUSE_ALV_GRID_DISPLAY_LVC`函数中,我们可以通过`I_CALLBACK_PROGRAM`指定回调程序,并在回调程序中使用`GET REFERENCE OF`来获取ALV对象。但更常见的做法是使用类`CL_GUI_CFW`的静态方法`GET_ALV_GRID`来获取当前屏幕上的ALV网格实。 然而,在函数模块`REUSE_ALV_GRID_DISPLAY_LVC`中,它内部创建了一个ALV网格控件,我们可以通过设置一个导出参数来获取这个网格对象的引用?查看函数文档,我们发现它并没有直接导出网格对象。 因此,我们需要改变方法:使用`REUSE_ALV_GRID_DISPLAY_LVC`的一个变通方式,即先创建一个自定义容器,然后将这个容器传递给函数,这我们就可以通过容器来获取ALV网格对象。 具体步骤: 1. 在屏幕上创建一个自定义容器控件(比如在屏幕绘制器中创建一个容器区域,并命名,如`CC_ALV`)。 2. 在程序中使用`DATA: gr_container TYPE REF TO cl_gui_custom_container, gr_alv TYPE REF TO cl_gui_alv_grid.`声明引用。 3. 实化容器:`CREATE OBJECT gr_container EXPORTING container_name = 'CC_ALV'.` 4. 然后使用函数`REUSE_ALV_GRID_DISPLAY_LVC`时,传递容器参数: ```abap CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_program = sy-repid i_grid_settings = ls_setting is_layout_lvc = ls_layout it_fieldcat_lvc = lt_fieldcat i_callback_user_command = 'USER_COMMAND' i_save = 'A' TABLES t_outtab = gt_data EXCEPTIONS program_error = 1 OTHERS = 2. ``` 注意:这里我们没有传递容器,所以函数会自己创建容器(默认是弹出一个对话框)。为了能够控制ALV对象,我们需要传递容器参数`I_CONTAINER`,即: ```abap CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_program = sy-repid i_container = gr_container " 传递自定义容器 ... ``` 但是,这个函数模块并没有`I_CONTAINER`参数!实际上,`REUSE_ALV_GRID_DISPLAY_LVC`函数内部会创建容器,并不支持传入外部容器。 所以,我们需要使用另一种方法:使用`CL_GUI_ALV_GRID`类来创建ALV网格。这我们就可以完全控制网格对象。 步骤: 1. 创建自定义容器。 2. 使用`CL_GUI_ALV_GRID`的构造函数创建ALV网格,并关联到容器。 3. 调用`SET_TABLE_FOR_FIRST_DISPLAY`方法显示数据。 这,我们就拥有了ALV网格对象的引用(`gr_alv`),然后就可以在需要刷新时调用`gr_alv->refresh_table_display()`方法,并且在刷新前后处理滚动位置。 关于刷新并保持位置: - 在用户修改单元格后,会触发`DATA_CHANGED`事件(需要设置`ls_setting-edt_cll_cb = 'X'`)。 - 在事件处理程序`ON_DATA_CHANGED`中,我们可以保存修改到内(通过`ER_DATA_CHANGED`对象的`MOD_CELLS`属性获取修改),然后刷新网格。 但是,刷新网格时,我们希望在刷新后保持滚动位置。因此,在刷新前保存滚动位置,刷新后恢复。 具体代码框架: ```abap * 定义类来处理事件 CLASS lcl_event_handler DEFINITION. PUBLIC SECTION. METHODS: handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid IMPORTING er_data_changed. ENDCLASS. CLASS lcl_event_handler IMPLEMENTATION. METHOD handle_data_changed. " 在此处理数据修改,更新内 " 然后刷新网格 DATA: ls_scroll TYPE lvc_s_scroll. " 保存当前滚动位置 gr_alv->get_scroll_info( IMPORTING e_row = lv_row e_col = lv_col ). " 或者使用结构ls_scroll gr_alv->get_scroll_info( IMPORTING es_scroll = ls_scroll ). " 更新内(根据er_data_changed的修改) " ... 这里需要编写代码将修改从er_data_changed应用到内gt_data " 刷新ALV gr_alv->refresh_table_display( ). " 恢复滚动位置 gr_alv->set_scroll_info( EXPORTING is_scroll = ls_scroll ). ENDMETHOD. ENDCLASS. ``` 注意:在刷新后恢复滚动位置,但是刷新操作可能会改变网格的结构(比如排序、过滤),所以需要确保在刷新前保存的滚动位置在刷新后仍然有效(即行号没有因为排序等操作而改变)。如果内数据顺序改变,那么原先的行号指向的行可能已经改变位置。所以,更安全的方法是保存关键字段的值,然后刷新后找到该行在刷新后的行号,再滚动到该行。 但是,如果只是简单的单元格修改(不改变行顺序),那么直接保存行索引(行号)即可。 因此,解决方案总结如下: 1. 使用类`CL_GUI_ALV_GRID`创建ALV网格,以便持有对象引用。 2. 注册事件`data_changed`,并设置`edt_cll_cb = 'X'`。 3. 在事件处理程序中,保存当前滚动位置(行号和列号),更新内数据,刷新网格,然后恢复滚动位置。 但是,用户要求使用`REUSE_ALV_GRID_DISPLAY_LVC`函数。如果我们无法通过该函数获取网格对象,那么我们就不能使用上述方法。那么,有没有办法在`REUSE_ALV_GRID_DISPLAY_LVC`创建的网格中实现呢? 实际上,我们可以通过类`CL_GUI_CFW`获取当前屏幕上的ALV网格实。但是,这种方法依赖于屏幕上的第一个ALV网格,如果只有一个ALV网格,可以这获取: ```abap DATA: gr_grid TYPE REF TO cl_gui_alv_grid. gr_grid ?= cl_gui_alv_grid=>get_instance( ). IF gr_grid IS BOUND. " 然后就可以调用方法 ENDIF. ``` 但是,请注意,`get_instance`方法在没有网格时会返回空。而且,如果有多个网格,还需要使用`get_instance_by_sub_id`等。 因此,在`REUSE_ALV_GRID_DISPLAY_LVC`之后,我们可以这获取网格对象: ```abap DATA: lo_grid TYPE REF TO cl_gui_alv_grid. lo_grid = cl_gui_alv_grid=>get_instance( ). IF lo_grid IS BOUND. " 保存滚动位置 lo_grid->get_scroll_info( ... ) " 刷新 lo_grid->refresh_table_display( ) " 恢复滚动位置 lo_grid->set_scroll_info( ... ) ENDIF. ``` 但是,在事件处理函数中,我们也可以使用`GET REFERENCE OF`来获取事件来源的对象(即触发事件的网格)。在事件处理程序方法中,可以使用参数`sender`来获取事件来源的网格对象。 因此,在`REUSE_ALV_GRID_DISPLAY_LVC`中,我们可以通过事件处理来获取网格对象: 1. 设置单元格编辑回调(`edt_cll_cb = 'X'`)。 2. 定义`DATA_CHANGED`事件的事件处理程序(通过设置`I_CALLBACK_DATA_CHANGED`参数)。 3. 在事件处理程序中,参数`ER_EVENT_DATA`(或`EO_DATA_CHANGED`,取决于事件类型)会传递一个对象,这个对象就是`CL_GUI_ALV_GRID`的实?实际上,在`REUSE_ALV_GRID_DISPLAY_LVC`中,事件处理程序`I_CALLBACK_DATA_CHANGED`被调用时,系统会传递一个类型为`CL_ALV_CHANGED_DATA_PROTOCOL`的对象(该对象包含了修改的单元格信息),但它不直接提供网格对象。 所以,我们还是要通过其他方式获取网格对象。 结论:为了可靠地获取ALV网格对象,建议使用自定义容器和`CL_GUI_ALV_GRID`类来创建ALV网格,而不是使用`REUSE_ALV_GRID_DISPLAY_LVC`函数。这我们就可以完全控制网格对象。 但是,如果用户坚持使用`REUSE_ALV_GRID_DISPLAY_LVC`,那么我们可以尝试在事件处理程序中使用`cl_gui_alv_grid=>get_instance()`来获取网格对象。由于函数模块默认会创建一个网格,所以我们可以这获取: ```abap DATA: lo_grid TYPE REF TO cl_gui_alv_grid. lo_grid = cl_gui_alv_grid=>get_instance( ). IF lo_grid IS BOUND. " 成功获取 ENDIF. ``` 因此,在回调函数`I_CALLBACK_DATA_CHANGED`中,我们可以这写: ```abap FORM data_changed USING p_data_changed TYPE REF TO cl_alv_changed_data_protocol. DATA: lo_grid TYPE REF TO cl_gui_alv_grid, ls_scroll TYPE lvc_s_scroll. " 获取网格实 lo_grid = cl_gui_alv_grid=>get_instance( ). IF lo_grid IS BOUND. " 保存滚动位置 lo_grid->get_scroll_info( IMPORTING es_scroll = ls_scroll ). " 将修改应用到内(根据p_data_changed) " ... " 刷新网格 lo_grid->refresh_table_display( is_stable = VALUE #( row = abap_true col = abap_true ) ). " 这里的is_stable参数可以保持稳定性,但可能还不够 " 恢复滚动位置 lo_grid->set_scroll_info( EXPORTING is_scroll = ls_scroll ). ENDIF. ENDFORM. ``` 但请注意,在刷新时使用`is_stable`参数可以告诉网格刷新时保持滚动位置,但实际上,在`refresh_table_display`方法中,有一个参数`IS_STABLE`,设置`row`和`col`为`abap_true`可以尝试保持稳定性,但文档说它只能保持滚动位置到可能的程度(比如行还在,没有过滤掉)。所以我们不需要自己手动设置滚动位置?但是,根据经验,仅仅设置`IS_STABLE`不一定能完全保持位置,尤其是当修改导致行高变化等情况时。 因此,手动保存和恢复滚动位置是更可靠的方法。 最终解决方案: 在`REUSE_ALV_GRID_DISPLAY_LVC`中,设置单元格编辑回调(`ls_setting-edt_cll_cb = 'X'`),并设置`I_CALLBACK_DATA_CHANGED`为`'DATA_CHANGED'`。 在`DATA_CHANGED`单中,使用`cl_gui_alv_grid=>get_instance()`获取网格实,然后保存滚动位置,修改内,刷新网格,最后恢复滚动位置。 注意:刷新前需要将修改保存到内,否则刷新后修改会丢失。如何保存?通过事件参数`p_data_changed`(类型为`cl_alv_changed_data_protocol`)可以获取修改的单元格信息。 示代码: ```abap FORM data_changed USING p_data_changed TYPE REF TO cl_alv_changed_data_protocol. DATA: lo_grid TYPE REF TO cl_gui_alv_grid. DATA: ls_scroll TYPE lvc_s_scroll. lo_grid = cl_gui_alv_grid=>get_instance( ). IF lo_grid IS BOUND. " 保存滚动位置 lo_grid->get_scroll_info( IMPORTING es_scroll = ls_scroll ). " 将修改应用到内 " 遍历p_data_changed->mt_mod_cells,修改内gt_data LOOP AT p_data_changed->mt_mod_cells ASSIGNING FIELD-SYMBOL(<fs_mod_cell>). " 修改内对应行的字段 ASSIGN gt_data[ <fs_mod_cell>-row_id ] TO FIELD-SYMBOL(<fs_line>). IF sy-subrc = 0. ASSIGN COMPONENT <fs_mod_cell>-fieldname OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_field>). IF sy-subrc = 0. <fs_field> = <fs_mod_cell>-value. ENDIF. ENDIF. ENDLOOP. " 刷新网格 lo_grid->refresh_table_display( ). " 恢复滚动位置 lo_grid->set_scroll_info( EXPORTING is_scroll = ls_scroll ). ENDIF. ENDFORM. ``` 注意:这里没有考虑修改验证等,实际应用中需要根据业务逻辑进行验证。 另外,如果修改导致行顺序变化(如,修改了排序字段),那么保存的行号可能不再指向同一行。在这种情况下,可能需要根据内容重新定位,但用户问题中没有提到这种情况,所以我们假设只是普通字段修改。 总结:通过获取ALV网格实,在刷新前保存滚动位置,刷新后恢复,可以实现刷新网格并保持位置。 因此,给用户的回答应该包含上述代码框架,并给出使用`REUSE_ALV_GRID_DISPLAY_LVC`时的事件处理设置方法。 </think>在ABAP使用`REUSE_ALV_GRID_DISPLAY_LVC`修改单元格数据后刷新网格并保持位置的解决方案如下: ### 核心步骤 1. **启用单元格编辑功能** 调用函数前需设置`I_GRID_SETTINGS-EDT_CLL_CB = 'X'`,启用单元格修改回调: ```abap DATA: ls_grid_settings TYPE lvc_s_glay. ls_grid_settings-edt_cll_cb = 'X'. " 启用单元格编辑回调[^3] ``` 2. **实现DATA_CHANGED事件处理** 在`I_CALLBACK_DATA_CHANGED`指定的子程式中处理修改: ```abap FORM data_changed USING p_changed TYPE REF TO cl_alv_changed_data_protocol. " 1. 保存当前滚动位置 DATA(lo_grid) = cl_gui_alv_grid=>get_instance( ). DATA: ls_scroll TYPE lvc_s_scroll. lo_grid->get_scroll_info( IMPORTING es_scroll = ls_scroll ). " 2. 将修改应用到内 LOOP AT p_changed->mt_mod_cells ASSIGNING FIELD-SYMBOL(<fs_mod>). MODIFY gt_data INDEX <fs_mod>-row_id FROM VALUE #( ( ... ) ) " 根据修改更新内 TRANSPORTING <字段名>. ENDLOOP. " 3. 刷新网格并恢复位置 lo_grid->refresh_table_display( is_stable = VALUE #( row = abap_true col = abap_true ) " 保持稳定性 ). lo_grid->set_scroll_info( is_scroll = ls_scroll ). " 恢复滚动位置 ENDFORM. ``` 3. **调用函数时传递参数** ```abap CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_data_changed = 'DATA_CHANGED' " 事件处理程式[^2] i_grid_settings = ls_grid_settings is_layout_lvc = ls_layout it_fieldcat_lvc = lt_fieldcat TABLES t_outtab = gt_data. ``` ### 关键点说明 1. **滚动位置保持** - 使用`get_scroll_info()`保存滚动状态(行/列位置)[^2] - 刷新后通过`set_scroll_info()`恢复位置 - `is_stable`参数确保刷新时界面稳定 2. **数据更新逻辑** - 通过`mt_mod_cells`获取修改的单元格列[^3] - 需同步更新底层内(`gt_data`),否则刷新后修改会丢失 3. **LVC特性利用** - 使用`REUSE_ALV_GRID_DISPLAY_LVC`(非旧版)支持单元格级操作[^1] - 结合`CL_GUI_ALV_GRID`方法实现精细控制 > 此方案通过事件捕获修改->保存界面状态->更新数据->恢复界面的流程,在保障数据一致性的同时维持用户体验[^2][^3]。 ---
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值