对于任何必须运行的命令或者在循环本身开始运行之前必须初始化的变量,似乎控制级处理的AT FIRST
语句是理想的。鉴于AT
命令如何清除工作区中的列,这是我仍然为他们看到的少数用途之一。
为了说明而不是这样做:
CLEAR lv_loopcounter.
LOOP AT lt_itab INTO ls_wa.
ADD 1 TO lv_loopcounter.
...
ENDLOOP.
我们可以这样做:
LOOP AT lt_itab INTO ls_wa.
AT FIRST.
CLEAR lv_loopcounter.
ENDAT.
ADD 1 TO lv_loopcounter.
...
ENDLOOP.
这里显而易见的是,变量需要初始化以使循环按预期运行。当你有很多需要在循环之前运行的语句时,它还可以使代码更清晰。我看到的唯一缺点是它在LOOP
语句中将代码移到逻辑上不应该是。
这里有最好的做法吗?我应该注意隐藏的警告吗?
答案 0 :(得分:5)
这两种变体都是可能的,但它们在语义上是不同的:在第一个版本中,命令CLEAR
无条件执行,在第一个版本中,仅在lt_itab
包含至少一行时执行。对于实际的循环实现,差异是无关紧要的,但对于空表,有问题的变量的值在达到ENDLOOP
语句后会有所不同。只要你理智地处理空表,这不是问题......: - )
第二个版本的唯一其他微观警告是AT FIRST
将清除ls_wa
的所有非字符字段,并将ls_wa
的所有字符字段设置为'*'。< / p>
答案 1 :(得分:4)
虽然vwegert的答案对于我在我的问题中描述的简单循环案例是正确的,但是有一个非常重要的次要案例,AT FIRST
不功能正如您所料,并且那就是用条件循环时。
正如SAP的AT
文档所述:
控制级别由内部表的第一行定义。读取此行时会发生控制中断。
换句话说,AT FIRST
不会在循环的第一次迭代中触发,但是当读取内部表的绝对第一行时。这意味着如果我们只遍历内部表的几行,那么我们就不会在第一行上循环。如果是这种情况,控制块将不输入。
举个例子:
LOOP AT lt_itab INTO DATA(ls_itab) WHERE itab_col1 = iv_value.
AT FIRST.
CLEAR lv_loopcounter.
ENDAT.
ADD 1 to lv_loopcounter.
...
ENDLOOP.
如果第一个内部表行的itab_col1
与iv_value
匹配,则将清除循环计数器。如果第一行与此值不匹配,则循环计数器将不清除!