有朋友向我咨询,SAP ABAP 报表输入字段,如何实现联动效果?
所谓联动效果,如下图所示,我们有三个输入框,类型都是 Checkbox:
- 激活缓存
- 使用共享内存
- 使用二级缓存
默认情况下,使用共享内存和使用二级缓存这两个 Checkbox 处于禁用状态。只有当我们选中 激活缓存
时,这两个 Checkbox 才允许编辑:
当我们选中了使用共享内存和使用二级缓存后,如果将激活缓存的勾去掉:
那么使用共享内存和使用二级缓存的两个勾也应该自动被去掉。
这就是 Checkbox 的联动效果,即 Checkbox 1 需要控制 Checkbox 2 和 3 的编辑状态。同时,如果 Checkbox 1 被取消选择,那么 Checkbox 2 和 3 的选中状态也应该被取消。
本文余下部分介绍这个联动效果的具体实现。
我们首先把待实现的联动逻辑用自然语言书写出来:
- 如果激活缓存未勾选,则使用共享内存和使用二级缓存也不能勾选,并且不可编辑
- 如果激活缓存被勾选,则使用共享内存和使用二级缓存可以分别编辑
剩下的事情就是把上面两句话用 ABAP 编程语言实现出来。
我们首先使用 PARAMETERS
关键字定义三个输入参数,如下图红色高亮下划线所示。每个输入参数的类型都是 abap_bool, 再通过 AS CHECKBOX 将其修饰成 checkbox 外观。其中 p_active 即文本为激活缓存
的输入参数,因为在它上的点击还要负责起另外两个输入参数的联动效果,所以这个参数我们还必须加上 USER-COMMAND p
来修饰,这里的 p 可以任意换成其他的字母。
我们双击上图的 TEXT-001 和 002,在弹出的页面可以给这两个 Text Symbol 维护对应的文本,如下图所示:
点击 Selection Texts
,给三个输入参数也分别维护对应的文本:
- P_ACTIVE: 激活缓存
- P_PER_SA:使用二级缓存
- P_SHM:使用共享内存
下面我们需要把这两段伪代码,用 ABAP 编程实现。
- 如果激活缓存未勾选,则使用共享内存和使用二级缓存也不能勾选,并且不可编辑
- 如果激活缓存被勾选,则使用共享内存和使用二级缓存可以分别编辑
因为 P_SHM 和 P_PER_SA 的可编辑性是受 P_ACTIVE 动态控制的,这个动态控制的代码,需要书写在 AT SELECTION-SCREEN OUTPUT
这个事件上,也就是选择屏幕即将输出之前。
我们首先用一个 ABAP 变量 lv_screen_input 来维护 P_SHM 和 P_PER_SA 的可编辑状态,1 代表可以编辑,0 代表不可编辑,即禁用状态。
如果 P_ACTIVE 值为 abap_false, 说明其未被选中,则 P_SHM 和 P_PER_SA 应该处于禁用状态,lv_screen_input 应该被赋值为 0.
计算了 lv_screen_input 之后,我们还应设法将这个值的内容,写入 P_SHM 和 P_PER_SA 对应的数据结构中去。
这个数据结构就是上图 LOOP AT SCREEN 循环里的 screen. 可以看到,访问这个变量之前我们并没有显式声明它,双击第 30 行的 screen,就可以在 ABAP 数据字段里看到这个全局的数据对象:
ABAP 报表里每个输入参数都有一个专属于自己的 SCREEN 变量,通过 NAME 来区分。
我们可以在第 31 行设置断点。运行时当执行到这行语句时,说明当前 screen 变量的 name 字段值已经为 P_SHM 了,说明 LOOP AT SCREEN 循环体内正在处理 P_SHM 输入参数了,此时把 0 赋给 screen 变量的 input 字段,然后通过 ABAP 关键字 MODIFY SCREEN, 让这个赋值操作即时生效。
本例完整的源代码:
*&---------------------------------------------------------------------*
*& Report /IWFND/R_COF_CACHE_SETTINGS
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zscreen_test.
DATA lv_screen_input TYPE i.
SELECTION-SCREEN BEGIN OF BLOCK bl_all WITH FRAME TITLE TEXT-001.
PARAMETERS p_active TYPE abap_bool AS CHECKBOX USER-COMMAND p.
SELECTION-SCREEN BEGIN OF BLOCK bl_details WITH FRAME TITLE TEXT-002.
PARAMETERS p_shm TYPE abap_bool AS CHECKBOX.
PARAMETERS p_per_sa TYPE abap_bool AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK bl_details.
SELECTION-SCREEN END OF BLOCK bl_all.
AT SELECTION-SCREEN OUTPUT.
IF ( p_active = abap_false ).
lv_screen_input = 0.
p_shm = abap_false.
p_per_sa = abap_false.
ELSE.
lv_screen_input = 1.
ENDIF.
LOOP AT SCREEN.
IF screen-name = 'P_SHM'.
screen-input = lv_screen_input.
screen-color = 6.
MODIFY SCREEN.
ENDIF.
IF screen-name = 'P_PER_SA'.
screen-input = lv_screen_input.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
START-OF-SELECTION.
WRITE:/ '缓存激活状态:', p_active.
WRITE:/ '共享内存状态:', p_shm.
WRITE:/ '二级缓存状态:', p_per_sa.