ABAP:新语法
1.构建数据
*&---------------------------------------------------------------------* *& Report YTEST_ZJNEW01 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------* REPORT ytest_zjnew01. TYPES:BEGIN OF gty_student, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student. DATA:gt_student TYPE TABLE OF gty_student, gs_student TYPE gty_student. "利用VALUE #( LET ... IN ... FOR ... )的新语法,通过循环构建了10个学生的数据, "其中LET用于定义局部变量,IN用于指定循环的范围,FOR用于循环体的执行。在循环中,使用了cl_abap_random_int类生成随机数作为学生成绩。 gt_student = VALUE #( LET pre = 'Student' "LET 定义变量 random = cl_abap_random_int=>create( min = 0 max = 100 ) IN "seed = CONV #( sy-timlo ) FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 6 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). cl_demo_output=>display( gt_student ).
2.内联声明
******内联声明 DATA(lv_name) = 'Tom'. "Char DATA(lv_age) = 20. "Int DATA(lv_name_str) = CONV string( 'Tom' ). "String "Read READ TABLE gt_student INTO DATA(ls_read) INDEX 1. "Loop LOOP AT gt_student INTO DATA(ls_loop). ENDLOOP. "Assign ASSIGN lv_name TO FIELD-SYMBOL(<assign>). "Loop assign LOOP AT gt_student ASSIGNING FIELD-SYMBOL(<loop>). ENDLOOP. "Single field SELECT SINGLE carrname FROM scarr INTO @DATA(lv_carrname). "Multiple fields SELECT SINGLE carrid,carrname FROM scarr INTO @DATA(ls_scarr). "Internal table SELECT carrid,carrname FROM scarr INTO TABLE @DATA(lt_scarr) UP TO 10 ROWS. "Class parameters cl_gui_frontend_services=>get_ip_address( RECEIVING ip_address = DATA(lv_ip) ).
3.ITAB[ idx ]、ITAB[ key ]
*****ITAB[ idx ]、ITAB[ key ] *&---------------------------------------------------------------------- *& 2. 内表表达式 理解:内表表达式,相当于Read Table *&---------------------------------------------------------------------- *& 语法:itab[ idx ]. *& itab[ col1 = … col2 = … ]. *&---------------------------------------------------------------------- "不存在会抛出异常(cx_sy_itab_line_not_found) IF 1 <> 1. DATA(ls_index) = gt_student[ 1 ]. "index读取 DATA(ls_key) = gt_student[ id = '0000000005' age = 15 ]. "key读取 DATA(lv_index_name) = gt_student[ 1 ]-name. "index读取结构字段 DATA(lv_key_name) = gt_student[ id = '0000000002' ]-name. "key读取字段 ENDIF. "避免抛出异常的几种方式 ASSIGN gt_student[ id = '0000000003' name = 'Student 3' ] TO FIELD-SYMBOL(<stu>). IF sy-subrc EQ 0. ENDIF. IF line_exists( gt_student[ 1 ] ). DATA(ls_stu01) = gt_student[ 1 ]. lv_name = gt_student[ 1 ]-name. ENDIF. "使用VALUE #(gt_student[11] OPTIONAL),通过OPTIONAL选项在索引越界时避免抛出异常。 "使用VALUE #(gt_student[11] DEFAULT VALUE #(id = '0000000010' name = 'Student 10')),在索引越界时提供默认值。 DATA(ls_stu02) = VALUE #( gt_student[ 11 ] OPTIONAL ). DATA(ls_stu03) = VALUE #( gt_student[ 11 ] DEFAULT VALUE #( id = '0000000010' name = 'Student 10' ) ). DATA(ls_stu04) = VALUE #( gt_student[ 11 ] DEFAULT VALUE #( gt_student[ 10 ] OPTIONAL ) ). DATA(ls_stu05) = COND #( LET c = lines( gt_student ) IN WHEN c > 10 THEN gt_student[ 11 ] ). DATA(ls_stu06) = COND #( WHEN line_exists( gt_student[ 11 ] ) THEN gt_student[ 11 ] ). TRY . DATA(ls_stu07) = gt_student[ 11 ]. CATCH cx_sy_itab_line_not_found. * WRITE : 'Not Found!'. ENDTRY.
4.VALUE
*&---------------------------------------------------------------------- *& 3. VALUE关键字 理解:赋值语句 *&---------------------------------------------------------------------- *& 语法:Variables: VALUE dtype|#( ) *& Structures: VALUE dtype|#( comp1 = a1 comp2 = a2 … ) *& Tables: VALUE dtype|#( ( … ) ( … ) ( … ) … ) *&---------------------------------------------------------------------- DATA(lv_var) = VALUE i( ). * DATA ls_stu01 TYPE gty_student. ls_stu01 = VALUE #( name = 'Tom' gender = '男' age = 20 ). ls_stu02 = VALUE gty_student( name = 'Jack' gender = '男' age = 18 ). DATA lt_stu01 TYPE TABLE OF gty_student. lt_stu01 = VALUE #( ( ls_stu01 ) ( ls_stu02 ) ( ) ( name = 'Lisa' gender = '女' age = 18 ) ). TYPES lty_t_student TYPE TABLE OF gty_student WITH EMPTY KEY. DATA(lt_stu02) = VALUE lty_t_student( ( name = 'Tom' gender = '男' age = 20 ) ( name = 'Lisa' gender = '女' age = 18 ) ). "Range:不带表头 DATA r_data TYPE RANGE OF i. r_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 ) ). "Range:带表头 RANGES: r_erdat FOR usr02-erdat. r_erdat[] = VALUE #( sign = 'I' option = 'BT' ( low = '20210101' high = '20210301' ) sign = 'E' option = 'BT' ( low = '20210201' high = '20210228' ) ).
5.CORRESPONDING
*&---------------------------------------------------------------------- *& 4. CORRESPONDING关键字 理解:字段映射 *&---------------------------------------------------------------------- *& 语法:… CORRESPONDING dtype|#( [BASE ( base )] struct|itab [mapping|except] ) *& 后缀:MAPPING 映射字段,注意避免dump; *& EXCEPT 排除映射字段 *&---------------------------------------------------------------------- TYPES: * BEGIN OF gty_student, * name(10) TYPE c, "姓名 * gender TYPE c, "性别 * age TYPE i, "年龄 * id(10) TYPE n , "学生ID * class(10) TYPE c, "班级 * score TYPE p DECIMALS 1, "成绩 * level(10) TYPE c, "级别 * ispass TYPE c, "是否通过 * END OF gty_student, gty_t_student TYPE TABLE OF gty_student WITH EMPTY KEY. TYPES: BEGIN OF gty_teacher, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 seniority TYPE i, "工龄 office(12) TYPE c, "办公室 END OF gty_teacher, gty_t_teacher TYPE TABLE OF gty_teacher WITH EMPTY KEY. "初始结构数据 DATA(ls_corr01) = VALUE gty_teacher( name = 'Tom' gender = '男' age = 20 office = '101办公室' seniority = 10 ). DATA(ls_corr02) = VALUE gty_student( name = 'Lisa' gender = '女' age = 18 ). "基础 DATA(ls_teacher01) = ls_corr01. DATA(ls_teacher02) = ls_corr01. ls_teacher01 = CORRESPONDING gty_teacher( ls_corr02 ). "无BASE,无映射字段,置初始值 ls_teacher02 = CORRESPONDING gty_teacher( BASE ( ls_corr01 ) ls_corr02 ). "无映射字段,保留原值(同MOVE-CORRESPONDING ... to ...) "后缀 "使用ls_teacher03 = CORRESPONDING gty_teacher( ls_corr02 MAPPING seniority = age EXCEPT age ).,通过MAPPING指定映射关系,EXCEPT排除不需要映射的字段。 DATA(ls_teacher03) = CORRESPONDING gty_teacher( ls_corr02 MAPPING seniority = age EXCEPT age ). DATA(ls_teacher04) = CORRESPONDING gty_teacher( BASE ( ls_corr01 ) ls_corr02 MAPPING seniority = age EXCEPT age ). *------------------------------------* "初始化内表数据 DATA(lt_corr01) = VALUE gty_t_teacher( ( name = 'Tom' gender = '男' age = 20 office = '101办公室' seniority = 10 ) ( name = 'Tom2' gender = '男' age = 21 office = '102办公室' seniority = 11 ) ( name = 'Tom3' gender = '男' age = 22 office = '103办公室' seniority = 12 ) ). DATA(lt_corr02) = VALUE gty_t_student( ( name = 'Lisa' gender = '女' age = 18 ) ( name = 'Lisa2' gender = '女' age = 19 ) ). "基础 DATA(lt_teacher01) = lt_corr01. DATA(lt_teacher02) = lt_corr01. lt_teacher01 = CORRESPONDING gty_t_teacher( lt_corr02 ). "无BASE,清空原表数据,映射赋值 lt_teacher02 = CORRESPONDING gty_t_teacher( BASE ( lt_corr01 ) lt_corr02 ). "有BASE,保留内表数据,映射APPEND "后缀 DATA(lt_teacher03) = CORRESPONDING gty_t_teacher( lt_corr02 MAPPING seniority = age EXCEPT age ). DATA(lt_teacher04) = CORRESPONDING gty_t_teacher( BASE ( lt_corr01 ) lt_corr02 MAPPING seniority = age EXCEPT age ).
6.BASE
*&---------------------------------------------------------------------- *& 5. BASE关键字 理解:避免重置 *&---------------------------------------------------------------------- *& VALUE + BASE:基于结构or内表赋值(value) *& CORRESPONDING + BASE :基于结构or内表映射(corresponding) *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student2, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID END OF gty_student2, gty_t_student2 TYPE TABLE OF gty_student2 WITH EMPTY KEY. DATA(ls_base) = VALUE gty_student2( name = 'Tom' gender = '男' age = 20 ). DATA(ls_base01) = VALUE gty_student2( name = 'Tom_01' ). "除name字段,其他字段被重置 DATA(ls_base02) = VALUE gty_student2( BASE ls_base name = 'Tom_02' id = '1000' ). "基于结构修改 DATA(lt_base) = VALUE gty_t_student2( ( ls_base01 ) ( ls_base02 ) ). DATA(lt_base01) = VALUE gty_t_student2( ( name = 'Bob' gender = '男' age = 22 ) ). DATA(lt_base02) = VALUE gty_t_student2( BASE lt_base ( name = 'Bob' gender = '男' age = 22 ) ). "保留内表进行APPEND
7.SWITCH、COND
*&---------------------------------------------------------------------- *& 6. SWITCH关键字 理解:动态赋值(单条件) *&---------------------------------------------------------------------- *& 语法:… SWITCH dtype|#( operand *& WHEN const1 THEN result1 *& [ WHEN const2 THEN result2 ] *& … *& [ ELSE resultn ] ) … *&---------------------------------------------------------------------- DATA(lv_gender) = '男'. DATA(lv_gender_en) = SWITCH char12( lv_gender "单一变量 WHEN '男' THEN 'Man' "单条件 WHEN '女' THEN 'Woman' ELSE 'Man or Woman' ). *&---------------------------------------------------------------------- *& 7. COND关键字 理解:动态赋值(多条件) *&---------------------------------------------------------------------- *& 语法:… COND type|#( WHEN log_exp1 AND log_exp2 THEN result1 *& [ WHEN log_exp3 THEN result2 ] *& … *& [ ELSE resultn ] ) … *&---------------------------------------------------------------------- DATA(lv_score) = 95. DATA(lv_level) = COND char12( WHEN lv_score >= 90 THEN '优秀' WHEN lv_score >= 80 AND lv_score < 90 THEN '良好' "多条件 WHEN lv_score >= 60 AND lv_score < 80 THEN '及格' ELSE '不及格' ).
8.LET
*&---------------------------------------------------------------------- *& 8. LET关键字 理解:临时变量 *&---------------------------------------------------------------------- *& 语法:... LET {var1 = rhs1}|{<fs1> = wrexpr1} *& {var2 = rhs2}|{<fs2> = wrexpr2} ... IN ... *& 常与VALUE,SWIDCH,COND配合使用 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student3, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 score TYPE p DECIMALS 1, "成绩 END OF gty_student3, gty_t_student3 TYPE TABLE OF gty_student3 WITH EMPTY KEY. TYPES: BEGIN OF gty_school, school(30) TYPE c, "学校 address TYPE string, "学校地址 date TYPE d, "创建日期 time TYPE t, "创建时间 END OF gty_school, gty_t_school TYPE TABLE OF gty_school WITH EMPTY KEY. TYPES: BEGIN OF lty_let, name(10) TYPE c, "姓名 gender TYPE c, "性别 gender_en(12) TYPE c, "性别英文 age TYPE i, "年龄 level(12) TYPE c, "评级 school(30) TYPE c, "学校 info TYPE string, END OF lty_let. DATA(gt_student3) = VALUE gty_t_student3( ( name = 'Tom' gender = '男' age = 20 score = '30' ) ( name = 'Jack' gender = '男' age = 25 score = '85' ) ). "Let常和Value,Swith,Cond,For等构造表达式使用 DATA(ls_let) = VALUE lty_let( LET ls_stu = VALUE #( gt_student3[ name = 'Jack' ] OPTIONAL ) ls_sch = VALUE gty_school( school = 'A' date = '20210401' time = '080000' ) l_gender_en = SWITCH char12( ls_stu-gender WHEN '男' THEN 'Man' WHEN '女' THEN 'Woman' ELSE 'Man or Woman' ) l_score = ls_stu-score l_level = COND char12( WHEN l_score >= 90 THEN '优秀' WHEN l_score >= 80 AND l_score < 90 THEN '良好' WHEN l_score >= 60 AND l_score < 80 THEN '及格' ELSE '不及格' ) l_sep = ';' l_info = 'Name:' && ls_stu-name && l_sep && 'Age:' && ls_stu-age && l_sep && 'School:' && ls_sch-school IN "************************************** name = ls_stu-name "Jack gender = ls_stu-gender "男 gender_en = l_gender_en "Man age = ls_stu-age "25 level = l_level "良好 school = ls_sch-school "A info = l_info ). "Name:Jack;Age:25;School:A
9.FOR
*&---------------------------------------------------------------------- *& 9. For关键字 理解:循环内表 *&---------------------------------------------------------------------- *& 语法:... FOR wa|<fs> IN itab [INDEX INTO idx] [cond] ... *& ... FOR var = ... [THEN expr] UNTIL|WHILE log_exp [let_exp] ... *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student5, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student5, gty_t_student5 TYPE TABLE OF gty_student5 WITH EMPTY KEY. DATA(gt_student5) = VALUE gty_t_student5( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 6 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). "FOR <stu> IN gt_student INDEX INTO lv_index WHERE ( score >= 60 ) ( <stu> ) 表示遍历gt_student内表,只选择成绩大于等于60的学生。 DATA(lt_stu05) = VALUE gty_t_student5( FOR <stu5> IN gt_student5 INDEX INTO lv_index WHERE ( score >= 60 ) ( <stu5> ) ). cl_demo_output=>display( lt_stu05 ). TYPES: BEGIN OF line, col1 TYPE i, col2 TYPE i, col3 TYPE i, END OF line, itab TYPE STANDARD TABLE OF line WITH EMPTY KEY. DATA(lt_itab01) = VALUE itab( FOR j = 11 THEN j + 10 WHILE j < 40 "初始值,递增量,结束条件 ( col1 = j col2 = j + 1 col3 = j + 2 ) ). cl_demo_output=>display( lt_itab01 ). DATA(lt_itab02) = VALUE itab( FOR j = 11 THEN j + 10 UNTIL j > 40 ( col1 = j col2 = j + 1 col3 = j + 2 ) "11 12 13 - value 到 lt_for03 "21 22 23 - value 到 lt_for03 "31 32 33 - value 到 lt_for03 "41 - 结束循环 ). cl_demo_output=>display( lt_itab02 ).
10.CONV
*&---------------------------------------------------------------------- *& 10. CONV关键字 理解:类型装换 *&---------------------------------------------------------------------- *& 语法:CONV dtype|#( … ) *&---------------------------------------------------------------------- "Variable DATA(lv_score_c) = '95.5'. DATA(lv_score_i) = CONV i( lv_score_c ). DATA(lv_score_str) = CONV string( lv_score_c ). "Function Module DATA lv_day_in(8) TYPE n VALUE '20231115'. DATA lv_day_out TYPE d. CALL FUNCTION 'SN_LAST_DAY_OF_MONTH' EXPORTING day_in = CONV d( lv_day_in ) IMPORTING end_of_month = lv_day_out. "Class DATA lv_text(255) TYPE c VALUE 'ABCDEFG'. DATA(lv_xstr) = cl_abap_codepage=>convert_to( source = CONV string( lv_text ) codepage = 'UTF-8' ).
11.REDUCE
*&---------------------------------------------------------------------- *& 11. Reduce关键字 理解:内表处理 *&---------------------------------------------------------------------- *& 语法:... 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} *& ... ) ... *& *& 处理场景:计数、求和、最大值、最小值、平均值、文本拼接等 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student6, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student6, gty_t_student6 TYPE TABLE OF gty_student6 WITH EMPTY KEY. DATA(gt_student6) = VALUE gty_t_student6( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 5 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 3 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). DATA(lv_lines) = REDUCE i( INIT lines = 0 FOR <stu1> IN gt_student6 WHERE ( gender = '女' ) NEXT lines = lines + 1 ). DATA(lv_ages) = REDUCE i( INIT ages = 0 FOR <stu2> IN gt_student6 WHERE ( gender = '女' ) NEXT ages = ages + <stu2>-age ). TYPES: BEGIN OF lty_reduce, idx TYPE i, cnt TYPE i, sum TYPE i, max TYPE i, min TYPE i, avg TYPE i, str TYPE string, END OF lty_reduce, lty_t_reduce TYPE TABLE OF lty_reduce WITH EMPTY KEY. DATA(ls_reduce) = REDUCE lty_reduce( INIT res = VALUE lty_reduce( min = 10 ) FOR <stu3> IN gt_student6 INDEX INTO idx WHERE ( gender = '女' ) NEXT res-idx = idx res-cnt = res-cnt + 1 "计数 res-sum = res-sum + <stu3>-age "求和 res-max = nmax( val1 = res-max val2 = <stu3>-age ) "最大值 res-min = nmin( val1 = res-min val2 = <stu3>-age ) "最小值 res-avg = res-sum / res-cnt "平均值 res-str = res-str && <stu3>-name && <stu3>-gender && <stu3>-age && ';' "文本拼接 ).
12.FILTER
*&---------------------------------------------------------------------- *& 12. FILTER 关键字 理解:内表过滤 *&---------------------------------------------------------------------- *& 语法:1. ... FILTER type( itab [EXCEPT] [USING KEY keyname] * WHERE c1 op f1 [AND c2 op f2 [...]] ) ... * * 2. ... FILTER type( itab [EXCEPT] IN ftab [USING KEY keyname] * WHERE c1 op f1 [AND c2 op f2 [...]] ) ... *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student7, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 END OF gty_student7. TYPES gty_t_student7 TYPE SORTED TABLE OF gty_student7 WITH NON-UNIQUE KEY gender. DATA(gt_student7) = VALUE gty_t_student7( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 5 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). DATA(lt_stu01_7) = FILTER #( gt_student7 WHERE gender = '男' ). DATA(lt_stu02_7) = FILTER #( gt_student7 EXCEPT WHERE gender = '男' )."EXCEPT:如果使用,表示排除符合条件的行。 TYPES lty_t_filter TYPE SORTED TABLE OF c WITH NON-UNIQUE KEY table_line. DATA(lt_filter) = VALUE lty_t_filter( ( '女' ) ). DATA(lt_stu03_7) = FILTER #( gt_student7 IN lt_filter WHERE gender = table_line ).
13.GROUP BY
*&---------------------------------------------------------------------- *& 13. GROUP BY 关键字 理解:内表分组 *&---------------------------------------------------------------------- *& 语法:LOOP AT itab result [cond] GROUP BY group_key *& [ASCENDING|DESCENDING [AS TEXT]] *& [WITHOUT MEMBERS] *& [group_result]. *& ... *& LOOP AT GROUP ... *& ... *& ENDLOOP.] *& ... *& ENDLOOP. *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student8, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 END OF gty_student8, gty_t_student8 TYPE TABLE OF gty_student8 WITH EMPTY KEY. DATA(gt_student8) = VALUE gty_t_student8( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). SORT gt_student8 BY score DESCENDING. "在第一个 LOOP 中,按照 gender 字段进行分组,生成 grp,然后在内部 LOOP AT GROUP 中处理每个组。 LOOP AT gt_student8 INTO DATA(gs_student8) WHERE score > 60 GROUP BY ( gender = gs_student8-gender size = GROUP SIZE "size是本组条目数量 index = GROUP INDEX ) "INDEX组索引 INTO DATA(grp). "分组处理 DATA(lt_grp_stu) = VALUE gty_t_student8( FOR ls_grp IN GROUP grp ( ls_grp ) ). LOOP AT GROUP grp ASSIGNING FIELD-SYMBOL(<fs_grp>). ENDLOOP. ENDLOOP. *------------------------------------------------------------------------------* "在第二个 LOOP 中,使用 COND 关键字自定义分组,将分组结果存储在 custom_grp 中,然后在内部 LOOP AT GROUP 中处理每个自定义组。 LOOP AT gt_student8 INTO gs_student8 WHERE score >= 60 GROUP BY "COND关键字实现自定义分组 ( text = COND string( WHEN gs_student8-score >= 60 AND gs_student8-score < 70 THEN 'GRP1_Pass' WHEN gs_student8-score >= 70 AND gs_student8-score < 80 THEN 'GRP2_Average' WHEN gs_student8-score >= 80 AND gs_student8-score < 90 THEN 'GRP3_Good' ELSE 'GRP4_Excellent' ) size = GROUP SIZE "size是本组条目数量 index = GROUP INDEX ) DESCENDING"INDEX组索引 ) INTO DATA(custom_grp). lt_grp_stu = VALUE gty_t_student8( FOR ls_grp IN GROUP custom_grp ( ls_grp ) ). "分组处理 LOOP AT GROUP custom_grp ASSIGNING FIELD-SYMBOL(<grp>). * ... ENDLOOP. ENDLOOP.
14.SEGMENT 关键字
*&---------------------------------------------------------------------- *& 14. SEGMENT 关键字 理解:字符分割 *&---------------------------------------------------------------------- *& 语法:... segment( val = text index = idx [sep|space = delim] ) ... *&---------------------------------------------------------------------- DATA lv_str TYPE string VALUE '2023/12/27'. *index:指定要获取的分割后的部分的索引。 *sep|space:可选项,指定分隔符,如果不提供,默认为单个空格。可以使用 sep 或 space 两者之一。 DATA(lv_year) = segment( val = lv_str index = 1 sep = '/' ). WRITE:/ lv_year. TRY . DATA(lv_inva_index) = segment( val = lv_str index = 4 sep = '/' ). CATCH cx_sy_strg_par_val INTO DATA(exc). WRITE:/ exc->get_text( ). ENDTRY. DO . TRY . DATA(lv_value) = segment( val = lv_str index = sy-index sep = '/' ). WRITE:/ lv_value. CATCH cx_sy_strg_par_val INTO exc. * WRITE:/ exc->get_text( ). EXIT. ENDTRY. ENDDO.
15.OPEN SQL
*&---------------------------------------------------------------------- *& 15. Open Sql Part 1 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student9, id(10) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 END OF gty_student9, gty_t_student9 TYPE TABLE OF gty_student9 WITH EMPTY KEY. DATA(gt_student9) = VALUE gty_t_student9( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). *------------------------------------------------------------------------------* DATA lv_score9 TYPE i VALUE '80.5'. SELECT id, name, score, '->' AS sep1, *&****使用常量,变量,表达式 'XUWENPAN' AS constant, @lv_score9 AS variable, @( COND #( WHEN lv_score >= 90 THEN '优秀' WHEN lv_score >= 80 AND lv_score < 90 THEN '良好' WHEN lv_score >= 70 AND lv_score < 80 THEN '中等' WHEN lv_score >= 60 AND lv_score < 70 THEN '及格' ELSE '不及格' ) ) AS expression, '-->' AS sep2 FROM @gt_student9 AS stu_info WHERE id < @( VALUE #( gt_student9[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql). cl_demo_output=>display( lt_sql ).
SELECT name, age, gender, '->' AS sep1, *&****CASE 动态赋值 (对应表达式:SWITCH ,COND ) CASE gender "switch WHEN '男' THEN 'Man' WHEN '女' THEN 'Woman' ELSE 'Man or Woman' END AS case, CASE "cond WHEN gender = '男' AND age > 13 THEN '阳光大男孩' WHEN gender = '女' AND age > 13 THEN '阳光大女孩' ELSE name && '_' && gender END AS case2, '-->' AS sep2 FROM @gt_student9 AS stu_info WHERE id < @( VALUE #( gt_student9[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql2). cl_demo_output=>display( lt_sql2 ).
TYPES: BEGIN OF gty_student10, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 date TYPE d, "入学日期 END OF gty_student10, gty_t_student10 TYPE TABLE OF gty_student10 WITH EMPTY KEY. DATA(gt_student10) = VALUE gty_t_student10( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) date = sy-datum + n ) ). SELECT id, name, gender, '->' AS sep1, *&****字符类型(连接、截取、替换、填充、移除、转换、属性、查找) "连接 concat( id , name ) AS concat, concat_with_space( id , name , 2 ) AS concat_with_space, name && '&&' && gender AS connection_symbol, "截取 left( date , 4 ) AS left, substring( date , 5 , 2 ) AS substring, right( date , 2 ) AS right, "替换 replace( gender , '男' , 'Man' ) AS replace, "填充 lpad( id , 5 , '0' ) AS lpad, rpad( id , 5 , 'X' ) AS rpad, "移除 ltrim( id , '0' ) AS ltrim, rtrim( name , '3' ) AS rtrim, "转换 upper( name ) AS upper, lower( name ) AS lower, "属性 length( date ) AS length, "查找 instr( date , '4' ) AS instr, '-->' AS sep2 FROM @gt_student10 AS stu_info WHERE id < @( VALUE #( gt_student10[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql3). cl_demo_output=>display( lt_sql3 ).
*&---------------------------------------------------------------------- *& 15. Open Sql Part 4 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student11, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 2, "成绩 date TYPE d, "入学日期 END OF gty_student11, gty_t_student11 TYPE TABLE OF gty_student11 WITH EMPTY KEY. DATA(gt_student11) = VALUE gty_t_student11( LET pre = 'Student' random2 = cl_abap_random_packed_dec2=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random2->get_next( ) date = sy-datum + n ) ). *------------------------------------------------------------------------------* SELECT id, name, '->' AS sep1, *&****数值类型(绝对值、取整、四舍五入、除法) score * -1 AS neg_score, "绝对值 abs( score * -1 ) AS abs, '->' AS sep2, score, "取整 ceil( score ) AS ceil, "向上取整 floor( score ) AS floor, "向下取整 "四舍五入 round( score , 1 ) AS round, "舍小数 round( score , -1 ) AS round2, "舍整数 '->10' AS sep3, "除法 division( 10 , 3 , 2 ) AS division, "取商:保留小数位 div( 10 , 3 ) AS div, "取商:舍去小数位 mod( 10 , 3 ) AS mod, "取余 '-->' AS sep4 FROM @gt_student11 AS stu_info WHERE id < @( VALUE #( gt_student11[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql4).
*&---------------------------------------------------------------------- *& 15. Open Sql Part 5 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student12, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 2, "成绩 date TYPE d, "入学日期 END OF gty_student12, gty_t_student12 TYPE TABLE OF gty_student12 WITH EMPTY KEY. DATA(gt_student12) = VALUE gty_t_student12( LET pre = 'Student' random2 = cl_abap_random_packed_dec2=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random2->get_next( ) date = sy-datum - n ) ). *------------------------------------------------------------------------------* SELECT id, name, date, @( sy-datum ) AS today, '->' AS sep1, *&****日期 dats_is_valid( date ) AS dats_is_valid, "日期有效性 dats_days_between( date , @sy-datum ) AS dats_days_between, "间隔天数 dats_add_days( date , 10 ) AS dats_add_days, "增加天数 dats_add_months( date , 1 ) AS dats_add_months, "增加月份 '-->' AS sep2 FROM @gt_student12 AS stu_info WHERE id < @( VALUE #( gt_student12[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql5). cl_demo_output=>display( lt_sql5 ).
*&---------------------------------------------------------------------* *& Report YTEST_ZJNEW01 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------* REPORT ytest_zjnew01. *******构建演示数据 TYPES:BEGIN OF gty_student, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student. DATA:gt_student TYPE TABLE OF gty_student, gs_student TYPE gty_student. "利用VALUE #( LET ... IN ... FOR ... )的新语法,通过循环构建了10个学生的数据, "其中LET用于定义局部变量,IN用于指定循环的范围,FOR用于循环体的执行。在循环中,使用了cl_abap_random_int类生成随机数作为学生成绩。 gt_student = VALUE #( LET pre = 'Student' "LET 定义变量 random = cl_abap_random_int=>create( min = 0 max = 100 ) IN "seed = CONV #( sy-timlo ) FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 6 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). *cl_demo_output=>display( gt_student ). ******内联声明 DATA(lv_name) = 'Tom'. "Char DATA(lv_age) = 20. "Int DATA(lv_name_str) = CONV string( 'Tom' ). "String "Read READ TABLE gt_student INTO DATA(ls_read) INDEX 1. "Loop LOOP AT gt_student INTO DATA(ls_loop). ENDLOOP. "Assign ASSIGN lv_name TO FIELD-SYMBOL(<assign>). "Loop assign LOOP AT gt_student ASSIGNING FIELD-SYMBOL(<loop>). ENDLOOP. "Single field SELECT SINGLE carrname FROM scarr INTO @DATA(lv_carrname). "Multiple fields SELECT SINGLE carrid,carrname FROM scarr INTO @DATA(ls_scarr). "Internal table SELECT carrid,carrname FROM scarr INTO TABLE @DATA(lt_scarr) UP TO 10 ROWS. "Class parameters cl_gui_frontend_services=>get_ip_address( RECEIVING ip_address = DATA(lv_ip) ). *****ITAB[ idx ]、ITAB[ key ] *&---------------------------------------------------------------------- *& 2. 内表表达式 理解:内表表达式,相当于Read Table *&---------------------------------------------------------------------- *& 语法:itab[ idx ]. *& itab[ col1 = … col2 = … ]. *&---------------------------------------------------------------------- "不存在会抛出异常(cx_sy_itab_line_not_found) IF 1 <> 1. DATA(ls_index) = gt_student[ 1 ]. "index读取 DATA(ls_key) = gt_student[ id = '0000000005' age = 15 ]. "key读取 DATA(lv_index_name) = gt_student[ 1 ]-name. "index读取结构字段 DATA(lv_key_name) = gt_student[ id = '0000000002' ]-name. "key读取字段 ENDIF. "避免抛出异常的几种方式 ASSIGN gt_student[ id = '0000000003' name = 'Student 3' ] TO FIELD-SYMBOL(<stu>). IF sy-subrc EQ 0. ENDIF. IF line_exists( gt_student[ 1 ] ). DATA(ls_stu01) = gt_student[ 1 ]. lv_name = gt_student[ 1 ]-name. ENDIF. "使用VALUE #(gt_student[11] OPTIONAL),通过OPTIONAL选项在索引越界时避免抛出异常。 "使用VALUE #(gt_student[11] DEFAULT VALUE #(id = '0000000010' name = 'Student 10')),在索引越界时提供默认值。 DATA(ls_stu02) = VALUE #( gt_student[ 11 ] OPTIONAL ). DATA(ls_stu03) = VALUE #( gt_student[ 11 ] DEFAULT VALUE #( id = '0000000010' name = 'Student 10' ) ). DATA(ls_stu04) = VALUE #( gt_student[ 11 ] DEFAULT VALUE #( gt_student[ 10 ] OPTIONAL ) ). DATA(ls_stu05) = COND #( LET c = lines( gt_student ) IN WHEN c > 10 THEN gt_student[ 11 ] ). DATA(ls_stu06) = COND #( WHEN line_exists( gt_student[ 11 ] ) THEN gt_student[ 11 ] ). TRY . DATA(ls_stu07) = gt_student[ 11 ]. CATCH cx_sy_itab_line_not_found. * WRITE : 'Not Found!'. ENDTRY. *&---------------------------------------------------------------------- *& 3. VALUE关键字 理解:赋值语句 *&---------------------------------------------------------------------- *& 语法:Variables: VALUE dtype|#( ) *& Structures: VALUE dtype|#( comp1 = a1 comp2 = a2 … ) *& Tables: VALUE dtype|#( ( … ) ( … ) ( … ) … ) *&---------------------------------------------------------------------- DATA(lv_var) = VALUE i( ). * DATA ls_stu01 TYPE gty_student. ls_stu01 = VALUE #( name = 'Tom' gender = '男' age = 20 ). ls_stu02 = VALUE gty_student( name = 'Jack' gender = '男' age = 18 ). DATA lt_stu01 TYPE TABLE OF gty_student. lt_stu01 = VALUE #( ( ls_stu01 ) ( ls_stu02 ) ( ) ( name = 'Lisa' gender = '女' age = 18 ) ). TYPES lty_t_student TYPE TABLE OF gty_student WITH EMPTY KEY. DATA(lt_stu02) = VALUE lty_t_student( ( name = 'Tom' gender = '男' age = 20 ) ( name = 'Lisa' gender = '女' age = 18 ) ). "Range:不带表头 DATA r_data TYPE RANGE OF i. r_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 ) ). "Range:带表头 RANGES: r_erdat FOR usr02-erdat. r_erdat[] = VALUE #( sign = 'I' option = 'BT' ( low = '20210101' high = '20210301' ) sign = 'E' option = 'BT' ( low = '20210201' high = '20210228' ) ). *&---------------------------------------------------------------------- *& 4. CORRESPONDING关键字 理解:字段映射 *&---------------------------------------------------------------------- *& 语法:… CORRESPONDING dtype|#( [BASE ( base )] struct|itab [mapping|except] ) *& 后缀:MAPPING 映射字段,注意避免dump; *& EXCEPT 排除映射字段 *&---------------------------------------------------------------------- TYPES: * BEGIN OF gty_student, * name(10) TYPE c, "姓名 * gender TYPE c, "性别 * age TYPE i, "年龄 * id(10) TYPE n , "学生ID * class(10) TYPE c, "班级 * score TYPE p DECIMALS 1, "成绩 * level(10) TYPE c, "级别 * ispass TYPE c, "是否通过 * END OF gty_student, gty_t_student TYPE TABLE OF gty_student WITH EMPTY KEY. TYPES: BEGIN OF gty_teacher, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 seniority TYPE i, "工龄 office(12) TYPE c, "办公室 END OF gty_teacher, gty_t_teacher TYPE TABLE OF gty_teacher WITH EMPTY KEY. "初始结构数据 DATA(ls_corr01) = VALUE gty_teacher( name = 'Tom' gender = '男' age = 20 office = '101办公室' seniority = 10 ). DATA(ls_corr02) = VALUE gty_student( name = 'Lisa' gender = '女' age = 18 ). "基础 DATA(ls_teacher01) = ls_corr01. DATA(ls_teacher02) = ls_corr01. ls_teacher01 = CORRESPONDING gty_teacher( ls_corr02 ). "无BASE,无映射字段,置初始值 ls_teacher02 = CORRESPONDING gty_teacher( BASE ( ls_corr01 ) ls_corr02 ). "无映射字段,保留原值(同MOVE-CORRESPONDING ... to ...) "后缀 "使用ls_teacher03 = CORRESPONDING gty_teacher( ls_corr02 MAPPING seniority = age EXCEPT age ).,通过MAPPING指定映射关系,EXCEPT排除不需要映射的字段。 DATA(ls_teacher03) = CORRESPONDING gty_teacher( ls_corr02 MAPPING seniority = age EXCEPT age ). DATA(ls_teacher04) = CORRESPONDING gty_teacher( BASE ( ls_corr01 ) ls_corr02 MAPPING seniority = age EXCEPT age ). *------------------------------------* "初始化内表数据 DATA(lt_corr01) = VALUE gty_t_teacher( ( name = 'Tom' gender = '男' age = 20 office = '101办公室' seniority = 10 ) ( name = 'Tom2' gender = '男' age = 21 office = '102办公室' seniority = 11 ) ( name = 'Tom3' gender = '男' age = 22 office = '103办公室' seniority = 12 ) ). DATA(lt_corr02) = VALUE gty_t_student( ( name = 'Lisa' gender = '女' age = 18 ) ( name = 'Lisa2' gender = '女' age = 19 ) ). "基础 DATA(lt_teacher01) = lt_corr01. DATA(lt_teacher02) = lt_corr01. lt_teacher01 = CORRESPONDING gty_t_teacher( lt_corr02 ). "无BASE,清空原表数据,映射赋值 lt_teacher02 = CORRESPONDING gty_t_teacher( BASE ( lt_corr01 ) lt_corr02 ). "有BASE,保留内表数据,映射APPEND "后缀 DATA(lt_teacher03) = CORRESPONDING gty_t_teacher( lt_corr02 MAPPING seniority = age EXCEPT age ). DATA(lt_teacher04) = CORRESPONDING gty_t_teacher( BASE ( lt_corr01 ) lt_corr02 MAPPING seniority = age EXCEPT age ). *&---------------------------------------------------------------------- *& 5. BASE关键字 理解:避免重置 *&---------------------------------------------------------------------- *& VALUE + BASE:基于结构or内表赋值(value) *& CORRESPONDING + BASE :基于结构or内表映射(corresponding) *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student2, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID END OF gty_student2, gty_t_student2 TYPE TABLE OF gty_student2 WITH EMPTY KEY. DATA(ls_base) = VALUE gty_student2( name = 'Tom' gender = '男' age = 20 ). DATA(ls_base01) = VALUE gty_student2( name = 'Tom_01' ). "除name字段,其他字段被重置 DATA(ls_base02) = VALUE gty_student2( BASE ls_base name = 'Tom_02' id = '1000' ). "基于结构修改 DATA(lt_base) = VALUE gty_t_student2( ( ls_base01 ) ( ls_base02 ) ). DATA(lt_base01) = VALUE gty_t_student2( ( name = 'Bob' gender = '男' age = 22 ) ). DATA(lt_base02) = VALUE gty_t_student2( BASE lt_base ( name = 'Bob' gender = '男' age = 22 ) ). "保留内表进行APPEND *&---------------------------------------------------------------------- *& 6. SWITCH关键字 理解:动态赋值(单条件) *&---------------------------------------------------------------------- *& 语法:… SWITCH dtype|#( operand *& WHEN const1 THEN result1 *& [ WHEN const2 THEN result2 ] *& … *& [ ELSE resultn ] ) … *&---------------------------------------------------------------------- DATA(lv_gender) = '男'. DATA(lv_gender_en) = SWITCH char12( lv_gender "单一变量 WHEN '男' THEN 'Man' "单条件 WHEN '女' THEN 'Woman' ELSE 'Man or Woman' ). *&---------------------------------------------------------------------- *& 7. COND关键字 理解:动态赋值(多条件) *&---------------------------------------------------------------------- *& 语法:… COND type|#( WHEN log_exp1 AND log_exp2 THEN result1 *& [ WHEN log_exp3 THEN result2 ] *& … *& [ ELSE resultn ] ) … *&---------------------------------------------------------------------- DATA(lv_score) = 95. DATA(lv_level) = COND char12( WHEN lv_score >= 90 THEN '优秀' WHEN lv_score >= 80 AND lv_score < 90 THEN '良好' "多条件 WHEN lv_score >= 60 AND lv_score < 80 THEN '及格' ELSE '不及格' ). *&---------------------------------------------------------------------- *& 8. LET关键字 理解:临时变量 *&---------------------------------------------------------------------- *& 语法:... LET {var1 = rhs1}|{<fs1> = wrexpr1} *& {var2 = rhs2}|{<fs2> = wrexpr2} ... IN ... *& 常与VALUE,SWIDCH,COND配合使用 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student3, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 score TYPE p DECIMALS 1, "成绩 END OF gty_student3, gty_t_student3 TYPE TABLE OF gty_student3 WITH EMPTY KEY. TYPES: BEGIN OF gty_school, school(30) TYPE c, "学校 address TYPE string, "学校地址 date TYPE d, "创建日期 time TYPE t, "创建时间 END OF gty_school, gty_t_school TYPE TABLE OF gty_school WITH EMPTY KEY. TYPES: BEGIN OF lty_let, name(10) TYPE c, "姓名 gender TYPE c, "性别 gender_en(12) TYPE c, "性别英文 age TYPE i, "年龄 level(12) TYPE c, "评级 school(30) TYPE c, "学校 info TYPE string, END OF lty_let. DATA(gt_student3) = VALUE gty_t_student3( ( name = 'Tom' gender = '男' age = 20 score = '30' ) ( name = 'Jack' gender = '男' age = 25 score = '85' ) ). "Let常和Value,Swith,Cond,For等构造表达式使用 DATA(ls_let) = VALUE lty_let( LET ls_stu = VALUE #( gt_student3[ name = 'Jack' ] OPTIONAL ) ls_sch = VALUE gty_school( school = 'A' date = '20210401' time = '080000' ) l_gender_en = SWITCH char12( ls_stu-gender WHEN '男' THEN 'Man' WHEN '女' THEN 'Woman' ELSE 'Man or Woman' ) l_score = ls_stu-score l_level = COND char12( WHEN l_score >= 90 THEN '优秀' WHEN l_score >= 80 AND l_score < 90 THEN '良好' WHEN l_score >= 60 AND l_score < 80 THEN '及格' ELSE '不及格' ) l_sep = ';' l_info = 'Name:' && ls_stu-name && l_sep && 'Age:' && ls_stu-age && l_sep && 'School:' && ls_sch-school IN "************************************** name = ls_stu-name "Jack gender = ls_stu-gender "男 gender_en = l_gender_en "Man age = ls_stu-age "25 level = l_level "良好 school = ls_sch-school "A info = l_info ). "Name:Jack;Age:25;School:A *&---------------------------------------------------------------------- *& 9. For关键字 理解:循环内表 *&---------------------------------------------------------------------- *& 语法:... FOR wa|<fs> IN itab [INDEX INTO idx] [cond] ... *& ... FOR var = ... [THEN expr] UNTIL|WHILE log_exp [let_exp] ... *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student5, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student5, gty_t_student5 TYPE TABLE OF gty_student5 WITH EMPTY KEY. DATA(gt_student5) = VALUE gty_t_student5( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 6 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). "FOR <stu> IN gt_student INDEX INTO lv_index WHERE ( score >= 60 ) ( <stu> ) 表示遍历gt_student内表,只选择成绩大于等于60的学生。 DATA(lt_stu05) = VALUE gty_t_student5( FOR <stu5> IN gt_student5 INDEX INTO lv_index WHERE ( score >= 60 ) ( <stu5> ) ). * cl_demo_output=>display( lt_stu05 ). TYPES: BEGIN OF line, col1 TYPE i, col2 TYPE i, col3 TYPE i, END OF line, itab TYPE STANDARD TABLE OF line WITH EMPTY KEY. DATA(lt_itab01) = VALUE itab( FOR j = 11 THEN j + 10 WHILE j < 40 "初始值,递增量,结束条件 ( col1 = j col2 = j + 1 col3 = j + 2 ) ). * cl_demo_output=>display( lt_itab01 ). DATA(lt_itab02) = VALUE itab( FOR j = 11 THEN j + 10 UNTIL j > 40 ( col1 = j col2 = j + 1 col3 = j + 2 ) "11 12 13 - value 到 lt_for03 "21 22 23 - value 到 lt_for03 "31 32 33 - value 到 lt_for03 "41 - 结束循环 ). * cl_demo_output=>display( lt_itab02 ). *&---------------------------------------------------------------------- *& 10. CONV关键字 理解:类型装换 *&---------------------------------------------------------------------- *& 语法:CONV dtype|#( … ) *&---------------------------------------------------------------------- "Variable DATA(lv_score_c) = '95.5'. DATA(lv_score_i) = CONV i( lv_score_c ). DATA(lv_score_str) = CONV string( lv_score_c ). "Function Module DATA lv_day_in(8) TYPE n VALUE '20231115'. DATA lv_day_out TYPE d. CALL FUNCTION 'SN_LAST_DAY_OF_MONTH' EXPORTING day_in = CONV d( lv_day_in ) IMPORTING end_of_month = lv_day_out. "Class DATA lv_text(255) TYPE c VALUE 'ABCDEFG'. DATA(lv_xstr) = cl_abap_codepage=>convert_to( source = CONV string( lv_text ) codepage = 'UTF-8' ). *&---------------------------------------------------------------------- *& 11. Reduce关键字 理解:内表处理 *&---------------------------------------------------------------------- *& 语法:... 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} *& ... ) ... *& *& 处理场景:计数、求和、最大值、最小值、平均值、文本拼接等 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student6, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 ispass TYPE c, "是否通过 END OF gty_student6, gty_t_student6 TYPE TABLE OF gty_student6 WITH EMPTY KEY. DATA(gt_student6) = VALUE gty_t_student6( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 5 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n < 3 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). DATA(lv_lines) = REDUCE i( INIT lines = 0 FOR <stu1> IN gt_student6 WHERE ( gender = '女' ) NEXT lines = lines + 1 ). DATA(lv_ages) = REDUCE i( INIT ages = 0 FOR <stu2> IN gt_student6 WHERE ( gender = '女' ) NEXT ages = ages + <stu2>-age ). TYPES: BEGIN OF lty_reduce, idx TYPE i, cnt TYPE i, sum TYPE i, max TYPE i, min TYPE i, avg TYPE i, str TYPE string, END OF lty_reduce, lty_t_reduce TYPE TABLE OF lty_reduce WITH EMPTY KEY. DATA(ls_reduce) = REDUCE lty_reduce( INIT res = VALUE lty_reduce( min = 10 ) FOR <stu3> IN gt_student6 INDEX INTO idx WHERE ( gender = '女' ) NEXT res-idx = idx res-cnt = res-cnt + 1 "计数 res-sum = res-sum + <stu3>-age "求和 res-max = nmax( val1 = res-max val2 = <stu3>-age ) "最大值 res-min = nmin( val1 = res-min val2 = <stu3>-age ) "最小值 res-avg = res-sum / res-cnt "平均值 res-str = res-str && <stu3>-name && <stu3>-gender && <stu3>-age && ';' "文本拼接 ). *&---------------------------------------------------------------------- *& 12. FILTER 关键字 理解:内表过滤 *&---------------------------------------------------------------------- *& 语法:1. ... FILTER type( itab [EXCEPT] [USING KEY keyname] * WHERE c1 op f1 [AND c2 op f2 [...]] ) ... * * 2. ... FILTER type( itab [EXCEPT] IN ftab [USING KEY keyname] * WHERE c1 op f1 [AND c2 op f2 [...]] ) ... *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student7, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 END OF gty_student7. TYPES gty_t_student7 TYPE SORTED TABLE OF gty_student7 WITH NON-UNIQUE KEY gender. DATA(gt_student7) = VALUE gty_t_student7( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 5 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). DATA(lt_stu01_7) = FILTER #( gt_student7 WHERE gender = '男' ). DATA(lt_stu02_7) = FILTER #( gt_student7 EXCEPT WHERE gender = '男' )."EXCEPT:如果使用,表示排除符合条件的行。 TYPES lty_t_filter TYPE SORTED TABLE OF c WITH NON-UNIQUE KEY table_line. DATA(lt_filter) = VALUE lty_t_filter( ( '女' ) ). DATA(lt_stu03_7) = FILTER #( gt_student7 IN lt_filter WHERE gender = table_line ). *&---------------------------------------------------------------------- *& 13. GROUP BY 关键字 理解:内表分组 *&---------------------------------------------------------------------- *& 语法:LOOP AT itab result [cond] GROUP BY group_key *& [ASCENDING|DESCENDING [AS TEXT]] *& [WITHOUT MEMBERS] *& [group_result]. *& ... *& LOOP AT GROUP ... *& ... *& ENDLOOP.] *& ... *& ENDLOOP. *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student8, name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 id(10) TYPE n , "学生ID class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 level(10) TYPE c, "级别 END OF gty_student8, gty_t_student8 TYPE TABLE OF gty_student8 WITH EMPTY KEY. DATA(gt_student8) = VALUE gty_t_student8( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). SORT gt_student8 BY score DESCENDING. "在第一个 LOOP 中,按照 gender 字段进行分组,生成 grp,然后在内部 LOOP AT GROUP 中处理每个组。 LOOP AT gt_student8 INTO DATA(gs_student8) WHERE score > 60 GROUP BY ( gender = gs_student8-gender size = GROUP SIZE "size是本组条目数量 index = GROUP INDEX ) "INDEX组索引 INTO DATA(grp). "分组处理 DATA(lt_grp_stu) = VALUE gty_t_student8( FOR ls_grp IN GROUP grp ( ls_grp ) ). LOOP AT GROUP grp ASSIGNING FIELD-SYMBOL(<fs_grp>). ENDLOOP. ENDLOOP. *------------------------------------------------------------------------------* "在第二个 LOOP 中,使用 COND 关键字自定义分组,将分组结果存储在 custom_grp 中,然后在内部 LOOP AT GROUP 中处理每个自定义组。 LOOP AT gt_student8 INTO gs_student8 WHERE score >= 60 GROUP BY "COND关键字实现自定义分组 ( text = COND string( WHEN gs_student8-score >= 60 AND gs_student8-score < 70 THEN 'GRP1_Pass' WHEN gs_student8-score >= 70 AND gs_student8-score < 80 THEN 'GRP2_Average' WHEN gs_student8-score >= 80 AND gs_student8-score < 90 THEN 'GRP3_Good' ELSE 'GRP4_Excellent' ) size = GROUP SIZE "size是本组条目数量 index = GROUP INDEX ) DESCENDING"INDEX组索引 ) INTO DATA(custom_grp). lt_grp_stu = VALUE gty_t_student8( FOR ls_grp IN GROUP custom_grp ( ls_grp ) ). "分组处理 LOOP AT GROUP custom_grp ASSIGNING FIELD-SYMBOL(<grp>). * ... ENDLOOP. ENDLOOP. *&---------------------------------------------------------------------- *& 14. SEGMENT 关键字 理解:字符分割 *&---------------------------------------------------------------------- *& 语法:... segment( val = text index = idx [sep|space = delim] ) ... *&---------------------------------------------------------------------- DATA lv_str TYPE string VALUE '2023/12/27'. *index:指定要获取的分割后的部分的索引。 *sep|space:可选项,指定分隔符,如果不提供,默认为单个空格。可以使用 sep 或 space 两者之一。 DATA(lv_year) = segment( val = lv_str index = 1 sep = '/' ). *WRITE:/ lv_year. TRY . DATA(lv_inva_index) = segment( val = lv_str index = 4 sep = '/' ). CATCH cx_sy_strg_par_val INTO DATA(exc). * WRITE:/ exc->get_text( ). ENDTRY. DO . TRY . DATA(lv_value) = segment( val = lv_str index = sy-index sep = '/' ). * WRITE:/ lv_value. CATCH cx_sy_strg_par_val INTO exc. * WRITE:/ exc->get_text( ). EXIT. ENDTRY. ENDDO. *&---------------------------------------------------------------------- *& 15. Open Sql Part 1 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student9, id(10) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 END OF gty_student9, gty_t_student9 TYPE TABLE OF gty_student9 WITH EMPTY KEY. DATA(gt_student9) = VALUE gty_t_student9( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) ) ). *------------------------------------------------------------------------------* DATA lv_score9 TYPE i VALUE '80.5'. SELECT id, name, score, '->' AS sep1, *&****使用常量,变量,表达式 'XUWENPAN' AS constant, @lv_score9 AS variable, @( COND #( WHEN lv_score >= 90 THEN '优秀' WHEN lv_score >= 80 AND lv_score < 90 THEN '良好' WHEN lv_score >= 70 AND lv_score < 80 THEN '中等' WHEN lv_score >= 60 AND lv_score < 70 THEN '及格' ELSE '不及格' ) ) AS expression, '-->' AS sep2 FROM @gt_student9 AS stu_info WHERE id < @( VALUE #( gt_student9[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql). *cl_demo_output=>display( lt_sql ). SELECT name, age, gender, '->' AS sep1, *&****CASE 动态赋值 (对应表达式:SWITCH ,COND ) CASE gender "switch WHEN '男' THEN 'Man' WHEN '女' THEN 'Woman' ELSE 'Man or Woman' END AS case, CASE "cond WHEN gender = '男' AND age > 13 THEN '阳光大男孩' WHEN gender = '女' AND age > 13 THEN '阳光大女孩' ELSE name && '_' && gender END AS case2, '-->' AS sep2 FROM @gt_student9 AS stu_info WHERE id < @( VALUE #( gt_student9[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql2). *cl_demo_output=>display( lt_sql2 ). TYPES: BEGIN OF gty_student10, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 1, "成绩 date TYPE d, "入学日期 END OF gty_student10, gty_t_student10 TYPE TABLE OF gty_student10 WITH EMPTY KEY. DATA(gt_student10) = VALUE gty_t_student10( LET pre = 'Student' random = cl_abap_random_int=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random->get_next( ) date = sy-datum + n ) ). SELECT id, name, gender, '->' AS sep1, *&****字符类型(连接、截取、替换、填充、移除、转换、属性、查找) "连接 concat( id , name ) AS concat, concat_with_space( id , name , 2 ) AS concat_with_space, name && '&&' && gender AS connection_symbol, "截取 left( date , 4 ) AS left, substring( date , 5 , 2 ) AS substring, right( date , 2 ) AS right, "替换 replace( gender , '男' , 'Man' ) AS replace, "填充 lpad( id , 5 , '0' ) AS lpad, rpad( id , 5 , 'X' ) AS rpad, "移除 ltrim( id , '0' ) AS ltrim, rtrim( name , '3' ) AS rtrim, "转换 upper( name ) AS upper, lower( name ) AS lower, "属性 length( date ) AS length, "查找 instr( date , '4' ) AS instr, '-->' AS sep2 FROM @gt_student10 AS stu_info WHERE id < @( VALUE #( gt_student10[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql3). *cl_demo_output=>display( lt_sql3 ). *&---------------------------------------------------------------------- *& 15. Open Sql Part 4 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student11, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 2, "成绩 date TYPE d, "入学日期 END OF gty_student11, gty_t_student11 TYPE TABLE OF gty_student11 WITH EMPTY KEY. DATA(gt_student11) = VALUE gty_t_student11( LET pre = 'Student' random2 = cl_abap_random_packed_dec2=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random2->get_next( ) date = sy-datum + n ) ). *------------------------------------------------------------------------------* SELECT id, name, '->' AS sep1, *&****数值类型(绝对值、取整、四舍五入、除法) score * -1 AS neg_score, "绝对值 abs( score * -1 ) AS abs, '->' AS sep2, score, "取整 ceil( score ) AS ceil, "向上取整 floor( score ) AS floor, "向下取整 "四舍五入 round( score , 1 ) AS round, "舍小数 round( score , -1 ) AS round2, "舍整数 '->10' AS sep3, "除法 division( 10 , 3 , 2 ) AS division, "取商:保留小数位 div( 10 , 3 ) AS div, "取商:舍去小数位 mod( 10 , 3 ) AS mod, "取余 '-->' AS sep4 FROM @gt_student11 AS stu_info WHERE id < @( VALUE #( gt_student11[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql4). *cl_demo_output=>display( lt_sql4 ). *&---------------------------------------------------------------------- *& 15. Open Sql Part 5 *&---------------------------------------------------------------------- TYPES: BEGIN OF gty_student12, id(3) TYPE n , "学生ID name(10) TYPE c, "姓名 gender TYPE c, "性别 age TYPE i, "年龄 class(10) TYPE c, "班级 score TYPE p DECIMALS 2, "成绩 date TYPE d, "入学日期 END OF gty_student12, gty_t_student12 TYPE TABLE OF gty_student12 WITH EMPTY KEY. DATA(gt_student12) = VALUE gty_t_student12( LET pre = 'Student' random2 = cl_abap_random_packed_dec2=>create( seed = CONV #( sy-timlo ) min = 0 max = 100 ) IN FOR n = 1 UNTIL n > 10 ( id = n name = |{ pre } { n }| gender = COND #( WHEN n MOD 2 = 0 THEN '男' ELSE '女' ) age = 10 + n class = |{ n }班| score = random2->get_next( ) date = sy-datum - n ) ). *------------------------------------------------------------------------------* SELECT id, name, date, @( sy-datum ) AS today, '->' AS sep1, *&****日期 dats_is_valid( date ) AS dats_is_valid, "日期有效性 dats_days_between( date , @sy-datum ) AS dats_days_between, "间隔天数 dats_add_days( date , 10 ) AS dats_add_days, "增加天数 dats_add_months( date , 1 ) AS dats_add_months, "增加月份 '-->' AS sep2 FROM @gt_student12 AS stu_info WHERE id < @( VALUE #( gt_student12[ 6 ]-id OPTIONAL ) ) INTO TABLE @DATA(lt_sql5). cl_demo_output=>display( lt_sql5 ).
转自公众号:ABAP猿