科莱特教育

 找回密码
 立即注册
查看: 3322|回复: 0

ABAP 内表与内表结构

[复制链接]

11

主题

11

帖子

35

积分

新手上路

Rank: 1

积分
35
发表于 2020-12-31 08:07:31 | 显示全部楼层 |阅读模式
ABAP 开发系列(05): ABAP 内表与内表结构2.内表和内表结构
2.1  结构体(Structure)
2.1.1 结构体的定义
ABAP 中可以定义结构来包含多个基本类型,便于整理及操作;
结构体不属于数据字典对象(数据字典中可以定义结构体,但不能存储数据),在程序运行时会被作为临时对象存储在内存空间;
在创建内表时,可参考直接定义的结构体作为内表结构
结构体的定义,可以通过两种方式实现:


1.第一种方式
语法:

DATA:  BEGIN OF <name>
<field1> . . .
<field2> . . .
. . .
END OF <name>.

如:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em][size=1em]TABLES: TABNA.

[size=1em]DATA: BEGIN OF ADDRESS,
[size=1em]       FLAG   TYPE C,
[size=1em]       ID     LIKE TABNA-ID,
[size=1em]       NAME1  LIKE TABNA-NAME1,
[size=1em]       CITY   LIKE TABNA-CITY,
[size=1em]      END OF ADDRESS.

[size=1em]* 为结构体字段赋值
[size=1em]  MOVE 'X'            TO ADDRESS-FLAG.
[size=1em]  MOVE '0001'         TO ADDRESS-ID.
[size=1em]  MOVE 'Smith'        TO ADDRESS-NAME1.
[size=1em]  MOVE 'Philadelphia' TO ADDRESS-CITY.

[size=1em]  WRITE ADDRESS.




2.第二种方式
语法:

TYPES: BEGIN OF <name1>,
<field1> . . . ,
<field2> . . . ,
. . .  ,
END OF <name1>.
DATA: <name2> TYPE <name1>.
如:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em][size=1em]TYPES: BEGIN OF ADDR,
[size=1em]        FLAG,
[size=1em]        ID      LIKE EMPLOYEE-ID,
[size=1em]        NAME1   LIKE EMPLOYEE-NAME1,
[size=1em]        CITY    LIKE EMPLOYEE-CITY,
[size=1em]       END OF ADDR.

[size=1em]DATA: ADDRESS TYPE ADDR.

[size=1em]MOVE:  'X'            TO ADDRESS-FLAG,
[size=1em]       '00001'        TO ADDRESS-ID,
[size=1em]       'Smith'        TO ADDRESS-NAME1,
[size=1em]       'Philadelphia' TO ADDRESS-CITY.

[size=1em]WRITE ADDRESS.




2.1.2  结构体的赋值
相同结构体之间可以通过 MOVE … TO … 语句进行赋值;
如若存在类型差异的结构体,则可以通过 MOVE-CORRESSPONDING … TO … 语句将两个结构体之间相同字段自动匹配赋值:

                               
登录/注册后可看大图
与基本变量定义类似,结构体的初始化操作也可以通过 CLEAR 语句实现。
如:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em]18

[size=1em][size=1em]TABLES: employee.

[size=1em]DATA: BEGIN OF address,
[size=1em]        flag,
[size=1em]        id      LIKE employee-id,
[size=1em]        name    LIKE employee-name1,
[size=1em]        city    LIKE employee-city,
[size=1em]      END OF ADDRESS.

[size=1em]SELECT * FROM employee.

[size=1em]     MOVE-CORRESPONDING employee TO address.

[size=1em]     WRITE: / address-flag,  address-id,
[size=1em]            address-name, address-city.

[size=1em]     CLEAR address.
[size=1em]ENDSELECT.




2.2  内表(Internal Table)
内表与结构体基本类似,同样在程序运行过程中存储在临时创建的内存空间,它是一个可以存储多条记录的数据表。

2.2.1 内表的定义
通过关键字DATA定义内表,可以直接参考结构体或者其他内表及透明表结构,也可以直接定义结构字段。
语法:
①.DATA <NAME> TYPE <STRUCTURE>        WITH [UNIQUE|NON-UNIQUE] [INITIAL SIZE n] [WITH HEADER LINE].
②.DATA <NAME> LIKE TABLE OF <TABLE> WITH [UNIQUE|NON-UNIQUE] [INITIAL SIZE n] [WITH HEADER LINE].
③.DATA: BEGIN OF itab OCCURS n,
<field>
<field>
END OF itab.

其中,关键字说明如下:
[UNIQUE|NON-UNIQUE]: 指定关键字,只用于排序表,使用NON-UNIQUE关键字的话,排序表数据记录允许重复关键字字段;
[INITIAL SIZE n]:指定初始化内表大小,比较少用,一般默认即可;
[WITH HEADER LINE]: 定义内表是否带表头;

[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em]18

[size=1em]19

[size=1em]20

[size=1em]21

[size=1em]22

[size=1em]23

[size=1em]24

[size=1em]25

[size=1em]26

[size=1em]27

[size=1em]28

[size=1em]29

[size=1em]30

[size=1em]31

[size=1em]32

[size=1em]33

[size=1em]34

[size=1em]35

[size=1em]36

[size=1em]37

[size=1em][size=1em]*--------------------------------------------------------------------*
[size=1em]* 通过定义结构体并参考该结构定义内表
[size=1em]*--------------------------------------------------------------------*
[size=1em]TABLES: employee.                           "参考某一透明表,必须先引用定义

[size=1em]TYPES:  BEGIN OF emp,
[size=1em]         id          LIKE employee-id,
[size=1em]         name1       LIKE employee-name1,
[size=1em]         country     LIKE employee-country,
[size=1em]        END OF emp.

[size=1em]*--------------------------------------------------------------------*
[size=1em]* 参考EMP 结构定义一个初始化大小为10,并有HEADER LINE的内表
[size=1em]*--------------------------------------------------------------------*
[size=1em]DATA: emptab TYPE STANDARD TABLE OF emp INITIAL SIZE 10 WITH HEADER LINE.


[size=1em]*--------------------------------------------------------------------*
[size=1em]* 参考EMPTAB内表,重新定义没有HEADER LINE的内表
[size=1em]*--------------------------------------------------------------------*
[size=1em]DATA: emptab_n LIKE STANDARD TABLE OF emptab.


[size=1em]*--------------------------------------------------------------------*
[size=1em]* 定义一个允许重复KEY,并且没有HEADER LINE的排序表
[size=1em]*--------------------------------------------------------------------*
[size=1em]DATA: emptab_s TYPE SORT TABLE OF emp WITH NON-UNIQUE KEY id.


[size=1em]*--------------------------------------------------------------------*
[size=1em]* 通过第三种方式定义的内表,可指定具体字段,默认内表存在HEADER LINE
[size=1em]*--------------------------------------------------------------------*
[size=1em]TYPES:  BEGIN OF emp OCCURS 0,
[size=1em]          id         LIKE employee-id,
[size=1em]          name1      LIKE employee-name1,
[size=1em]          country    LIKE employee-country,
[size=1em]        END OF emp.




2.2.2  内表有无 HEADER LINE 的区别
对于有HEADER LINE的内表,可以通过填充HEADER LINE数据后或通过 外部Work Area 向内表存储空间中追加数据。

                               
登录/注册后可看大图

对于没有HEADER LINE的内表,只能通过 外部Work Area来传递数据:

                               
登录/注册后可看大图
语法:
①.APPEND [<Work Area> INTO] <ITAB>.
如:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em]18

[size=1em]19

[size=1em]20

[size=1em]21

[size=1em]22

[size=1em]23

[size=1em]24

[size=1em]25

[size=1em]26

[size=1em][size=1em]TABLES: employee.

[size=1em]TYPES: BEGIN OF emp,
[size=1em]    id  LIKE employee-id,
[size=1em]    name1   LIKE employee-name1,
[size=1em]    country LIKE employee-country,
[size=1em]       END OF emp.

[size=1em]* 有 HEADER LINE 的内表
[size=1em]DATA: emptab  TYPE STANDARD TABLE OF emp INITIAL SIZE 10 WITH HEADER LINE.

[size=1em]* 没有 HEADER LINE 的内表
[size=1em]DATA: emptab2 TYPE STANDARD TABLE OF emp INITIAL SIZE 10,        

[size=1em]* Work Area
[size=1em]      emptab_wa TYPE emp.                                                                          

[size=1em]SELECT * FROM employee.

[size=1em]    MOVE-CORRESPONDING employee TO emptab.
[size=1em]    APPEND emptab.

[size=1em]    MOVE-CORRESPONDING employee TO emptab_wa.
[size=1em]    APPEND emptab_wa TO emptab2.

[size=1em]ENDSELECT.




由于没有HEADER LINE的内表通过Work Area 传递数据在性能上会优于HEADER LINE直接填充HEADER LINE,
所以,一般基本都使用没有 HEADER LINE 的内表。
除非一些特殊情况,才会使用 HEADER LINE 内表。


2.2.3 内表数据处理
1. 遍历读取内表数据 (LOOP … ENDLOOP.)
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em][size=1em]LOOP AT emptab WHERE country BETWEEN ‘A’ AND ‘D’.

[size=1em]     WRITE:  / emptab-country, emptab-name1, emptab-sales.

[size=1em]ENDLOOP.

[size=1em]IF sy-subrc NE 0.  

[size=1em]     WRITE: / ‘NO ENTRIES’.  

[size=1em]ENDIF.




解析:
a.LOOP 语句后,允许使用WHERE语句筛选数据。
b.程序中,出现 sy-subrc 变量,这是系统全局变量,用于检查是否符合条件,
如若符合条件 sy-subrc 返回0 ,如果不符合,则返回4.

2. 读取内表数据 (READ TABLE …)
在数据内表,可以通过READ TABLE关键字根据具体行数或主键字段读取内表中的某行记录:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em][size=1em]TABLES: employee.

[size=1em]TYPES:  BEGIN OF emp,
[size=1em]         country     LIKE employee-country,
[size=1em]         name1       LIKE employee-name1,
[size=1em]        END OF emp.

[size=1em]DATA: emptab TYPE STANDARD TABLE OF emp INITIAL SIZE 10 WITH HEADER LINE.

[size=1em]SELECT * FROM EMPLOYEE.

[size=1em]    MOVE-CORRESPONDING employeeTO emptab.
[size=1em]    APPEND EMPTAB.

[size=1em]ENDSELECT.

[size=1em]READ TABLE ….




READ TABLE 选项:
1) READ TABLE <EMPTAB>.
2) READ TABLE <EMPTAB>  WITH KEY <k1> = <v1>…  <kn> = <vn>.
3) READ TABLE <EMPTAB>  WITH TABLE KEY <k1> = <v1> …  <kn> = <vn>.
4) READ TABLE <EMPTAB>  WITH KEY  = <value>.
5) READ TABLE <EMPTAB>  WITH KEY . . .  BINARY SEARCH.
6) READ TABLE <EMPTAB>  INDEX <i>.
7) READ TABLE <EMPTAB> COMPARING <f1> <f2> . . . .
8) READ TABLE <EMPTAB> COMPARING ALL FIELDS.
9) READ TABLE <EMPTAB> TRANSPORTING <f1> <f2> . . . .
10) READ TABLE <EMPTAB> TRANSPORTING NO FIELDS.

关键字说明:
[KEY|TABLE KEY]: 通过内表的主键字段查找
[BINARY SEARCH]: 二分法查找,使用该方法时,在READ TABLE之前,必须对内表排序
[INDEX]: 根据内表索引查找
[COMPARING]:只查找设置的字段
[COMPARING ALL FIELDS]:查找内表所有的字段
[TRANSPORTING]: 只输出设置的字段数据
[TRANSPORTING NO FIELDS]: 不输出任何数据

3. 内表排序
对内表进行排序,指定具体排序的排序字段、排序方式(升序/降序)
默认情况下,为升序。
语法:
SORT itab [BY <f1> <f2> …] [ASCENDING|DESCENDING]

4. 内表分类汇总(COLLECT TABLE …
通过COLLECT TABLE关键字,可以对内表中相同记录合并,若有数字类型(I、P、F)的字段,会将其合并汇总。
语法:
COLLECT [<work area> INTO] itab.

[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em]18

[size=1em]19

[size=1em]20

[size=1em]21

[size=1em]22

[size=1em]23

[size=1em]24

[size=1em]25

[size=1em]26

[size=1em]27

[size=1em]28

[size=1em]29

[size=1em]30

[size=1em]31

[size=1em]32

[size=1em]33

[size=1em]34

[size=1em]35

[size=1em]36

[size=1em]37

[size=1em]38

[size=1em][size=1em]TABLES: EMPLOYEE.

[size=1em]TYPES:  BEGIN OF EMP,
[size=1em]      COUNTRY    LIKE EMPLOYEE-COUNTRY,
[size=1em]      SALES      LIKE EMPLOYEE-SALES,
[size=1em]        END OF EMP.

[size=1em]DATA:  EMPTAB   TYPE STANDARD TABLE OF EMP INITIAL SIZE 10 WITH HEADER LINE,
[size=1em]       EMPTAB_C TYPE STANDARD TABLE OF EMP INITIAL SIZE 10 WITH HEADER LINE.

[size=1em]DATA:  EMPTAB_WA TYPE EMP.

[size=1em]* 赋值
[size=1em]EMPTAB-COUNTRY = 'D'.
[size=1em]EMPTAB-SALES         = 400.
[size=1em]APPEND EMPTAB.

[size=1em]EMPTAB-COUNTRY = 'USA'.
[size=1em]EMPTAB-SALES         = 1000.
[size=1em]APPEND EMPTAB.

[size=1em]EMPTAB-COUNTRY = 'GB'.
[size=1em]EMPTAB-SALES         = 500.
[size=1em]APPEND EMPTAB.

[size=1em]EMPTAB-COUNTRY = 'D'.
[size=1em]EMPTAB-SALES         = 7800.
[size=1em]APPEND EMPTAB.

[size=1em]SORT EMPTAB BY COUNTRY.

[size=1em]LOOP EMPTAB.
[size=1em]      
[size=1em]     MOVE-CORRESPONDING EMPTAB TO EMPTAB_WA.

[size=1em]     COLLECT EMPTAB INTO EMPTAB_C.

[size=1em]ENDLOOP.



输出结果:
D       8200
GB       500
USA    1000

或者直接从数据表取数汇总:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em][size=1em]SELECT * FROM EMPLOYEE.

[size=1em]   MOVE-CORRESPONDING EMPLOYEE TO EMPTAB.
[size=1em]   COLLECT EMPTAB.

[size=1em]ENDSELECT.

[size=1em]LOOP AT EMPTAB.

[size=1em]   WRITE:  / EMPTAB-COUNTRY, EMPTAB-SALES.

[size=1em]ENDLOOP.




5.系统字段 SY-TABIX
与前面提到的 SY-SUBRC 字段一样,SY-TABIX 也为系统的全局变量;
用于在循环遍历内表时,当前记录的索引值:
[size=1em]
[size=1em]1

[size=1em]2

[size=1em]3

[size=1em]4

[size=1em]5

[size=1em]6

[size=1em]7

[size=1em]8

[size=1em][size=1em]SELECT * FROM EMPLOYEE
[size=1em]   INTO CORRESPONDING FIELDS OF TABLE EMPTAB.

[size=1em]LOOP AT EMPTAB.

[size=1em]   WRITE:  / SY-TABIX, EMPTAB-COUNTRY, EMPTAB-NAME1.

[size=1em]ENDLOOP.




2.2.4 维护内表数据
1.通过索引值维护内表

语法:
INSERT   <EMPTAB> INDEX <i>.
MODIFY <EMPTAB> INDEX <i>.
DELETE   <EMPTAB> INDEX <i>.

说明:
INSERT: 向内表数据I处插入数据记录
MODIFY:修改内表数据I处记录
DELETE:删除内表I处数据记录
如:
[size=1em]
[size=1em]01

[size=1em]02

[size=1em]03

[size=1em]04

[size=1em]05

[size=1em]06

[size=1em]07

[size=1em]08

[size=1em]09

[size=1em]10

[size=1em]11

[size=1em]12

[size=1em]13

[size=1em]14

[size=1em]15

[size=1em]16

[size=1em]17

[size=1em]18

[size=1em]19

[size=1em]20

[size=1em]21

[size=1em]22

[size=1em][size=1em]SELECT * FROM EMPLOYEE.
[size=1em]   MOVE-CORRESPONDING EMPLOYEE TO EMPTAB.
[size=1em]   APPEND EMPTAB.
[size=1em]ENDSELECT.

[size=1em]READ TABLE EMPTAB INDEX 1.
[size=1em]MOVE 'ABC' TO EMPTAB-NAME1.
[size=1em]MODIFY EMPTAB INDEX SY-TABIX.

[size=1em]* 每次执行完之后,判断SY-SUBRC是否为0
[size=1em]IF SY-SUBRC NE 0.

[size=1em]   WRITE:  / ‘Attempt to modify failed.’.

[size=1em]ELSE.

[size=1em]  WRITE:  / EMPTAB-COUNTRY, EMPTAB-NAME1.

[size=1em]ENDIF.

[size=1em]INSERT EMPTAB INDEX 1.
[size=1em]DELETE EMPTAB INDEX SY-TABIX.




2. 维护没有HEADER LINE的内表

APPEND <work area> TO <internal table>.
COLLECT <work area> INTO <internal table>.
INSERT <work area> INTO <internal table>.
MODIFY <internal table> FROM <work area>.
READ TABLE <internal table> INTO <work area>.
LOOP AT <internal table> INTO <work area>.

说明:
APPEND: 向内表追加数据
COLLECT:内表数据分类汇总
INSERT:向内表插入数据
MODIFY:修改内表数据
READ TABLE:读取内表数据
LOOP AT:遍历内表数据

3. 清空内表
清空内表有4种方式:
CLEAR <internal table> :仅清空HEADER LINE,对内表数据存储空间不影响
REFRESH <internal table>:清空内表数据存储空间,对HEADER LINE不影响
FREE <internal table>:清空内表数据存储空间,对HEADER LINE不影响

4.获取内表信息
可以通过 DESCRIBE 关键字获取内表的相关信息。
语法:
DESCRIBE TABLE <internal table> [LINES <var1>] [OCCURS <var2>].

说明:
LINES: 获取内表存储记录数
OCCURS:获取内表存储空间大小


回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则


QQ|科莱特教育

GMT, 2025-4-19 00:37 , Processed in 0.051841 second(s), 23 queries .

福州科莱特教育科技有限公司 版权所有 闽ICP备2021003729号-2

Copyright C 2018-2022 All Rights Reserved

快速回复 返回顶部 返回列表