[SAP Abap] X-DOC: Colección de nuevos ejemplos de sintaxis de SAP ABAP

X-DOC: Colección de nuevos ejemplos de sintaxis de SAP ABAP

1. Declaración en línea

(1) Escenarios aplicables:

  • Definir variables
  • definir estructura
  • Definir tabla interna
  • Definir objeto
  • definir puntero

(2) Sintaxis de declaración:

  • DATOS(…)
  • SÍMBOLO DE CAMPO(<…>)

2. Construir expresiones

(1) Escenarios aplicables:

  • Construir un valor único
  • Construir estructura
  • Construir mesa interna
  • Construir objeto de clase

(2) Tipo:

  • NUEVO, construye un objeto de clase, es decir, una instancia de una clase, y es adecuado para la creación de instancias de clases que definen un método de construcción.

  • Asignación de VALOR, asigne un valor de acuerdo con el tipo de datos del objeto asignado (valor #(...)); o especifique un tipo de datos específico (valor dtype) al asignar el valor.
    Sintaxis:
    ① Asignación de estructura: valor dtype/#( [BASE dobj] comp1 = v1 comp2 = v2 … )
    ② Asignación de tabla interna: valor dtype/#( [BASE itab] ( line1_comp1 = dobj1 line1_comp2 = dobj2 … ) ( … ) (…)).

  • Asignación CORRESPONDIENTE, coincidencia de campos con el mismo nombre en diferentes estructuras para asignación, o asignación basada en tabla de mapeo MAPPING.
    Sintaxis: toobj = correspondiente dtype/#( [BASE dobj] fromobj MAPPING comp1 = v1 comp2 = v2… Excepto compX…).

  • FILTER filtrado interno de la tabla

  • REDUCIR Resumen

  • CAMBIAR

  • COND.

3. Demostración

*&---------------------------------------------------------------------*
*& Report Y_XLEVON_NEW_SYNTAX
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_xlevon_new_syntax.

****************************************************
*   1、内联声明  DATA(...),FIELD-SYMBOL(...)
****************************************************
*1)赋值动态声明变量:系统根据所赋的值来确定变量类型及数据长度
DATA(gv_str) = 'hello xlevon'.    " C(12)
DATA(gv_int) = 1024.              " I(4)
DATA(gr_container) = NEW cl_gui_custom_container( container_name = 'cust_container').   " 类实例

*2)SELECT动态声明内表/结构/变量:组件类型与 SELECT LIST 对应一致
SELECT carrid, carrname FROM scarr UP TO 2 ROWS
INTO TABLE @DATA(gt_scarr).  " 内表

SELECT SINGLE carrid, carrname FROM scarr
INTO @DATA(gw_scarr).        " 结构

SELECT COUNT(*) FROM scarr
INTO @DATA(gv_count).        " 变量

*3)LOOP动态声明结构/指针
LOOP AT gt_scarr INTO DATA(ls_scarr).   " 工作区结构
  ...
ENDLOOP.
LOOP AT gt_scarr ASSIGNING FIELD-SYMBOL(<fs_scarr>).  " 工作区指针
  ...
ENDLOOP.

*4)READ TABLE动态声明结构/指针
READ TABLE gt_scarr INTO DATA(lw_scarr) WITH KEY carrid = 'AA'.   " 工作区结构
READ TABLE gt_scarr ASSIGNING FIELD-SYMBOL(<fw_scarr>) WITH KEY carrid = 'AA'.    " 工作区指针

*5)调用类方法时动态声明(输出)对象
cl_salv_table=>factory(
  IMPORTING
    r_salv_table = DATA(lr_table)   " 类实例
  CHANGING
    t_table = gt_scarr[]
).


****************************************************
*   2、VALUE 赋值
****************************************************
TYPES: BEGIN OF ty_person,
         code TYPE char4,
         name TYPE char20,
       END OF ty_person,
       tty_person TYPE TABLE OF ty_person.

* 以下演示结构赋值及操作
DATA(gr_output) = cl_demo_output=>new( )->next_section( |一、VALUE 赋示例| ).
gr_output->next_section( |1、VALUE 结构赋值| ).

*1)VALUE dtype/# 结构赋值
DATA(gw_person1) = VALUE ty_person( code = '1000' name = 'XLevon' ).
*gr_output->write( gw_person1 ).

DATA gw_person2 TYPE ty_person.
gw_person2 = VALUE #( code = '2000' name = 'XLevon' ).  " 初始赋值
gr_output->write( gw_person2 ).

*2)使用 VALUE 赋值,默认会覆盖原有数据
gw_person2 = VALUE #( name = 'Leo' ).                   " 重新赋值,原值被清空,code变为空
gr_output->write( gw_person2 ).

*3)使用 VALUE 和 BASE 赋值
gw_person2 = VALUE #( BASE gw_person2 code = '2000' ).  " 更新,name保留原值
gr_output->write( gw_person2 ).

*4)使用 LET 引入临时变量,只能在当前语句中使用
*   LET关键字可以使用在VALUE,SWITCH,COND等语句中
*   与 FOR 语句类似,LET 语句中定义的临时变量同样只能在当前语句中使用
DATA(gw_person3) = VALUE ty_person( LET
                                    let_name = gw_person2-name && '-let'   " 临时变量
                                    IN
                                    code = '3000'
                                    name = let_name  ).    " 引用临时变量
gr_output->write( gw_person3 ).

* 以下演示内表赋值及操作
gr_output->next_section( |2、VALUE 内表赋值| ).

*5)VALUE 内表赋值
DATA: gt_person TYPE tty_person.
gt_person = VALUE #( ( gw_person1 ) ).              " 赋值
gt_person = VALUE #( BASE gt_person ( gw_person2 )  " 相当于在原来内表上 append line
                      ( code = '3000' name = 'L' ) ).

*6)使用 VALUE 追加数据 & 更新数据
APPEND VALUE #( code = '4000' name = 'X' ) TO gt_person.  " 相当于向内表追加(由VALUE构造的)结构
MODIFY gt_person FROM VALUE #( name = 'XLevon' )          " 相当于从(由VALUE构造的)结构更新内表
      TRANSPORTING name WHERE name EQ 'X'.                " 限定更新字段name及更新条件
gr_output->write( gt_person ).

*7)FOR 循环:从其他内表中批量引入数据
TYPES: BEGIN OF ty_person_for,
         index TYPE int4.
         INCLUDE TYPE ty_person.
TYPES: END OF ty_person_for,
tty_person_for TYPE TABLE OF ty_person_for WITH EMPTY KEY. " 或者:WITH DEFAULT KEY

DATA(gt_person_xlevon_with_index) =
  VALUE tty_person_for(       "备注:定义的表类型需要 WITH KEY
    FOR lw_ps IN gt_person    " 临时变量,遍历行工作区
    INDEX INTO lv_i           " 临时变量,当前遍历行
    WHERE ( name = 'XLevon' ) " 备注:此处必须有小括号
    (
      index = CONV #( lv_i )  " 引用行号
      code = lw_ps-code       " 引用工作区
      name = lw_ps-name
    )
  ).
gr_output->write( gt_person_xlevon_with_index ).

DATA(gt_person_xlevon_corresspond) =
  VALUE tty_person_for(        "备注:定义的表类型需要有 WITH KEY
    FOR lw_ps IN gt_person
    WHERE ( name = 'XLevon' )
    ( CORRESPONDING #( lw_ps ) ) " 部分字段匹配赋值,未匹配的保持为空
  ).
gr_output->write( gt_person_xlevon_corresspond ).

DATA(gt_person_for_then_def) = VALUE tty_person_for(
  FOR i = 1 WHILE i < lines( gt_person )   " 默认:then i + 1
  (
    index = i    " 当前FOR循环的i
    code = gt_person[ i ]-code
    name = gt_person[ i ]-name
  )
).
gr_output->write( gt_person_for_then_def ).

DATA(gt_person_for_then_2) = VALUE tty_person_for(
  FOR i = 1 THEN i + 2 WHILE i < lines( gt_person )
  ( CORRESPONDING #( gt_person[ i ] ) )
).
gr_output->write( gt_person_for_then_2 ).


* 以下演示内表读取及操作
gr_output->next_section( |3、内表读取| ).
*8)读取内表
TRY.
    DATA(gw_person_index) = gt_person[ 1 ].           " Index:从1开始,超出会dump
    gr_output->write( gw_person_index ).
  CATCH cx_sy_itab_line_not_found INTO DATA(cx).
*    gr_output->write( cx->get_text( ) ).
ENDTRY.

" 取出符合件的第一条记录,取不到则为空值
DATA(gw_person_name) = VALUE #( gt_person[ name = 'XLevon' ] OPTIONAL ).
gr_output->write( gw_person_name ).

* 读取不到时赋默认值
DATA(gw_ps_def) = VALUE ty_person( code = '0000' name = 'I am XLevon' )..
DATA(gw_person_def) = VALUE #( gt_person[ code = '11' ] DEFAULT gw_ps_def ).
gr_output->write( gw_person_def ).

*gr_output->display( ).

****************************************************
*   3、CORRESPONDING 赋值
* 语法:CORRESPONDING dtype/#( [BASE ( base )] struct|itab [mapping] )
****************************************************
*  结构赋值语句,CORRESPONDING语句允许控制组件映射关系。
*  在ABAP 7.40之前,主要通过 MOVE-CORRESPONDING 来传递结构化数据,
*  但需要保持结构内部组件名称一致,否则数据将不会被传递,
*  而使用 CORRESPONDING 后,该语句在保持同名组件自动进行数据传递的基础上,
*  MAPPING 可以允许我们将不同名称的组件映射到一起,
*  EXCEPT 可以规避掉我们不需要传值的一些字段

*gr_output = cl_demo_output=>new( )->next_section( |二、CORRESPONDING 使用示例| ).
gr_output->next_section( |二、CORRESPONDING 使用示例| ).
gr_output->next_section( |1、CORRESPONDING 结构赋值| ).

TYPES:BEGIN OF ty_person2,
        code TYPE char4,
        name TYPE char10,
        age  TYPE i,
      END OF ty_person2.

DATA(ls_p1) = VALUE ty_person( code = '1000' name = 'XLevon' ).
DATA(ls_p2) = VALUE ty_person2( code = '2000' name = 'Leo' age = 16 ).
gr_output->write( ls_p1 ).
gr_output->write( ls_p2 ).

ls_p2 = CORRESPONDING #( ls_p1 ).   " 此时 ls_p2-age = 0 在赋值过程中被覆盖
gr_output->write( ls_p2 ).

ls_p2  =  VALUE ty_person2( code = '2000' name = 'Leo' age = 16 ).
ls_p2 = CORRESPONDING #( BASE ( ls_p2 ) ls_p1 ).   "此时 ls_p2-age = 16 未被覆盖
gr_output->write( ls_p2 ).

ls_p2  =  VALUE ty_person2( code = '2000' name = 'Leo' age = 16 ).
DATA(ls_p3) = CORRESPONDING ty_person2( BASE ( ls_p2 ) ls_p1 ).  " 同上
gr_output->write( ls_p3 ).

gr_output->next_section( |2、CORRESPONDING MAPPING 结构赋值| ).

DATA:BEGIN OF customer_crm,
       code TYPE char10 VALUE '1000001000',
       name TYPE char35 VALUE 'XLevon',
       BEGIN OF information,
         company_code       TYPE char4 VALUE '1000',
         sales_organization TYPE char4 VALUE '1010',
         country            TYPE char3 VALUE 'CN',
       END OF information,
     END OF customer_crm,

     BEGIN OF customer_sap,
       kunnr TYPE kna1-kunnr,
       name1 TYPE kna1-name1,
       BEGIN OF info,
         bukrs TYPE knb1-bukrs,
         vkorg TYPE knvv-vkorg,
         land1 TYPE kna1-land1,
       END OF info,
     END OF customer_sap.

"两个名字不相同的工作区相互赋值
customer_sap = CORRESPONDING #(
  customer_crm
  MAPPING kunnr = code name1 = name
    (
      info = information
      MAPPING
      bukrs = company_code
      vkorg = sales_organization
      land1 = country
    )
  ).
gr_output = gr_output->write( customer_crm ).
gr_output = gr_output->write( customer_sap ).

gr_output->next_section( |3、CORRESPONDING 嵌套表赋值| ).
*在 MAPPING 语句中,需要注意两边的字段类型,以免类型不兼容而导致程序 dump。
* 使用DEEP处理深层结构数据,相当于MOVE CORRESPONDING [ EXPANDING NESTED TABLES ]* 使用BASE保留初始数据,
* 为结构赋值时类似于 VALUE [ BASE ]* 为内表赋值时相当于 MOVE CORRESPONDING [ KEEPING TARGET LINES ]

DATA: BEGIN OF gs_emps,
        dept      TYPE char10,
        t_persons TYPE TABLE OF ty_person,
        count     TYPE i VALUE 0,
      END OF gs_emps,
      gt_emps LIKE TABLE OF gs_emps.

TYPES: BEGIN OF ty_sales,
         code       TYPE char4,
         sales_name TYPE char20,    " 字段名不同,需要mapping
       END OF ty_sales.

DATA: BEGIN OF gs_sales,
        dept      TYPE char10,
        t_persons TYPE TABLE OF ty_sales,
        count     TYPE i VALUE 0,
      END OF gs_sales,
      gt_sales   LIKE TABLE OF gs_sales,
      gt_sales_b LIKE TABLE OF gs_sales.

gt_person = VALUE #( ( code = '1000' name = 'XLevon' ) ( code = '2000' name = 'Leo' ) ).

gs_sales = VALUE #( dept = 'SALES-A' count = 2
                    t_persons = CORRESPONDING #( gt_person MAPPING sales_name = name ) ).
gs_emps = CORRESPONDING #( gs_sales
                          MAPPING ( t_persons = t_persons MAPPING name = sales_name )
                          EXCEPT dept ).    " 结构赋值
gr_output = gr_output->write( gs_sales ).   " mapping
gr_output = gr_output->write( gs_emps ).    " except dept

gt_sales = VALUE #( ( gs_sales ) ).
gt_emps = CORRESPONDING #( gt_sales
                          MAPPING ( t_persons = t_persons MAPPING name = sales_name ) ).  " 内表赋值

gt_sales_b = VALUE #( ( dept = 'DEPT-B' count = 1
                        t_persons = VALUE #( ( code = '3000' sales_name = 'L' ) ) ) ).
gt_emps = CORRESPONDING #(  BASE ( gt_emps )      " 保留原有数据
                            gt_sales_b            " 追加新数据
                            MAPPING ( t_persons = t_persons MAPPING name = sales_name )
                            EXCEPT dept ).  " 内表赋值
gr_output = gr_output->write( gt_sales ).
gr_output = gr_output->write( gt_emps ).   " except dept

gr_output->next_section( |4、CORRESPONDING 内表更新| ).
*CORRESPONDING中可以从两个内表中引入数据,FORM子句后的内表结构需要定义为排序表或哈希表
* 该语法不能与DEEP/BASE关键字同时使用,但是可以使用MAPPING/EXCEPT
* 如下例所示,以表1为基表,根据USING定义的关联条件去表2查找数据,如果查找到,
* 则将表2的该条数据复写到表1对应的记录上并返回,否则直接返回表1的数据
* MAPPING/EXCEPT作用于表2数据复写到表1对应记录的过程中,特定条件下可以用来实现读取数据
* 并更新内表的操作,但是需要定义非标准表,有一定的局限性

TYPES:BEGIN OF ty_data_a,
        index TYPE i,
        text1 TYPE char1,
        text2 TYPE char1,
        text3 TYPE char1,
      END OF ty_data_a,
      BEGIN OF ty_data_b,
        id    TYPE i,
        text1 TYPE char1,
        text2 TYPE char1,
        char3 TYPE char1,
      END OF ty_data_b.

DATA: lt_tmp1            TYPE SORTED TABLE OF ty_data_a WITH UNIQUE KEY index,
      "TYPE STANDARD TABLE OF ty_data_a WITH EMPTY KEY,
      lt_tmp2            TYPE SORTED TABLE OF ty_data_b WITH UNIQUE KEY id,     " TYPE HASHED TABLE
      lt_data            TYPE TABLE OF ty_data_a,
      lt_data_map_except TYPE TABLE OF ty_data_a.

lt_tmp1 = VALUE #( FOR i = 1 UNTIL i > 4 ( index = i text1 = 'L' ) ).   " 默认 THEN i + 1
lt_tmp2 = VALUE #( text2 = 'E' char3 = 'O' ( id = 2 ) ( id = 3 ) ).

"按照using后条件对应,from后表的数据传递给前表
lt_data = CORRESPONDING #( lt_tmp1 FROM lt_tmp2 USING id = index ).
"可以使用mapping和except
lt_data_map_except = CORRESPONDING #( lt_tmp1 FROM lt_tmp2 USING id = index
                                      MAPPING text3 = char3 EXCEPT text1 ).

gr_output = gr_output->write( lt_tmp1 ).
gr_output = gr_output->write( lt_tmp2 ).
gr_output = gr_output->write( lt_data ).
gr_output = gr_output->write( lt_data_map_except ).

*gr_output->display( ).


****************************************************
*   4、内表筛选 Filter
****************************************************
gr_output->next_section( |三、Filter 使用示例| ).
gr_output->next_section( |1、排序表赋值(自动排序)| ).

*定义数据类型
*TYPES tty_person2 TYPE TABLE OF ty_person WITH DEFAULT KEY.

*  初始化内表
" 需要是排序表或者哈希表
TYPES: ty_sorted_tab TYPE SORTED TABLE OF ty_person WITH NON-UNIQUE KEY code.

DATA(gt_person_sorted) = VALUE ty_sorted_tab(
                                ( code = '1000' name = 'XLevon1' )
                                ( code = '3000' name = 'XLevon3' )
                                ( code = '2000' name = 'XLevon2' ) ).
gr_output->write( gt_person_sorted ).   " 输出时已经排序

*  直接Filter WHERE code = '1000'
DATA(gt_person_1000) = FILTER #( gt_person_sorted WHERE code = '1000' ).
gr_output->next_section( |1.1、直接 WHERE code = '1000'| )->write( gt_person_1000 ).

*  使用except语句 EXCEPT WHERE code = '1000'
DATA(gt_person_except_1000) = FILTER #( gt_person_sorted EXCEPT WHERE code = '1000').
gr_output->next_section( |1.2、使用 EXCEPT WHERE code = '1000'| )->write( gt_person_except_1000 ).

*  标准表赋值
TYPES: ty_std_tab TYPE STANDARD TABLE OF ty_person
             WITH NON-UNIQUE SORTED KEY cod COMPONENTS code.
DATA gt_person_std TYPE ty_std_tab.
gt_person_std  = VALUE #(
                    ( code = '1000' name = 'XLevon1' )
                    ( code = '3000' name = 'XLevon3' )
                    ( code = '2000' name = 'XLevon2' ) ).
gr_output->next_section( |2、标准表赋值(无排序)| )->write( gt_person_std ).

*  标准表filter USING KEY cod WHERE code = '01'
DATA(gt_person2_1000) = FILTER #( gt_person_std USING KEY cod WHERE code = '1000').
gr_output->next_section( |2.1、标准表 USING KEY| )->write( gt_person2_1000 ).

*  标准表except语句 EXCEPT USING KEY cod  WHERE code = '01'
DATA(gt_person2_except_1000) = FILTER #( gt_person_std EXCEPT USING KEY cod  WHERE code = '1000').
gr_output->next_section( |2.2、标准表 EXCEPT USING KEY| )->write( gt_person2_except_1000 ).

*  使用多个值筛选
DATA it_codes TYPE SORTED TABLE OF ty_person-code WITH NON-UNIQUE KEY table_line.
it_codes = VALUE #( ( '1000' ) ( '3000' ) ).
DATA(gt_person_cond) = FILTER #( gt_person_std IN it_codes WHERE code = table_line ).
gr_output->next_section( |3.1、使用单个关键字多个值筛选 IN| )->write( gt_person_cond ).

DATA(gt_person_exept_cond) = FILTER #( gt_person_std EXCEPT IN it_codes WHERE code = table_line ).
gr_output->next_section( |3.2、使用单个关键字多个值筛选 EXCEPT IN| )->write( gt_person_exept_cond ).

*  使用多个关键字筛选
TYPES: ty_filter_tab TYPE HASHED TABLE OF ty_person WITH UNIQUE KEY code name.
DATA(lt_filter) = VALUE ty_filter_tab(
                      ( code = '1000' name  ='XLevon1' )
                      ( code = '3000' name = 'XLevon3' )  ).
gr_output->next_section( |4、使用多个关键字的行记录筛选| )->write( lt_filter ).

DATA(gt_person2_cond) = FILTER #( gt_person_std IN lt_filter
                              WHERE code = code AND name = name ).
gr_output->next_section( |4.1、使用多个关键字的行记录筛选 IN| )->write( gt_person2_cond ).

*    排除
DATA(gt_person2_except_cond) = FILTER #( gt_person_std EXCEPT IN lt_filter
                              WHERE code = code AND name = name ).
gr_output->next_section( |4.2、使用多个关键字的行记录筛选 EXCEPT IN| )->write( gt_person2_except_cond ).

*  显示数据
*gr_output->display( ).


****************************************************
*   5Reduce 汇总求和 ( ≥ NW 7.40****************************************************
gr_output->next_section( |四、REDUCE 使用示例| ).

*  数字汇总
DATA(lv_sum) = REDUCE i( INIT s = 0 FOR  i = 1 UNTIL i > 10 NEXT s += i ).
gr_output->next_section( |1、简单汇总| )->write( lv_sum ).

*   字符串连接
DATA(lv_str) = REDUCE string( INIT st = |数字连接:|
                           FOR i = 10 THEN i - 1 UNTIL i = 0  " 或者: while i > 0
                           NEXT st = st && |{
    
     i }| ).
gr_output->next_section( |2、字符串连接| )->write( lv_str ).

*   内表汇总
TYPES: tty_30 TYPE TABLE OF i WITH EMPTY KEY.
DATA(itab31) = VALUE tty_30( FOR j = 1 WHILE j <= 10 ( j ) ).
DATA(it_sum) = REDUCE i( INIT x = 0 FOR ls_tab IN itab31 NEXT x = x + ls_tab ).
gr_output->next_section( |3、内表| )->write( itab31 ).
gr_output->next_section( |4、内表汇总| )->write( it_sum ).

*  复杂汇总
TYPES:BEGIN OF ty_031,
        code  TYPE char2,
        group TYPE char1,
        quan  TYPE i,
      END OF ty_031.
DATA itab32 TYPE TABLE OF ty_031
      WITH NON-UNIQUE SORTED KEY grp COMPONENTS group       " 按照group汇总时需要
      WITH NON-UNIQUE SORTED KEY cod COMPONENTS code group. " 按照code和group汇总时需要

itab32 = VALUE #( ( code = '1' group = 'A' quan = 1 )
                  ( code = '1' group = 'A' quan = 3 )
                  ( code = '3' group = 'A' quan = 2 )
                  ( code = '2' group = 'C' quan = 4 )
                  ( code = '2' group = 'A' quan = 5 )
                  ( code = '3' group = 'B' quan = 8 )
                  ( code = '3' group = 'A' quan = 4 )
                  ( code = '1' group = 'C' quan = 2 ) ).
gr_output->next_section( |5、复杂汇总-示例表| )->write( itab32 ).

*  按照group汇总
DATA itabg TYPE TABLE OF ty_031.
LOOP AT itab32 INTO DATA(ls_itab32).
  DATA(lscheck) = VALUE #( itabg[ group = ls_itab32-group ] OPTIONAL ).
  IF lscheck IS NOT INITIAL.
    CONTINUE.
  ENDIF.

  DATA(ls_itabg) = ls_itab32.
  CLEAR:ls_itabg-code.
  ls_itabg-quan = REDUCE i(
    INIT sum = 0
    FOR ls IN FILTER #( itab32 USING KEY grp WHERE group = ls_itabg-group )
    NEXT sum += ls-quan ).
  APPEND ls_itabg TO itabg.
ENDLOOP.
gr_output->next_section( |5.1、按照group汇总| )->write( itabg ).

*  按照 code 和 group 汇总
DATA itabcg TYPE TABLE OF ty_031.
CLEAR: lscheck, ls_itabg.
LOOP AT itab32 INTO ls_itab32.
  lscheck = VALUE #( itabcg[ code = ls_itab32-code group = ls_itab32-group ] OPTIONAL ).
  IF lscheck IS NOT INITIAL.
    CONTINUE.
  ENDIF.

  ls_itabg = ls_itab32.
  ls_itabg-quan = REDUCE i(
    INIT sum = 0
    FOR ls IN FILTER #( itab32 USING KEY cod WHERE code = ls_itabg-code AND group = ls_itabg-group )
    NEXT sum += ls-quan ).
  APPEND ls_itabg TO itabcg.
ENDLOOP.
gr_output->next_section( |5.2、按照 code 和 group 汇总| )->write( itabcg ).

*  显示数据
*gr_output->display( ).

****************************************************
*   6、SWITCH、COND 赋值
****************************************************
gr_output->next_section( |五、SWITCH、COND 赋值| ).
gr_output->next_section( |1、SWITCH 赋值| ).

* 1)SWITCH
*  SWITCH动态赋值语句,通常根据同一变量的不同数据来动态处理,用法类似于 CASE 语句。
DATA(number) = SWITCH string( sy-index
                              WHEN 1 THEN 'one'
                              WHEN 2 THEN 'two'
                              WHEN 3 THEN 'three'
                              ELSE 'unkown' ).  "THROW cx_overflow( ) ).
gr_output->write( number ).

DATA(lv_indicator) = 1.
DATA(lv_day1) = SWITCH char10( lv_indicator
                              WHEN 1 THEN 'MONDAY'
                              WHEN 2 THEN 'TUESDAY'
                              WHEN 3 THEN 'WEDNESDAY'
                              WHEN 4 THEN 'THURSDAY'
                              WHEN 5 THEN 'FRIDAY'
                              WHEN 6 THEN 'SATURDAY'
                              WHEN 7 THEN 'SUNDAY'
                              ELSE '404' && '-ERROR'
                             ).
gr_output->write( lv_day1 ).

* 23)COND
*COND动态赋值语句,可以根据不同条件来动态处理,用法类似于CASE/IF语句。
*COND语句中允许使用较为复杂的判断条件,因此VALUE语句中动态赋值通常会使用COND。
lv_indicator = 7.
DATA(lv_day7) = COND char10( WHEN lv_indicator = 1 THEN 'MONDAY'
                            WHEN lv_indicator = 2 THEN 'TUESDAY'
                            WHEN lv_indicator = 3 THEN 'WEDNESDAY'
                            WHEN lv_indicator = 4 THEN 'THURSDAY'
                            WHEN lv_indicator = 5 THEN 'FRIDAY'
                            WHEN lv_indicator = 6 THEN 'SATURDAY'
                            WHEN lv_indicator = 7 AND sy-langu EQ 'E' THEN 'SUNDAY'
                            WHEN lv_indicator = 7 AND sy-langu EQ 'F' THEN 'DIMANCHE'
                            WHEN lv_indicator = 7 AND sy-langu EQ '1' THEN '星期天'
                            ELSE '404' && '-ERROR'
                           ).
gr_output->next_section( |2、COND 赋值| )->write( lv_day7 ).

*gr_output->display( ).

****************************************************
*   7、其他
****************************************************
* 1)前导零处理
DATA:lv_matnr1 TYPE matnr VALUE 'X999',
     lv_matnr2 TYPE matnr VALUE '999',
     lv_matnr6 TYPE matnr,
     lv_matnr7 TYPE matnr.

* Width/Alignment/Padding 宽度/对齐/填充
"按指定宽度(18)位置(RIGHT)填充指定字符(0),不管是否含非数字
DATA(lv_matnr3) = |{
    
     lv_matnr1  WIDTH = 18 ALIGN = RIGHT PAD = '0' }|.
DATA(lv_matnr4) = |{
    
     lv_matnr1 ALPHA = IN }|.           "含有非数字,不补前导0
"不有非数字,补前导040位,物料标准转换例程为补前导018位,故这个方法不适合物料补前导0
DATA(lv_matnr5) = |{
    
     lv_matnr2 ALPHA = IN }|.

"物料标准转换例程,含有非数字,不做转换
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
  EXPORTING
    input        = lv_matnr1
  IMPORTING
    output       = lv_matnr6
  EXCEPTIONS
    length_error = 1
    OTHERS       = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

"物料标准转换例程,不含非数字,则补前导018位
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
  EXPORTING
    input        = lv_matnr2
  IMPORTING
    output       = lv_matnr7
  EXCEPTIONS
    length_error = 1
    OTHERS       = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

DATA(lv_matnr8) = |{
    
     lv_matnr7 ALPHA = OUT }|.
DATA(lv_matnr9) = lv_matnr7.
SHIFT lv_matnr9 LEFT DELETING LEADING '0'.  "去前导0

WRITE / : '非纯数字物料号:lv_matnr1:' && lv_matnr1 ,
          '纯数字物料号:lv_matnr2:' && lv_matnr2 ,
          'WIDTH ALIGN PAD lv_matnr3:' && lv_matnr3 ,
          'ALPHA = IN lv_matnr4:' && lv_matnr4 ,
          'ALPHA = IN lv_matnr5:' && lv_matnr5 ,
          'CONVERSION_EXIT_MATN1_INPUT lv_matnr6:' && lv_matnr6 ,
          'CONVERSION_EXIT_MATN1_INPUT lv_matnr7:' && lv_matnr7 ,
          'ALPHA = OUT lv_matnr8:' && lv_matnr8 ,
          'SHIFT LEFT DELETING LEADING lv_matnr9:' && lv_matnr9 .

* 2) 日期格式
WRITE / : ,
|ISO日期:{
    
     sy-datum DATE = ISO }|,                "Date Format YYYY-MM-DD
|USER日期:{
    
     sy-datum DATE = USER }|,              "As per user settings
|ENVIRONMENT日期:{
    
     sy-datum DATE = ENVIRONMENT }|."Formatting setting of language environment

* 3)字符串内表拼接
TYPES: BEGIN OF ty_test,
         code TYPE char4,
         name TYPE char10,
       END OF ty_test,
       tty_test TYPE TABLE OF ty_test.
DATA: gt_test  TYPE tty_test,
      lt_split LIKE gt_test.
gt_test = VALUE #( ( code = '10' name = 'Leo' )
                   ( code = '20' name = 'XLevon' )
                   ( code = '30' name = 'Leo' )
                   ( code = '40' name = 'XLevon' ) ).

DATA(lv_concat_lines) = concat_lines_of( table = gt_test  sep = '/' ).  " 内表拼接为字符串
SPLIT lv_concat_lines AT '/' INTO TABLE lt_split.    " 字符串拆分成内表

WRITE / : ,'concat_lines_of:'&& lv_concat_lines.
LOOP AT lt_split ASSIGNING FIELD-SYMBOL(<fs_split>).
  WRITE / : 'SPLIT-' && sy-tabix && ':' && <fs_split>-code && ':'&& <fs_split>-name.
ENDLOOP.

* 4)LINES、LINE_INDEX、LINE_EXISTS
*  LINES 计算内表总行数。
*  LINE_EXISTS 判断根据特定条件能否在内表中读取到记录,返回值为布尔型数据。使用此语法,可判断内表中行是否有满足条件的,无需LOOP判断,省去好多代码。
*  LINE_INDEX 获取内表中满足特定条件的记录所在的行数( INDEX ),如果存在多个条件值,则只会返回第一个搜索到的值的行数。
DATA(lv_lines) = lines( gt_test ).
DATA(lv_index) = line_index( gt_test[ code = '20' name = 'XLevon' ] ).
DATA(lv_exist) = xsdbool( line_exists( gt_test[ code = '20' name = 'XLevon' ] ) ).
IF line_exists( gt_test[ code = '20' name = 'XLevon' ] ).
  DATA(ls_data) = gt_test[ code = '20' name = 'XLevon' ]. "取该行数据
  WRITE / : ,'从' && lv_lines && '条记录中找到第' && lv_index && '条数据为:', ls_data.
ENDIF.

* 5||{
    
    }&&的使用
*  || 里面内容除{
    
    }内的原样输出,包括空格;
*  || 里面可以使用{
    
    }引入ABAP代码
WRITE / : , |有空格: {
    
     gt_test[ name = 'XLevon' ]-code }| ,   " 空格会保留
'没空格: '&& gt_test[ name = 'XLevon' ]-code  .   " 空格被忽略

* 6)REPLACE
*  如果occ为正,则从左边开始计数;如果occ为负,则从右数。
*12....表示第一,第二,事件。取值为-1-2....表示最后一个,倒数第二个,。
DATA(lv_string1) = 'XLevon'.
DATA(lv_string2) = 'Leo'..
DATA(lv_string3) = replace(   val = lv_string1
                               sub = 'Lev'
                               case = abap_true
                               with = to_upper( lv_string2 ) "如果发现sta,用lv_string2的大写替换
                               occ = 1   "val中只有1处为sub
                            ).
WRITE / : , '替换后的字符串:' &&  lv_string3.

* 7)CASE TYPE OF dobj
TRY.
    DATA(lv_value) = 10 / 0.
    WRITE: / , '10 / 0,触发错误:'.
  CATCH cx_root INTO DATA(exc).
    CASE TYPE OF exc.
      WHEN TYPE cx_sy_arithmetic_error.
        WRITE: 'Arithmetic error' .
      WHEN TYPE cx_sy_conversion_error.
        WRITE:  'Conversion error' .
      WHEN OTHERS.
        WRITE:  'Other error' .
    ENDCASE.
ENDTRY.

* 8)GROUP BY分组循环
*  分组处理,不像at end of 那样需要调整字段顺序
gr_output->next_section( |六、其他| )->next_section( |1、GROUP BY分组| ).

DATA lt_groupby_name LIKE gt_test.
LOOP AT gt_test INTO DATA(ls_test)
  GROUP BY ( name = ls_test-name )
  ASCENDING INTO DATA(lt_group).
  "组内循环
  LOOP AT GROUP lt_group INTO DATA(ls_group).
    APPEND ls_group TO lt_groupby_name.
  ENDLOOP.
  gr_output->write( lt_groupby_name ).
  CLEAR lt_groupby_name[].
ENDLOOP.

* 9)GROUP BY SWITCH 动态条件分组。
gr_output->next_section( |2、GROUP BY SWITCH 动态条件分组| ).

SELECT
  code, name,
  CASE WHEN code IN ('10', '20') THEN 'A' ELSE 'B' END AS group
  FROM @gt_test AS t
  INTO TABLE @DATA(gt_group).

DATA lt_groupby_switch LIKE gt_group.
DATA: lv_switch_field TYPE c VALUE 'B'.
LOOP AT gt_group ASSIGNING FIELD-SYMBOL(<fs_group>)
  GROUP BY SWITCH string( lv_switch_field
      WHEN 'A' THEN |name = {
    
     <fs_group>-name }|
      WHEN 'B' THEN |group = {
    
     <fs_group>-group }| )
*  GROUP BY ( group = <fs_group>-group )    " 等同
    ASSIGNING FIELD-SYMBOL(<ls_group>).
  LOOP AT GROUP <ls_group> ASSIGNING FIELD-SYMBOL(<fs1>).
    APPEND <fs1> TO lt_groupby_switch.
  ENDLOOP.
  gr_output->write( lt_groupby_switch ).
  CLEAR lt_groupby_switch[].
ENDLOOP.

gr_output->display( ).

Artículo original, indique la fuente al reimprimir - Expediente X

Supongo que te gusta

Origin blog.csdn.net/XLevon/article/details/129232646
Recomendado
Clasificación