基础语法-内表(七)

7.1
创建内表

TYPES: BEGIN OF <f> OCCURS <n>,
<component declaration>,
               ..............
END OF <f>.

DATA: <itab> TYPE STANDARD
OF <f>,

<wa> TYPE <f>.

其作用与先创建字段串<f>,然后再创建与该字段串行结构相同的内表<f>相同。<n>指定行的初始号。将第一行写入用类型<t>创建的内表数据对象之后,就为指定行保留内存。如果添加到内表中的行比<n>指定的要多,则自动扩展保留的内存。如果内存中没有足够空间可用于内表,则将其写入缓冲区或磁盘(分页区域)。

7.2
填充内表

要填充内表,既可逐行添加数据,也可复制另一个表格的内容。要逐行填充内表,可以使用 APPEND COLLECT
INSERT
语句。

要将内表仅用于存储数据,出于性能方面的考虑,建议使用 APPEND。用 APPEND 也可以创建序列清单。

7.2.1无关键字附加行

要将行附加到内表中,使用
APPEND
语句,用法如下:

APPEND [<wa> TO|INITIAL
LINE TO] <itab>.

该语句将新行附加到内表<itab>中。

通过使用<wa>
TO
选项,指定要附加的源区域<wa>。对于带表头行的表格,可以忽略 TO 选项。这样,表格工作区域就成了源区域。

可以使用 INITIAL
LINE TO
选项替代<wa> TO,将用其类型的正确值初始化的行添加到表格中。

APPEND
不考虑是否存在标准关键字相同的行。这样,可能会出现相同条目。系统字段 SY-TABIX 在每个 APPEND 语句之后包含附加行的索引。

7.2.2根据标准关键字附加行

要用有唯一标准关键字的行填充内表,使用 COLLECT 语句,用法如下:

COLLECT [<wa> INTO]
<itab>.

该语句通过使用 INTO
选项指定想附加的源区域<wa>。如果表格有表头行,则可以忽略 INTO 选项。这样,表格工作区域就成了源区域。

系统检查表格条目的标准关键字是否相同。如果没有,COLLECT 语句的作用与 APPEND 语句相似,并将新行添至表格中。

如果存在关键字相同的条目,COLLECT 语句不附加新行,但将工作区域中数字字段的内容添加到现有条目中数字字段的内容中。系统字段 SY-TABIX 包含处理过的行的索引。

COLLECT 指定的工作区域必须与内表的行类型兼容,不仅仅是可转换为内表的行类型。COLLECT 语句无法用于带深层结构的内表,例如,将内表作为组件的行。

如果仅使用
COLLECT
语句填充内表,则不会出现重复条目。因此要填充没有重复条目的内表,应该使用 COLLECT 而不是 APPEND INSERT

7.2.3插入行

要在内表行之前插入新行,使用 INSERT 语句,用法如下:

INSERT [<wa> INTO|INITIAL LINE
INTO] <itab> [INDEX <idx>].

该语句通过使用 INTO
选项指定想插入的源区域<wa>。如果表格有表头行,则可以忽略 INTO 选项。这样,表格工作区域就成了源区域。

可以使用 INITIAL
LINE TO
选项替代<wa> TO,将用其类型的正确值初始化的行添至表格中。

如果使用 INDEX 选项,则将新行插入到有索引<idx>的行之前。插入之后,新条目索引为<idx>,下行索引加 1

如果表格包含<idx>
- 1
条目,系统将新条目附加到最后的现有表格行之后。如果表格的条目小于<idx> - 1,系统无法插入条目并将 SY-SUBRC 设置为4。如果操作成功,将 SY-SUBRC 设置为0

如果使用不带 INDEX
选项的 INSERT 语句,系统只能在 LOOP -
ENDLOOP
循环内通过在当前行(例如带 SY-TABIX 返回索引的行)前插入新条目来处理它。

7.2.4附加内表行

要将部分或全部内表附加到另一个内表中,使用 APPEND 语句,用法如下:

APPEND LINES OF <itab1>
[FROM <n1>] [TO <n2>] TO <itab2>.

如果没有 FROM TO 选项,该语句将整个表格 ITAB1 附加到 ITAB2 中。如果使用这些选项,则可通过索引<n1><n2>指定 ITAB1 中要附加的第一或最后一行。

用该方式将表格行附加到另一个表格中的速度比在循环中逐行进行附加快34倍。在 APPEND 语句之后,系统字段 SY-TABIX 包含附加的最后一行的索引。

7.2.5插入内表行

要将部分或全部内表插入到另一个内表中,使用 INSERT 语句,用法如下:

INSERT LINES OF <itab1> [FROM
<n1>] [TO <n2>]
                        INTO
<itab2> [INDEX <idx>].

如果没有 FROM TO 选项,该语句将整个表格 ITAB1 附加到 ITAB2 中。如果使用这些选项,则可通过索引<n1><n2>指定 ITAB1 中要附加的第一或最后一行。

如果使用 INDEX 选项,将<itab1>的行插入到<itab2>中索引为<idx>的行之前。如果不使用 INDEX 选项,系统只能在 LOOP - ENDLOOP 块中通过在当前行(例如,其索引在SY-TABIX 中返回的行)之前插入新条目来处理它。

7.2.6复制内表

如果想一次将内表的全部内容复制到另一内表中,请使用 MOVE 语句或赋值操作符 (=),用法如下:

MOVE <itab1> TO
<itab2>.

该语句等价于:<itab2>
= <itab1>.
也可进行多重赋值,例如,<itab4> =
<itab3> = <itab2> = <itab1>.
也是可能的。ABAP/4
从右到左进行处理:<itab2> = <itab1>.<itab3> =
<itab2>.<itab4> = <itab3>.
这些语句执行完整操作。复制整个表格内容,包括作为表格组件的任何其它内表的数据。覆盖目标表格原来的内容。

对于有表头行的表格,表格工作区域和表格本身同名。要在上述语句中进行区分,必须在名称之后输入两个方括号 ([]) 来定位内表而不是表格工作区域。

7.3
读取内表

7.3.1逐行读取内表

要将内表逐行读入工作区域,可以使用 LOOP 语句编一个循环。语法如下所示:

LOOP AT <itab> [INTO
<wa>] [FROM <n1>] [TO <n2>]
                           [WHERE
<condition>].

  
.....

ENDLOOP.

INTO 选项指定目标区域<wa>。如果表格有表头行,则可以忽略 INTO选项。这样,表格工作区域就成了目标区域。

逐行将内表<itab>读入<wa>或表格工作区域<itab>。对于读取的每一行,系统都处理以 LOOP 开始,以 ENDLOOP 结束的语句块。可以用控制关键字 AT LOOP - ENDLOOP 块内控制语句块流。

在语句块内,系统字段
SY-TABIX
包含当前行的索引。处理完表格的所有行之后循环结束。在 ENDLOOP 语句之后,如果至少读取了一行,则将系统字段 SY-SUBRC 设置为0。否则,将其设置为4

可以使用 FROM TO WHERE 选项限制要在循环中进行处理的行数。

   使用 FROM 选项,可以用<n1>指定要读取的第一行。

   使用 TO 选项,可以用<n2>指定要读取的最后一行。

   WHERE 选项,可以指定<condition>的任何逻辑表达式。第一个操作数必须是内表行结构的组件。如果在循环中使用控制关键字 AT ,则不能使用 WHERE 选项。

FROM TO 选项限制系统必须读取的行数。WHERE 选项仅避免对工作区域进行不必要的填充。用 WHERE 选项,系统必须读取所有行。为了提高效率,应该尽可能使用 FROM TO 选项。在某些条件下用 EXIT 语句而不是 WHERE 选项跳出循环也十分有效。

7.3.2用索引读取单行

要用索引从内表中读取单行,使用 READ 语句,用法如下:

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

INTO 选项指定目标区域<wa>。如果表格有表头行,可以忽略 INTO 选项。这样,表格工作区域就成了目标区域。

系统用索引<idx>从表格<itab>中读取行。这比用关键字访问表格要快。

如果找到有指定索引的条目,则将系统字段 SY-SUBRC 设置为0,而且
SY-TABIX
包含该行的索引。否则,SY-SUBRC 包含非0值。

如果<idx>小于或等于 0,则会发生实时错误。如果<idx>超过表格大小,系统将 SY-SUBRC 中的返回代码值设置为 4

7.3.3 读取自定义关键字的单行

要从有自定义关键字的内表中读取单行,使用 READ 语句的 WITH KEY 选项,用法如下:

READ TABLE <itab> [INTO
<wa>] WITH KEY <key> [BINARY SEARCH].

INTO 选项可以指定目标区域。如果表格有表头行,则可以忽略INTO 选项。这样,表格工作区域就成了目标区域。

系统读取<itab>中匹配<key>中所定义的关键字的第一个条目。如果找到有适当关键字的条目,则将系统字段 SY-SUBRC 设置为0,并且
SY-TABIX
包含该行的索引。否则,将 SY-SUBRC 设置为非0值。

如下所述,可以定义多个关键字<key>

1)定义一系列关键字段

要定义自己的一系列关键字段,使用 WITH KEY 选项,用法如下:

....WITH KEY <k1> =
<f1> ... <kn> = <fn> ...

自定义关键字包含表格组件<k1>...<kn>。字段<f1>...<fn>是关键字段的内容必须匹配的值。如果<fi>的数据类型与数据类型<ki>不兼容,则<fi>转换为类型<ki>。可以用 (<ni>) 代替<ki>来实时设置关键字段。关键字段是字段<ni>的内容。如果在运行时<ni>为空,则系统忽略该关键字段。如果<ni>包含无效的组件名称,则发生实时错误。

用户可以为任何在关键字中使用的组件指定偏移量和长度。

2)将整行定义为关键字

通过使用 WITH
KEY
选项可将内表整行定义为其关键字,如下所示:

....WITH KEY = <value> ...

如果<value>的数据类型与表格行的数据类型不兼容,则将<value>转换为表格行的数据类型。

对于此类关键字,也可以选择由某个基本数据类型或内表直接定义的,而不是由字段串直接定义的特定内表行。

3)将行首定义为关键字

要将内表的行首定义为关键字,使用 WITH KEY 选项,用法如下:

....WITH KEY <k> ...

系统将(左对齐)的行首与<k>进行比较。<k>不能包含内表或包含内表的结构。与上面两个选项不同之处在于用<k>的数据类型进行比较。

7.3.4 读取标准关键字的单行

要从内表中读取有特定标准关键字的第一行,使用 READ 语句,用法如下:

READ TABLE <itab> [INTO
<wa>] [BINARY SEARCH].

用户必须指定要从<itab>的表格工作区域中读取行的关键字。

读取语句的该变式只能用于有表头行的内表。

系统在表格中搜索第一个条目以匹配表格工作区域中的所有标准关键字段并将该行读入表格工作区域。如果使用 INTO 选项,则将该行读入工作区域<wa>

标准关键字包含内表关键字中所述的全部关键字段,其中不包含 SPACE。如果找到有匹配关键字的条目,则将系统字段 SY-SUBRC 设置为0并且 SY-TABIX 包含该行的索引。否则,将 SY-SUBRC 设置为4

7.3.5 二分法搜索

用关键字读取单行时,可以执行二分法搜索以代替标准顺序搜索。为此,使用 READ 语句的二分法搜索选项。

READ TABLE <itab>
.....BINARY SEARCH.

如果使用二分法搜索选项,则必须按关键字中指定的次序对内表进行排序。

如果系统找到匹配指定关键字的多行,则读取索引最低的行。

二分法搜索比线性搜索要快。因此,应尽可能将内表排序并且使用二分法搜索选项。

7.3.6 比较单行的内容

要将使用 READ 语句读取的单行内容与目标区域的内容进行比较,可使用 READ 语句的 COMPARING 选项,用法如下:

READ TABLE <itab> [INTO
<wa>] <key-option> COMPARING <fields>.

系统读取由关键字或<key
option>
中的索引指定的单行。读取行之后,将<fields>中指定的组件与目标区域中的相应组件进行比较。可以用 INTO 选项指定目标区域<wa>。如果表格有表头,则可以忽略 INTO 选项。这样,表格工作区域就成了目标区域。

对于<field>,可以编写一系列组件... <f1> ...<fn>。也可以用... ALL
FIELDS
指定所有组件。

如果系统找到包含指定<key-option>的条目,且进行比较的字段内容相同,则将 SY-SUBRC 设置为0。如果进行比较的字段内容不同,则返回值 2。如果系统找不到条目,则包含 4

如果系统找到条目,则无论比较结果如何,都将其读入目标区域。

7.3.7 读取一行部分列内容

要读取一行部分列的内容,使用 READ 语句的 TRANSPORTING 选项,用法如下:

READ TABLE <itab> [INTO
<wa>] <key-option> TRANSPORTING <fields>.

系统读取由关键字或<key
option>
中索引指定的单行。读取行之后,将<fields>中指定的组件传输给目标区域。可以使用 INTO 选项指定目标区域<wa>。如果表格有表头行,可以忽略 INTO 选项。这样,表格工作区域就成了目标区域。

对于<fields>,可以用... <f1> ...<fn>指定一系列组件。也可以用...
NO FIELDS
指定不传输任何组件。

对于后一种情况,READ
语句只影响系统字段 SY-SUBRC SY-TABIX

7.3.8 确定内表属性

如果在处理过程中想知道内表一共包含多少行,或者想知道定义的 OCCURS 参数的大小,使用 DESCRIBE 语句,用法如下:

DESCRIBE TABLE <itab>
[LINES <lin>] [OCCURS <occ>].

如果使用 LINES 参数,则将填充行的数量写入变量<lin>。如果使用 OCCURS 参数,则将行的初始号写入变量<occ>

7.4
修改和删除内表行

7.4.1 MODIFY更改行

要用 MODIFY 语句更改行,使用:

MODIFY <itab> [FROM
<wa>] [INDEX <idx>].

FROM 选项中指定的工作区域<wa>代替<itab>中的行。如果表格有表头行,可以忽略 FROM 选项。这样,表格工作区域就代替行。

如果使用 INDEX 选项,则新行代替索引为<idx>的现有行。如果替换成功,则将 SY-SUBRC 设置为0。如果内表包含的行少于<idx>,则不更改任何行并且 SY-SUBRC 包含4

如果使用没有 INDEX
选项的 MODIFY 语句,则系统只能在 LOOP -
ENDLOOP
块中通过更改当前行(例如由 SY-TABIX 返回其索引的行)来处理它。

7.4.2 WRITE TO更改行

要用 WRITE TO 语句更改行,请使用下列语法:

WRITE
<f>[+<o1>][(<l1>)] TO <itab>[+<o2>][(<l2>)]
INDEX <idx>.

将字段<f>中偏移量为<o1>,长度为<l1>部分的内容复制到索引为<idx>的表格行中,覆盖偏移量为<o2>,长度为<l2>的部分。请注意,即使对于有表头行的表格,带 INDEX 选项的 WRITE TO 语句也不访问表格工作区域,而是访问表格的某一行。

WRITE
TO
语句不能识别表格行的结构。SAP 建议只在转换已知其确切位置的标志时才使用该语句。另一种情况是用一个基本字符字段定义的内表。该结构的表格非常重要,例如,用于程序的动态生成。

7.4.3 在循环中删除行

要在循环中从内表中删除行,使用 DELETE 语句,用法如下:

DELETE <itab>.

系统只能在 LOOP -
ENDLOOP
块中处理该语句。删除第一行后,可以取消当前行的定义并取消其对 SY-TABIX 内容的赋值。要在该循环内进一步处理行,需使用有 INDEX 选项的语句。

7.4.4 用索引删除行

要使用索引删除行,使用有
INDEX
选项的 DELETE 语句,用法如下:

DELETE <itab> INDEX
<idx>.

如果使用 INDEX 选项,则从 ITAB 中删除索引为<idx>的行。删除行之后,下面行的索引减1。如果操作成功,则将 SY-SUBRC 设置为0。否则,如果不存在索引为<idx>的行,则 SY-SUBRC 包含 4

如果在 LOOP -
ENDLOOP
块中删除某一条目,则当前行及其对 SY-TABIX 内容的赋值可成为未定义。要在该循环内进一步处理行,需使用有 INDEX 选项的语句。

7.4.5 删除邻近的重复条目

要删除邻近重复条目,使用
DELETE
语句,用法如下:

DELETE ADJACENT DUPLICATE ENTRIES
FROM <itab> [COMPARING <comp>].

系统从内表<itab>中删除所有邻近重复条目。

如果没有
COMPARING
选项,则标准关键字段的内容必须相同。

如果有
COMPARING
选项.... COMPARING <f1><f2>... ,指定字段<f1><f2> ... 的内容必须相同。也可以通过写入
(<name>)
代替<f1>在运行时在括号中指定字段名。字段<name>包含排序关键字段的名称。如果<name>在运行时为空,则系统将其忽略。如果包含无效的组件名,则会发生实时错误。

如果有
COMPARING
选项.... COMPARING ALL FIELDS ,所有字段的内容必须相同。如果系统找到并删除至少一个重复条目,则将 SY-SUBRC 设置为0。否则,将其设置为4

如果表格根据指定的比较标准进行过排序,则可使用该语句从内表中删除所有重复条目。

7.4.6 删除选定行

要删除一组选定行,使用
DELETE
语句,用法如下:

DELETE <itab> [FROM
<n1>] [TO <n2>] [WHERE <condition>].

用户必须至少指定三个选项之一。如果使用没有 WHERE 选项的该语句,则系统从<itab>中删除所有索引在<n1><n2>之间的行。如果不使用 FROM 选项,则系统从第一行开始删除。如果不使用 TO 选项,则系统删除所有行直到最后一行。

如果使用 WHERE 选项,则系统仅从<itab>中删除满足条件<condition>的行。对于<condition>,可指定任何逻辑表达式。第一个操作数必须是内表行结构的组件。

如果系统至少删除一行,则将 SY-SUBRC 设置为0。否则,将其设置为4

7.5
内表排序

要将内表排序,使用
SORT
语句,用法如下:

SORT <itab> [<order>]
[AS TEXT]
   [BY <f1> [<order>] [AS
TEXT] ... <fn> [<order>] [AS TEXT]].

如果不使用 BY 选项,则根据其标准关键字对内表<itab>进行排序。要定义不同的排序关键字,使用 BY 选项。系统就根据指定组件<f1> ... <fn>对数据集进行排序。这些字段可以是任何类型,包括类型 PI F 字段,或者表格。排序关键字段的数目限制在 250 以内。如果指定多个关键字段,则系统首先根据<f1>,然后根据<f2>,以此类推对记录进行排序。系统使用 BY 之前指定的选项作为 BY 之后指定的所有字段的缺省选项。在单个字段之后指定的选项覆盖选项在 BY之前指定的这些字段。

如果在运行时排序标准仍然未知,可以通过写入 (<name>) 代替<fi>进行动态设置。字段<name>包含排序关键字段的名称。如果<name>在运行时为空,系统就将其忽略。如果包含无效的组件名,则发生实时错误。对于任何在排序字段中使用的字段,用户都可指定偏移量和长度。

用户可以通过在<order>选项中输入 DESCENDING ASCENDING 来指定排序顺序。标准顺序是升序。

用户可以用选项 AS
TEXT
影响字符字段的排序方式。如果没有 AS TEXT,则系统二分排序字符字段并根据它们的平台相关内部编码。如果有选项 AS TEXT,系统根据当前文本环境按字母顺序排序字符字段。用户可用语句 SET
LOCAL LANGUAGE
设置文本环境,这是例外。使用选项 AS TEXT,用户可免除在排序之前将字符字段转换为可排序格式之劳。此类转换仅在下列情况下才有必要:

首先按字母顺序对内表进行排序,然后二分法进行搜索。按字母顺序排序后的内表次序与按二分法排序后的次序不同。

用字母关键字多次对内表进行排序。在这种情况下效率更佳,因为只进行一次转换。在程序中为数据库表格创建字母索引。

如果在 BY 之前指定 AS TEXT,则选项仅影响排序关键字中的字符字段。如果在字段名之后指定 AS
TEXT
,则该字段必须为类型 C

如果自己指定排序关键字,通过使关键字相对短些可提高效率。但是,如果排序关键字包含内表,则排序进程可能会慢很多。

排序并不稳定。这意味着也许没有必要保留排序关键字相同的行的旧次序。

如果主内存中没有足够的空间用于排序,系统就将数据写入临时外部文件。该文件名在 SAP 参数文件参数 DIR_SORTTMP 中定义。

7.6
创建顺序表

内表适合于生成顺序表。为此,从空的内表开始,然后使用 APPEND 语句的 SORTED BY 选项,用法如下:

APPEND [<wa> TO]
<itab> SORTED BY <f>.

如果使用有 SORTED
BY
选项的 APPEND 语句,则并不将新行附加为内表<itab>的最后一行。而是系统插入新行,这样内表<itab>就根据字段<f>以降序排序。

要生成包含多达 100 个条目的顺序表,则应该使用 APPEND 语句。在处理更大的表时,由于效率方面的原因,建议用 SORT 语句对表格进行排序。

如果使用 SORTED
BY
选项,表格只能包含 OCCURS 参数中指定的行数。这是一般规则的一个例外。如果添加的行数比指定的要多,则丢弃最后一行。这对于创建长度有限的次序表十分有用。

使用 APPEND 语句的 SORTED BY 选项指定的工作区域必须与内表的行类型兼容。可转换性对该选项不充分。

7.7
AT
……ENDAT行组控制级别

用控制级别语句 AT 可以打开语句块,用控制级别语句 ENDAT 可以关闭它。语法如下所示:

AT <line>.

<statement block>

ENDAT.

在处理 AT-
ENDAT
内语句块的行条件<line>可以是:

<line>

含义

FIRST

内表的第一行

 LAST

内表的最后一行

NEW <f>

行组的开头,与字段<f><f>剩余字段中的内容相同

 END Of <f>

行组的结尾,与字段<f><f>剩余字段中的内容相同

 AT - ENDAT 块中的语句块使用这些行条件代表预定义的控制结构。用户可以使用它们处理内表中的控制断点,而不必使用编程分支和循环中所述的语句自己编程。

AT - ENDAT
语句块中,工作区域没有用当前表格行进行填充。初始化所有不是标准关键字部件的字段。对于行条件 FIRST LAST,系统用星号 (*) 改写所有标准关键字段。对于行条件 NEW <f> END OF <f>,系统用星号 (*) 改写所有出现在工作区域中指定字段<f>右边的标准关键字段。用户可根据自己的需求在 AT - ENDAT 语句块中填充工作区域。

使用AT NEW f AT
END OF f
时需注意:

1f必须是内表的第一个字段;

2)内表中f之后的字段的值都会变成“*”。

使用AT NEW, AT FIRST, AT LAST,AT END OF时需注意:LOOP的时候不能加条件;ATENDAT之间不能使用LOOP
INTO
working aera。手动实现AT
NEW,AT END OF
的时候,需要注意,尤其是在AT END OF的时候。

7.8
比较内表

可以将内表用做逻辑表达式的操作数:

....
<itab1><operator><itab2> ...

对于<operator>,可以使用比较所有的字段类型中的表格内列出的所有操作符(EQ = NE<>><
GE
>= LE<= GT> LT<)。

进行内表比较的第一个条件是它们包含的行数。内表包含的行数越多,则内表就越大。如果两个内表行数相同,则逐行、逐个组件进行比较。如果表格行的组件本身就是内表,则进行递归比较。如果使用等于操作符以外的操作符,则系统找到一对不相等的组件后就立即停止比较并返回该结果。

对于有表头行的内表,则可在表格名之后使用方括号[]以将表格工作区域和表格体区别开来。

7.9
初始化内表

要初始化有或没有表头的内表,使用 REFRESH 语句,用法如下:

REFRESH <itab>.

该语句将内表重置为填充它以前的状态。这意味着表格将不包含任何行。如果使用没有表格工作区域的内表,可以使用 CLEAR 语句代替 REFRESH 语句,用法如下:

CLEAR <itab>.

如果使用有表头行的内表,CLEAR
语句仅清除表格工作区域。要重置整个内表而不清除表格工作区域,使用 REFRESH 语句或 CLEAR 语句,用法如下:

CLEAR <itab>[].

内表名称之后的方括号指内表体。

使用 REFRESH CLEAR 初始化内表后,系统保持在内存中保留的空间。可以用 FREE 语句释放内存,用法如下:

FREE <itab>.

也可以使用 FREE 语句重置内表并直接释放其内存,而不必先使用 REFRESH CLEAR。与
REFRESH
一样,FREE 在表格体上,而不在表格工作区域上工作。

FREE 语句之后,可以再次定位内表。这样,系统就再次保留内存空间。可以使用如下逻辑表达式检查内表是否为空:

... <itab> IS INITIAL ...   

RIPRO主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
SapiBook » 基础语法-内表(七)

发表评论