SAP ABAP 内部表:创建、读取、填充、复制和删除

⚡ 智能摘要

SAP ABAP 内部表对象以固定的结构存储数据,供程序内部动态使用。本页将介绍工作区、表头行、四种创建方法,以及用于填充、复制、读取和删除表行的语句。

  • 📋 核心定义: 内部表将结构相同的行存储在主内存中,最常用的方法是格式化从数据库表中读取的数据。
  • 🧾 工作领域角色: 工作区是一行,格式与表格相同,它一次处理表格中的一行。
  • 🏷️ 标题行: 带有表头的表格会获得一个隐式工作区,因此可以直接插入或读取行而无需指定工作区。
  • 🛠️ 四种创作方法: TYPES 语句、对现有表的引用、对现有结构的引用,或使用 OCCURS 声明的新结构。
  • ➕ 填充: APPEND 添加一行,COLLECT 聚合重复键的数值字段,INSERT 在选定的索引处插入一行。
  • 🔍 阅读并复制: LOOP AT 读取每一行,READ TABLE 按索引读取一行,MOVE 或等号复制整个表。
  • 🗑️ 删除: 在 LOOP 中使用 DELETE 会删除当前行,而 DELETE … INDEX 会删除指定位置的行。

SAP ABAP 内部表

什么是内部表?

内部表 用于从固定结构中获取数据,以便在 ABAP 中动态使用。内部表中的每一行具有相同的字段结构。内部表的主要用途是用于在程序中存储和格式化数据库表中的数据。

内部工作台总是与工作区配合使用,所以接下来要介绍的就是这个概念。

什么是工作区?

工作区是单行数据,其格式应与任何内部表相同。它用于一次处理内部表中的一行数据。

内部表格和工作区有什么区别?

一张图片胜过千言万语

内部表和工作区之间的区别

该图显示了一个包含多行数据的表,而工作区仅包含当前正在处理的行。工作区是由系统创建还是由开发人员创建,取决于下文所述的表类型。

内部表的类型

内部表有两种类型。

  1. 带有 HEADER行的内部表格
  2. 没有 HEADER 行的内部表格。

带标题行的内部表格

  • 这里系统自动创建工作区。
  • 工作区具有与内部表相同的数据类型。
  • 这个工作区域被称为HEADER行。
  • 对表内容的所有更改或任何操作都在这里完成。因此,可以将记录直接插入表中或直接从内部表访问。

无标题行的内部表格 :

  • 这里没有与表关联的工作区。
  • 当我们需要访问这样的表时,必须明确指定工作区。
  • 因此这些表不能被直接访问。

💡提示: 带有表头的表及其工作区使用相同的名称,这会导致代码歧义。新程序应该声明一个不带表头的表,并显式指定工作区。

标准、排序和哈希内部表

除了表头行的区别之外,每个内部表还有一个表类型,它决定了如何查找行。表类型通过添加 `TYPE STANDARD TABLE`、`TYPE SORTED TABLE` 或 `TYPE HASHED TABLE` 参数来选择,它直接影响运行时性能。

表格类型 访问方式 主要 最适合用于
标准版 索引和键,对键进行线性搜索 非唯一 顺序处理,以及使用索引读取小表。
排序 索引和键,对键进行二分查找 无论唯一与否,都会自动排序。 通过前导键字段重复读取较大的表
散列 仅密钥,使用哈希算法 独特优势 非常大的表,总是通过全键读取,例如数据库记录缓冲区

标准表是默认设置,适合顺序处理。哈希表无论存储多少行数据,都能保持访问时间恒定,这就是其性能规则的原因。 Open SQL 推荐用于缓存记录。

创建内部表

创建内部表的方法有很多种。让我们逐一看看:

1.使用 Type 语句

现在让我们使用 TYPE 语句创建一个内部表 itab。

语法是——

Types : begin of line,

column1 type I,

column2 type I,

end of line.

计费示例:

TYPES : begin of line,

empno		type I,

empname(20)   	type c	,

end of line.

TYPES 语句根据定义创建结构线。

要实际创建内部表 itab,请使用以下命令-

Data itab type line occurs 10.

内部表 itab 以行结构创建。除了声明内部表的结构之外,OCCURS 子句还定义在主存储器中维护多少个表条目(在本例中为 10 个)。额外的记录将写入分页区域,并会影响性能

2. 参照另一张表

您可以通过引用现有表来创建内部表。现有表可以是标准表。 SAP 表、Z 表或另一个内部表。

句法-

Data <f> <type> [with header line].

例-

DATA itab TYPE line OCCURS 10 with header line.

这里创建了一个内部表 itab,类型为行带标题行。请注意,“带标题行”是可选的。

3.参考现有结构

句法-

Data	<f> LIKE <struct> occurs n [with header line].

例-

DATA itab LIKE sline OCCURS 10.

这里创建了一个名为 itab 的表,其结构与 sline 表相同。

4.创建新结构

现在让我们创建一个具有我们自己的结构的内部表。此处的表格带有标题行, 默认情况下,.

句法 -

Data : Begin of <f> occurs <n>,

<component declaration>,

................................,

End of <f>.

示例–

Data : Begin of itab occurs 10,

column1       type I,

column2(4)  type C,

column3      like  mara-ernam,

End of itab.

内部表itab被创建

空表格没什么用处,所以下一节将用行填充它。

填充内部表

现在我们已经成功创建了一些内部表,让我们看看如何用一些记录填充它们。有多种方法可以填充表格

1.逐行追加数据

第一个可用的方法是使用 APPEND 语句。

使用 APPEND 语句,我们可以将另一个工作区的一行添加到内部表,或者将一个初始行添加到内部表。

句法 -

APPEND [<wa> TO / INITIAL LINE TO] <itable>.

这里是工作区或将初始行附加到内部表。

系统变量 SY-TABIX 包含附加行的索引。

计费示例:

Data: Begin of itab occurs 10,

col1 type C,

col2 type I,

end of itab.

Append initial line to itab.

结果:' ' '0'

`initial lines` 命令会向表中添加一行,并为其初始化与其类型相符的值。这里,`col1` 是字符型,`col2` 是整数型。然后,`APPEND initial line` 命令会添加一行,并根据列的数据类型进行初始化,即 `col1` 初始化为空格,`col2` 初始化为 0。

2.使用 COLLECT 语句

COLLECT 是用于填充内部表的另一种形式的语句。一般来说,在将行插入具有唯一标准键的内部表时使用 COLLECT。

句法-

COLLECT [<wa> INTO] <itable>.

对于带有标题行的表,INTO 选项被省略。假设已经有一个条目具有与您尝试附加的键相同的键,则不会将新行添加到表中,但会添加两个条目的数字字段,并且只有一个与该键对应的条目。SY-TABIX 的值更改为原始条目的行。否则 COLLECT 的作用类似于 APPEND,SY-TABIX 包含已处理行的索引。

3.使用 INSERT 语句

INSERT 语句向内部表添加行/工作区。您可以使用 INSERT 语句中的 INDEX 子句来指定要添加新行的位置。

句法

INSERT [<wa> INTO / INITIAL LINE INTO] <itable> [index <idx>].

这里是工作区或首字母 LINE 插入到内部表中在索引处。

复制内部表

可以使用 APPEND 命令将一个内部表的内容复制到另一个内部表。 LINES 或 INSERT LINES 语句。更简单的方法是使用以下任何一种语法。

MOVE  <itab1> To <itab2>.

OR

<itab1> = <itab2>.

这些将 ITAB1 的内容复制到 ITAB2。对于带有标题行的内部表,我们必须使用 [] 来区分工作区。因此,要复制带有标题行的内部表的内容,语法如下,

itab1[] = itab2[].

读取内部表

我们现在已经熟悉了如何创建内部表并向其中填充数据。接下来,我们将了解如何实际使用这些数据或从内部表中检索数据。

1. 使用 Loop -Endloop

访问或读取内部表的方法之一是使用 LOOP-ENDLOOP。

句法

LOOP AT <itable> [INTO <wa>]

...................................

ENDLOOP.

在这里,当您说 LOOP AT ITABLE 时,内部表 ITABLE 会逐行读取。您可以在 LOOP-ENDLOOP 结构的任何部分访问该行的列的值。SY-SUBRC 的值设置为 0,即使只读取了一条记录。

2. 使用 READ

读取内部表的另一种方法是使用 READ 语句。

句法-

READ TABLE <itable> [INTO <wa>] INDEX <idx>.

此语句读取当前行或索引指定的行。 SY-TABIX 的值是读取行的索引。如果找到具有指定索引的条目,则将 SY-SUBRC 设置为 0。如果指定的索引小于 0,则会发生运行时错误。如果指定的索引超过表大小,则将 SY-SUBRC 设置为 4。

⚠️警告: READ TABLE … INDEX 0 会引发运行时错误,因此在执行该语句之前应该检查运行时计算的索引。

删除内部表

有很多种方法可以从内部表中删除行。

1.循环删除行。

这是删除线条最简单的方法。

句法

DELETE <ITABLE>.

此语句仅在循环内有效。它会删除当前行。您可以通过添加以下语句有条件地删除循环中的行: WHERE 子句.

2.使用索引删除行。

这用于从内部表中的任何已知索引中删除一行。

句法

DELETE <ITABLE> INDEX <IDX>.

带索引的行被删除。下一行的索引减 1。

3.删除重复行。

按键字段对表格进行排序后,会删除重复行。

SORT itab BY col1.

DELETE ADJACENT DUPLICATES FROM itab COMPARING col1.

仅比较相邻行,因此必须先执行 SORT 语句。要完全清空表,请使用 CLEAR itab[] 或 REFRESH itab。

常见问题

`CLEAR itab` 只清空头部,`CLEAR itab[]` 清空整个数据框。`REFRESH` 总是清空数据框,但会保留内存。`FREE` 清空数据框并释放内存。

SY-TABIX 保存当前正在处理的内部表的行号。SY-INDEX 保存 DO 或 WHILE 循环的遍历次数。哈希表的 SY-TABIX 值为零,因为它没有索引。

LOOP AT itab ASSIGNING a field symbol 避免将每一行复制到工作区,因此在大表上运行速度更快,并且允许在不使用 MODIFY 语句的情况下就地更改行。

是的。ABAP 开发工具中的 AI 助手会将 OCCURS 和表头行声明重写为带有显式工作区的 TYPE STANDARD TABLE OF,并且它们会标记出表头行消失后会中断的语句。

AI性能顾问会检查表格的填充和读取方式,然后在线性搜索耗时过长时推荐使用排序表或哈希表。该推荐会通过验证来确认。 trace 在 SAT 交易中。

总结一下这篇文章: