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猿

 

posted @ 2024-01-19 11:10  阿胖的阿多  阅读(632)  评论(0编辑  收藏  举报