动态修改ALV(自定义 From)

本文介绍如何在ABAP中实现ALV的动态修改功能,包括定义事件处理、设置字段属性及实现刷新操作等关键步骤。通过具体代码示例展示了从初始化字段类别到最终显示ALV表格的全过程。

*代码部分为修改alv必须部分
*& 动态修改alv和内表
*& 步骤: 1.定义ls_events。
2.在layout部分写入events参数
3.在filecat将需编辑字段设置为可编辑。
4.在pf_status 和 user_commd部分注册和实现功能。
5.在CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY_LVC’中调用pf_status 和user_commd.

tips: 
如果不在pf_status 和user_commd中定义events,
使用alv刷新,CALL METHOD ref_grid->refresh_table_display.会downp。
动态修改alv功能会实现不了

DATA:BEGIN OF gs_data,
a TYPE int8,
b TYPE int8,
c TYPE int8,
END OF gs_data.
DATA gt_data LIKE TABLE OF gs_data.

DATA: gs_fieldcat TYPE lvc_s_fcat,
gt_fieldcat TYPE lvc_t_fcat,
gt_fieldcat2 TYPE lvc_t_fcat,
gs_fieldcat2 TYPE lvc_s_fcat,
gs_layout TYPE lvc_s_layo,

ls_events TYPE slis_alv_event, "ALV修改
lt_events TYPE slis_t_event,
ref_grid TYPE REF TO cl_gui_alv_grid.

SELECTION-SCREEN BEGIN OF BLOCK blk0 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS:s_a FOR gs_data-a.
SELECTION-SCREEN END OF BLOCK blk0.

INITIALIZATION.

START-OF-SELECTION.
PERFORM frm_get_data.
PERFORM frm_init_fieldcat.
PERFORM frm_init_layout.
PERFORM frm_display_alv.

FORM frm_init_fieldcat .
DEFINE fcat.
CLEAR gs_fieldcat.
gs_fieldcat-fieldname = &1.
gs_fieldcat-coltext = &2.
gs_fieldcat-edit = &3.
gs_fieldcat-ref_table = &4.
gs_fieldcat-ref_field = &5.

gs_fieldcat-key = &6.
APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.

fcat ‘A’ ‘A’ ‘X’ ‘’ ‘’ ‘’.
fcat ‘B’ ‘B’ ‘’ ‘’ ‘’ ‘’.
fcat 'C' 'C' '' '' '' 'X'.
ENDFORM.
&---------------------------------------------------------------------
*& Form INIT_LAYOUT
&---------------------------------------------------------------------

  •   text ALV输出格式
    

----------------------------------------------------------------------
FORM frm_init_layout."ALV输出格式
i_grid_settings-edt_cll_cb = 'X'. "ALV 控制: 退出可编辑单元格时回调 ls_events-form = 'DATA_CHANGED_METHOD'.
ls_events-name = slis_ev_data_changed.
APPEND ls_events TO lt_events.
ENDFORM."FRM_INIT_LAYOUT
&---------------------------------------------------------------------
*& Form DISPLAY_ALV
&---------------------------------------------------------------------

  •   text  输出ALV
    

----------------------------------------------------------------------
FORM frm_display_alv."输出ALV
CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY_LVC’
EXPORTING
i_callback_program = sy-repid
is_layout_lvc = gs_layout
i_grid_settings = i_grid_settings ""设置参数回调,屏幕修改值,自动保存到ALV 内表
i_callback_pf_status_set = 'FRM_SET_STATUS'
i_callback_user_command = 'FRM_USER_COMMAND'
it_fieldcat_lvc = gt_fieldcat
i_save = ‘A’
it_events = lt_events[]
TABLES
t_outtab = gt_data[]
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."FRM_DISPLAY_ALV
*&---------------------------------------------------------------------
**& Form FRM_SET_STATUS
*&---------------------------------------------------------------------
** text 状态栏
*----------------------------------------------------------------------
FORM frm_set_status USING pu_extab TYPE kkblo_t_extab .
DATA:lt_fcode TYPE TABLE OF sy-ucomm.
* SET PF-STATUS 'STATU'.
"获取grid
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = ref_grid.
"注册事件
CALL METHOD ref_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_modified.
IF sy-subrc <> 0. ENDIF.
ENDFORM. " FRM_SET_STATUS

*&---------------------------------------------------------------------
**& Form USER_COMMAND
*&---------------------------------------------------------------------

FORM frm_user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.

CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = ref_grid. "获取全局变量

CALL METHOD ref_grid->check_changed_data. "获取响应事件
CASE r_ucomm.
WHEN ‘&IC1’.

ENDCASE.
rs_selfield-refresh = 'X'."刷新界面
rs_selfield-col_stable = 'X'. "列保持
rs_selfield-row_stable = ‘X’. "行保持`

ENDFORM. "FRM_USER_COMMAND

FORM data_changed_method USING pcl_data TYPE REF TO cl_alv_changed_data_protocol.
DATA: mod_data TYPE lvc_t_modi,
wa_mod_data TYPE lvc_s_modi.
DATA: count TYPE n.
mod_data = pcl_data->mt_mod_cells.

LOOP AT mod_data INTO wa_mod_data WHERE fieldname = 'A'.
gs_data-c = wa_mod_data-value + gs_data-b.
MODIFY gt_data FROM gs_data INDEX wa_mod_data-row_id.
ENDLOOP.
CALL METHOD ref_grid->refresh_table_display.

ENDFORM.

&---------------------------------------------------------------------
*& Form frm_get_data
&---------------------------------------------------------------------
*& text
&---------------------------------------------------------------------
*& --> p1 text
*& <-- p2 text
&---------------------------------------------------------------------
FORM frm_get_data .

gs_data = VALUE #( a = s_a-low b = 2 ) .
gs_data-c = gs_data-a + gs_data-b.
APPEND gs_data TO gt_data.

gs_data = VALUE #( a = s_a-low b = 3 ) .
gs_data-c = gs_data-a + gs_data-b.
APPEND gs_data TO gt_data.

gs_data = VALUE #( a = s_a-low ) .
gs_data-c = gs_data-a + gs_data-b.
APPEND gs_data TO gt_data.

gs_data = VALUE #( b = 2 ) .
gs_data-c = gs_data-a + gs_data-b.
APPEND gs_data TO gt_data.

ENDFORM.

<think>好的,我现在需要帮助用户了解如何在ABAP的OOALV中实现双屏并创建自定义的保存按钮。首先,我得回忆一下ABAP中OOALV的基本结构以及双屏处理的方法。 用户提到的是双屏,也就是主屏和子屏的切换。通常,在OOALV中,主屏幕显示列表,子屏幕用于详细显示或编辑。可能需要用到CL_GUI_DIALOGBOX_CONTAINER或者导航到另一个屏幕。但具体的实现步骤可能需要详细分析。 接下来是自定义保存按钮。用户可能希望在子屏上有一个保存按钮,当用户点击时,将修改的数据保存到数据库。这时候,需要在子屏的PBO和PAI中处理事件,特别是要处理按钮的点击事件,并调用保存逻辑。 首先,可能需要创建两个屏幕:一个主屏幕(比如1000)显示ALV列表,另一个子屏幕(比如2000)显示详细数据。主屏幕的ALV可能需要设置事件处理程序,比如双击事件,以便导航到子屏幕。 然后,在子屏幕上放置自定义容器,比如CL_GUI_CUSTOM_CONTAINER,并在上面创建输入字段或者另一个ALV用于编辑。同时,添加保存按钮到子屏幕的GUI状态或者直接作为按钮控件。 保存按钮的事件处理需要通过USER-COMMAND来处理。当用户点击按钮时,系统会触发PAI事件,并根据sy-ucomm的值执行相应的保存逻辑。这时候,需要从子屏幕的ALV或输入字段中获取修改后的数据,验证数据,然后更新到数据库表中。 需要注意的是,双屏之间的数据传递可能需要使用全局变量或者通过类属性来传递。同时,确保在子屏幕关闭后,主屏幕的ALV能够刷新显示更新后的数据。 可能的难点包括正确处理屏幕流,确保两个屏幕之间的导航顺畅,以及数据的一致性和完整性。此外,保存按钮的事件处理需要与ABAP的对话编程模型结合,正确处理PAI和PBO模块。 另外,关于OOALV的创建,主屏和子屏可能需要分别创建不同的ALV实例,并管理它们的数据对象。在子屏中,可能需要使用可编辑的ALV,允许用户修改数据,然后通过保存按钮触发保存操作。 总结一下,步骤可能包括: 1. 创建主屏幕和子屏幕,定义各自的屏幕编号。 2. 在主屏幕中创建OOALV显示列表,并设置事件处理程序(如双击进入子屏)。 3. 在子屏幕中添加自定义容器和ALV,允许编辑数据。 4. 在子屏幕中添加保存按钮,并处理其USER-COMMAND。 5. 在PAI中处理保存逻辑,更新数据库。 6. 返回主屏幕时刷新ALV数据。 需要验证每一步的具体实现,比如如何导航到子屏幕,如何在子屏幕中布局控件,如何捕获按钮点击事件,以及如何将数据写回数据库。此外,错误处理和数据验证也是关键点,确保用户输入的有效性。 可能还需要参考SAP的标准程序或文档,确认双屏导航的最佳实践,以及如何在OOALV中正确处理用户交互。同时,确保在保存时使用BAPI或直接更新数据库表,并处理可能的异常情况。</think>在ABAP中实现OOALV双屏并创建自定义保存按钮,需遵循以下结构化步骤: --- ### **步骤1:定义屏幕及容器** 1. **主屏幕(如1000)** - 使用`CL_GUI_CUSTOM_CONTAINER`或`CL_GUI_DOCKING_CONTAINER`创建容器。 - 初始化主ALV对象(`CL_SALV_TABLE`),绑定到容器。 - 设置事件处理器(如双击事件`DOUBLE_CLICK`)。 2. **子屏幕(如2000)** - 创建对话框容器`CL_GUI_DIALOGBOX_CONTAINER`或导航至新屏幕。 - 添加可编辑的ALV或输入字段,绑定到子容器。 - 添加自定义GUI状态,包含保存按钮(`SAVE`)。 --- ### **步骤2:实现双屏导航** 1. **主屏跳转子屏** - 在主ALV的`DOUBLE_CLICK`事件中调用子屏: ```abap CALL SCREEN 2000. ``` - 或通过对话框容器动态创建子屏。 2. **子屏返回主屏** - 在子屏的PAI模块中处理`BACK`命令或关闭按钮: ```abap LEAVE TO SCREEN 0. ``` --- ### **步骤3:自定义保存按钮逻辑** 1. **GUI状态添加按钮** - 在子屏的GUI状态(`STATUS`)中定义保存按钮: ```abap SET PF-STATUS 'ZSAVE_STATUS'. ``` - 按钮功能码设为`SAVE`。 2. **处理PAI事件** - 在子屏的PAI模块中捕获`sy-ucomm = 'SAVE'`: ```abap MODULE user_command_2000 INPUT. CASE sy-ucomm. WHEN 'SAVE'. PERFORM save_data. ENDCASE. ENDMODULE. ``` 3. **保存数据逻辑** - 从子屏ALV获取修改后的数据(`GET_CHANGED_DATA`)。 - 验证数据有效性。 - 调用BAPI或直接更新数据库表: ```abap UPDATE ztable SET ... WHERE ... COMMIT WORK. ``` --- ### **步骤4:刷新主屏数据** - 子屏关闭后,在主屏的PBO中调用`REFRESH`方法: ```abap METHOD refresh_main_alv. lo_alv->refresh( ). ENDMETHOD. ``` --- ### **关键代码示例** ```abap " 子屏PAI处理保存 MODULE user_command_2000 INPUT. CASE sy-ucomm. WHEN 'SAVE'. " 获取ALV修改数据 lo_sub_alv->get_changed_data( CHANGING ct_data = lt_modified_data ). " 数据验证及保存 IF validate_data( lt_modified_data ). UPDATE ztarget_table FROM TABLE lt_modified_data. IF sy-subrc = 0. MESSAGE '保存成功' TYPE 'S'. LEAVE TO SCREEN 1000. " 返回主屏 ELSE. MESSAGE '保存失败' TYPE 'E'. ENDIF. ENDIF. ENDCASE. ENDMODULE. ``` --- ### **注意事项** 1. **数据一致性** - 使用事务码`SE11`锁对象或`ENQUEUE`确保并发安全。 2. **错误处理** - 在保存逻辑中捕获异常(如`CX_SALV_ERROR`)。 3. **性能优化** - 批量提交数据(`UPDATE ... FROM TABLE`)。 通过以上步骤,可实现双屏数据编辑及自定义保存功能,确保用户交互流畅且数据可靠。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值