ABAP 开发系列(05): ABAP 内表与内表结构2.内表和内表结构 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.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 向内表存储空间中追加数据。
语法: ①.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:获取内表存储空间大小
|