SAP-ABAP:条件判断与循环控制语句(7篇) 第三篇:循环基础:for、while、do-while三种循环的差异与适用场景

条件判断与循环控制语句(7篇)

第三篇:循环基础:for、while、do-while三种循环的差异与适用场景

编程中有一句经典名言:"当一件事情需要重复做,就用循环。"无论是遍历内表、累加求和,还是反复请求用户输入,循环都是最基础的控制结构。ABAP提供了多种循环语句:DO(条件循环/计数循环)、WHILE(前置条件循环)以及通过LOOP...ENDLOOP实现的内表遍历。虽然没有传统的for关键字,但DO配合TIMES可以完美替代计数循环。本文将逐一解析这些循环的语法结构、执行流程,并结合遍历内表、累加计数、用户输入校验等场景,给出选型标准,助你写出简洁高效的循环逻辑。


一、ABAP中的三种循环结构总览

结构 语法关键字 特点 适用场景
计数循环 DO [n TIMES]. 明确知道循环次数 遍历固定范围的数字、处理已知行数的数组
条件循环 WHILE condition. 进入前检查条件,可能一次都不执行 条件未知,需依赖外部状态变化
内表遍历 LOOP AT itab [INTO wa]. 专用于内表,自动处理索引 遍历内表所有行
模拟do-while DO... EXIT. 至少执行一次,后判断条件 需要先执行一次逻辑再决定是否继续

注意 :ABAP没有原生的fordo-while关键字,但可以用DOEXIT灵活模拟。同时,WHILE只支持前置条件判断,后置条件需手动实现。


二、计数循环:DO [n TIMES]

2.1 基本语法

abap 复制代码
" 固定次数循环
DO 10 TIMES.
  WRITE / sy-index.   " sy-index 从1开始递增
ENDDO.

" 无限循环(需配合 EXIT 退出)
DO.
  IF sy-index > 10.
    EXIT.
  ENDIF.
  WRITE / sy-index.
ENDDO.

sy-index是系统字段,记录当前循环的次数(从1开始)。DO...TIMES是最常见的计数循环。

2.2 典型场景:遍历固定范围

示例1:输出九九乘法表

abap 复制代码
DO 9 TIMES.
  DATA(lv_i) = sy-index.
  DO lv_i TIMES.
    DATA(lv_j) = sy-index.
    WRITE: / lv_i, '*', lv_j, '=', lv_i * lv_j.
  ENDDO.
  SKIP.
ENDDO.

示例2:累加1到100

abap 复制代码
DATA(lv_sum) = 0.
DO 100 TIMES.
  lv_sum = lv_sum + sy-index.
ENDDO.
WRITE lv_sum.   " 输出5050

2.3 注意事项

  • sy-index在循环内是只读的,不应手动修改。
  • 当循环次数为变量时,确保变量为整数且非负。
  • 如果循环次数非常大(如百万级),考虑性能影响,避免循环体内频繁数据库操作。

三、条件循环:WHILE

3.1 基本语法

abap 复制代码
WHILE condition.
  " 当 condition 为真时执行
ENDWHILE.

条件在每次循环开始前判断,若为假则直接跳过循环体(可能一次都不执行)。

示例:读取用户输入直到输入正确

abap 复制代码
PARAMETERS: p_num TYPE i.

WHILE p_num <= 0.
  WRITE: '请输入大于0的数字'.
  READ p_num.
ENDWHILE.

3.2 典型场景:条件控制的不确定次数循环

场景:计算某个数除以2直到小于1的次数

abap 复制代码
DATA(lv_value) = 100.
DATA(lv_count) = 0.
WHILE lv_value >= 1.
  lv_value = lv_value / 2.
  lv_count = lv_count + 1.
ENDWHILE.
WRITE: '共除', lv_count, '次,结果为', lv_value.

3.3 WHILEDO的对比

特性 WHILE DO(无限+EXIT)
条件判断时机 每次循环开始前 循环体内部通过EXIT控制
至少执行次数 0次 1次(如果EXIT在末尾)
适用场景 条件自然决定是否开始 需要先执行一次再判断

四、内表遍历:LOOP AT

4.1 基本语法

abap 复制代码
DATA lt_ekpo TYPE TABLE OF ekpo.

" 方式1:INTO 工作区(复制数据)
LOOP AT lt_ekpo INTO DATA(ls_ekpo).
  WRITE: / ls_ekpo-ebeln.
ENDLOOP.

" 方式2:ASSIGNING 字段符号(直接引用,性能好)
LOOP AT lt_ekpo ASSIGNING FIELD-SYMBOL(<fs_ekpo>).
  <fs_ekpo>-menge = <fs_ekpo>-menge * 2.
ENDLOOP.

4.2 典型场景:处理内表所有行或部分行

场景1:计算内表金额总和

abap 复制代码
DATA(lv_total) = 0.
LOOP AT lt_orders INTO DATA(ls_order).
  lv_total = lv_total + ls_order-netwr.
ENDLOOP.

场景2 :使用WHERE条件过滤

abap 复制代码
LOOP AT lt_mara INTO DATA(ls_mara) WHERE mtart = 'ROH'.
  WRITE: / ls_mara-matnr, '是原材料'.
ENDLOOP.

场景3:按索引循环(不推荐,除非特殊需求)

abap 复制代码
DATA(lv_tabix) = 1.
WHILE lv_tabix <= lines( lt_data ).
  READ TABLE lt_data INDEX lv_tabix INTO ls_data.
  " 处理...
  lv_tabix = lv_tabix + 1.
ENDWHILE.

通常直接LOOP AT即可,无需手动索引。


五、模拟do-while:至少执行一次的后置条件循环

在某些语言中,do-while保证循环体至少执行一次。ABAP中没有原生支持,但可以通过DO...EXIT轻松模拟。

模板

abap 复制代码
DO.
  " 循环体(至少执行一次)
  IF exit_condition.
    EXIT.
  ENDIF.
ENDDO.

实例:用户输入密码,至少显示一次提示

abap 复制代码
DATA: lv_password TYPE string,
      lv_input    TYPE string.

" 预设正确密码
lv_password = '123456'.

DO.
  WRITE: '请输入密码:'.
  READ lv_input.
  IF lv_input = lv_password.
    WRITE '密码正确,欢迎登录.'.
    EXIT.
  ELSE.
    WRITE '密码错误,请重试.'.
  ENDIF.
ENDDO.

六、循环控制语句:提前结束与跳过

6.1 EXIT:立即退出循环

abap 复制代码
DO 100 TIMES.
  IF sy-index = 10.
    EXIT.   " 当循环到第10次时,直接退出
  ENDIF.
ENDDO.

6.2 CONTINUE:跳过本次循环剩余部分,进入下一次

abap 复制代码
DO 10 TIMES.
  IF sy-index MOD 2 = 0.
    CONTINUE.   " 跳过偶数次,不输出
  ENDIF.
  WRITE / sy-index.   " 只输出奇数
ENDDO.

6.3 CHECK:类似于CONTINUE,但常用于LOOP AT的条件过滤

abap 复制代码
LOOP AT lt_ekpo INTO ls_ekpo.
  CHECK ls_ekpo-ebelp > 5.   " 只处理行项目号大于5的行
  " 处理...
ENDLOOP.

七、循环选型决策树

复制代码
是否需要遍历内表?
├─ 是 → LOOP AT ... ENDLOOP.
└─ 否 → 循环次数已知?
        ├─ 是 → DO ... TIMES.
        └─ 否 → 需要至少执行一次?
                ├─ 是 → DO ... EXIT (模拟do-while)
                └─ 否 → WHILE

八、常见错误与避坑

8.1 无限循环

错误 :忘记在WHILE循环中修改条件变量

abap 复制代码
DATA lv_cnt TYPE i VALUE 1.
WHILE lv_cnt <= 10.
  WRITE / lv_cnt.   " 忘记增加 lv_cnt,死循环
ENDWHILE.

解决:在循环体内确保条件最终变为假。

8.2 在LOOP AT中使用SY-TABIX时混淆

SY-TABIXLOOP AT中代表当前行的索引,但在DO循环中代表循环次数。不要混用。

8.3 循环内提交事务(COMMIT WORK)

在循环内使用COMMIT WORK会破坏事务的原子性,且每次提交都消耗大量资源。应尽量在循环外提交。

8.4 使用READ TABLE逐行访问代替LOOP AT

abap 复制代码
" 错误方式:效率极低
DO lines( lt_itab ) TIMES.
  READ TABLE lt_itab INDEX sy-index INTO ls_wa.
  " ...
ENDDO.

" 正确方式:直接 LOOP AT
LOOP AT lt_itab INTO ls_wa.
  " ...
ENDLOOP.

九、性能提示

  • **使用字段符号(ASSIGNING)**在LOOP AT中修改内表数据,避免MODIFY语句。
  • 减少循环内的数据库操作:尽量在循环外批量读取数据,循环内仅做内存计算。
  • 大数据量内表 :优先使用LOOP AT而不是WHILE手动控制索引。
  • 提前退出 :当找到目标后立即EXIT,避免无谓的后续循环。

十、总结

循环类型 适用场景 示例
DO n TIMES 明确次数(如1...100求和) DO 100 TIMES.
WHILE 前置条件不确定,可能零次执行 读取文件直到结束
LOOP AT 遍历内表 处理所有行项目
DO...EXIT 至少执行一次的后置条件 输入密码重试

循环是程序中最常见的控制结构,选对了类型,代码既简洁又高效。下一篇将聚焦循环控制中的break、continue、return的用法边界,帮你精准控制循环的执行流程,避开逻辑陷阱。

📌 下篇预告:避坑指南:循环控制中break、continue、return的用法边界

作者 :你的ABAP学习伙伴
版本记录:2026年5月

💬 你是否有过在WHILE循环中忘记更新条件导致死循环的经历?欢迎留言分享。

相关推荐
编程大师哥2 小时前
Marvelous Designer 2025|新一代工业级 3D 布料仿真专业软件
性能优化
zt1985q2 小时前
本地部署服务器聚合平台 MCPHub 并实现外部访问
运维·服务器·网络·网络协议
wanhengidc2 小时前
服务器如何高效防御网络攻击
运维·服务器·网络
小程故事多_802 小时前
AI智能体长周期AI自动化任务,Checkpoint与回滚机制深度设计解析
运维·人工智能·自动化
小新同学^O^2 小时前
简单学习 --> llm是怎么训练出来的?
人工智能·深度学习·学习
wuxinyan1232 小时前
工业级大模型学习之路028:多智能体系统基础与双智能体协作
人工智能·python·学习
handler012 小时前
【MySQL】常用约束语法总结
linux·运维·数据库·笔记·mysql
189228048612 小时前
N9BYX固态MT29F16T08ESLHHL5-42QMES:H
性能优化
Shadow(⊙o⊙)2 小时前
Linux内核级文件系统分析——文件系统入门内核级文章!
linux·运维·服务器·开发语言·c++