ABAP-7.40新语法(二)
作者:互联网
- 随着 ABAP 的迭代升级,产生了许多新语法,为了在以后的工作中提高工作效率,也为了能够看懂大佬写的代码,这边对新语发进行了一些总结,以便于学习和回顾.
*&---------------------------------------------------------------------* *& Report YTEST_ZJ009 *&---------------------------------------------------------------------* *&new为最新理解 *&---------------------------------------------------------------------* REPORT YTEST_ZJ009. *TABLES TABLES:ytest_ng. TYPES: BEGIN OF ty_data. INCLUDE TYPE ytest_ng. TYPES: flag TYPE char1, END OF ty_data. CONSTANTS:c_name2(4) VALUE '王明', c_gender2(1) VALUE '男', c_education2(2) VALUE '专科', c_rank1(4) VALUE '销售主管', c_rank2(4) VALUE '销售雇员', c_name3(4) VALUE 'LISA', c_gender3(1) VALUE '女', c_education3(2) VALUE '本科', c_name4(4) VALUE 'TOM'. *&---------------------------------------------------------------------- * 练习一:内联声明 * 语法:DATA(...) ,ASSIGNING FILED-SYMBOL(…) * ALPHA conversion * Concatenation 串联 *&---------------------------------------------------------------------* cl_demo_output=>write( '练习一:内联声明' ). *1>取数ytest_ng表 第1 行数据到内表 并输出 SELECT * FROM ytest_ng INTO TABLE @DATA(gt_data) UP TO 1 ROWS. cl_demo_output=>write( gt_data ). *3> 定义结构,读取内表第一行 并输出 READ TABLE gt_data INTO DATA(gs_data) INDEX 1. IF sy-subrc EQ 0. cl_demo_output=>write( gs_data ). CLEAR gs_data. ENDIF. *4> 定义指针并修改000001人员职级为销售主管 CONSTANTS: c_xszg(10) VALUE '销售主管'. LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<fs_data>) . <fs_data>-rank = c_xszg. "修改职级 ENDLOOP. cl_demo_output=>write( gt_data ). *4> 定义变量将000001工号去除前导0赋值给变量,并输出 DATA(lv_id) = |{ <fs_data>-id ALPHA = OUT }|. cl_demo_output=>write( lv_id ). *5> 定义变量输出去年的明天,并输出(使用新语法连接字符串) DATA(lv_date) = |{ sy-datum(4) - 1 }{ sy-datum+4 + 1 } |. *DATA(lv_date1) = ( sy-datum(4) - 1 ) && ( sy-datum+4 + 1 ). cl_demo_output=>write( lv_date ). *&---------------------------------------------------------------------- * 练习二:构造表达式 * 1. 值构造: VALUE - 创建一个类型为dypee的数据 * 2.1 构造结构 * 语法: ... VALUE dtype | #( [BASE dobj] comp1 = dobj1 comp2 = dobj2 ... ) ... * 2.2 构造内表 : * 语法: ... VALUE dtype | #( [BASE itab] ( (line1-com1 = dobj1) ( line2 ..) ... ) ... * note: dytpe可接具体类型或者# ,接#数据类型必须确定 * 可以嵌套使用; * 内表赋值不能带表头; *&---------------------------------------------------------------------* cl_demo_output=>write( '练习二:构造表达式' ). *1> 结构赋值 (id :2 name :王明 gender:男 education:专科 rank:销售雇员)/输出 gs_data = VALUE #( id = 2 name = c_name2 gender = c_gender2 education = c_education2 rank = c_rank2 ). DATA(gw_data) = VALUE ty_data( id = 2 name = c_name2 gender = c_gender2 education = c_education2 rank = c_rank2 ). cl_demo_output=>write( gs_data ). *2> 结构内附加王明薪资信息为6000/输出 gs_data = VALUE #( BASE gs_data salary = 6000 ). cl_demo_output=>write( gs_data ). *3> 结构内修改王明薪资为5000,更新至内表/输出内表 gs_data = VALUE #( BASE gs_data salary = 5000 ). APPEND gs_data TO gt_data. cl_demo_output=>write( gt_data ). *4> 内表基础上附加额外数据之后,更新TABLE:YTEST_NG *id :3 name :LISA gender:女 education:本科 rank:销售雇员 *id :4 name :TOM gender:男 education:专科 rank:销售雇员 gt_data = VALUE #( BASE gt_data ( id = 3 name = c_name3 gender = c_gender3 education = c_education3 rank = c_rank2 salary = 4300 ) ( id = 4 name = c_name4 gender = c_gender2 education = c_education2 rank = c_rank2 salary = 4400 ) ). cl_demo_output=>write( gt_data ). *4.1new>内表基础上附加额外数据 APPEND VALUE #( id = 9 ) TO gt_data. MODIFY ytest_ng FROM TABLE gt_data. *5> 定义Range 表并赋值 id = 1 和 id>=3 DATA: r_range TYPE RANGE OF ytest_ng-id. r_range = VALUE #( sign = 'I' ( option = 'EQ' low = 1 ) ( option = 'GE' low = 3 ) sign = 'E' ( option = 'EQ' low = 2 ) ). cl_demo_output=>write( r_range ). *&---------------------------------------------------------------------- * 练习三:内表操作 * 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. 內表筛选-FILTER -筛选内表中的数据 * 语法: FILTER type( itab [EXCEPT] [IN ftab] [USING KEY keyname ] * WHERE c1 op f1 [AND c2 op f2 [...] ] ) ... * note: WHERE对应过滤的条件,是必须要指定的,注意有些操作符是不能在WHERE中使用的,如:OR , NOT 等 * EXCEPT如果不指定则表示满足条件的找出来,如果指定则表示不满足条件的找出来 * 4. 內表缩减 * 语法: ... 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} * ... ) ... *&---------------------------------------------------------------------* cl_demo_output=>write( '练习三:内表操作' ). *1> 判断内表第3行是否存在,若存在,定义结构获取第3行记录/输出,定义变量获取第3行员工姓名/输出 IF line_exists( gt_data[ 3 ] ). "获取第3行记录 TRY. DATA(ls_data) = gt_data[ 3 ]. CATCH cx_sy_itab_line_not_found. ENDTRY. "获取第3行员工姓名 TRY. DATA(lv_name) = gt_data[ 3 ]-name. CATCH cx_sy_itab_line_not_found. ENDTRY. cl_demo_output=>write( ls_data ). cl_demo_output=>write( lv_name ). ENDIF. *1.1new>读取内表 *data(ls_data3) = gt_data[ id = '10' ]. "若读不到会dump,一般处理方式为try catch data(ls_data3) = VALUE #( gt_data[ id = 10 ] OPTIONAL ). "加上VALUE…OPTIONAL,如果读不到的话,就是一个新定义的,所以为空 *1.2new>DEFAULT如果读不到就为默认值 data(wa_def) = VALUE ty_data( id = 10 name = 'rr'). CLEAR ls_data3. ls_data3 = VALUE #( gt_data[ id = 10 ] DEFAULT wa_def ). *2> 获取id=3,名字是1>中员工姓名的索引值,并输出其下一行人员信息 DATA(lv_index) = line_index( gt_data[ id = 1 name = '李华' ] ). IF lv_index NE 0 . CLEAR ls_data. TRY. ls_data = gt_data[ lv_index + 1 ]. CATCH cx_sy_itab_line_not_found. ENDTRY. cl_demo_output=>write( ls_data ). ENDIF. *3> 将gt_data用销售主管和销售雇员分别放到两个内表并输出(使用FILTER关键字语法) "使用多个值筛选 DATA: gt_filter TYPE SORTED TABLE OF CHAR10 WITH NON-UNIQUE KEY table_line. ***INitialize filter Table gt_filter = VALUE #( ( c_xszg ) )."可以写多个 "找出满足条件的数据 DATA(gt_out) = FILTER #( gt_data IN gt_filter WHERE rank = table_line ) . cl_demo_output=>write( gt_out ). "找出不满足条件的数据 DATA(gt_out_t) = FILTER #( gt_data EXCEPT IN gt_filter WHERE rank = table_line ) . cl_demo_output=>write( gt_out_t ). *new3.1>FILTER语法-使用SORT表 TYPES: BEGIN OF ty_001, code TYPE char2, value TYPE char10, END OF ty_001. DATA :itab TYPE SORTED TABLE OF ty_001 WITH NON-UNIQUE KEY code value. DATA :itabs TYPE STANDARD TABLE OF ty_001 WITH NON-UNIQUE SORTED KEY cod COMPONENTS code value. "初始化内表,此时被FILTER表应为SORT 或 HASH表 itab = VALUE #( ( code = '01' value = 'test01') ( code = '01' value = 'test001') ( code = '02' value = 'test02') ( code = '03' value = 'test003') ( code = '02' value = 'test021') ( code = '03' value = 'test031') ). "直接Filter"找出满足条件的数据 DATA(it_filter) = FILTER #( itab WHERE code = '01' ). "使用excpt 语句 DATA(it_exp) = FILTER #( itab EXCEPT WHERE code = '01' ). *new3.2>FILTER语法 "标准表赋值 itabs = VALUE #( ( code = '01' value = 'test01') ( code = '01' value = 'test001') ( code = '02' value = 'test02') ( code = '03' value = 'test003') ( code = '02' value = 'test021') ( code = '03' value = 'test031') ). "直接Filter"找出满足条件的数据 DATA(it_filters) = FILTER #( itabs USING KEY cod WHERE code = '01' ). "显示数据 cl_demo_output=>new( )->next_section( |初始化内表| )->write( itab )->next_section( |直接Filter| )->write( it_filter )->next_section( |使用excpt 语句| )->write( it_exp )->next_section( |标准表赋值| )->write( itabs )->next_section( |标准表Filter| )->write( it_filters )->display( ). *----------------------------------------------------------------------* *4> a,内表行数 * b,内表中男性员工有几位 * c,累计内表gt_data中销售雇员工资之和 * d,定义结构将销售雇员工资总和、最大值、平均工资、员工个数输出 "内表行数 DATA(lv_lines) = lines( gt_data ). "内表中男性员工有几位 -- 计数 DATA(lv_lines_nan) = REDUCE i( INIT x = 0 FOR ls_man IN gt_data WHERE ( gender = '男' ) NEXT x = x + 1 ). cl_demo_output=>write( lv_lines ). cl_demo_output=>write( lv_lines_nan ). "累计内表gt_data中销售雇员工资之和 --简单汇总 TYPES: ty_sal TYPE p DECIMALS 2 . DATA(lv_sum_salary) = REDUCE ty_sal( INIT sum_sal = VALUE ty_sal( ) FOR wa IN gt_data WHERE ( rank = c_rank2 ) NEXT sum_sal = sum_sal + wa-salary ). cl_demo_output=>write( lv_sum_salary ). TYPES:BEGIN OF ty_result, sum TYPE p DECIMALS 2, "总和 max TYPE p DECIMALS 2, "最大值 min 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( min = 999999999 max = 0 ) "给一个最大值0,给一个最小值相对大的数据,然后再NEXT中比较大小 FOR <fs_data1> IN gt_data WHERE ( rank = c_rank2 ) NEXT res-sum = res-sum + <fs_data1>-salary "工资总和 res-max = nmax( val1 = res-max val2 = <fs_data1>-salary )"最高工资 res-min = nmin( val1 = res-min val2 = <fs_data1>-salary )"最di工资 res-cunt = res-cunt + 1 "几个销售雇员 ). ls_result-avg = ls_result-sum / ls_result-cunt. "平均工资 cl_demo_output=>write( ls_result ). *4.1>复杂汇总 -- 按照group汇总与at new ,at end ,loop group by类似 TYPES: BEGIN OF ty_002, code type char2, group type char1, quan type i, end of ty_002. DATA itab1 TYPE TABLE OF ty_002 WITH NON-UNIQUE SORTED KEY grp COMPONENTS group. itab1 = VALUE #( ( code = '1' group = 'A' quan = 1 ) ( code = '1' group = 'A' quan = 3 ) ( code = '3' group = 'A' quan = 2 ) ( code = '2' group = 'C' quan = 4 ) ( code = '2' group = 'A' quan = 5 ) ( code = '3' group = 'B' quan = 8 ) ( code = '3' group = 'A' quan = 4 ) ( code = '1' group = 'C' quan = 2 ) ). "按照group汇总 DATA itabg TYPE TABLE OF ty_002. LOOP AT itab1 INTO data(ls_itab1). DATA(ls_check) = VALUE #( itabg[ group = ls_itab1-group ] OPTIONAL ). IF ls_check is NOT INITIAL. CONTINUE. ENDIF. data(ls_itabg) = ls_itab1. CLEAR ls_itabg-code. ls_itabg-quan = REDUCE i( INIT v = 0 FOR ls IN FILTER #( itab1 USING KEY grp WHERE group = ls_itabg-group ) NEXT v = v + ls-quan ). APPEND ls_itabg TO itabg. CLEAR: ls_itabg,ls_check,ls_itab1. ENDLOOP. *4.2>复杂汇总 -- 按照code与group汇总 DATA itab2 TYPE TABLE OF ty_002 WITH NON-UNIQUE SORTED KEY cod COMPONENTS code group WITH NON-UNIQUE SORTED KEY grp COMPONENTS group. itab1 = VALUE #( ( code = '1' group = 'A' quan = 1 ) ( code = '1' group = 'A' quan = 3 ) ( code = '3' group = 'A' quan = 2 ) ( code = '2' group = 'C' quan = 4 ) ( code = '2' group = 'A' quan = 5 ) ( code = '3' group = 'B' quan = 8 ) ( code = '3' group = 'A' quan = 4 ) ( code = '1' group = 'C' quan = 2 ) ). "按照group汇总 DATA itabcg TYPE TABLE OF ty_002. LOOP AT itab1 INTO ls_itab1. ls_check = VALUE #( itabcg[ code = ls_itab1-code group = ls_itab1-group ] OPTIONAL ). IF ls_check is NOT INITIAL. CONTINUE. ENDIF. data(ls_itabcg) = ls_itab1. CLEAR ls_itabg-code. ls_itabg-quan = REDUCE i( INIT v = 0 FOR ls IN FILTER #( itab2 USING KEY cod WHERE code = ls_itabcg-code AND group = ls_itabcg-group ) NEXT v = v + ls-quan ). APPEND ls_itabcg TO itabcg. CLEAR: ls_itabcg,ls_check,ls_itab1. ENDLOOP. *&---------------------------------------------------------------------- * 练习四:OPEN SQL *&---------------------------------------------------------------------* cl_demo_output=>write( '练习四:' ). *1> 工资大于等于1000为 * ... CASE WHEN sql_cond1 THEN result1 * [WHEN sql_cond2 THEN result2] * [WHEN sql_cond3 THEN result3] * ... * [ELSE resultn] * END ... SELECT id,name,salary, CASE WHEN salary GE 10000 THEN 'A' WHEN salary GE 5000 AND salary LT 9999 THEN 'B' WHEN salary LT 5000 THEN 'C' ELSE ' ' END AS salary_1 FROM ytest_ng * GROUP BY id,name,salary INTO TABLE @DATA(gt_out_s). cl_demo_output=>write( gt_out_s ). SELECT rank, SUM( CASE WHEN education = '本科' THEN 1 ELSE 0 END ) AS sum_ben_num , "--本科人数 SUM( CASE WHEN education = '专科' THEN 1 ELSE 0 END ) AS sum_zhuan_num "--专科人数 FROM ytest_ng GROUP BY rank INTO TABLE @DATA(gt_out_e). cl_demo_output=>write( gt_out_e ). *&---------------------------------------------------------------------* *CORRESPONDING关键字 *关键字MAPPING指定不同的字段赋值 *关键字EXCEPT排除某个字段不赋值 *&---------------------------------------------------------------------* "1.工作区中相同字段赋值,可以省去不同字段赋值的语句 DATA:BEGIN OF ls_data1, fd1 TYPE char10, fd2 TYPE char10, fd3 TYPE char10, END OF ls_data1. DATA:BEGIN OF ls_data2, fd1 TYPE char10, fd2 TYPE char10, fd4 TYPE char10, END OF ls_data2. ls_data1 = VALUE #( fd1 = |First| fd2 = |Second| fd3 = |Third| ). "类似MOVE-CORRESPONDING ls_data2 = CORRESPONDING #( ls_data1 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同字段赋值的基础上,指定把ls_data1-fd3赋值给ls_data2-fd4 ls_data2 = CORRESPONDING #( ls_data1 MAPPING fd4 = fd3 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同字段赋值的基础上,排除fd2初始化 ls_data2 = CORRESPONDING #( ls_data1 EXCEPT fd2 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同字段赋值的基础上,指定把ls_data1-fd3赋值给ls_data2-fd4,fd2初始化 ls_data2 = CORRESPONDING #( ls_data1 MAPPING fd4 = fd3 EXCEPT fd2 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. "2.内表相同字段赋值,可以省去LOOP中READ数据再赋值,只需要将不同的字段指定好 *DATA: LT_T001 TYPE STANDARD TABLE OF ACDOCA. * *SELECT * BUKRS, * BELNR, * GJAHR, * BUZEI * FROM BSEG * UP TO 3 ROWS * INTO TABLE @DATA(LT_BSEG). * *"CORRESPONDING *LT_T001 = CORRESPONDING #( LT_BSEG MAPPING RBUKRS = BUKRS * DOCLN = BUZEI ). * *3.CORRESPONDING构造RANGE表,省去循环赋值,提高代码速度 RANGES: lr_rank FOR ytest_ng-rank. lr_rank[] = CORRESPONDING #( gt_data[] MAPPING low = rank EXCEPT * ). SORT lr_rank BY LOW. DELETE ADJACENT DUPLICATES FROM lr_rank COMPARING LOW. DELETE lr_rank WHERE low is INITIAL. lr_rank-sign = 'I'. lr_rank-option = 'EQ'. MODIFY lr_rank TRANSPORTING sign option WHERE low IS NOT INITIAL. SELECT * from ytest_ng INTO TABLE gt_data WHERE rank in lr_rank. *LCL_ALV->DISPLAY( ). BREAK-POINT. *--------------------------------------------------------------------* *COND SWITCH 操作符 *在新语法中,可以使用COND、SWITCH来根据逻辑表达式或情况的不同确定指定变量的结果。 *COND SWITCH可以理解为IF CASE的替代语法,提高了代码可读性、简洁性 *--------------------------------------------------------------------* DATA(time) = COND string( WHEN sy-timlo < '120000' THEN |{ sy-timlo TIME = ISO } AM| WHEN sy-timlo > '120000' THEN |{ CONV t( sy-timlo - 12 * 3600 ) TIME = ISO } PM| WHEN sy-timlo = '120000' THEN |High noon| * ELSE ). WRITE: time. DATA: LV_STRING TYPE STRING VALUE 's'. "旧 IF LV_STRING is INITIAL. LV_STRING = ' inittial'. ELSEIF LV_STRING = 'K'. LV_STRING = 'is k'. *ELSE. ENDIF. LV_STRING = COND #( WHEN LV_STRING IS INITIAL THEN ' inittial' WHEN LV_STRING = 'K' THEN 'is k' ELSE LV_STRING "如果前面条件均不满足,一定要回写LV_STRING值,否则LV_STRING值将被回写的空值覆盖 ). WRITE: LV_STRING. *WHNE后面只能跟变量,类似 CASE 变量 when不同的值 DATA(a) = 11. DATA(text) = SWITCH #( a WHEN '11' THEN '11yyagd' WHEN '12' THEN '12dkdkkd' * ELSE ). WRITE: text. DATA: LV_STRING1 TYPE STRING VALUE 's'. lv_string1 = switch #( lv_string1 "如果非a b c,lv_string将被返回的空值覆盖; WHEN 'a' THEN 'is a' WHEN 'b' THEN 'is b' WHEN 'c' THEN 'is c' ). WRITE: LV_STRING. TYPES: BEGIN OF result, operand TYPE string, result TYPE string, fdpos TYPE sy-fdpos, END OF result. DATA results TYPE STANDARD TABLE OF result WITH EMPTY KEY. DATA: f1 TYPE c LENGTH 5 VALUE 'BD ', f2 TYPE c LENGTH 5 VALUE 'ABCDE'. cl_demo_input=>new( )->add_field( CHANGING field = f1 )->add_field( CHANGING field = f2 )->request( ). results = VALUE #( BASE results ( operand = 'CO' result = COND #( WHEN f1 CO f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CN' result = COND #( WHEN f1 CN f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CA' result = COND #( WHEN f1 CA f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NA' result = COND #( WHEN f1 NA f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CS' result = COND #( WHEN f1 CS f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NS' result = COND #( WHEN f1 NS f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CP' result = COND #( WHEN f1 CP f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NP' result = COND #( WHEN f1 NP f2 THEN abap_true ) fdpos = sy-fdpos ) ). cl_demo_output=>new( )->write( |'{ f1 WIDTH = 5 }' operand '{ f2 WIDTH = 5 }'| )->display( results ). *用于BAPI输出消息时,可用于拼接于一行显示的消息返回结果中 * CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST' * EXPORTING * DOCUMENTHEADER = LS_DOCUMENTHEADER * IMPORTING ** OBJ_TYPE = * OBJ_KEY = LV_KEY ** OBJ_SYS = * TABLES * ACCOUNTGL = LT_ACCOUNTGL * ACCOUNTRECEIVABLE = LT_ACCOUNTRECEIVABLE ** ACCOUNTPAYABLE = LT_ACCOUNTPAYABLE * CURRENCYAMOUNT = LT_CURRENCYAMOUNT * EXTENSION2 = LT_EXTENSION2 * RETURN = LT_RETURN. * * LOOP AT LT_RETURN INTO DATA(LS_RETURN) WHERE TYPE CA 'AEX'. * LS_OUT-MESSAGE = * COND #( WHEN LS_OUT-MESSAGE = SPACE THEN LS_RETURN-MESSAGE * ELSE |{ LS_OUT-MESSAGE }/{ LS_RETURN-MESSAGE }| ). * ENDLOOP. *--------------------------------------------------------------------* *LOOP……GROUP BY *--------------------------------------------------------------------* DATA BEGIN OF gs_data1. DATA: sss TYPE CHAR1, char TYPE char1, num TYPE i , end of gs_data1. DATA: gt_data1 LIKE TABLE OF gs_data1. DATA LV_COUNT TYPE I. *内部追加赋值 gt_data1 = VALUE #( base gt_data1 ( sss = '1' char = 'A' ) ( sss = '1' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '3' char = 'A' ) ( sss = '4' char = 'C' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '3' char = 'B' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ). *--------------------------------------------------------* "按照相同sss,char的分组排序编号给num字段赋值 *--------------------------------------------------------* SORT gt_data1 by sss char. LOOP AT gt_data1 INTO gs_data1 GROUP BY ( sss = gs_data1-sss "循环时gs_data没有数据,数据通过分组到<L_MEMBER>,如果给gt_data赋值,也是用<L_MEMBER>,指针不用MODIFY char = gs_data1-char size = GROUP SIZE "size是本组条目数量 index = GROUP INDEX ) "INDEX组索引 ASCENDING ASSIGNING FIELD-SYMBOL(<l_group>). "双击可以看到,size,index以及按条件分组的条件字段值 CLear lv_count. LOOP AT GROUP <l_group> ASSIGNING FIELD-SYMBOL(<l_member>). lv_count = lv_count + 1. <l_member>-num = lv_count. ENDLOOP. ENDLOOP. BREAK-POINT. *--------------------------------------------------------* "按照相同sss,char为一组,累加数据字段,并合并重复项 *--------------------------------------------------------* DATA :gt_data_temp LIKE gt_data1, gs_data_temp LIKE gs_data1. SORT gt_data1 by sss char. LOOP AT gt_data1 INTO gs_data1 GROUP BY ( sss = gs_data1-sss char = gs_data1-char size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING <l_group>. CLear lv_count. LOOP AT GROUP <l_group> ASSIGNING <l_member>. lv_count = <l_member>-num + lv_count. gs_data_temp = <l_member>. ENDLOOP. gs_data_temp-num = lv_count. APPEND gs_data_temp to gt_data_temp. CLEAR gs_data_temp. ENDLOOP. BREAK-POINT. DATA lv_netwr TYPE vbak-netwr. DATA: BEGIN OF lt_vbak_temp OCCURS 0, vkgrp LIKE vbak-vkgrp, vkbur LIKE vbak-vkbur, netwr LIKE vbak-netwr, waerk LIKE vbak-waerk, END OF lt_vbak_temp. *DATA lt_vbak_temp TYPE TABLE OF vbak WITH HEADER LINE. SELECT * FROM vbak INTO TABLE @DATA(lt_vbak) UP TO 100 ROWS. SORT lt_vbak BY vkgrp vkbur. LOOP AT lt_vbak INTO DATA(ls_vbak) GROUP BY ( vkgrp = ls_vbak-vkgrp vkbur = ls_vbak-vkbur waerk = ls_vbak-waerk size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING FIELD-SYMBOL(<group>). LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>). TRY. ADD <member>-netwr TO lv_netwr. CATCH cx_sy_arithmetic_error. ENDTRY. MOVE-CORRESPONDING <member> TO lt_vbak_temp. ENDLOOP. lt_vbak_temp-netwr = lv_netwr. APPEND lt_vbak_temp. CLEAR: lt_vbak_temp,lv_netwr,ls_vbak. ENDLOOP. cl_demo_output=>write( lt_vbak_temp[] ). cl_demo_output=>display( ). *&---------------------------------------------------------------------* *& Report YTEST_NEW_GRAMMAR_AN2 *&---------------------------------------------------------------------* *&SAP SQL杂项函数 *select 与 case结合使用最大的好处有两点,一是在显示查询结果时可以灵活 *的组织格式,二是有效避免了多次对同一个表或几个表的访问 *&---------------------------------------------------------------------* REPORT ytest_new_grammar_an2. *连接字符串的两种写法 DATA(lv_date1) = sy-datum && sy-uzeit. DATA(lv_date2) = |{ sy-datum(4) - 1 }{ sy-datum+4 + 1 }|. *cl_demo_output=>write( lv_date1 ). *cl_demo_output=>write( lv_date2 ). SELECT COUNT( DISTINCT carrid ) FROM spfli WHERE cityto = 'NEW YORK' INTO @DATA(count). *cl_demo_output=>write( count ). SELECT * FROM scustom USING CLIENT '100' INTO TABLE @DATA(lt_customers). *cl_demo_output=>write( lt_customers ). *1. ... CASE operand * WHEN operand1 THEN result1 * [WHEN operand2 THEN result2] * ... * [ELSE resultn] * END ... DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'x' char1 = 'aaaaa' char2 = 'bbbbb' ) ( id = 'y' char1 = 'xxxxx' char2 = 'yyyyy' ) ( id = 'z' char1 = 'mmmmm' char2 = 'nnnnn' ) ) ) ACCEPTING DUPLICATE KEYS. DATA(else) = 'fffff'. SELECT id, char1, char2, CASE char1 WHEN 'aaaaa' THEN concat( char1 , char2 ) WHEN 'xxxxx' THEN substring( char1,1,2 ) ELSE @else END AS text FROM demo_expressions INTO TABLE @DATA(lt_results1). *cl_demo_output=>write( lt_results1 ). "实际应用 SELECT c~bukrs, b~werks, a~budat, b~matnr, h~maktx, e~waers, c~lifnr, g~name1, g~land1, i~aplfz, b~meins, CASE b~kzabs WHEN 'X' THEN 'VMI' ELSE ' ' END AS kzabs1, CASE substring( c~zterm,1,1 ) WHEN 'B' THEN 'BWT' ELSE ' ' END AS zterm1, SUM( CASE a~shkzg WHEN 'S' THEN ( a~dmbtr ) WHEN 'H' THEN ( a~dmbtr * -1 ) END ) AS dmbtr1, SUM( CASE a~shkzg WHEN 'S' THEN ( b~menge ) WHEN 'H' THEN ( b~menge * -1 ) END ) AS menge, CASE e~waers WHEN 'KRW' THEN 100 WHEN 'JPY' THEN 100 WHEN 'VND' THEN 100 ELSE 1 END AS factor FROM ekbe AS a INNER JOIN ekpo AS b ON b~ebeln = a~ebeln AND b~ebelp = a~ebelp INNER JOIN ekko AS c ON c~ebeln = a~ebeln INNER JOIN t001k AS f ON f~bwkey = b~werks INNER JOIN t001 AS e ON e~bukrs = f~bukrs INNER JOIN lfa1 AS g ON g~lifnr = c~lifnr INNER JOIN makt AS h ON h~matnr = a~matnr INNER JOIN zm094v AS i ON i~lifnr = g~lifnr AND i~matnr = a~matnr AND i~werks = a~werks WHERE h~spras = 'E' AND b~mtart = 'ROH' GROUP BY c~bukrs, b~werks, a~budat, b~matnr, h~maktx, e~waers, c~lifnr, g~name1, g~land1, i~aplfz, b~meins, b~kzabs, c~zterm INTO TABLE @DATA(gt_vmi). *cl_demo_output=>write( gt_vmi ). *--------------------------------------------------------------------* *2. ... CASE WHEN sql_cond1 THEN result1 * [WHEN sql_cond2 THEN result2] * [WHEN sql_cond3 THEN result3] * ... * [ELSE resultn] * END ... *CASE WHEN可以用大于,小于,SUBSTRING,CONCAT,LIKE,BETWEEN,不能用IN ,EXISTS,等条件 DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'w' char1 = 'vvvvv' char2 = 'wwwww' dec1 = 1018 dec2 = '11.11') ( id = 'x' char1 = 'aaa77' char2 = 'bbbbb' dec1 = 1018 ) ( id = 'y' char1 = 'xxxxx' char2 = 'yyyyy' dec1 = 1118 ) ( id = 'z' char1 = 'mmmmm' char2 = 'nnnnn' dec1 = -1218 ) ( id = 'm' char1 = 'mmmmm' char2 = 'nnnnn' dec1 = 1318 dec2 = '12.12') ) ) ACCEPTING DUPLICATE KEYS. SELECT id , CASE WHEN char1 LIKE '%a77' "LIKE THEN ( char1 && char2 ) ELSE ( char2 && char1 ) END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77). *cl_demo_output=>write( lt_a77 ). SELECT id , CASE WHEN substring( char1,3,3 ) = 'a77' "SUBSTRING THEN ( char1 && char2 ) ELSE concat( char2 ,char1 ) "CONCAT END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77_sub). *cl_demo_output=>write( lt_a77_sub ). SELECT id , * case when ( char1 && '%' ) = 'aaa77%' CASE WHEN concat( char1 , '%' ) = 'aaa77%' THEN ( char1 && char2 ) ELSE concat( char2 , char1 ) END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77_con). *cl_demo_output=>write( lt_a77_con ). SELECT id,ceil( dec2 ) AS dec2_ceil,floor( dec2 ) AS dec2_floor, CASE WHEN dec1 BETWEEN 1101 AND 1130 "ONLY Numerical type THEN 'BETWEEN' WHEN abs( dec1 ) = 1218 THEN 'ABS' ELSE 'others' END AS text_dec1, CASE WHEN ceil( dec2 ) = 12 THEN 'CEIL' WHEN floor( dec2 ) = 12 THEN 'FLOOR' ELSE 'OTHERS' END AS text_dec2 FROM demo_expressions INTO TABLE @DATA(lt_dec). *cl_demo_output=>write( lt_dec ). *--------------------------------------------------------------------* GET TIME STAMP FIELD DATA(gv_timestamp). DELETE FROM demo_expressions. INSERT demo_expressions FROM @( VALUE #( id = 'X' timestamp1 = gv_timestamp ) ). *--------------------------------------------------------------------* "CAST数据转换函数& div|mod|*|/|substring|concat等嵌套使用 *--------------------------------------------------------------------* SELECT SINGLE FROM demo_expressions FIELDS CAST( CAST( div( timestamp1 , 1000000 ) AS CHAR ) AS DATS ) AS date, CAST( substring( CAST( timestamp1 AS CHAR ), 9, 6 ) AS TIMS ) AS time INTO @DATA(ls_expressions). *cl_demo_output=>write( ls_expressions ). *--------------------------------------------------------------------* "fields与SINGLE的区别 & 日期类型与char类型显示的不同 *--------------------------------------------------------------------* SELECT SINGLE CAST( div( timestamp1 , 1000000 ) AS CHAR ) AS date, CAST( substring( CAST( timestamp1 AS CHAR ), 9, 6 ) AS TIMS ) AS time FROM demo_expressions INTO @DATA(ls_expressions1). *cl_demo_output=>write( ls_expressions1 ). DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'X' num1 = 111 ) ( id = 'Y' num1 = 222 ) ( id = 'Z' num1 = 333 ) ) ). *--------------------------------------------------------------------* "WHERE 中等号左右两边都可以使用CAST,SUBSTRING,CONCAT,*,+,-等 *--------------------------------------------------------------------* *SELECT FROM demo_expressions * FIELDS id, num1 * WHERE CAST( num1 AS CHAR ) LIKE '2%' * INTO TABLE @DATA(result). select t1~matnr, werks, charg, cuobj from mchb as t1 left outer join inob as t2 on substring( t2~objek , 1, 18 ) = t1~matnr "1-18位 是物料号 and substring( t2~objek, 41,10 ) = t1~charg "41~50位 是批次 where t2~klart = '023' into table @data(lt_mchb). SELECT * FROM bkpf "AS t1 WHERE substring( awkey , 1, 10 ) = '1' AND substring( awkey , 11, 4 ) = 1 INTO TABLE @data(gt_outt) . SELECT * FROM bkpf "AS t1 WHERE awkey = '___5555_' "假设共8位,想取4-7位数据为5555的 AND substring( awkey , 1, 4 ) = 1 INTO TABLE @data(gt_outtt) . "SELECT…聚合函数&CAST SELECT carrid, SUM( CAST( price AS DEC( 20,2 ) ) ) AS price1 FROM ysflight_oolav_1 WHERE carrid = 'JL' GROUP BY carrid INTO TABLE @DATA(lt_ysflight_oolav_1). *cl_demo_output=>write( lt_ysflight_oolav_1 ). *--------------------------------------------------------------------* *case…when& concat& substring& cast嵌套使用 *CAST,SUBSTRING,CONCAT,*,+,-等也可以在CASE WHEN,THEN,WHERE关键字等号左右两边均可使用, * CASE WHEN中小数怎么处理,可以给左边取数乘以10 *CAST也可用于同类型修改长度 *--------------------------------------------------------------------* "Get Goal GET TIME STAMP FIELD data(lv_start_time)."获取当前系统的时间戳 SELECT a~zcustg, b~name, a~goal_rate AS goal_deci, a~gjahr, " goal_rate = 0 CASE WHEN a~goal_rate = 0 THEN ' ' "goal_rate >=1 WHEN a~goal_rate >= 1 THEN concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,3 ), '%' ) "0 < goal_rate < 0.1 WHEN ( a~goal_rate * 10 ) < 1 AND a~goal_rate > 0 THEN concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,1 ), '%' ) "0.1 <= goal_rate < 1 ELSE concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,2 ), '%' ) END AS goal FROM zsa6202 AS a INNER JOIN zsa6001 AS b ON a~zcustg = b~zcustg ORDER BY a~zcustg, b~name INTO TABLE @DATA(lt_data) . GET TIME STAMP FIELD data(lv_end_time). DATA(lv_rfc_time) = lv_end_time - lv_start_time. " GET TIME STAMP FIELD data(lv_start_time1)."获取当前系统的时间戳 SELECT a~zcustg, b~name, a~goal_rate AS goal_deci, a~gjahr, a~goal_rate FROM zsa6202 AS a INNER JOIN zsa6001 AS b ON a~zcustg = b~zcustg ORDER BY a~zcustg, b~name INTO TABLE @DATA(lt_data1) . GET TIME STAMP FIELD data(lv_end_time1). DATA(lv_rfc_time1) = lv_end_time1 - lv_start_time1. " *cl_demo_output=>write( lt_data ). cl_demo_output=>write( lv_rfc_time ). cl_demo_output=>write( lv_rfc_time1 ). *--------------------------------------------------------------------* *除了CAST、CONCAT之外,ROUND, LPAD, LENGTH, REPLACE, RIGHT, RTRIM,SUBSTRING *等函数也可以使用,杂项函数COALESCE 也可以使用,但是最多255个表达式 *--------------------------------------------------------------------* "LPAD可用于补0,或者补任何字符 SELECT CONCAT( CONCAT( carrid, LPAD( carrname,30,' ' ) ), LPAD( url,40,' ' ) ) AS line FROM scarr INTO TABLE @DATA(result1). cl_demo_output=>write( result1 ). DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'X' char1 = ' 0123' char2 = ' 4567' ) ) ). SELECT SINGLE char1 AS text1, char2 AS text2, CONCAT( char1,char2 ) AS concat, LENGTH( char1 ) AS length, "字符串长度,包含空格长度 "从左边去除字符串的所有空格,类似SHIFT <l_tbtco>-periode LEFT DELETING LEADING '0'.不止为0,可以为其他字符 LTRIM( char1,' ' ) AS ltrim, LPAD( char1,10,'0' ) AS LPAD, "补0,或者补任何其他字符至10位 REPLACE( char1,'12','__' ) AS replace, "替换 RIGHT( char1,3 ) as right, "从右边截取,且包含空格 RTRIM( char1,'3' ) AS rtrim, ""该函数功能是在arg的右边查找char字符,如果找到,则去掉; SUBSTRING( char1,3,3 ) AS substring FROM demo_expressions INTO @DATA(result2). cl_demo_output=>write( result2 ). *--------------------------------------------------------------------* *REPLACE *RIGHT( arg, len ) 从右往左截取固定长度 *RTRIM( arg, char ) 该函数功能是在arg的右边查找char字符,如果找到,则去掉; *COALESCE( sql_exp1, sql_exp2, ..., sql_expn ) 凝聚函数,该函数的功能是将参数中的第一个不为空的参数返回来 *可以用于不同的表取值 *--------------------------------------------------------------------* SELECT matnr, replace( vpsta,'VE','HU' ) AS str, vpsta, ernam FROM mara WHERE vpsta LIKE 'KCV%' INTO TABLE @DATA(gt_out) UP TO 10 ROWS. SELECT matnr, right( matkl,3 ) AS str, matkl FROM mara WHERE vpsta LIKE 'KCV%' INTO TABLE @DATA(gt_out1) UP TO 10 ROWS. *其实该语法也可以用于inner join,从而可以解决在inner join时字段长度不一致的问题 SELECT a~* FROM vbrp AS a INNER JOIN ekpo AS b ON a~aubel = b~ebeln AND right( a~aupos,5 ) = b~ebelp WHERE b~ebeln <> '' INTO TABLE @DATA(gt_out2). *该函数的功能是将参数中的第一个不为空的参数返回来,或者是将参数中第一个成立的表达式的值返回到别名 *比如请假,先找cell长审批,再找part长,再找group长,再找team长,也可以innerjoin等 SELECT FROM mara FIELDS matnr, coalesce( CASE vpsta WHEN 'KDG' THEN 'HUJIE' END, CASE vpsta WHEN 'KDA' THEN 'LAIMIN' ELSE 'DUODUO' END ) AS str, vpsta WHERE vpsta LIKE 'KD%' INTO TABLE @DATA(lt_out) UP TO 10 ROWS. SELECT LFA1~LIFNR, COALESCE( EKKO~LIFNR, EKKO~EBELN, '无采购订单' ) as vendor FROM LFA1 INNER JOIN EKKO ON LFA1~LIFNR = EKKO~LIFNR INTO TABLE @DATA(LT_OUT1). cl_demo_output=>display( ).
标签:gt,DATA,7.40,WHEN,语法,ABAP,ls,demo,data 来源: https://www.cnblogs.com/ap-ad-java-abap/p/16549392.html