NEW,构造类对象,即类的实例,适用于定义了构造方法的类实例化。
VALUE 赋值,根据被赋值对象的数据类型来赋值(value #(…));或者赋值时指定具体的数据类型(value dtype)。 语法: ① 结构赋值:value dtype/#( [BASE dobj] comp1 = v1 comp2 = v2 … ). ② 内表赋值:value dtype/#( [BASE itab] ( line1_comp1 = dobj1 line1_comp2 = dobj2 … ) ( … ) ( … ) ).
CORRESPONDING 赋值,匹配不同结构中的同名字段进行赋值,或者是依据映射表MAPPING 进行赋值。 语法:toobj = corresponding dtype/#( [BASE dobj] fromobj MAPPING comp1 = v1 comp2 = v2 … Except compX …).
代码语言:javascript复制*&---------------------------------------------------------------------*
*& Report Y_NEW_SYNTAX
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_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( ).
****************************************************
* 5、Reduce 汇总求和 ( ≥ 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
"不有非数字,补前导0至40位,物料标准转换例程为补前导0至18位,故这个方法不适合物料补前导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.
"物料标准转换例程,不含非数字,则补前导0至18位
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为负,则从右数。
* 值1、2、....表示第一,第二,事件。取值为-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( ).