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( ).