创建一个report显示alv,在gui上提供一个按钮,更改数据
点击按钮后的效果如下
如上面2图所示,实时依据按钮的触发,刷新alv上的数据,将最新的数据内容显示出来。
report中的alv表格显示的内容是自定义的内表中的数据,如果希望alv显示的内容及时进行刷新,前提一定是有两个:
1.内表被修改了(而不仅仅是修改了透明表,必须内表也对应被修改)
2.在i_callback_user_command中将配置ls_selfield-refresh = 'X'
下面具体描述一下这个report中为了实现上述效果所需要添加的代码。
1.为alv所显示的内表添加红绿灯字段
TYPES:BEGIN OF itab_DATA,
ICON_MARK TYPE icon-internal, "icon标记
SEL(1), "多选用的灰色方块
END OF itab_DATA.
上述ICON_MARK字段,用于显示alv表格最左侧的红绿灯。
红绿灯图片的来源就是透明表icon,如下图
2.创建红绿灯的全局静态变量,用它们为内表的ICON_MARK进行赋值
INCLUDE <icon>.
CONSTANTS: light_r LIKE icon-internal VALUE '@0A@',"红灯
light_y LIKE icon-internal VALUE '@09@',"黄灯
light_g LIKE icon-internal VALUE '@08@',"绿灯
light_non LIKE icon-internal VALUE '@EB@'."全熄灭
触发alv表格中最左侧红绿灯变化的事件是,alv的gui上的按钮,点击按钮的本质是去修改某个透明表中某个字段的数据。记清楚哦,点击按钮的本质目的是修改透明表,只是我们为了便于观察修改的结果,所以顺带修改了alv上与透明表相对应的内表的对应字段。
3.添加gui及按钮(略)
4.为CHANGE按钮添加代码
GUI上的更改按钮,点击后,会触发修改去修改比如MARC这样的SAP标准透明表的某个字段的值,相当于直接修改数据库。
因此,按钮所执行的代码中,需要去调用相应的BAPI完成对于物料主数据的修改。修改完成后,基于BAPI的执行结果(成功or失败)来修改alv的ICON_MARK字段,体现在alv上的红绿灯显示哪种颜色。对于SAP中标准的透明表的修改一定要借助于BAPI,而不能自己写代码去update数据库中的表。
5.修改透明表的BAPI的调用
LW_HEADER-MATERIAL = LDATA-MATNR. "物料号
LW_HEADER-IND_SECTOR = LDATA-MBRSH. "行业领域
LW_HEADER-MATL_TYPE = LDATA-MTART. "物料类型
LW_MARC-PLANT = LDATA-WERKS. "工厂
LW_MARCX-PLANT = LDATA-WERKS. "工厂
LW_MARC-PUR_STATUS = '99'. "特定工厂状态
LW_MARCX-PUR_STATUS = 'X'.
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
EXPORTING
HEADDATA = LW_HEADER
PLANTDATA = LW_MARC
PLANTDATAX = LW_MARCX
IMPORTING
RETURN = LW_RETURN.
IF LW_RETURN-TYPE = 'E'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
ENDIF.
上述BAPI的名字叫做BAPI_MATERIAL_SAVEDATA,至于我怎么知道自己需要去使用这个BAPI,我怎么使用这个BAPI,我在哪里找到这个BAPI的使用方法的,我也不知道。
上述BAPI的调用过程,简单解释一下:
EXPORTING部分提供了三个输入参数,但是这里可能出现N多个输入参数,只是我们的代码简化了。因为我们只打算去修改MARC中的一个字段的内容。
BAPI的IMPORTING部分提供了1个输出参数,也就是相当于方法返回值吧。这个输出参数是一个名为LW_RETURN的变量,我们通过LW_RETURN的值来判断,BAPI的执行结果。因为调用BAPI不一定会成功,也可能失败呀。
上述代码分别对两种可能的结果,进行了处理。完成事务或者回滚事务。
好的,终于我们的alv的gui上的按钮调用BAPI修改了物料主数据,下面终于可以解释有关于alv刷新和红绿灯显示的内容了。
6.ALV自动刷新的配置
在上一步中,我们已经通过BAPI修改了透明表MARC的内容,下面我们需要把这种变化,体现在ALV上。也就是说既然透明表都修改了,我们的ALV要把刚刚点击按钮修改数据的情况,体现出来。
ALV显示的数据,虽然来源于透明表,但是它的直接数据来源,其实是内表。我们之前只是用BAPI修改了透明表,现在我们需要,通过代码的赋值,修改内表数据。
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA' "调用BAPI修改透明表
EXPORTING
HEADDATA = LW_HEADER
PLANTDATA = LW_MARC
PLANTDATAX = LW_MARCX
IMPORTING
RETURN = LW_RETURN.
IF LW_RETURN-TYPE = 'E'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
GS_DATA-MMSTA = R_MMSTA. "修改内表
MODIFY GT_DATA FROM GS_DATA. "修改内表
ENDIF.
上述代码补充了修改内表的代码,其实只是一个赋值语句,修改了内表中的对应数据。
但是通过上述代码,还不能实现alv的自动刷新,原因是需要在alv的显示语句上动动手脚
我们先看看alv调用的语句
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'SET_PF_STATUS'
i_callback_user_command = 'USER_COMMAND'
is_layout = gs_layout
it_fieldcat = gt_fieldcat[]
i_save = 'A'
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.
上述语句中i_callback_user_command中传递来的参数,是一个form的名字,form是一个子例程,其实就是一个方法。
我们需要在这个方法中,添加一些语句,才能让alv本身具备【当内表被修改,alv的显示跟随刷新】的效果。
FORM user_command USING uv_ucomm TYPE sy-ucomm
ls_selfield TYPE slis_selfield.
..........
ls_selfield-refresh = 'X'.
..........
ENDFORM.
上述,一方面修改了内表内容,另一方面为user_command添加了必要语句。当我们的alv的GUI的按钮触发了BAPI的调用,并且触发了内表的修改,然后提交了BAPI的事务以后,我们的ALV就会自动刷新出最新的显示数据。