前言
看以下代码片段,你认为两个变量输出的值是一样的吗?
REPORT ztest.DO 10 TIMES. PERFORM run.ENDDO.cl_demo_output=>display( ).
FORM run. DATA local TYPE i. STATICS static TYPE i. local += 1. static += 1. cl_demo_output=>write( |Local: { local }, | && |Static: { static }| ).ENDFORM.输出结果及解释
上述代码运行输出结果如下
可见每次进入FORM的时候,
使用DATA定义的局部变量,都被初始化为初始值0,+1后,变量值变为1;
而 使用STATICS定义的静态局部 变量 ,保留的是上一次运算后的值 , +1 后 ,变量值逐次增大。
原因分析:
F1看下官方介绍,意思是使用STATICS定义的变量,当编译单元加载到内部会话时,将创建 一次 变量,并分配初始值, 在 其作用
域(上例为FORM ) 内 ,相当于一个全局变量 。
所以在循环进入FORM的时候,不会重新创建变量,所以其值每次会增加1.
需要注意的是, stat ics定义的变量只 在 其作用 域 (上例为FORM ) 内可见,在作用域外引用的话,激活会报错,如下图所示
引申应用
关于上述例子,可能很多小伙伴都了解,认为很简单,并没有想到它有什么用途。
我在平常项目中常用它来做数据缓存,减少直接使用SQL语句去查询数据库。
STATICS关键字不光可以用来定义基本数据类型,也可以用来定义内表,这样一来就大有用武之地了。
使用过VOFM的同学可能知道,在定价确定过程中会反复多次调用
自 定义例程,如果在程序中有查询物料相关的标准表
(MARA,MARC,MARD,MVKE,MBEW)等表,表数据量大,并且业务
单据量大的话,会非常影响性能,这时就可以使用 STAT ICS来定义
一个内表,先查询内表,查询到直接取值,没查到再去查数据库。
我最常用的一个转换例程函数便是,根据用户的登录名取用户名
称, 使用 STAT ICS 关键字定义一个用户登录名和用户名称的内表,
这样在ALV中如果有相同的用户,就不用每个都去数据库表中查询
最后附上一段代码,展示其用法
FUNCTION conversion_exit_zuser_output .*"--------------------------------------------------------------------*"*"局部接口:*" IMPORTING*" VALUE(INPUT) TYPE CLIKE*" EXPORTING*" VALUE(OUTPUT) TYPE CLIKE*"--------------------------------------------------------------------
TYPES: BEGIN OF lty_output, input TYPE user_addr-bname, output TYPE user_addr-name_textc, END OF lty_output. STATICS lt_output TYPE HASHED TABLE OF lty_output WITH UNIQUE KEY input. DATA:lv_uname TYPE user_addr-name_textc. READ TABLE lt_output INTO DATA(ls_output) WITH TABLE KEY input = input. IF sy-subrc = 0. output = ls_output-output. ELSE. SELECT SINGLE name_textc INTO lv_uname FROM user_addr WHERE bname = input. IF sy-subrc EQ 0. output = lv_uname. ELSE. output = input. ENDIF. INSERT VALUE #( input = input output = output ) INTO TABLE lt_output. ENDIF.
ENDFUNCTION.