本系列前一篇文章 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_STYLE
FORM 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_CELLTAB
FORM 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