介绍
在写接口函数的时候,采用了 ALV 报表中的 CHECK 语句,导致报错了整个函数就返回了,并没有将后台数据打印到后台表中。因此将 CHECK 的用法记录一下笔记。
CHECK 语句
CHECK 语句根据条件终止循环传递。如果 CHECK 语句中的条件被评估为 false,则忽略 CHECK 语句之后语句块中的所有剩余语句,则进程将退出当前循环跳过并处理下一个循环。 CHECK 语句中的条件可以是任何逻辑表达式。
例如:
CHECK input_value > 0 AND input_value <= 100.
CHECK input_value <= 0 OR input_value >= 200.
使用方法
循环块内:
CHECK <log_exp>.
带有逻辑数据库的报表:
CHECK sel.
CHECK SELECT-OPTIONS
检查由语句 SELECT-OPTIONS sel 要求的选择标准。如果这个检查的结果是否定的,那么这个事件的处理将被终止,任何下属数据库表的 GET 事件也不会被处理。
在各种循环中的使用:
DO … ENDDO
WHILE … ENDWHILE
LOOP … ENDLOOP
SELECT … ENDSELECT
*&---------------------------------------------------------------------*
*& Report ZCHECK
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcheck.
DO 10 TIMES.
CHECK sy-index MOD 2 = 0.
WRITE / sy-index.
ENDDO.
比如取 10 以内的整数:
如果语句 CHECK 位于一个循环之外,并且 log_exp 为 false,那么该语句将终止当前的处理块。可以为 log_exp 指定任何逻辑表达式。
*&---------------------------------------------------------------------*
*& Report ZCHECK
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcheck.
DATA: lv_sum TYPE i.
CHECK lv_sum IS NOT INITIAL.
" DO 之后的循环将不会执行
DO 10 TIMES.
lv_sum = sy-index.
CHECK sy-index MOD 2 = 0.
WRITE / sy-index.
ENDDO.
在处理块退出后,运行环境的进行方式与处理块以正常方式退出时相同(除了事件块 LOAD-OF-PROGRAM 和 reporting event block GET之外)。特别是,程序的输出参数被传递给绑定的实际参数。
- 事件块
LOAD-OF-PROGRAM不能使用CHECK退出。 - 在使用
CHECK退出 Report 事件块 GET 后,相关逻辑数据库的层次结构中的下级节点不再被处理。逻辑数据库读取当前节点的下一行,或者下一个更高的节点,如果它已经达到了层次结构级别的终点。
检查 SELECT-OPTIONS 的所有选择,其中 FOR 后面的参考字段属于当前表 dbtab 。而且它只在GET 事件后调用。
建议仅使用 RETURN 退出程序
例如在一个方法内的 CHECK 语句就像一个有条件的 RETURN 语句,所以要确定任何给定的 CHECK 语句的效果可能会很混乱。
在程序(方法、功能模块、子例程)中,CHECK log_exp 在循环外的工作方式与以下方式相同:
IF NOT log_exp.
RETURN.
ENDIF.
例如:
IF NOT sy-index MOD 2 = 0.
RETURN.
ENDIF.
用于退出处理块的语句 CHECK 的另一个变体是 CHECK SELECT-OPTIONS,只能在逻辑数据库的 GET 事件块中使用。
如果不是退出程序,可以使用 CONTINUE 代替:
IF not condition.
CONTINUE.
ENDIF.
在上面的例子中,即可以使用这段逻辑替换,也能打印出 1-10 之间的偶数:
REPORT zcheck.
*DATA: lv_sum TYPE i.
*CHECK lv_sum IS NOT INITIAL.
DO 10 TIMES.
* CHECK sy-index MOD 2 = 0.
IF sy-index MOD 2 = 0.
WRITE / sy-index.
ELSE.
* RETURN.
CONTINUE.
ENDIF.
ENDDO.
注意选择易于解释的逻辑表达式的形式。由于关键字
CONTINUE只能在循环中使用,现在继续到下一个迭代实例的意图是不明确的。
如果出现 exception 情况,该怎么做?
在 exception 情况下,你可以通过使用伪注释 "#EC CHECK_IN_LOOP " 来抑制这一问题,该注释应放在 CHECK 语句本身之后:
LOOP AT tadir ASSIGNING FIELD-SYMBOL(<tadir>).
CHECK <tadir>-delflag = abap_true. "#EC CHECK_IN_LOOP
ENDLOOP.
在 CHECK 语句之前:
LOOP AT tadir ASSIGNING FIELD-SYMBOL(<tadir>).
CHECK <tadir>-delflag = abap_true.
"some more code...
ENDLOOP.
改变之后:
LOOP AT tadir ASSIGNING FIELD-SYMBOL(<tadir>).
IF <tadir>-delflag = abap_false.
CONTINUE.
ENDIF.
"some more code...
ENDLOOP.
请注意,在此示例中,表达代码背后意图的最简洁方法是完全删除循环内的语句,并将其替换为 LOOP 语句中的 WHERE 子句:
LOOP AT tadir ASSIGNING FIELD-SYMBOL(<tadir>) WHERE delflag = abap_false.
"some more code...
ENDLOOP.
总结
CHECK 如果条件失败,它只是忽略剩余的行,并退出存在 CHECK 命令的模块。在循环中使用的话,就会退出当前循环,如果在循环外使用,就会退出整个方法或子例程。所以在不明确检查条件,或者检查条件过多的情况下,建议使用 IF + RETURN/CONTINUE 进行代替。
参考链接: