内表的增删改查与排序

types:begin of ty_stu,
num type n length 4,
sub type c length 4,
name type c length 10,
score type i,
end of ty_stu.

data:t_stu type table of ty_stu with non-unique key
primary_key compoents num sub." primary_key键名  主键由num与sub共同确认 non-unique不唯一
data: t_stu1 type table of ty_stu."没有写内表是标准或排序 不写默认为标准表,
"不写默认非数字字段组合为主键 结构中有结构则无主键

data:t_stu2 type table of ty_stu with non-unique key table_line."整行是主键
data:t_stu3 type table of ty_stu with empty key."没有主键
data:t_stu type table of scarr with default key."沿用scarr这个透明表原有的主键

*----------------------------------------------------------------------------------------
types:begin of ty_tu,
num type n length 4,
sub type c length 4,
name type c length 10,
score type i,
end of ty_tu.
data: t_tu type table of ty_tu with header line,
s_stu type ty_tu."类似只有一行的工作区
data:s_stu1 like table of s_stu.
"================="
s_stu-num ='0001'.
s_stu-sub ='math'.
s_stu-name='tom'.
s_stu-score= '80'.
"=================="
append s_stu to s_stu1.
*insert s_stu into table s_stu1.
*insert s_stu into  s_stu1.
t_tu-num ='0002'.
t_tu-sub ='math'.
t_tu-name='jack'.
t_tu-score= '89'.
"=================="
append t_tu."不使用工作区
*无HEADER LINE赋值
move t_tu[] to s_stu1.

内表带有标题行

types:begin of ty_stu,
num type n length 4,
sub type c length 4,
name type c length 10,
score type i,
end of ty_stu.
data: t_stu type table of ty_stu,
s_stu type ty_stu.
s_stu-num='0001'.
s_stu-sub='math'.
s_stu-name='tom'.
s_stu-score='80'.
insert s_stu into table t_stu."添加一行数据进t_stu表中
field-symbols<fs> type ty_stu."代号moq
data stu_ref type ref to ty_stu."代号moqe
"================================================
*insert initial line into t_stu index 1 assigning<fs>."插入在位置1 之前 <fs>是一个结构指针
*<fs>-num ='0001'.
"效果一样
*insert initial line into t_stu index 1 reference into stu_ref.
*stu_ref->num = 0001.
"效果一样
*insert initial line into t_stu index 1 assigning field-symbol(<fs>)."可以少写moq这行
*<fs>-num=0001.
"效果一样
*insert initial line into t_stu index 1 reference into data(stu_ref)"可以少写moqe这行
*stu_ref->num = 0001.
data t1 type table of ty_stu.
insert s_stu into table t1. 
insert s_stu into table t1. 
insert s_stu into table t1. 

insert lines of t1 into table t_stu."将多行的表全部插入到t_stu中
loop at t1 into s_stu."将内表按照s_stu中的结构循环
insert s_stu into t1.将s_stu这一行数据插入t1中
endloop.
s_stu-numm=0002.
insert s_stu into t1 index 1.插入第一行 结果改变了第一行的num值
*append 可用于标准表和排序表不可用于哈希表
append s_stu to t_stu."填充一行

"聚集行
collect s_stu into t_stu."将s_stu的数值加入到t_stu中
collect s_stu into t_stu.
collect s_stu into t_stu."会累加数字部分

"排序行
sort t_stu."进行排序
sort t_stu by sore."根据sore字段排序由低到高
SORT t_stu DESCENDING BY sore ASCRNDING."根据sore字段排序由低到高
SORT t_stu DESCENDING BY sore DESCENDING."根据sore字段排序由高到低,降序

"读取数据
data t_stu type table of ty_stu with non-unique sorted key k_num.
data wa type ty_stu.
wa_num = 0001.
read table t_stu into s_stu from wa using key."不指名就是主键
read table t_stu into s_stu from wa using k_num."指明主键
*s_stu中存取进num=0001的数据
read table t_stu into s_stu with table key k_num component num=0002.
READ TABLE t_stu INTO s_stu INDEX 5 ."读取t_stu 的第 5 个行数据, 放入 s_stu 的字段中
t_stu-name = 'ABC'. 
READ TABLE t_stu INTO s_stu. "找出 ITAB 中name字段内容是 ABC 的行,找到的值放入 LINE 中
read table t_stu into s_stu with table key num=0001 sub='math'.
"s_stu中存取进num=0001且sub=math的数据
read table t_stu into s_stu index 2."s_stu中存取进第二行的元素
read table t_stu into s_stu index 2 using key k_num."用k_num排序后的第二行元素
loop at t_su into s_stu using key k_num."根据k_num键顺序
write /s_stu-num.
endloop.
loop at t_stu into s_stu from 1 to 2."执行两次
write s_stu-num.
endloop.
loop at t_stu into s_stu where name='Tom'."执行name=Tom的循环
write s_stu-num.
endloop.
data str type string value 'name = Jerry'.
loop at t_stu into s_stu where(str)."查询name = Jerry的行
write s_stu-num.
endloop.
loop at t_stu into s_stu.
at first.
write /s_stu-num."只有循环第一次进入at first中执行唯一的一次
endat.
at last.
write /s_stu-num."只有循环最后一次进入at last中执行唯一的一次
endat.
endloop.
loop at t_stu into s_stu.
at new sub."执行中其余字段会变为初始值字符串变****
endat 
at end of sub.
endat.
endloop.
loop at t_stu into s_stu.
at end of num.
sum."根据学号num求和不影响不改变t_stu表
endat.
endloop.

s_stu-num =0001.
s_stu-sub ='math'.
s_stu-score=50.
modify table t_stu using key k_num from s_stu."结果name为空分数为50学科math num为0001.
modify t_stu from s_stu index 2."将第二行的值改为s_stu的一样没有的name保持不变 
modify t_stu from s_stu."标准写法无论内表是否带表头行
loop at t_stu into s_stu using key k_num.
s_stu-score -=10.
"设置键名为loop_key
modify t_stu using key loop_key from s_stu transporting score."使t_stu中的分数都减少10.
endloop.
s_stu-score+= 20.
modify t_stu from s_stu transporting score where num = 0001and sub='math'.
"将0001 sub为math的分数加20.
modify t_stu from s_stu index 3 transporting score sub."将第三行的sub加20
s_stu-num = 0001.
s_stu-sub ='math'.
s_stu-name ='Tom'.
DELETE table t_stu from s_stu."正确写法无论内表是否带表头行
DELETE t_stu." "要在loop中用
delete table t_stu from s_stu."删除s_stu的这样的一行
delete table t_stu with table key primary_key component num=0001 sub='math' name='tom'."删除这样一行
delete t_stu index 3.删除第三行
delete t_stu where col = '000'."正确写法无论内表是否带表头行
loop at t_stu into s_stu using key k_num.
delete t_stu using key loop_key."一行一行的删除
endloop.
delete t_stu using key k_num from 1 to 2.删除一行到二行
DELETE t_stu FROM 3 TO 10. "删除第 3 至第 10 个行
delete  adjacent duplicates from t_stu using key k_num comparing num.
"删除重复num值数据只保留排在前面的第一个数据
sort t_stu by name.
delete adjacent DUPLICATES from t_stu comparing name."上一句根据name排序后再删除重复数据.
***********************************************************************************
SORT lt_resb_tmp BY rsnum.
DELETE ADJACENT DUPLICATES FROM lt_resb_tmp COMPARING rsnum.
"按什么字段排序删除什么重复,二分法读表也是如此
describe table t_stu lines data(lines).
write lines."输出结果为4表示有四行.
data(str) =lines(t_stu).
write str."结果为4
data(str) =line_index(t_stu[key k_num num=0002 sub='math']).
write str."结果为 num=0002 sub='math'满足条件的索引行数
data:begin of str1 occurs 10,
num type i,
name type c,
end of str1.
data:str2 like table of str1 with header line.
break-point.
Str2-num=10.
str2-name='A'.
append str2.
read table str2 index 1."结果为第一行为10,A
if str1[]  is initial."判断str1表是否为空.
endif.
clear:str1."清空工作区
clear str[]."清空str1[]表
refresh str2."清空.

COLLECT用法:

do 5 times.
gs_stu-col1 = 'a'.           
gs_stu-col2 = 10.
collect gs_stu into gt_stu.
enddo.
等同于
gs_stu-col1 = 'a'.
gs_stu-col2 = 10 + 10 + 10 + 10 + 10.
append gs_stu into gt_stu.

loop at gt_stu into gs_stu.
collect gs_stu into gt_stu.
endloop.
等同于
gs_stu-col1 = 'a'.
gs_stu-col2 = 10 + 10 + 10 + 10 + 10 + 50.
append gs_stu into gt_stu.

insert的高贵

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

data:begin of gt_stu occurs 0,
     col1 type c,
     col2 type i,
    end of gt_stu.
data gs_stu like line of gt_stu.
do 5 timms.
gs_stu-col1 = 'a'.
gs_stu-col2 = 2 * sy-index.
append gs_stu to gt_stu.
clear gs_stu.
enddo.
loop at gt_stu into gs_stu.
gs_stu-col1 = 'b'.
gs_stu-col2 = 2 * sy-tabix.
insert gs_stu into gt_stu.
clear gs_stu.
endloop.
"在 LOOP - ENDLOOP 循环内通过在当前行(例如带 SY-TABIX 返回索引的行)前插入新条目来处理它。
即在插入 1 插入 2 插入 3 插入 4 插入 5.这里插入在读取行的之前避免了死循环.
错误 loop -endloop 循环内append的会导致死循环. 

read的用法细节.

ABAP READ TABLE-CSDN博客

data: a type i,
      b type i.
sort gt_ekbe by col1 col2.
loop at gt_alv into gs_alv.
   a = sy-tabix."这里sy-tabix是loop循环次数记录
read table gt_ekbe into gs_ekbe with key col1 = gs_alv-col1 col2 = gs_alv-col2 binary search.
if sy-subrc is initial.
   b = sy-tabix."这里sy-tabix是read读到满足条件的行索引
endif.
endloop.
"通过上述可以加快双重loop循环效率.
"毕竟read的效率比loop高许多

read table t_stu into s_stu with key 字段名 = 值 binary search."二分查找需要排序
 READ TABLE GT_VBFA WITH KEY VBELV = GS_LIST-Billing_Doc BINARY SEARCH TRANSPORTING NO FIELDS.
"其中TRANSPORTING NO FIELDS表示只读取不传值给工作区.

read table进阶

READ TABLE ITAB  WITH TABLE KEY COL1 = 3 INTO LINE.
或者
READ TABLE ITAB INTO LINE WITH TABLE KEY COL1 = 3 .均可

TRANSPORTING读取一行的部分字段
系统根据<key>(关键字段)条件查找对应的条目后,只将TRANSPORTING中指定的组件字段存储到工作区域中。
DATA: BEGIN OF LINE,
        COL1 TYPE I,
        COL2 TYPE I,
      END OF LINE.
DATA ITAB LIKE SORTED TABLE OF LINE WITH UNIQUE KEY COL1.

DO 4 TIMES.
  LINE-COL1 = SY-INDEX.
  LINE-COL2 = SY-INDEX ** 2.
  INSERT LINE INTO TABLE ITAB.
ENDDO.

CLEAR LINE.
READ TABLE ITAB WITH TABLE KEY COL1 = 3 INTO LINE TRANSPORTING COL2."主键没有被传输

WRITE: 'SY-SUBRC =', SY-SUBRC,
       'SY-TABIX =', SY-TABIX.
WRITE: / LINE-COL1, LINE-COL2.


DATA: BEGIN OF LINE,
        COL1 TYPE I,
        COL2 TYPE I,
      END OF LINE.
DATA ITAB LIKE HASHED TABLE OF LINE WITH UNIQUE KEY COL1.

DO 3 TIMES.
  LINE-COL1 = SY-INDEX.
  LINE-COL2 = SY-INDEX ** 2.
  INSERT LINE INTO TABLE ITAB.
ENDDO.

LINE-COL1 = 2.
LINE-COL2 = 4.

READ TABLE ITAB FROM LINE INTO LINE COMPARING COL2."这里需要key,没有会提示如图一
WRITE: 'SY-SUBRC =', SY-SUBRC.
WRITE: / LINE-COL1, LINE-COL2.


DATA: BEGIN OF LINE,
        COL1 TYPE I,
        COL2 TYPE I,
        COL3 TYPE I,
      END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.

DO 10 TIMES.
  LINE-COL1 = SY-INDEX.
  LINE-COL2 = SY-INDEX ** 2.
  LINE-COL3 = SY-INDEX ** 3.
  APPEND LINE TO ITAB.
ENDDO.

*CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( ITAB ).

CLEAR: LINE.
LINE-COL1 = 2.
LINE-COL2 = 4.

"只要根据关键字或索引条件在内表中读取到相应数据,不管该数据行是否
"与COMPARING 指定的字段相符,都会覆盖存储到工作区中。
READ TABLE ITAB INTO LINE INDEX 4 COMPARING COL1 COL2.
WRITE: / SY-SUBRC, SY-TABIX,LINE-COL1,LINE-COL2,LINE-COL3.

CLEAR: LINE-COL3.
"也可以使用关键字KEY来读取指定行再进行比较  当二者相等时sy-subrc 为 0
READ TABLE ITAB INTO LINE WITH KEY COL1 = 4 COL2 = 16 COMPARING COL1 COL2.
WRITE: / SY-SUBRC, SY-TABIX,LINE-COL1,LINE-COL2,LINE-COL3.

图一

内表排序语法

【转】ABAP的坑4_abap sort by-CSDN博客

6、稳定排序
按照指定序列对内表排序后,如果还要按照更高级别的字段排序,请使用稳定排序法,语法为:SORT itab STABLE BY...

STABLE 可用于执行稳定的排序。行的相对顺序(在排序键中相同)在排序时保持不变。如果没有添加 STABLE,顺序就不稳定,对具有相同排序键的提取数据集进行重复排序会改变每次排序的顺序。

7、动态指定字段排序

SORT itab BY (comp1)...(compn) .

或者:

SORT itab BY (otab).

otab是一个内表,结构是ABAP_SORTORDER。

ABAP SORT的语法小记-CSDN博客

关于ABAP排序不稳定的问题_abap stable by-CSDN博客

那又在表名后面加又在字段加的话,还是有个先后顺序的,就跟ALV字段颜色设鲁一样、单元格,行,列的颜色局时左在会有优先级。排序也一样,先讲行表的排序,再对字段讲行排序。具体例子就不举例了,自己去DEBUG看能更好的理解,也不是很难理解
SORT TABLE DESCENDING BY XXX ASCENDING XX(对TABLE进行降序之后,再对XXX进行升序)

SORT在用于给内表排序时,后面可以用ASCENDING和DESCENDING进行升序和降序排列,但是这其中用法很多,经过尝试后总结如下:

1.SORT LT_TAB BY WERKS LGORT EMAIL.

正常排序并使用默认ASCENDING.

2.SORT LT_TAB BY WERKS LGORT EMAIL DESCENDING.

前两个字段默认升序排列,EMAIL字段为降序排列。

3.SORT LT_TAB BY WERKS LGORT DESCENDING EMAIL .

第一第三字段为默认升序,第二字段为降序

由此可知写在字段后面的ASC和DES只能控制这一个字段。

4.SORT LT_TAB DESCENDING BY WERKS LGORT EMAIL .

写在表名后面的ASC和DEC可以控制所有字段的排序。

5.SORT LT_TAB ASCENDING BY WERKS DESCENDING LGORT  EMAIL.

此时第一个字段降序,其他为升序。

6.SORT LT_TAB DESCENDING BY WERKS  LGORT ASCENDING EMAIL.

此时整体为降序,但第二个字段为升序。

总结,内表后的DEC会控制整个表的排序,如果此时某字段后面有DEC或者ASC,则在整个内表排序完成之后再进行字段排序。

对内表操作:  gt开头为内表(gt_zav,gt_S001),wa开头为工作区(wa_zav,wa_S001)

*修改
*MODIFY TABLE gt_zav FROM wa_zav. "修改整行
*MODIFY TABLE gt_zav FROM wa_zav TRANSPORTING carrid. "修改某行的一字段
*MODIFY gt_S001 FROM wa_S001 INDEX 1. "根据下标修改整行
*MODIFY gt_S001 FROM wa_S001 INDEX 1 TRANSPORTING spmon. "根据下标修改一行某个字段
*MODIFY gt_S001 FROM wa_S001 TRANSPORTING spmon WHERE spmon = '199701'. "根据条件修改多行符合条件的


*删除
*DELETE TABLE gt_zav from wa_zav. "删除一条
*DELETE gt_zav WHERE carrid = '1'. "根据条件删除多条
*DELETE gt_zav FROM 5 TO 10. "删除5到10
*DELETE gt_zav FROM 5. "除5以后的
*DELETE gt_zav TO 10. "除开始到第十条的


*插入 (如果带表头的表,或者内表和工作区同名,这可以用隐式插入,不需要什么工作区INTO到什么表)
*Append xx "带表头 插入到表最后一行
*APPEND 工作区 TO 内表 "不带表头 插入到表最后一行
*APPEND LINES OF gt_S002 TO gt_S001. "将gt_S002表所有数据插入gt_S001表的表尾巴
*APPEND LINES OF gt_S002 FROM 2 TO 4 TO gt_S001. "将gt_S002表的2到4行插入gt_S001表的表尾巴
*COLLECT wa_S001 INTO gt_S001. "所有字段不同插入表尾,所有字段相同,只有数值字段不同则数字字段汇总,变为一条数据
*INSERT wa_S001 INTO TABLE gt_S001. "插入一条到表尾
*INSERT wa_S001 INTO gt_S001 INDEX 3 . "插入一条数据至下标行
*INSERT LINES OF gt_S002 INTO TABLE gt_S001. "将gt_S002表所有数据插入gt_S001表的表尾巴
*INSERT LINES OF gt_S002 FROM 2 TO 4 INTO TABLE gt_S001. "将gt_S002表的2到4行插入gt_S001表的表尾巴
*注:使用INSERT时,如果表内已存在唯一主键,则sy-subrc会返回4,但不会dump error,反之sy-subrc会返回0


*读取 (读取内表数据 read是根据key去整个表里查,所以 read得表不用在循环了;带表头和工作区与表名一致的可以省略into后语句,读取成功sy-subrc返回0,否则返回4)
*读取内表
READ TABLE gt_S001 INTO wa_S001 WITH KEY matnr = 'PC_SERVICE_A'. "读取内表符合条件的字段入工作区,如果有多条,取内表符合的第一条sy-subrc返回0
READ TABLE gt_S001 FROM wa_S001 INTO wa_S001. "读取内表符合条件的字段入工作区,如果有多条,则取不到值sy-subrc返回4
READ TABLE gt_S001 INTO wa_S001 INDEX 1. "读取内表下标为x的放入工作区
READ TABLE gt_S001 WITH TABLE KEY 字段 = 'xxxx' 字段 ='xxx' INTO wa_S001. "这必须key的键值条件写全,否则报错缺少表xx的键值primary_key的组件 字段说明..
READ TABLE 内表 INTO 工作区

*备注:

*读取alv双击的下标行数据放入工作区 (注:rs_selfield TYPE slis_selfield.)
READ TABLE 内表 INTO DATA(工作区) INDEX rs_selfield-tabindex
*获取点击的字段的值
rs_selfield-fieldname

追加行

语法:
APPEND [<wa>] TO [Initial Line To] <itab>
[Initial Line To] 为增加一预设初值的行
append  INITIAL LINE TO <内表>."增加一行初值行
示例 1 :使用工作区
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 2 TIMES.
LINE-COL1 = SY-INDEX. "SY-INDEX 为循环的计数器
LINE-COL2 = SY-INDEX ** 2.
APPEND LINE TO ITAB. " 新增至内表中
ENDDO.
LOOP AT ITAB INTO LINE. "ITAB 总共有两个行
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
执行结果为:
1 1
2 4
示例 2 :不使用工作区
DATA: BEGIN OF ITAB OCCURS 10,
COL1 TYPE I,
COL2 TYPE I,
END OF ITAB.
DO 2 TIMES.
ITAB-COL1 = SY-INDEX.
ITAB-COL2 = SY-INDEX ** 2.
APPEND ITAB. " 新增至内表中
ENDDO.
LOOP AT ITAB. "ITAB 总共有两个行
WRITE: / ITAB-COL1, ITAB-COL2.
ENDLOOP.
执行结果为:
22 ABAP/4 入门教程
1 1
2 4
加入另一内表的行
语法:
APPEND LINES OF <itab1> [FROM <n1>] [TO <n2>] TO <itab2>
<itab1> 的行加入至 <itab2> , 可选取自 <n1> <n2> 的范围
示例:
APPEND LINES OF ITAB TO JTAB.
ITAB 所有行加入JTAB
聚集行
在加入新行时将有相同标准键( standard key ,非数值字段)的数值字段汇总
语法:
COLLECT [<wa> INTO] <itab>
示例:
DATA: BEGIN OF ITAB OCCURS 3,
COL1(3) TYPE C,
COL2 TYPE I,
END OF ITAB.
ITAB-COL1 = 'ABC'. ITAB-COL2 = 10.
COLLECT ITAB.
ITAB-COL1 = 'XYZ'. ITAB-COL2 = 20.
COLLECT ITAB.
ITAB-COL1 = 'ABC'. ITAB-COL2 = 30.
COLLECT ITAB. " 汇总 COL2 COL1=ABC 的元素上
LOOP AT ITAB.
WRITE: / ITAB-COL1, ITAB-COL2.
ENDLOOP.
执行结果 :
ABC 40
XYZ 20
插入行
在指定的内表行位置之前插入行
语法:
INSERT [<wa> INTO] [INITIAL LINE INTO] <itab> [INDEX <idx>]
示例:
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 3 TIMES.
LINE-COL1 = SY-INDEX * 10.
LINE-COL2 = SY-INDEX * 20.
APPEND LINE TO ITAB.
ENDDO.
LINE-COL1 = 100.
LINE-COL2 = 200.
INSERT LINE INTO ITAB INDEX 2. "插入在位置2 之前
LOOP AT ITAB INTO LINE.
WRITE: / SY-TABIX, LINE-COL1, LINE-COL2. "SY-TABIX 为Table 位置
ENDLOOP.
执行结果:
1 10 20
2 100 200 “ 插入的行
3 20 40
4 30 60
插入另一内表行
语法:
INSERT LINES OF <itab1> [FROM <n1> TO <n2>] TO <itab2> INDEX <idx>
<itab1> 的行插入至 <itab2> 中,位置在 <idx> 之前,可选取自 <n1> <n2> 的范围
示例:
INSERT LINES OF ITAB TO JTAB INDEX 3.
ITAB 所有行插入 JTAB 中,位置在第三个行之前
INSERT INITIAL LINE TO  <内表>.

向内表插入初值行

内表行数据的读取
语法:
LOOP AT <itab> [INTO <wa>] [FROM <n1> TO <n2>] [WHERE <condition>]
<loop expression>
ENDLOOP.

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

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

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

24 ABAP/4 入门教程
根据设定的范围选取行记录,读完后自动移往下一行
示例:
LOOP AT ITAB INTO LINE WHERE COL1 >100.
WRITE: / SY-TABIX, LINE-COL1.
ENDLOOP.
仅读取 COL1 > 100 的行
读取内表指定位置的行
语法:
READ TABLE <itab> [INTO <wa>] INDEX <idx>
自指定位置 <idx> 读取行数据
示例:
READ TABLE ITAB INTO LINE INDEX 5
读取 ITAB 的第 5 个行数据 , 放入 LINE 的字段中
二分查找( 效率高
语法:
read table <itab> binary search with key col1>10
                                                                 col2>12.
      仅读取 COL1 > 10且col2 > 12 的行.
示例:
sort line by vkorg
             vtweg.
read table line binary search with key vkorg = 10
                                       vtweg = 20."使用二分法读必须要先排序

根据字段内容寻找

语法:
READ TABLE <itab> INTO <wa>
示例:
ITAB-COL1 = 'ABC'.
READ TABLE ITAB INTO LINE.
找出 ITAB COL1 字段内容是 ABC 的行,找到的值放入 LINE
若找到 SY-SUBRC 的值为 0 ,找不到则值为 4 <itab> 必须声明有工作区
更改行内容
语法:
MODIFY <itab> [FROM <wa>] [INDEX <idx>] [TRANSPORTING <f1>…<f2>] [WHERE
<condition>]
TRANSPORTING <f1> ..<f2> : 指定更改的字段名称
示例:
LINE-COL1 = 4.
LINE-COL2 = 100.
MODIFY ITAB INDEX 2 FROM LINE.
将目前位置行以 LINE 的内容更改
示例:
LINE-COL1 = 10.
MODIFY ITAB FROM LINE INDEX 3 TRANSPORTING COL1 COL2.
将第三个行的 COL1 字段更改为 10
通过工作区修改内表
loop at gt_xyy into wa_xyy.
wa_xyy-b = wa_xyy-b + 1.
modify gt_xyy from wa_xyy."这个只在loop循环中能用
endloop.

modify <itab>."自带工作区的内表都不能直接用而是要在loop循环中加

modify <wa_itab> from <itab>.不能直接用而是要在loop循环中加

[原因]modify在内表中不是有就修改 没有就添加的modify.

删除行
删除内表的行
语法:
DELETE <itab> INDEX <idx>
示例:
DELETE ITAB INDEX 4
删除第四个行
加上删除条件:
DELETE <itab> [FROM <n1> TO <n2>] [WHERE <condition>]
示例:
DELETE ITAB FROM 3 TO 10.
删除第 3 至第 10 个行
删除重复行
delete adjacent duplicates from <itab> comparing <col1>
                                                                                <col2>
                                                                                <col3>.
示例:
sort <itab> by <col1>
               <col2>
               <col3>.
delete adjacent duplicates from <itab> comparing <col1>
                                                 <col2>
                                                 <col3>."删除重复数据时必须先排序

内表排序

语法:
SORT <itab> [<order>] [BY <f1>] ….
[<order>] : 可分成递减 (DESCENDING) 和递增 (ASCENDING) ,空白表示 ASCENDING
<f1>: 为指定的字段
示例:
SORT ITAB DESCENDING BY COL2.
ITAB 根据 COL2 字段递减排序
计算数值字段总和
语法:
SUM
计算得总和存在工作区中,但只能存在 LOOP 语句中
示例:
LOOP AT ITAB INTO LINE.
SUM.
ENDLOOP.
WRITE: / LINE-COL1, LINE-COL2.
LINE-COL1 LINE-COL2 存数值总和
计算表行数
DESCRIBE TABLE <itab> lines <int类型变量>.
示例:
data variable type i.
describe table itab lines variable.
if variable = 0.
endif."可以判断内表是否为空

初始化表

1. REFRESH <itab>
使用在没有 HEADER LINE 的内表中,清除所有行
示例:
REFRESH ITAB.
2. CLEAR <itab>[ ]
使用在有 HEADER LINE 的内表中,清除所有行
示例:
CLEAR ITAB[ ].
3. FREE <itab>
释放 (Release) 内表所占的内存空间,用在 REFRESH CLEAR 命令之后
示例:
FREE ITAB.

ABAP内表操作的基本语法

1、将内表中所有的数据数据拼接在一行上的语法。

CONCATENATE LINES OF GT_ZMTZBZ INTO LV_ZBZ SEPARATED BY '/'.

"将内表中的字段全部拼接在一行,以/的方式隔开。
GT_ZMTZBZ是内表的名字

2、将内表中几个字段进行拼接的语法

CONCATENATE LV_ZBZ1 LV_ZBZ2  INTO LV_ZBZ SEPARATED BY '/'.

这句话只能拼接几个字符,个数是确定的
LV_ZBZ1 LV_ZBZ2是两个字段的名字
eg: * CONCATENATE合并字符串

 DATA: c1(10)  TYPE c VALUE  'Sum',
        c2(3)   TYPE c VALUE  'mer',
        c3(5)   TYPE c VALUE  'holi ',
        c4(10)  TYPE c VALUE  'day',
        c5(30)  TYPE c ,
        sep(3)  TYPE c VALUE ' - '.
  CONCATENATE c1 c2 c3 c4 INTO c5.
  WRITE c5.
 CONCATENATE c1 c2 c3 c4 INTO c5 SEPARATED BY sep.
 WRITE / c5.
输出结果:
Summerholiday
Sum - mer - holi - day

3、modify 的使用
modify 内表 from 工作区。
modify用于更新和新增数据,当表中没有数据时就新增,有就修改。

4、在函数模块中建立的表要进行赋值的话,一定要用传入的参数中的字段才能进行赋值。
5、如果在ALV中出现了重复的列,那么要删除fieldcat的内表值。
6、INTO CORRESPONDING FIELDS OF TABLE
INTO CORRESPONDING FIELDS OF TABLE 是根据字段名匹配,如果有时候定义的内表直接参照一个表的话,没有单独为他写一个结构,那么在添加数据的时候就需要加上这句话。

7、内表的整体赋值:
如果想一次 将内表的全 部内容复制 到另一内表 中,请使用 MOVE 语句或赋值 操作符 (=),用 法如下:
MOVE TO . 该语句等价于:
= .

8、如何删除动态内表中的数据以及怎样写条件。
 

  READ TABLE  <DYN_TABLE>  ASSIGNING <DYN_WA>  WITH KEY (<LFS_MATNR>)= LS_MARD-MATNR
 (<LFS_WERKS>) = LS_MARD-WERKS
 (<LFS_LGORT>) = LS_MARD-LGORT.

9、删除内表中因为某一列有重复的数据
SORT GT_KEY BY MKMNR DESCENDING. "如果要按照某个字段进行删除的话,那么一定要先按照那个字段进行排序
DELETE ADJACENT DUPLICATES FROM GT_KEY COMPARING MKMNR. "删除MKMAN相同的重复列
MKMNR是内表中字段的名字。

10、SELECT DISTINCT
distinct 去掉重复的 取唯一

11、在ABAP 中左连接LEFT JOIN、右连接NIGHT JOIN后,不能使用WHERE 加限制条件,否则会报错:
12、使用SELECT语句选择查询:
SY-SUBRC = 0: 至少有一行数据,当ENDSELECT语句执行完,SY-DBCNT中保存着记录的个数。
SY-SUBRC = 4: 没有数据。
SY-SUBRC = 8: 只有使用“SELECT SINGLE FOR UPDATE”时才会有,
表示: WHERE条件指定的记录不止一行,结果是没有记录被选中。

13、使用INSERT语句,向表中插入一行,必须注意INSERT的顺序与表中字段的顺序一致:
SY-SUBRC = 0: 插入成功,SY-DBCNT包含了插入的行数,0或1。
SY-SUBRC = 4: 由于有相同的KEY存在,所以插入失败。
13、使用LOOP语句来遍历一个内表:
SY-SUBRC = 0: 循环至少被执行一次。
SY-SUBRC = 4: 循环没有被执行,可能是没有数据,也可能是没有符合条件的记录。

14、使用DELETE语句来删除一条记录:
SY-SUBRC = 0: 找到一行并删除之,如果该表有不唯一主键,也就是有多条重复的记录,则只删除第一条记录。
SY-SUBRC = 4: 没有找到符合条件的记录,也没有删除。

15、使用UPDATE语句来更新一条记录:
SY-SUBRC = 0: 找到记录并更新,(如果有多条记录呢?)
SY-SUBRC = 4: 没有找到符合条件的记录,也没有更新。

16、sy-index和sy-tabix字段
sy-index和sy-tabix都是系统字段,用来记录循环的次数。
sy-index 在DO…ENDDO循环里有效;
而sy-tabix在loop at …endloop里有效。

17、一个表中有物料另一个表中没有此物料,如何写该语句
 

SELECT MBEWH~MATNR
     FROM MBEWH
    WHERE MBEWH~BWKEY IN @S_WERKS
    INTO TABLE @DATA(LT_MATNR).
SELECT MBEW~MATNR,
       MBEW~SALK3, "总价值
       MBEW~LBKUM,  "总库存
       MBEW~LFGJA,
       MBEW~LFMON
  INTO TABLE @DATA(LT_MBEW1)
  FROM MBEW
  FOR ALL ENTRIES IN @LT_MATNR
  WHERE MATNR <> @LT_MATNR-MATNR
       AND MBEW~BWKEY IN @S_WERKS.

18、定义一个包含表头的内表

data: begin of lt_mat occurs 0,
matnr type matnr,
maktx type maktx,
end of lt_mat.

19、参考数据结构来定义内表
data: lt_mat like table of ls_matnr with header line

20、参考数据结构来创建内表
data:begin of lt_matnr occurs 0.
include structure ls_matnr.
data:end of lt_matnr.

21、constants定义常量,需要赋予初始值,且常量在程序运行中不能被更改
eg:constants l_str(10)type c value ‘hello world’.

22、内表,字符串以及循环的处理
(1)读内表是加上扩展语句 binary search.
eg: read table tab1 with key id = ‘01’ binary search.
(2)通过loop语句循环读取内表时,可以根据数据需求加上where条件

23、ABAP中的系统字段
(1)sy-batch
sy-batch ='X ’ 是后台运行,
sy-batch等于空就是前台运行。

24、Ranges的用法
 

 RANGES: R_HKONT FOR BSEG-HKONT.
  R_HKONT-SIGN = 'I'.
  R_HKONT-OPTION = 'CP'.

1.SIGN 值为 I 和 E 。 I是包含, E是排除, 一般使用I。
2.OPTION 如果HIGH 为空 ,为单值选择 。有 EQ、NE、GT、LE、LT等逻辑操作 对于*的 CP包含 NP是排除

如果HIGH 不为空 为区间选择 有BT,NB可选
3.LOW 低值
4.HIGH 高值
25、AT NEW 和AT END OF 的用法
AT New f 或者 AT END OF f
f 是内表的一个字段,当f字段或者f字段左边的字段内容发生变化是该事件后面的语句都会执行。
使用 AT NEW f … ENDAT。 和 AT END OF f … ENDAT。 时需要注意:
1,f 必须是内表的第一个字段。
2,内表中f 之后的字段的值都会变成 *。

26、 read Table的语句使用注意点:
(1)READ TABLE itab WITH KEY = v BINARY SEARCH.
(2)WITH KEY 中的检索条件比较符不能使用‘<>’(不等于)。
(3) read table 和loop table 中的条件问题:
 

Eg: READ TABLE  GT_BSEG_CFL INTO  LS_BSEG_JE WITH  KEY BELNR =  <LFS_BSEG>-BELNR.

BELNR 字段是 GT_BSEG_CFL 表中的字段,
<LFS_BSEG>-BELNR 字段是另一个内表中的字段

Eg:LOOP AT GT_ZFIT0045 INTO LS_ZFIT0045 WHERE ZFIHKONT1 =  GS_OUTPUT-HKONT. 

endloop.
ZFIHKONT1字段是GT_ZFIT0045表中的字段。
GS_OUTPUT-HKONT字段是另一个内表GT_OUTPUT中的字段。

补充https://mp.csdn.net/mp_blog/creation/editor/129039268?not_checkout=1

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 中要附加的第一或最后一行。

用该方式将表格行附加到另一个表格中的速度比在循环中逐行进行附加快 3 到 4 倍。在 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> = <itab 1>. <itab3> = <itab 2>. <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 值。

如下所述,可以定义多个关键字 :

  • 定义一系列关键字段

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

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

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

  • 将整行定义为关键字

通过使用 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 用 MODIF 更改行#

要用 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> 对数据集进行排序。这些字段可以是任何类型,包括类型 P 、 I 和 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> 的最后一行。而是系统插入新行,这样内表 就根据字段 <f> 以降序排序。

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

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

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

7.7 AT……ENDAT行组控制级别#

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

AT <line>.

<statement block>

ENDAT.

在处理 AT - ENDAT 内语句块的行条件 <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时需注意:

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

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

使用AT NEWAT FIRSTAT 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 ...

DELETE 内表语法

代码

DELETE table t_stu from s_stu.      "正确写法无论内表是否带表头行
DELETE lt_table2 where col = '0000'."正确写法无论内表是否带表头行
"删除重复num值数据只保留排在前面的第一个数据
sort t_stu by name.
delete adjacent ouplicates from t_stu comparing name."
sort lt_table2.
delete adjacent DUPLICATES  from lt_table2.
*注意内表行数
delete lt_table2 index 3."删除第三行
DELETE lt_table2 FROM 3 TO 10. "删除第 3 至第 10 个行
DELETE lt_table2 FROM 3."删除第三行及后面的所有行最终只留两行
"DELETE lt_table2 where col < '0020'."正确写法无论内表是否带表头行

错误写法

DELETE itab FROM wa.
***不在loop中执行则会报错
DELETE itab[ ].
DELETE itab.

DELETE itab FROM wa.错误原因

这里会将wa这个工作区当成数字从而引发强制类型转换错误CONVT_NO_NUMBER.

类似

DATA nt TYPE string.

nt = '的'   .

DATA: lo_root TYPE REF TO cx_root.
DATA: lv_message TYPE string.
TRY.
  IF NT < 0.
    WRITE : 12.
  ENDIF.

  CATCH cx_root INTO lo_root.
    CLEAR lv_message.
    lv_message = lo_root->get_text( ).
ENDTRY.

这里就会报错.因为是CONVT_NO_NUMBER.错误不是CX开头错误所以这里也捕获不到,程序dump.

DELETE table itab FROM wa.加上table 才能正确执行

加上delete <数据表> form ls_stu.删除数据库表数据是这样子 需要有所区分

table 不可以去掉

LOOP AT ITAB INTO DATA(WA).
WA-COL = '9999'.
MODIFY ITAB FROM WA.
DELETE itab[ ]."DELETE itab.两句效果一样内表不管带不带表头
ENDLOOP.

"MODIFY ITAB FROM WA.同样只能在loop itab循环中执行

带表头和不带表头的区别

delete table t_stu."带表头可以执行

delete table t_stu[]."带表头也不可以执行

delete table t_stu."不带表头也不可以执行

往内表中加入空行

INSERT INITIAL LINE INTO <内表> INDEX 1.

如果只是往内表最后一行增加一行空数据,则可使用语句APPEN INITIAL LINE TO <内表>

https://www.cnblogs.com/zyhcs/p/15707043.html#:~:text=%E8%A6%81%E5%B0%86%E8%A1%8C%E9%99%84%E5%8A%A0%E5%88%B0%E5%86%85%E8%A1%A8%E4%B8%AD%EF%BC%8C%E4%BD%BF%E7%94%A8%20APPEND%20%E8%AF%AD%E5%8F%A5%EF%BC%8C%E7%94%A8%E6%B3%95%E5%A6%82%E4%B8%8B%EF%BC%9A%20APPEND%20%5B%3Cwa%3E%20TO%7CINITIAL%20LINE%20TO%5D,%3Citab%3E%20%E4%B8%AD%E3%80%82%20%E9%80%9A%E8%BF%87%E4%BD%BF%E7%94%A8%20%3Cwa%3E%20TO%20%E9%80%89%E9%A1%B9%EF%BC%8C%E6%8C%87%E5%AE%9A%E8%A6%81%E9%99%84%E5%8A%A0%E7%9A%84%E6%BA%90%E5%8C%BA%E5%9F%9F%20%3Cwa%3E%20%E3%80%82

内表操作的注意事项

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值