ABAP 7.40 快速参考-新语法
- 内联声明
- 表表达式
- 转换运算符 CONV
- 值运算符 VALUE
- FOR 运算符
- 缩减运算符 REDUCE
- 条件运算符 COND 和 SWITCH
- CORRESPONDING 运算符
- 字符串
- 循环分组
- 类/方法
- 网格
- 筛选
- 文档目的
1.内联声明
7.40 之前 | 7.40 | |
数据 |
DATA text TYPE string. text = 'ABC'. |
DATA(text) = 'ABC'. |
循环进入工作区 |
DATA wa like LINE OF itab. LOOP AT itab INTO wa. ... ENDLOOP. |
LOOP AT itab INTO DATA(wa). ... ENDLOOP. |
调用方法 |
DATA a1 TYPE ... DATA a2 TYPE ... oref->meth( IMPORTING p1 = a1 IMPORTING p2 = a2 ). |
oref->meth( IMPORTING p1 = DATA(a1) IMPORTING p2 = DATA(a2) ). |
分配时循环 |
FIELD-SYMBOLS: <line> type … LOOP AT itab ASSIGNING <line>. ... ENDLOOP. |
LOOP AT itab ASSIGNING FIELD-SYMBOL(<line>). ... ENDLOOP. |
读取分配 |
FIELD-SYMBOLS: <line> type … READ TABLE itab ASSIGNING <line>. |
READ TABLE itab ASSIGNING FIELD-SYMBOL(<line>). |
选择进入表 |
DATA itab TYPE TABLE OF dbtab. SELECT * FROM dbtab INTO TABLE itab WHERE fld1 = lv_fld1. |
SELECT * FROM dbtab INTO TABLE @DATA(itab) WHERE fld1 = @lv_fld1. |
选择单进 |
SELECT SINGLE f1 f2 FROM dbtab INTO (lv_f1, lv_f2) |
SELECT SINGLE f1 AS my_f1, f2 AS abc FROM dbtab INTO DATA(ls_struct) WHERE ... WRITE: / ls_struct-my_f1, ls_struct-abc. |
2.表表达式
如果未找到表格行,则会引发异常CX_SY_ITAB_LINE_NOT_FOUND 。没有sy-subrc。
7.40 之前 | 7.40 | |
Read Table index | READ TABLE itab INDEX idx INTO wa. |
wa = itab[ idx ]. |
使用键读取表 |
READ TABLE itab INDEX idx USING KEY key INTO wa. |
|
使用 key 读取表 | READ TABLE itab WITH KEY col1 = … col2 = … INTO wa. |
wa = itab[ col1 = … col2 = … ]. |
Read Table with key components |
READ TABLE itab WITH TABLE KEY key COMPONENTS col1 = … col2 = … INTO wa. |
wa = itab[ KEY key col1 = …
col2 = … ].
|
记录存在吗?
|
READ TABLE itab ... TRANSPORTING NO FIELDS. IF sy-subrc = 0. ... ENDIF. |
IF line_exists( itab[ ... ] ). ... ENDIF. |
获取表索引 |
DATA idx type sy-tabix. READ TABLE ... TRANSPORTING NO FIELDS. idx = sy-tabix. |
DATA(idx) = line_index( itab[ ... ] ). |
注意:如果您使用引用不存在记录的内联表达式,则会出现短暂转储。SAP表示您应该分配一个字段符号并检查 sy-subrc。
ASSIGN lt_tab[ 1 ] to FIELD-SYMBOL(<ls_tab>). IF sy-subrc = 0. ... ENDIF.
注意:对于无类型表格,请使用 itab [ table_line = … ]。
一、定义
CONV dtype|#( ... )
dtype = 您想要转换的类型(显式)
# = 编译器必须使用上下文来决定要转换的类型(隐式)
示例
方法cl_abap_codepage=>convert_to需要一个字符串
5. FOR 运算符
一、定义
FOR wa|<fs> IN itab [索引到 idx] [cond]
二、解释
这实际上导致 itab 处出现循环。对于每个循环,读取的行被分配给工作区 (wa) 或字段符号 (<fs>)。
此 wa 或 <fs> 是表达式的局部变量,即,如果在子程序中声明,则变量 wa 或 <fs> 是该子程序的局部变量。循环中的索引类似于 SY-TABIX。
给定:
TYPES: BEGIN OF ty_ship, tknum TYPE tknum, "Shipment Number name TYPE ernam, "Name of Person who Created the Object city TYPE ort01, "Starting city route TYPE route, "Shipment route END OF ty_ship. TYPES: ty_ships TYPE SORTED TABLE OF ty_ship WITH UNIQUE KEY tknum. TYPES: ty_citys TYPE STANDARD TABLE OF ort01 WITH EMPTY KEY.
GT_SHIPS 类型 ty_ships.-> 已填充如下:
行 TKNUM[C(10)] 名称[C(12)] 城市[C(25)]路线[C(6)]
1 | 001 | 约翰 | 墨尔本 | R0001 |
2 | 002 | 加文 | 悉尼 | R0003 |
3 | 003 | 露西 | 阿德莱德 | R0001 |
4 | 004 | 伊莱恩 | 珀斯 | R0003 |
三. Example 1
使用 GT_SHIPS 中的城市填充内部表 GT_CITYS。
|
四. Example 2
用GT_SHIPS中路线为R0001的城市填充内表GT_CITYS。
7.40之前
DATA: gt_citys TYPE ty_citys, gs_ship TYPE ty_ship, gs_city TYPE ort01. LOOP AT gt_ships INTO gs_ship WHERE route = 'R0001'. gs_city = gs_ship-city. APPEND gs_city TO gt_citys. ENDLOOP.
7.40
DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships WHERE ( route = 'R0001' ) ( ls_ship-city ) ).
注意:ls_ship似乎没有声明,但它是隐式声明的。
V. FOR with THEN and UNTIL|WHILE
FOR i = ... [THEN expr] UNTIL|WHILE log_exp
按如下方式填充内部表:
TYPES: BEGIN OF ty_line, col1 TYPE i, col2 TYPE i, col3 TYPE i, END OF ty_line, ty_tab TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
7.40之前
DATA: gt_itab TYPE ty_tab, j TYPE i. FIELD-SYMBOLS <ls_tab> TYPE ty_line.j= 1. DO. j = j + 10. IF j > 40. EXIT. ENDIF. APPEND INITIAL LINE TO gt_itab ASSIGNING <ls_tab>. <ls_tab>-col1 = j. <ls_tab>-col2 = j + 1. <ls_tab>-col3 = j + 2. ENDDO.
7.40
DATA(gt_itab) = VALUE ty_tab( FOR j = 11 THEN j + 10 UNTIL j > 40 ( col1 = j col2 = j + 1 col3 = j + 2 ) ).
6. 缩减运算符 REDUCE
一、定义
... REDUCE 类型(
INIT 结果 = 起始值
...
对于 for_exp1
FOR for_exp2
...
下一个 ...
结果 = 迭代值
... )
二、注意事项
虽然 VALUE 和 NEW 表达式可以包含 FOR 表达式,但 REDUCE 必须至少包含一个 FOR 表达式。您可以在 REDUCE 中使用所有类型的 FOR 表达式:
- 使用 IN 迭代内部表
- 使用 UNTIL 或 WHILE 进行条件迭代
三、实施例1
计算满足条件的表格行数(字段 F1 包含“XYZ”)。
7.40 之前
DATA: lv_lines TYPE i. LOOP AT gt_itab INTO ls_itab where F1 = ‘XYZ’. lv_lines = lv_lines + 1. ENDLOOP.
7.40
DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab WHERE( F1 = ‘XYZ’ ) NEXT x = x + 1 ).
四、实施例2
对存储在表列中的值 1 到 10 求和,定义如下
DATA gt_itab TYPE STANDARD TABLE OF i WITH EMPTY KEY. gt_itab = VALUE #( FOR j = 1 WHILE j <= 10 ( j ) ).
7.40 之前
DATA: lv_line TYPE i, lv_sum TYPE i. LOOP AT gt_itab INTO lv_line. lv_sum = lv_sum + lv_line. ENDLOOP.
7.40
DATA(lv_sum) = REDUCE i( INIT x = 0 FOR wa IN itab NEXT x = x + wa ).
五、实施例3
使用类引用 - 有效,因为“write”方法返回对实例对象的引用
7.40
TYPES outref TYPE REF TO if_demo_output. DATA(output) = REDUCE outref( INIT out = cl_demo_output=>new( ) text = `Count up:` FOR n = 1 UNTIL n > 11 NEXT out = out->write( text ) text = |{ n }| ). output->display( ).
7.条件运算符 COND 和 SWITCH
一、定义
... COND dtype|#( 当 log_exp1 时则结果 1 [ 当 log_exp2 时则结果 2 ] ... [ 否则结果 n ] ) ...
... SWITCH dtype|#( 操作数WHEN const1 THEN result1 [ WHEN const2 THEN result2 ] ... [ ELSE resultn ] ) ...
二. COND 示例
DATA(time) = COND string( WHEN sy-timlo < '120000' THEN |{ sy-timlo TIME = ISO } AM| WHEN sy-timlo > '120000' THEN |{ CONV t( sy-timlo - 12 * 3600 ) TIME = ISO } PM| WHEN sy-timlo = '120000' THEN |High Noon| ELSE THROW cx_cant_be( ) ).
三、SWITCH示例
DATA(text) = NEW class( )->meth( SWITCH #( sy-langu WHEN 'D' THEN `DE` WHEN 'E' THEN `EN` ELSE THROW cx_langu_not_supported( ) ) ).
8. 对应运算符
一、定义
... 对应类型([BASE(base)] struct|itab [ mapping|except ])
二、示例代码
TYPES: BEGIN OF line1, col1 TYPE i, col2 TYPE i, END OF line1. TYPES: BEGIN OF line2, col1 TYPE i, col2 TYPE i, col3 TYPE i, END OF line2. DATA(ls_line1) = VALUE line1( col1 = 1 col2 = 2 ). WRITE: / 'ls_line1 =' ,15 ls_line1-col1, ls_line1-col2. DATA(ls_line2) = VALUE line2( col1 = 4 col2 = 5 col3 = 6 ). WRITE: / 'ls_line2 =' ,15 ls_line2-col1, ls_line2-col2, ls_line2-col3. SKIP 2. ls_line2 = CORRESPONDING #( ls_line1 ). WRITE: / 'ls_line2 = CORRESPONDING #( ls_line1 )' ,70 'Result is ls_line2 = ' ,ls_line2-col1, ls_line2-col2, ls_line2-col3.
SKIP. ls_line2 = VALUE line2( col1 = 4 col2 = 5 col3 = 6 ). "Restore ls_line2 ls_line2 = CORRESPONDING #( BASE ( ls_line2 ) ls_line1 ). WRITE: / 'ls_line2 = CORRESPONDING #( BASE ( ls_line2 ) ls_line1 )' , 70 'Result is ls_line2 = ', ls_line2-col1 , ls_line2-col2, ls_line2-col3.
SKIP. ls_line2 = VALUE line2( col1 = 4 col2 = 5 col3 = 6 ). "Restore ls_line2 DATA(ls_line3) = CORRESPONDING line2( BASE ( ls_line2 ) ls_line1 ). WRITE: / 'DATA(ls_line3) = CORRESPONDING line2( BASE ( ls_line2 ) ls_line1 )' , 70 'Result is ls_line3 = ' , ls_line3-col1 , ls_line3-col2, ls_line3-col3.
三、输出
四、解释
给定结构 ls_line1 和 ls_line2 的定义和填充如上所述。
7.40 之前 | 7.40 | |
1 |
CLEAR ls_line2. MOVE-CORRESPONDING ls_line1 TO ls_line2. |
ls_line2 = CORRESPONDING #( ls_line1 ).
|
2 |
MOVE-CORRESPONDING ls_line1 TO ls_line2. |
ls_line2 = CORRESPONDING # ( BASE ( ls_line2 ) ls_line1 ).
|
3 |
DATA: ls_line3 like ls_line2. ls_line3 = ls_line2. MOVE-CORRESPONDING ls_line1 TO ls_line2. |
DATA(ls_line3) = CORRESPONDING line2( BASE ( ls_line2 ) ls_line1 ). |
1. ls_line1 的内容将移动到具有匹配列名的 ls_line2 中。如果没有匹配,则初始化 ls_line2 的列。
2. 这将使用 ls_line2 的现有内容作为基础,并覆盖 ls_line1 中的匹配列。
这与 MOVE-CORRESPONDING 完全相同。
3. 这将创建第三个新结构 (ls_line3),它基于 ls_line2 但被
ls_line1 的匹配列覆盖。
V. 附加 MAPPING 和 EXCEPT
MAPPING 允许您映射具有非同名组件的字段以满足数据传输的条件。...
MAPPING t1 = s1 t2 = s2
EXCEPT 允许您列出必须从数据传输中排除的字段
... EXCEPT {t1 t2 ...}
9. 字符串
一、字符串模板
字符串模板由两个字符“ | ”括起来,创建一个字符串。
文字由所有不在括号 {} 中的字符组成。括号可以包含:
- 数据对象,
- 计算表达式,
- 构造函数表达式,
- 表表达式,
- 预定义函数,或
- 功能方法 和方法链
7.40 之前
DATA itab TYPE TABLE OF scarr. SELECT * FROM scarr INTO TABLE itab.
DATA wa LIKE LINE OF itab. READ TABLE itab WITH KEY carrid = 'LH' INTO wa. DATA output TYPE string. CONCATENATE 'Carrier:' wa-carrname INTO output SEPARATED BY space. cl_demo_output=>display( output ).
7.40
SELECT * FROM scarr INTO TABLE @DATA(lt_scarr). cl_demo_output=>display( |Carrier: { lt_scarr[ carrid = 'LH' ]-carrname }| ).
二. 串联
7.40 之前
DATA lv_output TYPE string. CONCATENATE 'Hello' 'world' INTO lv_output SEPARATED BY space.
7.40
DATA(lv_out) = |Hello| & | | & |world|.
三. 宽度/对齐/填充
WRITE / |{ 'Left' WIDTH = 20 ALIGN = LEFT PAD = '0' }|. WRITE / |{ 'Centre' WIDTH = 20 ALIGN = CENTER PAD = '0' }|. WRITE / |{ 'Right' WIDTH = 20 ALIGN = RIGHT PAD = '0' }|.
四、Case
WRITE / |{ 'Text' CASE = (cl_abap_format=>c_raw) }|. WRITE / |{ 'Text' CASE = (cl_abap_format=>c_upper) }|. WRITE / |{ 'Text' CASE = (cl_abap_format=>c_lower) }|.
五、 ALPHA 转换
DATA(lv_vbeln) = '0000012345'. WRITE / |{ lv_vbeln ALPHA = OUT }|. “or ALPHA = IN to go in other direction
六、日期转换
WRITE / |{ pa_date DATE = ISO }|. “Date Format YYYY-MM-DD WRITE / |{ pa_date DATE = User }|. “As per user settings WRITE / |{ pa_date DATE = Environment }|. “As per Environment
LOOP AT itab result [cond] GROUP BY key ( key1 = dobj1 key2 = dobj2 ...
[gs = GROUP SIZE] [gi = GROUP INDEX] )
[ASCENDING|DESCENDING [AS TEXT]]
[WITHOUT MEMBERS]
[{INTO group}|{ASSIGNING <group>}]
...
[LOOP AT GROUP group|<group>
...
ENDLOOP.]
...
ENDLOOP.
二.解释
外循环将对每个键执行一次迭代。因此,如果有 3 条记录与该键匹配,则这 3 条记录将只执行一次迭代。结构“group”(或 “<group>”)不同寻常,因为它可以使用“LOOP AT GROUP”语句进行循环。这将循环遍历组的 3 条记录(成员)。结构 “group”还包含当前键以及组的大小和组的索引(如果已为 GROUP SIZE 和 GROUP INDEX 分配了 字段名称)。通过一个例子可以更好地理解这一点。
TYPES: BEGIN OF ty_employee, name TYPE char30, role TYPE char30, age TYPE i, END OF ty_employee, ty_employee_t TYPE STANDARD TABLE OF ty_employee WITH KEY name. DATA(gt_employee) = VALUE ty_employee_t( ( name = 'John' role = 'ABAP guru' age = 34 ) ( name = 'Alice' role = 'FI Consultant' age = 42 ) ( name = 'Barry' role = 'ABAP guru' age = 54 ) ( name = 'Mary' role = 'FI Consultant' age = 37 ) ( name = 'Arthur' role = 'ABAP guru' age = 34 ) ( name = 'Mandy' role = 'SD Consultant' age = 64 ) ). DATA: gv_tot_age TYPE i, gv_avg_age TYPE decfloat34. "Loop with grouping on Role LOOP AT gt_employee INTO DATA(ls_employee) GROUP BY ( role = ls_employee-role size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING FIELD-SYMBOL(<group>).
CLEAR: gv_tot_age. "Output info at group level WRITE: / |Group: { <group>-index } Role: { <group>-role WIDTH = 15 }| & | Number in this role: { <group>-size }|.
"Loop at members of the group LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<ls_member>). gv_tot_age = gv_tot_age + <ls_member>-age. WRITE: /13 <ls_member>-name. ENDLOOP. "Average age gv_avg_age = gv_tot_age / <group>-size. WRITE: / |Average age: { gv_avg_age }|. SKIP. ENDLOOP.
四、输出
Group: 1 Role: ABAP guru Number in this role: 3
John
Barry
Arthur
Average age: 40.66666666666666666666666666666667
Group: 2 Role: FI Consultant Number in this role: 2
Alice
Mary
Average age: 39.5
Group: 3 Role: SD Consultant Number in this role: 1
Mandy
Average age: 64
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示