直接在功能中使用这些关键字
代码语言:javascript复制*&---------------------------------------------------------------------*
*& Report ZQC_NEW_STATEMENT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zqc_new_statement.
*--------------------------------------------------------------------* "实例一
"在VALUE子句中,字段可以分开赋值,也可以使用结构整体赋值,为内表赋值时,需要用小括号将一行的数据包在一起
TYPES:BEGIN OF lty_data,
matnr TYPE mara-matnr,
mtart TYPE mara-mtart,
matkl TYPE mara-matkl,
text1 TYPE char50,
END OF lty_data.
DATA: lt_data TYPE TABLE OF lty_data.
*DATA: lwa_data TYPE TABLE OF lty_data.
DATA(lwa_data) = VALUE lty_data( matnr = 'MATERIAL-001'
mtart = 'FOOD'
matkl = '1020'
text1 = 'FIRST material' ).
lwa_data = VALUE #( BASE lwa_data
matnr = 'MATERIAL-001'
mtart = '数据已改'
matkl = '1020'
text1 = 'FIRST material' ).
*注意:使用 BASE 语句时,尽量保持前后结构一致,在使用不同的结构时,可能不报错但数据会错位
*lwa_data = VALUE #( ( matnr = 'MATERIAL-001'
* mtart = 'FOOD'
* matkl = '1020'
* text1 = 'FIRST material' ) ).
lt_data = VALUE #( ( lwa_data ) " 预定义的数据类型可以用#代替
( matnr = 'MATERIAL-002'
mtart = 'BAGA'
matkl = '1010'
text1 = 'SECOND material' ) ).
lt_data = VALUE #( BASE lt_data
( matnr = 'MATERIAL-003'
mtart = 'FOOD'
matkl = '1030'
text1 = '数据追加' ) ).
CALL METHOD cl_demo_output=>display( lt_data ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例二
"此外,VALUE语句作为结构时,可以直接在特定语句中使用
APPEND VALUE #( matnr = 'TEST1' text1 = '110') TO lt_data.
APPEND VALUE #( matnr = 'TEST2' ) TO lt_data.
APPEND VALUE #( matnr = 'TEST3' ) TO lt_data.
APPEND VALUE #( matnr = 'TEST4' text1 = '120') TO lt_data.
MODIFY lt_data FROM VALUE #( text1 = 'X' ) TRANSPORTING text1 WHERE text1 IS INITIAL.
CALL METHOD cl_demo_output=>display( lt_data ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例三
*数据类型的转换可以用 CONV 实现,部分类型不再需要通过中间变量来转换
DATA(lv_string) = '001001.001'.
DATA(lv_int) = CONV i( lv_string ).
DATA(lv_float) = CONV f( lv_string ).
DATA(lv_division) = 1 / 3. "浮点类型无法直接定义,可以通过类似的方法转化
DATA(lv_div) = CONV decfloat34( 1 / 3 ). "
*p 1~ 6 byte 压缩数类型,可存储小数,自定义长度和小数点位数 (尽量用decfloat16和decfloat34替代)
*decfloat16 8 byte 十进制浮点数,可最长有16位小数位(推荐使用)
*decfloat34 16 byte 十进制浮点数,可最长有34位小数位(推荐使用)
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例四
*动态赋值语句,通常根据同一变量的不同数据来动态处理,用法类似于 CASE 语句
DATA(lv_indicator1) = 1.
DATA(lv_day1) = SWITCH char10( lv_indicator1
WHEN 1 THEN 'Monday'
WHEN 2 THEN 'Tuesday'
WHEN 3 THEN 'Wednesday'
WHEN 4 THEN 'Thursday'
WHEN 5 THEN 'Friday'
WHEN 6 THEN 'Saturday'
WHEN 7 THEN 'Sunday'
ELSE '404' && '-Error' ).
CALL METHOD cl_demo_output=>display( lv_day1 ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例五
*COND语句中允许使用较为复杂的判断条件,因此VALUE语句中动态赋值通常会使用COND
DATA(lv_indicator2) = 7.
DATA(lv_day2) = COND char10( WHEN lv_indicator2 = 1 THEN 'Monday'
WHEN lv_indicator2 = 2 THEN 'Tuesday'
WHEN lv_indicator2 = 3 THEN 'Wednesday'
WHEN lv_indicator2 = 4 THEN 'Thursday'
WHEN lv_indicator2 = 5 THEN 'Friday'
WHEN lv_indicator2 = 6 THEN 'Saturday'
WHEN lv_indicator2 = 7 AND sy-langu EQ 'E' THEN 'Sunday'
WHEN lv_indicator2 = 7 AND sy-langu EQ 'F' THEN 'Dimanche'
ELSE '404' && '-Error' ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例六
*REDUCE语句返回值为结构时,常用来汇总字段或作其他处理(例如取最大值/最小值/平均值等)
TYPES:BEGIN OF lty_result,
sum TYPE netwr,
count TYPE i,
max TYPE netwr,
min TYPE netwr,
END OF lty_result.
TYPES: lty_table TYPE TABLE OF lty_result WITH DEFAULT KEY. "WITH DEFAULT KEY只要是CHAR类型的全是键值
SELECT netwr FROM ekpo INTO TABLE @DATA(lt_table) UP TO 8 ROWS WHERE netwr > 0.
SORT lt_table by netwr.
DELETE ADJACENT DUPLICATES FROM lt_table COMPARING ALL FIELDS.
CALL METHOD cl_demo_output=>display( lt_table ).
"初始化lwa_tmp参考lty_result 再根据 lt_table 定义 lwa_table 并且循环
"并通过nmax nmin返回值 再通过REDUCE计算获得最大最小值
DATA(lwa_result) = REDUCE #( INIT lwa_tmp = VALUE lty_result( )
FOR lwa_table IN lt_table
INDEX INTO lv_index
NEXT lwa_tmp = VALUE #( BASE lwa_tmp
sum = lwa_tmp-sum lwa_table-netwr
count = lwa_tmp-count 1
max = nmax( val1 = lwa_tmp-max val2 = lwa_table-netwr )
min = COND #( WHEN lv_index = 1 THEN lwa_table-netwr
ELSE nmin( val1 = lwa_tmp-min val2 = lwa_table-netwr
) ) ) ).
CALL METHOD cl_demo_output=>display( lwa_result ).
*ABS:取绝对值
*SIGN( N ):N>0 时返回 1;N<0 时返回 -1;N=0 时返回 0 CEIL:向上取整
*FLOOR:向下取整
*TRUNC:取整数位
*FRAC:取小数位
*IPOW:计算幂值,可以用来代替 ** 使用,避免部分数据丢失精度
*NMAX/NMIN:返回参数中的最大值/最小值,参数最多传入 9 个
*ROUND:计算舍入值,DEC 指定舍入位置,可以使用 MODE指定舍入规则
*RESCALE:与 ROUND 用法一致,但是当需要保留的位数大于实际位数时,RESCALE 会在尾部填充 0,而 ROUND不会
*DATA(lv_sign) = sign( lv_num ).
*DATA(lv_ceil) = ceil( lv_num ).
*DATA(lv_floor) = floor( lv_num ).
*DATA(lv_trunc) = trunc( lv_num ).
*DATA(lv_frac) = frac( lv_num ).
*DATA(lv_ipow) = |{ ipow( base = '1.2' exp = 2 ) } , { ( '1.2' ** 2 ) }|.
*DATA(lv_nmax) = nmax( val1 = lv_ceil val2 = lv_floor ).
*DATA(lv_nmin) = nmin( val1 = lv_ceil val2 = lv_floor ).
*DATA(lv_round) = round( val = lv_num dec = 3 ).
*DATA(lv_rescale) = rescale( val = lv_num dec = 8 ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例七
*使用 FILTER 时,待过滤的内表结构至少需要有一个用于访问的 SORTED KEY 或 HASHED KEY,否则不
*能通过语法检查,另外,在 WHERE 条件中运算符两边的字段类型需要完全兼容,否则也不能通过语法检查;4
*在 FILTER 语句中可以通过 EXCEPT 关键字来指定是需要过滤数据还是保留数据;
DATA:lt_data2 TYPE TABLE OF lty_data WITH KEY matnr WITH NON-UNIQUE SORTED KEY matkl COMPONENTS matkl. "NON-UNIQUE非唯一
lt_data2 = VALUE #( ( matnr = 'Material-001'
matkl = '1020'
text1 = 100 )
( matnr = 'Material-002'
matkl = '1030'
text1 = 200 )
( matnr = 'Material-003'
matkl = '1020'
text1 = 300 )
( matnr = 'Material-004'
matkl = '1040'
text1 = 300 )
( matnr = 'Material-005'
matkl = '1050'
text1 = 300 ) ).
"保留数据
DATA(lt_filter) = FILTER #( lt_data2 USING KEY matkl WHERE matkl = CONV matkl( '1020' ) ).
"过滤数据
lt_filter = FILTER #( lt_data2 EXCEPT USING KEY matkl WHERE matkl = CONV matkl( '1050' ) ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例八
*在 SELECT 语句中使用 CASE 作为条件语句,与一般条件判断使用的 CASE 类似,但有所区别
*该语句不仅可以用于单值判断,也可以根据复杂条件进行判断;此外,WHEN OTHERS 不再适用,
*需要使用 ELSE 代替,语句结束时使用 END,而不是 ENDCASE,且需要定义别名
*CARRID 航线ID
*CARRNAME 航线名称
*CURRCODE 航线货币
*URL URL
SELECT CASE currcode
WHEN 'EUR' THEN carrname
ELSE url
END AS case_simple,
CASE
WHEN currcode = 'EUR' THEN url
WHEN carrname <> ' ' THEN carrname
ELSE carrid && '@' && currcode
END AS case_complex
FROM scarr
INTO TABLE @DATA(lt_data3)
UP TO 5 ROWS.
CALL METHOD cl_demo_output=>display( lt_data3 ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例九
DATA:lv_dec(16) TYPE p DECIMALS 2.
CALL FUNCTION 'UNITS_STRING_CONVERT'
EXPORTING
units_string = '123,456.78'
dcpfm = 'X' "这个是根据tcode:su01里的数字格式来设置,sap标准的格式有三种:空,X,Y
* MLLN = 'M'
* TSND = 'T'
IMPORTING
units = lv_dec " UNITS 时参照你输入的l_p来定义的
EXCEPTIONS
invalid_type = 1
OTHERS = 2.
*CURRENCY 根据指定货币 cur 调整数值的小数位,参考表 TCURX 【 CURRENCY = cur 】
DATA(lv_currency) = |{ lv_dec CURRENCY = 'AU5' }|. "五位小数,输出123.45678
DATA(lv_currency1) = |{ lv_dec CURRENCY = 'BHD' }|. "三位小数,输出12345.678
*当数值为浮点数时,将不会调整小数点位置,而是在浮点数后增加0
DATA(lv_string1) = '123456.78'.
DATA(lv_dec1) = CONV f( lv_string ).
DATA(lv_currency2) = |{ lv_dec1 CURRENCY = 'BHD' }|. "三位小数,输出123456.780
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十
*默认不做变更(RAW)【 ALPHA = [ IN | OUT | RAW ] 】
DATA(lv_alpha) = |{ CONV char4( '1' ) ALPHA = IN }|. "移除前导0
DATA(lv_alpha1) = |{ '0001' ALPHA = OUT }|. "移除前导0
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十一
*TIMEZONE 将时间戳转换成指定时区的时间戳,参考表 TTZZ 【 TIMEZONE = tz 】
DATA(lv_stamp) = CONV timestamp( '20190601181609' ).
DATA(lv_timezone) = |{ lv_stamp TIMEZONE = 'CET' }|.
DATA(lv_timezone1) = |{ lv_stamp TIMEZONE = 'JAPAN' }|.
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十二
*ALIGN 定义字符串对齐方式,适用于使用了 WIDTH 选项且预定义长度超出实际长度的情况
*【 ALIGN = [ LEFT | CENTER | RIGHT ] 】
*PAD 使用指定字符串中的第一位字符填充剩余的位置,适用于使用了 WIDTH 选项且预定义
*长度超出实际长度的情况,默认会使用空格填充 【 PAD = c 】
*CASE 将字符串进行大小写转换,默认为 RAW,该选项不会更改大小写格式,
*[CASE = [ RAW | LOWER | UPPER ] ]
DATA(lv_width) = |"{ 'A' WIDTH = 5 }BCD"|. "以A为起始为计算 A也为占位 5 - 1 = 4 输出结果 "A BCD"
DATA(lv_align) = |"{ 'A' WIDTH = 2 ALIGN = RIGHT }BCD"|. "以字段首位为起始位向右偏移 2 - 1 = 1 输出结果 " ABCD"
DATA(lv_pad) = |"{ 'A' WIDTH = 2 ALIGN = RIGHT PAD = '@' }BCD"|."同上,空格用@填充
DATA(lv_case) = |"{ 'A' CASE = LOWER }BCD"|. "LOWER转换为小写a UPPER 反之
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十三
*SIGN
*用来调整数值类型符号的显示
*LEFT/RIGHT:不显示正号,将符号放置在数值左侧/右侧
*LEFTPLUS/RIGHTPLUS:显示正号,并将符号放置在数值左侧/右侧
*LEFTSPACE/RIGHTSPACE:用空格代替正号显示,并将符号放置在数值左侧/右侧
DATA(lv_sign_default) = |"{ -1 }"|. "输出默认值
DATA(lv_sign_left) = |"{ 1 SIGN = LEFT }"|. "不显示正号,数值放置在左侧
DATA(lv_sign_leftplus) = |"{ 1 SIGN = LEFTPLUS }"|. "显示正号,数值放置在左侧
DATA(lv_sign_leftspace) = |"{ 1 SIGN = LEFTSPACE }"|. "用空格代替正号,将符号放置在左侧
DATA(lv_sign_right) = |"{ -1 SIGN = RIGHT }"|. "符号放置在右侧
DATA(lv_sign_rightplus) = |"{ -1 SIGN = RIGHTPLUS }"|. "符号放置在右侧
DATA(lv_sign_rightspace) = |"{ -1 SIGN = RIGHTSPACE }"|. "符号放置在右侧
"负号前置
DATA VALUE TYPE char20 VALUE '5-'.
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING
value = value.
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十四
*REVERSE 字符串反转
DATA(lv_reverse) = reverse( 'DEMO' ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十五
*SEGMENT
*根据分隔符获取指定位置的字符串,可以用来拆分字符串,INDEX 用来指定位置,指定位置不存在时,
*会抛出异常 CX_SY_STRG_PAR_VAL
*通过 SEP 指定的分隔符会被当做一个整体进行操作,当分隔符连续出现时,该位置会返回空字符串;
DO.
TRY.
DATA(lv_sep) = segment( val = 'AB;CD ;EF ; ;GH'
index = sy-index
sep = ' ;' ).
CATCH cx_sy_strg_par_val.
EXIT.
ENDTRY.
IF sy-subrc = 0.
DATA:lt_sep LIKE TABLE OF lv_sep.
APPEND lv_sep to lt_sep.
ENDIF.
ENDDO.
CALL METHOD cl_demo_output=>display( lt_sep ).
*而通过 SPACE 指定的分隔符中,每个字符都会被视作单独的分隔符,且在分隔符连续出现时也不会单独返回空串
DO.
TRY.
DATA(lv_space) = segment( val = '2.12584261'
index = sy-index
space = '.' ).
CATCH cx_sy_strg_par_val.
EXIT.
ENDTRY.
IF sy-subrc = 0.
DATA:lt_space LIKE TABLE OF lv_space.
APPEND lv_space to lt_space.
READ TABLE lt_space INTO lv_space INDEX LINES( lt_space ).
* DATA(lv_fl) = lv_space
ENDIF.
ENDDO.
CALL METHOD cl_demo_output=>display( lt_space ).
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十六
*TYPES:BEGIN OF comm2,
* free TYPE bkpf-blart,
*END OF comm2.
*
*TYPES: BEGIN OF t_day,
* work TYPE c LENGTH 8,
* free TYPE c LENGTH 16.
* INCLUDE TYPE comm2.
*TYPES:END OF t_day.
*结构复用
*RENAMING WITH SUFFIX suffix:如果include进来的结构类型(或结构变量)的组件字段与现有的重复,
*则可以使用此选项重命名include进来的结构类型(或结构变量)的各组件字段名,具体做法只是在原
*来组件名后加上了指定的后缀suffix
TYPES: BEGIN OF t_day,
work TYPE c LENGTH 8,
free TYPE c LENGTH 16,
END OF t_day.
TYPES: BEGIN OF week,
work TYPE c LENGTH 8,
free TYPE c LENGTH 16.
INCLUDE TYPE t_day AS monday RENAMING WITH SUFFIX _01.
TYPES: END OF week.
DATA:lv_week TYPE week.
*--------------------------------------------------------------------*
*--------------------------------------------------------------------* 实例十七
*FIND ALL OCCURRENCES 用法
DATA: lv_str TYPE string.
DATA: LV_len1 TYPE i.
DATA: LV_len2 TYPE i.
DATA: lv_LONGTXT1 TYPE string.
DATA: lv_LONGTXT2 TYPE string.
lv_str = '微af老王df五十asdf今天asdf肯sdf德基d疯狂adF星期df四adf'.
DATA: lv_arktx TYPE string.
DATA: lt_result_tab TYPE match_result_tab,
lt_wa LIKE LINE OF lt_result_tab.
*https://blog.csdn.net/zhongguomao/article/details/83186939
*匹配双字节字符(包括汉字在内):[^x00-xff]
FIND ALL OCCURRENCES OF REGEX '[^x00-xff]*' IN lv_str
RESULTS lt_result_tab.
LOOP AT lt_result_tab INTO lt_wa WHERE length <> 0.
CONCATENATE lv_LONGTXT1 lv_str lt_wa-offset(lt_wa-length) INTO lv_LONGTXT1.
ENDLOOP.
lv_len1 = cl_abap_list_utilities=>dynamic_output_length( lv_LONGTXT1 ).
CLear lt_result_tab.
FIND ALL OCCURRENCES OF REGEX '[x00-xff]*' IN lv_str
RESULTS lt_result_tab.
LOOP AT lt_result_tab INTO lt_wa WHERE length <> 0.
CONCATENATE lv_LONGTXT2 lv_str lt_wa-offset(lt_wa-length) INTO lv_LONGTXT2.
ENDLOOP.
lv_len2 = cl_abap_list_utilities=>dynamic_output_length( lv_LONGTXT2 ).
WRITE:lv_LONGTXT1 , lv_len1.
WRITE:/ lv_LONGTXT2 , lv_len2.
*--------------------------------------------------------------------*