【ABAP】新语法

1. 内联声明

语法:DATA(...) ,FILED-SYMBOL(…)
1. 定义变量
2. 定义结构
3. 定义内表
4. 定义指针

*&*********取数
"用户
SELECT *
FROM ztuser
INTO TABLE @DATA(gt_data)
UP TO 5 ROWS.
cl_demo_output=>write( gt_data ).

SELECT SINGLE *
FROM ztuser
INTO @DATA(wa_data).
cl_demo_output=>write( wa_data ).

SELECT SINGLE bname
FROM ztuser
INTO @DATA(lv_bname1).
cl_demo_output=>write( lv_bname1 ).

*&*********定义变量
DATA(lv_bname2) = lv_bname1.
cl_demo_output=>write( lv_bname2 ).

*&*********定义结构
READ TABLE gt_data INTO DATA(gs_data) INDEX 1.
IF sy-subrc EQ 0.
DATA(ls_data) = gs_data.
cl_demo_output=>write( ls_data ).
ENDIF.

*&*********定义内表
DATA(lt_data) = gt_data.
cl_demo_output=>write( lt_data ).

*&*********定义指针
LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs_data>) WHERE bname EQ lv_bname1.
<fs_data>-bname = '修改测试'. "修改创建人
ENDLOOP.
cl_demo_output=>write( lt_data ).
cl_demo_output=>display(  ).

2. 构造表达式

1. 实现构造: NWE -创建数据对象或类的实现
1.1 构造单值
1.2 构造结构
1.3 构造内表
1.4 构造类
2. 值构造:  VALUE - 创建一个类型为dypee的数据
2.1 构造结构
语法: ... VALUE dtype | #(  [BASE dobj] comp1 = dobj1 comp2 = dobj2 ... ) ...
2.2 构造内表 :
语法: ... VALUE dtype | #( [BASE itab] (  (line1-com1 = dobj1) ( line2 ..) ... ) ...
note: dytpe可接具体类型或者# ,接#数据类型必须确定
可以嵌套使用;
内表赋值不能带表头;
3. 组件构造: CORRESPONDIN

语法:... CORRESPONDING dtype | #(  [BASE dobj] comp1 = dobj1 comp2 = dobj2 ... ) ...

" 自定义类型
TYPES: BEGIN OF ty_man,
name   TYPE char10,    " 姓名
sex    TYPE char1,       " 性别
age    TYPE p DECIMALS 2, " 年龄
school TYPE char20,      " 学校
END OF ty_man.
DATA: lt_man TYPE TABLE OF ty_man.
*&*********结构赋值
DATA(ls_man) = VALUE ty_man( name = 'Tom' sex = 'B' ).
cl_demo_output=>write( ls_man ).

"附加年龄信息
ls_man = VALUE #( name = 'Tom' sex = 'B' age = 18 ).
*DATA(ls_man_02) = VALUE #( name = 'Tom' sex = 'B' age = 18 ) . "错误,未明确类型
cl_demo_output=>write( ls_man ).

"附加学校信息
ls_man = VALUE ty_man( BASE ls_man school = 'A SCHOOL' ).
cl_demo_output=>write( ls_man ).

"调整学校信息
ls_man = VALUE #( BASE ls_man school = 'B SCHOOL' ).
cl_demo_output=>write( ls_man ).

*&*********内表赋值
lt_man = VALUE #( ( name = 'Anna' sex = 'G' age = 17 ) ( name = 'Ann' sex = 'G' age = 16 ) ).
cl_demo_output=>write( lt_man ).

"内表基础上附加额外数据
lt_man = VALUE #( BASE lt_man ( name = 'Xiaohong' sex = 'G' age = 20 school = 'C SCHOOL' )
( name = 'Xiaoming' sex = 'B' age = 21  school = 'D SCHOOL' ) ).
cl_demo_output=>write( lt_man ).

*&*********Range 表赋值
DATA:   lt_data    TYPE RANGE OF mara-matnr. "内表不带表头
RANGES: lt_data_01 FOR mara-matnr.           "内表带表头-不支持

"逐步往下填充内表数据
lt_data  = VALUE #( sign = 'I' option = 'BT'  ( low = 10 high = 20 )
( low = 100 high = 150 )
option = 'GT'  ( low  = 180 )
option = 'LT'  ( low = 200 )
option = 'EQ'  ( low = 8 )
sign = 'E' option = 'BT'  ( low = 15 high = 18 )
).
cl_demo_output=>write( lt_data ).
*&****对应字段赋值
TYPES: BEGIN OF ty_data.
TYPES:   flag TYPE char1.
INCLUDE TYPE ztuser.

TYPES: END OF ty_data.

TYPES: BEGIN OF ty_data_t.
TYPES:   flag_t TYPE char1.
INCLUDE TYPE ztuser.

TYPES: END OF ty_data_t.

DATA: ls_data_02 TYPE ty_data,
ls_data_03 TYPE ty_data_t.

*&*********取数
SELECT SINGLE *
FROM ztuser
INTO @DATA(ls_data).

*&*********对应字段赋值:忽略原工作区值
ls_data_02 = CORRESPONDING #( ls_data ).
cl_demo_output=>write( ls_data_02 ).

*&*********对应字段赋值:在原工作区值的基础上,赋值对应字段
ls_data_03-flag_t = abap_true.
ls_data_03 = CORRESPONDING #( BASE ( ls_data_03 ) ls_data_02 )."不指定BASE 初始值(flag_t = 'X')会丢失
cl_demo_output=>write( ls_data_03 ).

*&*********对应字段赋值:忽略原工作区值
ls_data_03 = CORRESPONDING #( ls_data_02 )."初始值丢失
cl_demo_output=>write( ls_data_03 ).
cl_demo_output=>display(  ).

3. 内表操作

1. 内表表达式- 相当于READ TABLE
语法:… itab[ … ] …
note: 如果未找到对应的记录就会抛出CX_SY_ITAB_LINE_NOT_FOUND异常,SY-SUBRC不会记录
可以通过line_exists预定义函数改进
2. 內表预定义函数
2.1 line_exists( ) - 判断记录是否存在
2.2 line_index( )  - 获取符合记录的索引值
3. 內表推导 - FOR 理解为LOOP,是对实现操作符 NEW 和值操作符VALUE的一种增强,作用是构造內表内容
语法1 : …FOR i = ... [THEN expr]  UNTIL | WHILE  log_exp ...
语法2 : …FOR wa|<fs> IN itab [INDEX INTO idx][cond][let_exp]...
4. 內表筛选-FILTER -筛选内表中的数据
语法:  FILTER  type(  itab   [EXCEPT]   [IN ftab]   [USING KEY keyname ]
WHERE c1 op f1  [AND c2 op f2  [...] ]  ) ...
note: WHERE对应过滤的条件,是必须要指定的,注意有些操作符是不能在WHERE中使用的,如:OR , NOT 等
EXCEPT如果不指定则表示满足条件的找出来,如果指定则表示不满足条件的找出来
5. 內表缩减
语法: ... REDUCE type(
[let_exp]
INIT {x1 = rhs1}|{<x1> = wrexpr1}|{x1|<x1> TYPE dtype1}
{x2 = rhs2}|{<x2> = wrexpr2}|{x2|<x2> TYPE dtype2}
...
FOR for_exp1
FOR for_exp2
...
NEXT ...
{x1 = rhs1}|{<x1> = wrexpr1}
{x2 = rhs2}|{<x2> = wrexpr2}
... ) ...
6. 内表分组

*&*********取数
SELECT *
FROM ztuser
INTO TABLE @DATA(lt_data)
UP TO 5 ROWS.

*&*********定义变量
DATA(lv_bname) = 'A2'.  "第二行用户主记录中的用户名称
cl_demo_output=>write( lt_data ).

"通过索引值判断某一行记录是否存在,也可通过条件判断
IF line_exists( lt_data[ 2 ] ).
"获取第4行记录
DATA(ls_data) = lt_data[ 2 ].
"获取第4行记录中的标签类型
DATA(lv_name_text) = lt_data[ 2 ]-name_text."
cl_demo_output=>write( ls_data ).
cl_demo_output=>write( lv_name_text ).
ENDIF.

"获取符合条件的索引值,未找到LV_INDEX为0,获得到的索引值比真实索引值小1
DATA(lv_index) = line_index( lt_data[ bname = lv_bname name_text = lv_name_text ] ).
IF lv_index NE 0 AND line_exists( lt_data[ lv_index + 1 ] ) .
CLEAR ls_data.
"获取下一行记录
ls_data = lt_data[ lv_index + 1 ].
cl_demo_output=>write( ls_data ).
ENDIF.
*&******
TYPES: BEGIN OF ty_line,
col1 TYPE i,
col2 TYPE i,
col3 TYPE i,
END OF ty_line,      "结构体
ty_tab TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.

*&*********通过语法1给新內表赋值 - 类似于JAVA中的FOR循环
"for每次遍历一次都将结果,通过value赋值给内表lt_itab
DATA(lt_itab) = VALUE ty_tab( FOR j = 11 THEN j + 10 UNTIL j > 40  "初始值,递增量,结束条件
" 结构中的字段赋值-参考类型ty_tab
( col1 = j col2 = j + 1 col3 = j + 2  )
"11    12    13   - value 到 lt_itab
"21    22    23   - value 到 lt_itab
"31    32    33   - value 到 lt_itab
"41               - 结束循环
).
cl_demo_output=>display( lt_itab ).

cl_demo_output=>display(  ).

*&*********同过语法2给新內表赋值
*&*********取数
"用户名/地址键值分配
SELECT *
FROM usr21
INTO TABLE @DATA(lt_data)
UP TO 5 ROWS.
IF lt_data IS NOT INITIAL.
"个人(办公地址管理)
SELECT *
FROM adrp
INTO TABLE @DATA(lt_data_t)
FOR ALL ENTRIES IN @lt_data
WHERE persnumber = @lt_data-persnumber.

SORT lt_data_t BY persnumber.
DELETE ADJACENT DUPLICATES FROM lt_data_t COMPARING persnumber.
ENDIF.
*  "测试:主表条件字段数据存在,从表条件字段数据不存在
*  READ TABLE lt_data INTO DATA(ls_data) WITH KEY persnumber = ''.
*  IF sy-subrc = 0.
*    ls_data-persnumber = lt_data[ sy-tabix - 1 ]-persnumber + 1.
*    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
*      EXPORTING
*        input  = ls_data-persnumber
*      IMPORTING
*        output = ls_data-persnumber.
*
*    MODIFY lt_data FROM ls_data INDEX sy-tabix.
*  ENDIF.
*  DELETE lt_data WHERE persnumber IS INITIAL.

cl_demo_output=>write( lt_data ).
cl_demo_output=>write( lt_data_t ).

TYPES: BEGIN OF ty_usr_line,
"usr21
bname      TYPE usr21-bname,       "用户主记录中的用户名称
persnumber TYPE usr21-persnumber,  "人员编号
addrnumber TYPE usr21-addrnumber,  "地址号码
"adrp
date_from  TYPE adrp-date_from,    "有效起始日期 - 当前版本中仅00010101可用
nation     TYPE adrp-nation,       "国际地址的版本标识
date_to    TYPE adrp-date_to,      "当前版本中的有效截止日期仅99991231可用
title      TYPE adrp-title,        "地址关键字的表格
name_first TYPE adrp-name_first,   "名
name_last  TYPE adrp-name_last,    "姓
END OF ty_usr_line,
ty_usr_tab TYPE STANDARD TABLE OF ty_usr_line WITH EMPTY KEY. "声明表类型

*&*********将用户名/地址键值分配和个人(办公地址管理)的数据整合在一起,构建新的内表
*  DATA(lt_itab) = VALUE ty_usr_tab( FOR ls_itab IN lt_data WHERE ( mandt = '100' )"ls_itab 为隐形声明或者<fs>
*        (
*        "usr21
*        bname      = ls_itab-bname
*        persnumber = ls_itab-persnumber
*        addrnumber = ls_itab-addrnumber
*        "adrp .
*        date_from  = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-date_from ) "通过VALUE语句和内表表达式赋值
*        nation     = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-nation )
*        date_to    = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-date_to )
*        title      = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-title )
*        name_first = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-name_first )
*        name_last  = VALUE #( lt_data_t[ persnumber = ls_itab-persnumber ]-name_last )
*        "当通过[ ]内的条件无法读取到表中数据时,发生程序运行时错误
*        )
*          ).
*  cl_demo_output=>write( lt_itab ).
*&****优化
DATA: lt_itab_01 TYPE TABLE OF ty_usr_line WITH HEADER LINE.
LOOP AT lt_data INTO DATA(ls_data).
"获取从表
IF line_exists( lt_data_t[ persnumber = ls_data-persnumber ] ) ."函数line_exists判断改行是否存在
DATA(ls_data_t) = VALUE #( lt_data_t[ persnumber = ls_data-persnumber ] ).
ENDIF.

lt_itab_01 = CORRESPONDING #( ls_data  )."USR21
lt_itab_01 = CORRESPONDING #(  BASE ( lt_itab_01 ) ls_data_t )."ADRP

APPEND lt_itab_01.
CLEAR: lt_itab_01, ls_data_t,ls_data.
ENDLOOP.
cl_demo_output=>write( lt_itab_01[] ).
*&*********使用操作符FILTER过滤
DATA: lt_filter TYPE HASHED TABLE OF ty_usr_line
WITH UNIQUE KEY bname persnumber.

***INitialize filter Table
lt_filter = VALUE #( ( bname = 'BPINST' persnumber = '0000025171') ).

"找出满足条件的数据
DATA(lt_out) = FILTER #( lt_itab_01[] IN lt_filter WHERE bname = bname AND persnumber = persnumber ) .
cl_demo_output=>write( lt_out ).

"找出不满足条件的数据
DATA(lt_out_t) = FILTER #( lt_itab_01[] EXCEPT IN lt_filter WHERE bname = bname AND persnumber = persnumber ) .
cl_demo_output=>write( lt_out_t ).

cl_demo_output=>display(  ).

*&*********取数
TYPES: BEGIN OF ty_man,
name   TYPE char10,       " 姓名
sex    TYPE char1,        " 性别
age    TYPE p DECIMALS 2, " 年龄
school TYPE char20,       " 学校
END OF ty_man.
DATA: lt_man TYPE TABLE OF ty_man.

lt_man = VALUE #( ( name = 'Anna' sex = 'G' age = 17 )
( name = 'Ann'  sex = 'G' age = 16 ) ).
cl_demo_output=>write( lt_man ).

"内表基础上附加额外数据
lt_man = VALUE #( BASE lt_man ( name = 'Xiaohong' sex = 'G' age = 20 school = 'C SCHOOL' )
( name = 'Xiaoming' sex = 'B' age = 21 school = 'D SCHOOL' ) ).
cl_demo_output=>write( lt_man ).

"内表行数
DATA(lv_lines) = lines( lt_man ).
"内表中符合条件的数据有几条
DATA(lv_lines_g) = REDUCE i( INIT x = 0
"for ls_man in lt_man 参考lt_man声明一个工作区ls_man 并循环取数取数
FOR  ls_man IN lt_man WHERE ( sex = 'G' )
NEXT x = x + 1 ).
cl_demo_output=>write( lv_lines ).
cl_demo_output=>write( lv_lines_g ).

"累计内表中符合条件的年龄之和
TYPES: ty_age TYPE p DECIMALS 2.
DATA(lv_sum_age) = REDUCE ty_age( INIT dage = VALUE ty_age( )
FOR  wa IN lt_man WHERE ( sex = 'G' )
NEXT dage = dage + wa-age ).
cl_demo_output=>write( lv_sum_age ).

"综合例子
TYPES:BEGIN OF ty_result,
sum  TYPE p DECIMALS 2, "总和
max  TYPE p DECIMALS 2, "最大值
avg  TYPE p DECIMALS 2, "平均
cunt TYPE i,            "记录数
END OF ty_result.

DATA(ls_result) = REDUCE ty_result( INIT res = VALUE ty_result( )  "可以默认值:ty_result( min = 0 max = 0 )
FOR  <fs_man> IN lt_man WHERE ( sex = 'G' ) "性别为G
NEXT res-sum = res-sum + <fs_man>-age       "年龄总和
res-max  = nmax( val1 = res-max val2 = <fs_man>-age )"最大年龄
res-cunt = res-cunt + 1                "满足条件的条目数
).

ls_result-avg = ls_result-sum / ls_result-cunt.  "平均值
cl_demo_output=>write( ls_result ).

cl_demo_output=>display(  ).

给TA打赏
共{{data.count}}人
人已打赏
ABAPSAP

【ABAP】为表维护SM30生成事务代码

2021-3-22 11:09:47

ABAPSAP

【ABAP】选择屏幕搜索帮助和DIALOG搜索帮助

2021-4-6 10:28:16

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索