内表:
1:ABAP中有三种类型的内表:
| Index Tables | Hashed Table | |
Table Type | STANDARD TABLE | SORTED TABLE | HASHED TABLE |
通过索引访问 | √ | √ |
|
通过键访问 | √ | √ | √ |
KEY 唯一性 | 键不唯一 | 可唯一或不唯一 | 键必须唯一 |
相同值关键字行 | 可从复 | 可从复或不可从复 | 不可从复 |
通常访问方式 | 主要通过索引 | 主要通过关键字 | 只能通过关键字 |
STANDARD TABLE:
DATA ITAB_STANDARD TYPE STANDARD TABLE OF MARA.
SORTED TABLE:
DATA ITAB_SORTED TYPE SORTED TABLE OF MARA WITH NON-UNIQUE KEY TABLE_LINE.
WITH UNIQUE KEY 或WITH NON-UNIQUE KEY 都可以。
HASHED TABLE:
DATA ITAB_HASHED TYPE HASHED TABLE OF MARA WITH UNIQUE DEFAULT KEY.
只能为WITH UNIQUE KEY。
- SORTED TABLE和HASHED TABLE 必须制定KEY字段的名称如果只是这样写报错:
×DATA ITAB_HASHED TYPE HASHED TABLE OF MARA WITH UNIQUE KEY.
×DATA ITAB_SORTED TYPE SORTED TABLE OF MARA WITH NON-UNIQUE KEY.
2:表关键字
1 ….WITH [UNIQUE|NON-UNIQUE] KEY COMP1……COMPn
2 ….WITH [UNIQUE|NON-UNIQUE] KEY TABLE LINE
如果内表整行都是由基本字段组成的,则可以把内表整行指定为表关键字。
3 ….WITH [UNIQUE|NON-UNIQUE] KEY DEFAULT KEY
如果不指定任何关键字,则可以使用默认的标准关键字。
3:OCCURS N 的含义
DATA: BEGIN OF ITAB OCCURS 10,
NAME(20) TYPE C,
ADDRESSES TYPE ADDRESS,
END OF ITAB.
该语句声明了一个标准内表,OCCURS 10 代表分配初使内存大小为10行
4:内表的初始大小设定
DATA ITAB TYPE STANDARD TABLE OF MARA WITH NON-UNIQUE DEFAULT KEY
INITIAL SIZE n
- INITIAL SIZE n声明内表的初始大小
WITH HEADER LINE.
先定义工作区与内表:
DATA IT_MARA TYPE STANDARD TABLE OF MARA.
DATA IS_MARA TYPE MARA.
IS_MARA-MANDT = SY-MANDT.
IS_MARA-MATNR = '000000000000000059'.
IS_MARA-ERSDA = SY-DATUM.
IS_MARA-ERNAM = '44444'.
5:INSERT语句
1 通过索引插入单行:
INSERT 工作区 INTO 内表 INDEX N.
e.g. INSERT gs_ INTO gt_ INDEX 2.
2 一般性插入单行的语法:
INSERT 工作区 INTO TABLE 内表.
e.g. INSERT IS_MARA INTO TABLE IT_MARA.
加入TABLE 关键字,对于不同类型的内表,其意义用法是有区别的:
- 对于标准表而言,该形式不指定索引值,附加至表的最后一行,与APPEND语句效果完全一致;
- 对于排序表来说,插入的行不可以打乱按照关键字排序的顺序,否则插入不成功;
- 对于哈希来说,插入过程中系统按照关键字对行进行定位
INSERT INITIAL LINE INTO IT_MARA INDEX 1.
效果是用行结构中各类型的初始值组成数据行添加到内表中。
3 插入内表
INSERT LINES OF [FROM ] [TO ] INTO [INDEX ].
如果没有FROM和TO选项,该语句将整个表格ITAB1附加到ITAB2中。如果使用这些选项,则可通过索引或指定ITAB1中要附加的第一行或最后一行。
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA: ITAB1 LIKE LINE OCCURS 10,
ITAB2 LIKE LINE OCCURS 10.
DO 3 TIMES.
LINE-COL1 = SY-INDEX. LINE-COL2 = SY-INDEX ** 2.
APPEND LINE TO ITAB1.
LINE-COL1 = SY-INDEX. LINE-COL2 = SY-INDEX ** 3.
APPEND LINE TO ITAB2.
ENDDO.
INSERT LINES OF ITAB1 INTO ITAB2 INDEX 1.
LOOP AT ITAB2 INTO LINE.
WRITE: / SY-TABIX, LINE-COL1, LINE-COL2.
ENDLOOP.
6:APPEND语句
只能操作索引表(哈希表不是以索引作为行的寻找方式,没有系统索引,因此也就不能通过索引进行操作)
APPEND默认插入到最后一行所以不用+ INDEX。
APPEND 工作区 TO 内表.
APPEND IS_MARA TO IT_MARA.
APPEND INITIAL LINE TO IT_MARA(内表).
原理与INSERT 只是 APPEND 是插入到最后一行。
* 附加内表行:
APPEND LINES OF [FROM ] [TO ] TO .
如果没有FROM 和 TO 选项,该语句将整个表格ITAB1附加到ITAB2中。如果使用这些选项,则可以通过索引或指定ITAB1中要附加的第一行或最后一行。
6:COLLECT语句
COLLECT IS_MARA(工作区) INTO IT_MARA(内表).
图解:内表 ITAB已经存在4行数据,其中CARR,CONN是表的关键字段,是一个航空数据系统中公司ID和航线ID,UMSATZ代表总的机票收入。如果此时添加一行新的数据,该数据仍然是LH的400航班。如果使用APPEND语句,则内表变为5行,如果使用COLLECT 语句,则在LH的0400航班原有基础上将收入累加。
6:READ语句
读取内表中的某一行,而不是循环读取内表,可以使用READ语句。
1 :用索引读取单行:
READ TABLE [INTO ] IDEEX .
DATA: BEGIN OF ITAB OCCURS 10,
COL1 TYPE I,
COL2 TYPE I,
END OF ITAB.
DO 20 TIMES.
ITAB-COL1 = SY-INDEX.
ITAB-COL2 = 2 * SY-INDEX.
APPEND ITAB.
ENDDO.
READ TABLE ITAB INDEX 17.
WRITE: SY-SUBRC, SY-TABIX.
WRITE: / ITAB-COL1, ITAB-COL2.
如果INDEX数大于DO 循环数INDEX = 21 WRITE输出结果
SY-INDEX(循环次数);SY-TABIX(索引数)也就是INDEX后的数
2 读取有关键字的单行:
READ TABLE [INTO ] INTO KEY [BINARY SEARCH]
DATA: BEGIN OF LINE,
COL1 TYPE C,
COL2 TYPE P DECIMALS 5,
COL3 TYPE I,
COL4 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 10 TIMES.
LINE-COL1 = SY-INDEX.
LINE-COL2 = SQRT( SY-INDEX ).
LINE-COL3 = SY-INDEX ** 2.
LINE-COL4 = SY-INDEX ** 3.
APPEND LINE TO ITAB.
ENDDO.
READ TABLE ITAB INTO LINE WITH KEY COL3 = 9 COL4 = 36.
WRITE: / SY-SUBRC, SY-TABIX.
READ TABLE ITAB INTO LINE WITH KEY COL3 = 9 COL4 = 27.
WRITE: / SY-SUBRC, SY-TABIX.
READ TABLE ITAB INTO LINE WITH KEY '2'.
WRITE: / SY-SUBRC, SY-TABIX.
DO循环后ITAB表结构:
第一个READ:没有COL3 = 9 COL4 = 36的数据。所以SY-SUBRC=4 SY-TABIX=0.
第二个READ:READ语句找到索引为3的行符合
第三个READ:READ语句搜索以’2’开始的表格行并找到索引为2的行。
3 二分法查找
READ TABLE [INTO ] [BINARY SEARCH]
查找之前需要先对表进行排序。
3 只读取内表
READ TABLE IT_MARA_MARD TRANSPORTING NO FIELDS BINARY SEARCH
WITH KEY MATNR = '000000000000000058'.
IF SY-SUBRC = 0.
ENDIF.
TRANSPORTING NO FIELDS表示只读取内表,用SY-SUBRC进行判断。
7:MODIFY语句
根据索引进行更新内表
MODIFY ITAB [FROM WA] [INDEX IAX] [TAANSPORTING F1 F2……]
MODIFY IT_MARA FROM IS_MARA INDEX 1.
使用表关键字更新内表
MODIFY ITAB FROM WA TRANSPORTING F1 F2………..WHERE COND.
F1 F2……….. 中必须为关键字。
如果只希望更新部分字段的值,可以使用TRANSPORTING
MODIFY IT_MARA FROM IS_MARA TRANSPORTING MATNR WHERE
MATNR=' '.
7:DELETE语句
用索引删除行:
DELETE IT_MARA INDEX 1.
在循环中删除行:
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 30 TIMES.
LINE-COL1 = SY-INDEX.
LINE-COL2 = SY-INDEX ** 2.
APPEND LINE TO ITAB.
ENDDO.
LOOP AT ITAB INTO LINE.
IF LINE-COL1 < 28.
DELETE ITAB.
ENDIF.
ENDLOOP.
LOOP AT ITAB INTO LINE.
WRITE: / SY-TABIX, LINE-COL1, LINE-COL2.
ENDLOOP.
在创建内表ITAB并用30行对其进行填充。在第一个LOOP-ENDLOOP中,删除COL1字段中所有小于28的行。
DELETE IT_MARA WHERE MATNR = ' '.
删除邻近重复条目
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE C,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
LINE-COL1 = 1. LINE-COL2 = 'A'. APPEND LINE TO ITAB.
LINE-COL1 = 1. LINE-COL2 = 'A'. APPEND LINE TO ITAB.
LINE-COL1 = 1. LINE-COL2 = 'B'. APPEND LINE TO ITAB.
LINE-COL1 = 2. LINE-COL2 = 'B'. APPEND LINE TO ITAB.
LINE-COL1 = 3. LINE-COL2 = 'B'. APPEND LINE TO ITAB.
LINE-COL1 = 4. LINE-COL2 = 'B'. APPEND LINE TO ITAB.
LINE-COL1 = 5. LINE-COL2 = 'A'. APPEND LINE TO ITAB.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
ULINE.
DELETE ADJACENT DUPLICATES FROM ITAB COMPARING ALL FIELDS.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
ULINE.
ALL FIELDS含义:所有字段同时比较,只有完全一样是删除从复。
DELETE ADJACENT DUPLICATES FROM ITAB COMPARING COL2.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
ULINE.
DELETE ADJACENT DUPLICATES FROM ITAB.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
ULINE.
删除选定行
DELETE [FROM ] [TO ] [WHERE].
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 40 TIMES.
LINE-COL1 = SY-INDEX.
LINE-COL2 = SY-INDEX ** 2.
APPEND LINE TO ITAB.
ENDDO.
DELETE ITAB FROM 3 TO 38 WHERE COL2 > 20.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1,LINE-COL2.
ENDLOOP.
7:内表排序
SORT ITAB [ASCENDING|DESCENDING] [AS TEXT] [STABLE]
[BY F1 [ASCENDING|DESCENDING] [AS TEXT]
……
Fn [ASCENDING|DESCENDING] [AS TEXT]]
DATA: BEGIN OF ITAB OCCURS 10,
LAND(3) TYPE C,
NAME(10) TYPE C,
AGE TYPE I,
WEIGHT TYPE P DECIMALS 2,
END OF ITAB.
ITAB-LAND = 'USA'. ITAB-NAME = 'NANCY'.
ITAB-AGE = 35. ITAB-WEIGHT = '45.00'.
APPEND ITAB.
ITAB-LAND = 'USA'. ITAB-NAME = 'HOWARD'.
ITAB-AGE = 40. ITAB-WEIGHT = '95.00'.
APPEND ITAB.
ITAB-LAND = 'GB'. ITAB-NAME = 'JENNY'.
ITAB-AGE = 18. ITAB-WEIGHT = '50.00'.
APPEND ITAB.
ITAB-LAND = 'F'. ITAB-NAME = 'MICHELE'.
ITAB-AGE = 30. ITAB-WEIGHT = '60.00'.
APPEND ITAB.
ITAB-LAND = 'G'. ITAB-NAME = 'KARL'.
ITAB-AGE = 60. ITAB-WEIGHT = '75.00'.
APPEND ITAB.
LOOP AT ITAB.
WRITE: / ITAB-LAND, ITAB-NAME, ITAB-AGE, ITAB-WEIGHT.
ENDLOOP.
ULINE.
SORT ITAB.
LOOP AT ITAB.
WRITE: / ITAB-LAND, ITAB-NAME, ITAB-AGE, ITAB-WEIGHT.
ENDLOOP.
ULINE.
SORT ITAB DESCENDING BY LAND WEIGHT ASCENDING.
LOOP AT ITAB.
WRITE: / ITAB-LAND, ITAB-NAME, ITAB-AGE, ITAB-WEIGHT.
ENDLOOP.
8:复制内表
MOVE TO .等价于 = .
也可以多重赋值:
= .
= .
= .
* ABAP是从做到右进行处理。
DATA: ITAB1 TYPE I OCCURS 10,
ITAB2 TYPE F OCCURS 10,
L2 TYPE F.
DO 3 TIMES.
APPEND SY-INDEX TO ITAB1.
ENDDO.
ITAB2 = ITAB1.
LOOP AT ITAB2 INTO L2.
WRITE: / L2.
ENDLOOP.
9:循环处理
LOOP AT 内表INTO 工作区.
……
ENDLOOP.
使用行组的控制级别:
用控制级别语句AT可以打开语句块,用控制级别语句ENDAT可以关闭它。
语法:AT .
ENDAT.
在其中处理AT- ENDAT内语句块的行条件可以是:
| 含义 |
FIRST | 内表的第一行 |
LAST | 内表的最后一行 |
NEW | 行组的开头,与字段和剩余字段中的内容相同 |
END OF | 行组的结尾,与字段和剩余字段中的内容相同 |
DATA: BEGIN OF LINE,
COL1 TYPE C,
COL2 TYPE I,
COL3 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
LINE-COL1 = 'A'.
DO 3 TIMES.
LINE-COL2 = SY-INDEX.
LINE-COL3 = SY-INDEX ** 2.
APPEND LINE TO ITAB.
ENDDO.
LINE-COL1 = 'B'.
DO 3 TIMES.
LINE-COL2 = 2 * SY-INDEX.
LINE-COL3 = ( 2 * SY-INDEX ) ** 2.
APPEND LINE TO ITAB.
ENDDO.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2, LINE-COL3.
AT END OF COL1.
* AT END OF COL1代表以COL1 字段为行组的结尾
ULINE.
SUM.
WRITE: / LINE-COL1, LINE-COL2, LINE-COL3.
SKIP.
ENDAT.
AT LAST.
ULINE.
SUM.
WRITE: / LINE-COL1, LINE-COL2, LINE-COL3.
ENDAT.
ENDLOOP.
初始化内表:要初始化有或没有表头的内表,请使用REFRESH语句:
语法:REFRESH
该语句将内表重置为填充它以前的状态。这意味着表将不包含任何行。
如果使用没有表格的工作区,可以使用CLEAR 代替REFRESH.
语法:CLEAR
如果使用有表头行的内表,CLEAR语句将仅清空表工作区域。要重置整个内表而不清除表格工作区域,使用REFRESH语句或CLEAR语句:
语法:CLEAR []
内表名称之后的方括号指表体。
使用REFRESH或CLEAR初始化内表后,系统保持在内存中保留空间。可以用FREE语句释放内存,用法如下:
语法:FREE
在FREE 语句之后,可以再次定位内表。这样,系统就再次保留内存空间。