本系列前一篇文章 69. 利用 ALV 实现增删改查系列之一:让 ALV 报表进入可编辑状态,咱们介绍了如何让 SAP ABAP ALV 报表进入可编辑状态。在该状态下,ALV 报表的每一行,每一列都能够被任意批改,如下图所示:
然而在理论的我的项目中,更常见的需要是,ALV 报表只容许局部列可能编辑。
本文介绍只将 ALV 报表的局部列设置为可编辑状态的技术实现。
先看一下实现的成果。执行报表,发现 ALV 背景色为灰色,意味着这个报表默认状态为不可编辑。点击工具栏的眼镜笔图标:
此时只有 Airfare 列能够被编辑,其余列依然处于不可编辑状态。
上面是实现关键点介绍。
- 因为从本例开始,咱们实际上将输入内容从逻辑上拆分成两局部,一部分可编辑,另一部分不可编辑。咱们须要通过某种数据结构,通知 ALV 框架如何辨别这两局部。这个数据结构就是下图红色区域所示。其中第 11 行 INCLUDE STRUCTURE sflight 即 ALV 输入的业务数据即 sflight 数据库表的内容。第 12 行定义的 celltab 即是
控制结构
,该构造负责保护 ALV 某一列是否容许被编辑。
- 调用第 31 行
set_table_for_first_display
进行 ALV 输入时,输出参数 gs_layout 的 stylefname 字段值设置为 CELLTAB, 意思是通知 ALV 报表框架程序,输入数据结构 gt_outtab 内表里行构造的 CELLLTAB 字段,负责管制 ALV 列的可编辑性。
- 在第 62 行,通过 SELECT SQL 语句,将 sflight 数据库表里的数据读取进去,写到 ALV 报表调用 set_table_for_first_display 的输入内表 gt_outtab 中。这只是实现了业务数据的读取,接下来从 68 行开始的 LOOP 循环,遍历 ALV 待输入的每一条 sflight 数据,在代码第 71 行判断,如果检测到其 seatsmax 字段值大于 300,就容许这一列的某个字段能够被编辑,反之设置成只读。
下图 72 行调用 fill_celltab 这个 subroutine,传入 RW
代表 Read & Write,可读可写。RO
的意思是 Read-Only, 只读。
那么当 seatsmax 大于 300 时,到底咱们容许哪一个字段能够被编辑呢?这就得进入 fill_celltab 外部去查看。
能够看到,除了第 103 行的 PRICE 字段的编辑性,咱们依据传入的 p_mode 的不同,别离进行设置之外,其余所有字段,都设置成 cl_gui_alv_grid=>mc_style_disabled 即禁用,也就是不可编辑。
如果 subroutine 传入的 p_mode 值为 RW,则 PRICE 设置为 cl_gui_alv_grid=>mc_style_enabled,即容许编辑。
本例剩下的其余逻辑,同本系列前一篇文章介绍的步骤完全一致:
- 69. 利用 ALV 实现增删改查系列之一:让 ALV 报表进入可编辑状态
本例残缺源代码:
REPORT z.DATA: ok_code LIKE sy-ucomm, save_ok LIKE sy-ucomm, g_container TYPE scrfname VALUE 'ALV_CONTAINER', grid1 TYPE REF TO cl_gui_alv_grid, g_custom_container TYPE REF TO cl_gui_custom_container, gs_layout TYPE lvc_s_layo.DATA: BEGIN OF gt_outtab OCCURS 0. INCLUDE STRUCTURE sflight. DATA: celltab TYPE lvc_t_styl.DATA: END OF gt_outtab.CALL SCREEN 100.MODULE pbo OUTPUT. SET PF-STATUS 'MAIN100'. SET TITLEBAR 'MAIN100'. IF g_custom_container IS INITIAL. CREATE OBJECT g_custom_container EXPORTING container_name = g_container. CREATE OBJECT grid1 EXPORTING i_parent = g_custom_container. PERFORM select_data_and_init_style. gs_layout-stylefname = 'CELLTAB'. CALL METHOD grid1->set_table_for_first_display EXPORTING i_structure_name = 'SFLIGHT' is_layout = gs_layout CHANGING it_outtab = gt_outtab[]. ENDIF.ENDMODULE.MODULE pai INPUT. save_ok = ok_code. CLEAR ok_code. CASE save_ok. WHEN 'EXIT'. PERFORM exit_program. WHEN 'SWITCH'. PERFORM switch_edit_mode. WHEN OTHERS. ENDCASE.ENDMODULE.FORM exit_program. LEAVE PROGRAM.ENDFORM.FORM select_data_and_init_style. DATA: lt_sflight TYPE TABLE OF sflight, ls_sflight LIKE LINE OF lt_sflight, lt_celltab TYPE lvc_t_styl, l_index TYPE i. SELECT * FROM sflight INTO TABLE lt_sflight UP TO 10 ROWS. LOOP AT lt_sflight INTO ls_sflight. MOVE-CORRESPONDING ls_sflight TO gt_outtab. APPEND gt_outtab. ENDLOOP. LOOP AT gt_outtab. l_index = sy-tabix. REFRESH lt_celltab. IF gt_outtab-seatsmax GE 300. PERFORM fill_celltab USING 'RW' CHANGING lt_celltab. ELSE. PERFORM fill_celltab USING 'RO' CHANGING lt_celltab. ENDIF. INSERT LINES OF lt_celltab INTO TABLE gt_outtab-celltab. MODIFY gt_outtab INDEX l_index. ENDLOOP.ENDFORM. " SELECT_DATA_AND_INIT_STYLEFORM fill_celltab USING VALUE(p_mode) CHANGING pt_celltab TYPE lvc_t_styl. DATA: ls_celltab TYPE lvc_s_styl, l_mode TYPE raw4. IF p_mode EQ 'RW'. l_mode = cl_gui_alv_grid=>mc_style_enabled. ELSE. "p_mode eq 'RO' l_mode = cl_gui_alv_grid=>mc_style_disabled. ENDIF. ls_celltab-fieldname = 'CARRID'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'CONNID'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'FLDATE'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'PRICE'. ls_celltab-style = l_mode. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'CURRENCY'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'PLANETYPE'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'SEATSMAX'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'SEATSOCC'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab. ls_celltab-fieldname = 'PAYMENTSUM'. ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled. INSERT ls_celltab INTO TABLE pt_celltab.ENDFORM. " FILL_CELLTABFORM switch_edit_mode. IF grid1->is_ready_for_input( ) EQ 0. CALL METHOD grid1->set_ready_for_input EXPORTING i_ready_for_input = 1. ELSE. CALL METHOD grid1->set_ready_for_input EXPORTING i_ready_for_input = 0. ENDIF.ENDFORM. " SWITCH_EDIT_MODE