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中执行
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."表里有key则删除s_stu的这样的一行,无key则永远删除第一行
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'."正确写法无论内表是否带表头行
DELETE GT_ITEM WHERE MATNR NOT IN S_MATNR .使用该语句前需要判断S_MATNR[]不为空
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博客
WITH KEY 中的检索条件比较符不能使用‘<>’(不等于)。
如果只想取得内部表中不等于某条件的一条记录,那么请使用下面变通方法。
LOOP AT itab WHERE KEY <> ‘XX’.
此处取得第一条记录。
EXIT.
ENDLOOP.
如果在运行时 <KEY> 值为空,则 统忽略该关键字段。另外可对关键字段指定偏移量和长度。
BTW:
感谢binary search,有一次到日本做项目,有这么个课题,
内部表中的数据如下
A B C
01 001 20060301
01 001 20060201
01 001 20060101
要求取出距现在时间最近的记录。
我的做法是先排序
SORT IT_TAB BY A
B ASCENDING
C DESCENDING.
然后用二分法读取
READ IT_TAB INTO WA_TAB WITH KEY A = '01'
B = '001'
BINARY SEARCH.
应该取到01 001 20060301这条记录。(也确实取得是这条记录)
这时来之日本SAP公司的检证人员就挑毛病了,说你用二分法从中间切入?怎么能保证取到20060301这条,而不是20060201?
SE接到质问让我抓图证明用二分法没错,否则改用普通READ。
我听了马上告诉SE,ABAP语法就是这样的,这是“常识”!
系统如果找到匹配指定关键字的多行,则读取索引最低的行。
经过我的特殊排序后,20060301所在行索引最低。
READ TABLE gt_table INTO gs_table INDEX 1.
READ TABLE gt_table INTO gs_table WITH TABLE KEY c1 = field.
READ TABLE gt_table INTO gs_table WITH KEY c1 = field.
READ TABLE gt_table INTO gs_table WITH KEY c1 = field BINARY SEARCH.
READ TABLE gt_table INTO gs_table INDEX 1 COMPARING c1.
READ TABLE gt_table INTO gs_table INDEX 1 COMPARING ALL FIELDS.
READ TABLE gt_table INTO gs_table INDEX 1 TRANSPORTING c1 c2.
READ TABLE gt_table INDEX 1 TRANSPORTING NO FIELDS.
INDEX :索引,根据内表索引来查找
WITH KEY/WITH TABLE KEY:通过内表的主键来查找
*WITH TABLE KEY 后必须把表的所有关键字都加上,WITH KEY不用
BINARY SEARCH:二分法(使用前需排序,常识不用多说吧)
COMPARING:只查找设置的字段
COMPARING ALL FIELDS:查找所有字段
TRANSPORTING:只输出设置的字段数据
TRANSPORTING NO FIELDS:不输出字段,只判断是否存在(与IF SY-SUBRC一起搭配)
下面重点提一下COMPARING和TRANSPORTING
原文链接:https://blog.csdn.net/qq_50300216/article/details/138277903
READ TABLE gt_table INTO gs_table INDEX 1 COMPARING c1.
COMPARING关键词会先将gs_table(工作区)的字段C1与gt_table(内表)的1行(INDEX 索引)中的C1做对比
如果比对结构相同,sy-subrc = 0.若不同,sy-subrc = 2,未找到则sy-subrc = 4.
不管如何只要找到(INDEX 1,找到第一条)就会进行赋值
如果COMPARING后面是ALL FIELDS,则将比较所有字段
DATA: BEGIN OF gs_table,
c1 TYPE i,
c2 TYPE i,
END OF gs_table.
DATA gt_table LIKE HASHED TABLE OF gs_table WITH UNIQUE KEY c1.
DO 6 TIMES.
gs_table-c1 = sy-index.
gs_table-c2 = sy-index * 2.
INSERT gs_table INTO TABLE gt_table.
ENDDO.
gs_table-c1 = 3.
gs_table-c2 = 8.
READ TABLE gt_table FROM gs_table INTO gs_table COMPARING c2.
WRITE: 'SY-SUBRC =', sy-subrc.
SKIP.
WRITE: / gs_table-c1, gs_table-c2.
输出:
SY-SUBRC = 2
3 6
READ TABLE gt_table INTO gs_table INDEX 1 TRANSPORTING c1.
TRANSPORTING关键词只将关键词后面的字段(c1)写入工作区(gs_table)
若TRANSPORTING关键词是 NO FIELDS,则只查询,工作区可不写(写了也无效果)
READ TABLE gt_table INDEX 1 TRANSPORTING c1.
一般后接 IF sy-subrc = 0.进行判断
DATA: BEGIN OF gs_table,
c1 TYPE i,
c2 TYPE i,
END OF gs_table.
DATA gt_table LIKE HASHED TABLE OF gs_table WITH UNIQUE KEY c1.
DO 6 TIMES.
gs_table-c1 = sy-index.
gs_table-c2 = sy-index * 2.
INSERT gs_table INTO TABLE gt_table.
ENDDO.
gs_table-c1 = 3.
gs_table-c2 = 8.
*READ TABLE gt_table INTO gs_table WITH KEY c1 = gs_table-c1 TRANSPORTING c1.
READ TABLE gt_table WITH KEY c1 = gs_table-c1 TRANSPORTING NO FIELDS.
WRITE: 'SY-SUBRC =', sy-subrc.
SKIP.
WRITE: / gs_table-c1, gs_table-c2.
结果都为:
SY-SUBRC = 0
3 8
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排序不稳定的问题_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
追加行
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.
INSERT LINES OF ITAB TO JTAB INDEX 3.
INSERT INITIAL LINE TO <内表>.
向内表插入初值行
可以使用 FROM
、 TO
或 WHERE
选项限制要在循环中进行处理的行数。
使用 FROM
选项,可以用 <n1>
指定要读取的第一行 。"往后继续读
使用 TO
选项,可以用 <n2>
指定要读取的最后一行。
sort line by vkorg
vtweg.
read table line binary search with key vkorg = 10
vtweg = 20."使用二分法读必须要先排序
根据字段内容寻找
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.
sort <itab> by <col1>
<col2>
<col3>.
delete adjacent duplicates from <itab> comparing <col1>
<col2>
<col3>."删除重复数据时必须先排序
内表排序
data variable type i.
describe table itab lines variable.
if variable = 0.
endif."可以判断内表是否为空
初始化表
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 NEW
, AT FIRST
, AT LAST
,AT END OF
时需注意:LOOP
的时候不能加条件;AT
和ENDAT
之间不能使用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."不带表头也不可以执行
DELETE语句使用建议与防坑介绍
ABAP 删除内表解析_abap删除内表中符合条件的行-CSDN博客
1. DELETE itab[ ]
用于loop当中,删除当前loop行,read table 会改变sy-tabix的值,但是不影响该语法执行结果
例:LOOP ATgt_item INTO gs_item .
DELETE gt_item[] .
ENDLOOP .
2. DELETE itab INDEX i.
删除内表中的指定行
例: DELETE GT_ITEM INDEX 20 .
注意:该语句不建议在loop循环中使用,因为loop循环中删除了行会影响内表的行索引。
3. DELETE TABLE itab FROM wa.
删除内表KEY值与工作区KEY值相同的行, 关键字TABLE不能丢,否则执行会报错.
4. 删除内表中的重复行
注意要先排序SORT itab BY ****.
DELETE ADJACENT DUPLICATES FROM itab. 保留第一条数据
例:DELETE ADJACENT DUPLICATES FROM lt_matdoc COMPARING matnr charg.
匹配参数 matnr charg ,删除物料编码与批次相同的行,如果不带COMPARING MATNR CHARG这段,只会删除完成一样的行。
5. 删除内表中符合条件的行。
DELETE GT_** WHERE ******
WHERE 后面的判断可以对字段做花式判断,也可以特意加一个字段用作删除标记,DELETE GT_** WHERE FIELD = ‘X’.删除有标记的行。
也可以使用range表
例:DELETE GT_ITEM WHERE MATNR NOT IN S_MATNR .使用该语句前需要判断S_MATNR[]不为空
建议连续删除使用
DELETE lt_table2 where col = '0000'.
delete lt_table2 index 3."删除第三行
连续删除不要使用
DELETE table t_stu from s_stu.
结论在删除的内表如果没有指定key且唯一的情况下,则永远删除第一行.
原因坑:
没有指定key值
REPORT ZTXYY_11134.
TYPES:BEGIN OF YU_STU,
COL TYPE I,
END OF YU_STU.
TYPES: TYU_STU TYPE STANDARD TABLE OF YU_STU WITH EMPTY KEY.
DATA GT_ITAB TYPE TYU_STU.
DATA GT_ITAB2 TYPE TYU_STU.
GT_ITAB = VALUE TYU_STU( FOR J = 0 THEN J + 1 UNTIL J > 300
( COL = J ) ).
GT_ITAB2 = VALUE TYU_STU( FOR J = 0 THEN J + 2 UNTIL J > 300
( COL = J ) ).
LOOP AT GT_ITAB INTO DATA(WA).
READ TABLE GT_ITAB2 WITH KEY COL = WA-COL BINARY SEARCH TRANSPORTING NO FIELDS.
IF SY-SUBRC EQ 0.
DELETE TABLE GT_ITAB FROM WA.
ENDIF.
ENDLOOP.
BREAK-POINT.
结果
删除的是前150行.
解决办法换语法后
LOOP AT GT_ITAB2 INTO DATA(WA).
READ TABLE GT_ITAB WITH KEY COL = WA-COL TRANSPORTING NO FIELDS BINARY SEARCH.
IF SY-SUBRC <> 0.
CONTINUE.
ELSE.
DELETE GT_ITAB INDEX SY-TABIX.
ENDIF.
ENDLOOP.
结果
在指定了key值
REPORT ZTXYY_11134.
TYPES:BEGIN OF YU_STU,
COL TYPE I,
END OF YU_STU.
TYPES: TYU_STU TYPE STANDARD TABLE OF YU_STU WITH key COL."WITH EMPTY KEY.
DATA GT_ITAB TYPE TYU_STU .
DATA GT_ITAB2 TYPE TYU_STU.
GT_ITAB = VALUE TYU_STU( FOR J = 0 THEN J + 1 UNTIL J > 300
( COL = J ) ).
GT_ITAB2 = VALUE TYU_STU( FOR J = 0 THEN J + 2 UNTIL J > 300
( COL = J ) ).
DATA(DO_I) = 20.
LOOP AT GT_ITAB INTO DATA(WA).
WHILE DO_I < 30.
SY-TABIX = DO_I.
DO_I = DO_I + 1.
WA-COL = SY-TABIX.
DELETE TABLE GT_ITAB FROM WA.
ENDWHILE.
ENDLOOP.
结果
没有key值时
REPORT ZTXYY_11134.
TYPES:BEGIN OF YU_STU,
COL TYPE I,
END OF YU_STU.
TYPES: TYU_STU TYPE STANDARD TABLE OF YU_STU WITH EMPTY KEY."WITH key COL."WITH EMPTY KEY.
DATA GT_ITAB TYPE TYU_STU .
DATA GT_ITAB2 TYPE TYU_STU.
GT_ITAB = VALUE TYU_STU( FOR J = 0 THEN J + 1 UNTIL J > 300
( COL = J ) ).
GT_ITAB2 = VALUE TYU_STU( FOR J = 0 THEN J + 2 UNTIL J > 300
( COL = J ) ).
DATA(DO_I) = 20.
LOOP AT GT_ITAB INTO DATA(WA).
WHILE DO_I < 30.
SY-TABIX = DO_I.
DO_I = DO_I + 1.
WA-COL = SY-TABIX.
DELETE TABLE GT_ITAB FROM WA.
ENDWHILE.
ENDLOOP.
或者
DATA wa TYPE YU_STU.
WA-COL = DO_I.
DELETE TABLE GT_ITAB FROM WA.
结果:
往内表中加入空行
INSERT INITIAL LINE INTO <内表> INDEX 1.
如果只是往内表最后一行增加一行空数据,则可使用语句APPEN INITIAL LINE TO <内表>
内表动态排序
ABAP 内表动态排序ABAP_SORTORDER_TAB_abap 动态内表怎么排序-CSDN博客
SORT itab BY (ABAP_SORTORDER_TAB),对动态内表进行排序
NAME为排序字段,DESCENDING:'X' (降序排序) or ' ' (默认为升序排序 ),ASTEXT:'X'(作为文本)或' '(不是作为文本(默认))。
FIELD-SYMBOLS: <F_TABLE> TYPE STANDARD TABLE.
DATA: L_SORT TYPE ABAP_SORTORDER_TAB.
...
L_SORT = VALUE #( (NAME = 'NAME' DESCENDING = '') ).
...
"动态内表按指定字段排序
SORT <F_DATA> BY (L_SORT).
"动态内表根据NAME字段升序排序
内表操作的注意事项