第007章 控制ABAP.docx
《第007章 控制ABAP.docx》由会员分享,可在线阅读,更多相关《第007章 控制ABAP.docx(26页珍藏版)》请在冰豆网上搜索。
![第007章 控制ABAP.docx](https://file1.bdocx.com/fileroot1/2023-6/6/1fbcdf9c-1869-4152-9bac-28d2d0151023/1fbcdf9c-1869-4152-9bac-28d2d01510231.gif)
第007章控制ABAP
第七章7–17–1控制ABAP/4程序流
概览
内容
ABAP/4中流控制的概念1
编程逻辑表达式2
比较所有的字段类型3
比较字符串和数字串4
二进制位结构的比较6
检查字段是否属于某一范围8
检查初始值9
检查选择条件9
组合几个逻辑表达式10
编程分支和循环10
使用IF的条件分支11
使用CASE的条件分支11
使用DO的无条件循环13
使用WHILE的条件循环15
终止循环16
要根据一定条件执行程序组件,或要将重复语句序列组合在循环中,可以使用ABAP/4提供的用于控制程序流的标准关键字。
ABAP/4也包含重要的附加特征。
ABAP/4程序流可以内部控制和外部控制。
ABAP/4程序流的内部控制和外部控制之间的差别在ABAP/4中流控制的概念中解释。
本节主要讨论内部流控制。
为此,可使用其他编程语言(例如,C、FORTRAN、PASCAL等等)中熟悉的标准控制关键字。
下列主题描述
7–1ABAP/4中流控制的概念
与其他高级编程语言一样(如,C、FORTRAN和PASCAL等等),ABAP/4提供也用于控制程序流的标准关键字。
这些关键字用于
_分支(IF、CASE)
_循环(DO、WHILE)
然而,ABAP/4与其他编程语言不同之处在于其具有程序流的内部控制和外部控制。
_内部控制由上述标准关键字引导。
在程序代码中对其进行定义。
_外部控制由事件引导。
事件由ABAP/4程序(系统程序或用户程序)或者交互式用户输入(例如,使用鼠标在屏幕上单击)生成。
系统不必按ABAP/4程序中列出的顺序对进行语句处理。
这使得ABAP/4成为事件驱动编程语言,类似于Microsoft的VisualBasic。
时间事件和ABAP/4程序的连接由事件关键字提供。
ABAP/4程序中的每个语句都属于特别的事件关键字。
即使在程序中没有指定任何事件关键字,所有语句都自动归属于标准事件关键字(START-OF-SELECTION),与程序中事件语句的次序完全不相干。
所有属于某一特定事件关键字的语句形成一个处理块。
处理块是一个在事件发生时执行的模块。
处理块内的程序流依赖于内部控制。
系统按顺序处理语句,或按照前面提到的标准关键字定义的顺序处理。
ABAP/4程序常规结构如下:
假设当用户选择一行后,生成列表且提供一些细分设备的报表程序必须作出反应(详细信息,参见交互列表)。
需要为该事件处理的代码必须插入事件关键字ATLINE-SELECTION之后。
ATLINE-SELECTION.
MOVE'X'TOFLAG.
.....
无论何时用户通过单击鼠标或按F2键在列表中选择一个项目时,ATLINE-SELECTION和下一个事件关键字之间的所有语句将被处理
关于外部控制的详细信息,如事件及其如何与ABAP/4程序相互作用的信息,参见C通过事件控制ABAP/4程序流。
该节说明如何使用外部控制控制处理块内的程序流。
要控制ABAP/4程序中的内部流,请遵循结构化编程原则并将程序模块划分为单个逻辑相关语句块(这些组成控制结构)。
其中的每个语句块都执行主任务的一部分。
要使程序易于阅读,应该缩排控制结构中的语句块。
出于布局需要,可以使用ABAP/4编辑器功能“编辑->插入语句...”和“程序->整齐打印程序”(详细信息,参见ABAP/4程序布局(页2–6))。
可以用IF、CASE、DO和WHILE之类的关键字控制处理块中不同语句之间的程序流。
这些语句允许编制条件和无条件的分支和循环。
条件使用逻辑表达式,可以是真,也可以为假。
7–2编程逻辑表达式
使用条件控制程序中的内部流。
要用公式指定条件,请使用比较数据字段的逻辑表达式,如下所示:
语法
.......
该表达式比较两个字段。
可能为真,也可能为假。
在带关键字IF、CHECK和WHILE的条件语句中使用逻辑表达式。
根据操作数和的数据类型,可以使用不同的逻辑运算符。
允许进行:
除上述比较之外,还可以执行测试以检查数据字段是否完全满足一定条件。
可以使用这些测试:
另外,可以将几个逻辑表达式组合为一个简单逻辑表达式。
7–3比较所有的字段类型
要比较所有的字段类型,可以在逻辑表达式中使用下列运算符:
<运算符>
含义
EQ
等于
=
等于
NE
不等于
<>
不等于
><
不等于
LT
小于
<
小于
LE
小于等于
<=
小于等于
GT
大于
>
大于
GE
大于等于
>=
大于等于
操作数可以是数据库字段、内部字段、文字或常数。
除基本字段外,还可以将结构数据类型和上表中的运算符结合起来作为操作数。
字段串逐个组件进行比较,嵌套的结构分为基本的字段。
关于比较内表的详细信息,参见比较内表。
如果有意义,可以对不同数据类型的字段进行比较。
如果字段可转换,就可以进行比较。
在比较之前,系统将按照下列层次规则执行自动类型转换(参见键入转换(页6–36)):
1.如果操作数之一是浮点数(类型F),则系统将其它操作数转换为类型F。
2.如果操作数之一是压缩字段(类型P),则系统将其它操作数转换为类型P。
3.如果操作数之一是日期字段(类型D)或时间字段(类型T),则系统将其它操作数转换为类型D或T。
不支持日期和时间字段之间的比较,这会导致程序中断。
4.如果操作数之一是字符字段(类型C)且其它操作数是十六进制字段(类型X),则系统将类型X的操作数转换为类型C。
5.如果操作数之一是字符字段(类型C),其它操作数为数字字段(类型N),则系统将这两种操作数都转换为类型P。
DATA:
FTYPEFVALUE'100.00',
PTYPEPVALUE'50.00'DECIMALS2,
ITYPEIVALUE'30.00'.
WRITE'Thefollowinglogicalexpressionsaretrue:
'.
IFF>=P.
WRITE:
/F,'>=',P.
ELSE.
WRITE:
/F,'<',P.
ENDIF.
IFIEQP.
WRITE:
/I,'EQ',P.
ELSE.
WRITE:
/I,'NE',P.
ENDIF.
这生成如下输出:
Thefollowinglogicalexpressionsaretrue:
1.000000000000000E+02>=50.00
30NE50.00
这里,在IF语句中使用两个逻辑表达式。
如果逻辑表达式为真,则屏幕上显示出来。
如果逻辑表达式为假,则将相反表达式显示在屏幕上。
7–4比较字符串和数字串
要比较字符串(类型C)和数字文本(类型N),可以在逻辑表达式中使用下列运算符。
<运算符>
含义
CO
仅包含
CN
不仅包含
CA
包含任何
NA
不包含任何
CS
包含字符串
NS
不包含字符串
CP
包含模式
NP
不包含模式
因为除类型N和C外,系统不能执行任何其它类型转换,所以,在进行包含这些运算之一的比较时,操作数应该是类型N或C。
运算符的功能如下:
CO(仅包含)
如果仅包含中的字符,则逻辑表达式
CO
为真。
该比较区分大小写,并包括尾部空格。
如果比较结果为真,则系统字段SY-FDPOS包括的长度。
如果为假,则SY-FDPOS包含中第一个未在内出现的字符的偏移量。
CN(不仅包含)
如果还包含之外的其他字符,则逻辑表达式
CN
为真。
该比较区分大小写,并包括尾部空格。
如果比较结果为真,则系统字段SY-FDPOS包含中第一个未同时在中出现的字符的偏移量。
如果为假,SY-FDPOS包含的长度。
CA(包含任何)
如果至少包含的一个字符,则逻辑表达式
CA
为真。
该比较区分大小写。
如果比较结果为真,则系统字段SY-FDPOS包含中第一个也在中出现的字符的偏移量。
如果为假,SY-FDPOS包含的长度。
NA(不包含任何)
如果不包含的任何字符,则逻辑表达式
NA
为真。
该比较区分大小写。
如果比较结果为真,则系统字段SY-FDPOS包含的长度。
如果为假,则SY-FDPOS包含中在内出现的第一个字符的偏移量。
CS(包含字符串)
如果包含字符串,则逻辑表达式
CS
为真。
忽略尾部空格并且比较不区分大小写。
如果比较结果为真,则系统字段SY-FDPOS包含在中的偏移量。
如果为假,SY-FDPOS包含的长度。
NS(不包含字符串)
如果不包含字符串,则逻辑表达式
NS
为真。
忽略尾部空格且比较不区分大小写。
如果比较为真,系统字段SY-FDPOS包含的长度。
如果为假,系统字段SY-FDPOS包含在中的偏移量。
CP(包含模式)
如果包含模式,则逻辑表达式
CP
为真。
如果属于类型C,则可以在中使用下列通配符:
_*用于任何字符串
_+用于任何单个字符
忽略尾部空格且比较不区分大小写。
如果比较结果为真,系统字段SY-FDPOS包含在中的偏移量。
如果为假,SY-FDPOS包含的长度。
如果要对中的特殊字符进行比较,请将换码字符#放到其前面。
可以使用换码字符#指定
_大小写字符
_通配符"*"(输入#*)
_通配符"+"(输入#+)
_换码符号本身(输入##)
_字符串结尾的空格(输入#___)
NP(不包含模式)
如果不包含模式,则逻辑表达式
NP
为真。
在中,可以使用与CP相同的通配符和换码字符。
忽略尾部空格且比较不区分大小写。
如果比较结果为真,则系统字段SY-FDPOS包含.的长度,如果为假,SY-FDPOS包含在中的偏移量。
DATA:
F1(5)TYPECVALUE,
F2(5)TYPECVALUE.
IFF1F2.
WRITE:
/'Comparisontrue,SY-FDPOS=',SY-FDPOS.
ELSE.
WRITE:
/'Comparisonfalse,SY-FDPOS=',SY-FDPOS.
ENDIF.
下表列出该程序的执行结果,取决于所用的运算符和F1/F2字段。
Result
SY-FDPOS
'BD'
CO
'ABCD'
真
5
'BD'
CO
'ABCDE'
假
2
'ABC12'
CN
'ABCD'
真
3
'ABABC'
CN
'ABCD'
假
5
'ABcde'
CA
'Bd'
真
1
'ABcde'
CA
'bD'
假
5
'ABAB'
NA
'AB'
假
0
'ababa'
NA
'AB'
真
5
'ABcde'
CS
'bC'
真
1
'ABcde'
CS
'ce'
假
5
'ABcde'
NS
'bC'
假
1
'ABcde'
NS
'ce'
真
5
'ABcde'
CP
'*b*'
真
1
'ABcde'
CP
'*#b*'
假
5
'ABcde'
NP
'*b*'
假
1
'ABcde'
NP
'*#b*'
真
5
7–6二进制位结构的比较
要将逻辑表达式初始操作数第一字节的二进制位结构与第二操作数的进行比较,请使用下列操作符。
<运算符>
含义
O
二进制位是1
Z
二进制位是0
M
混合二进制位
第二操作数的长度应为一个字节。
没有必要对第二操作数使用长度为1的十六进制字段(类型X),但却较方便,因为其长度为一个字节且数字值直接与二进制位结构相关。
操作符功能如下:
O(二进制位是1)
如果中二进制位是1的位置,在中是1,则逻辑表达式
O
为真。
Z(二进制位是0)
如果中二进制位是1的位置,在中是0,则逻辑表达式
Z
为真。
M(混合二进制位)
如果从中二进制位是1的位置起,中至少一个是1,一个是0,则逻辑表达式
M
为真。
DATA:
CVALUE'C',
HEXDECTYPEX,
ITYPEI.
HEXDEC=0.
DO256TIMES.
I=HEXDEC.
IFCOHEXDEC.
WRITE:
/HEXDEC,I.
ENDIF.
HEXDEC=HEXDEC+1.
ENDDO.
产生下列输出:
000
011
022
033
4064
4165
4266
4367
这里,使用运算符O将字符‘C’的二进制位结构与所有‘0’与‘FF’(10进制为255)之间的16进制数进行比较。
HEXDEC的10进制值I,在HEXDEC分配到I期间,通过使用自动类型转换确定。
如果比较结果为真,则在屏幕上显式16进制数及其10进制值。
下表列出这些数的二进制位结构。
16进制
10进制
二进制位结构
00
0
00000000
01
1
00000001
02
2
00000010
03
3
00000011
40
64
01000000
41
65
01000001
42
66
01000010
43
67
01000011
字符‘C’的二进制位结构由其ASCII码67为当前硬件平台进行定义。
与用户看到的一样,列表输出中出现的数字,填写1的二进制位位置与67的二进制位结构一样。
7–8检查字段是否属于某一范围
要检查值是否属于特定范围,请使用下列带有BETWEEN参数的逻辑表达式:
语法
....BETWEENAND.....
如果在和之间的范围内发生,则表达式为真。
它是下列逻辑表达式的短格式:
IFGEANDLE.
DATA:
NUMBERTYPEI,
FLAG.
....
NUMBER=...
....
IFNUMBERBETWEEN3AND7.
FLAG='X'.
ELSE.
FLAG=''.
ENDIF.
这里,如果NUMBER的内容在3和7之间出现,字段FLAG设置为“X”。
7–9检查初始值
要检查字段是否设置为初始值,请如下使用带有ISINITIAL参数的逻辑表达式。
语法
....ISINITIAL.....
如果包含本身类型的初始值,则表达式为真。
通常情况下,任何字段,基本的或结构化的(字符串和内表),在CLEAR语句执行后,都包含其初始值(参见重置缺省值(页6–10))。
DATAFLAGVALUE'X'.
IFFLAGISINITIAL.
WRITE/'Flagisinitial'.
ELSE.
WRITE/'Flagisnotinitial'.
ENDIF.
CLEARFLAG.
IFFLAGISINITIAL.
WRITE/'Flagisinitial'.
ELSE.
WRITE/'Flagisnotinitial'.
ENDIF.
这产生如下输出:
Flagisnotinitial
Flagisinitial.
这里,DATA语句之后,字符串FLAG不包含初始值,因为用VALUE参数设置为‘X’。
执行CLEAR语句之后,将其重置为初始值。
7–9检查选择条件
要检查字段内容是否与选择表中的选择条件匹配,可以如下使用带有IN参数的逻辑表达式:
语法
...IN....
如果字段内容的符合选择表中的条件,则表达式为真。
关于选择条件的详细信息,参见使用选择标准。
关于逻辑表达式中检查选择条件的详细信息,包括示例,参见使用逻辑表达式中的选择表。
7–10组合几个逻辑表达式
通过使用逻辑连接运算符AND、OR和NOT,可以将几个逻辑表达式组合为单个表达式:
_要将几个逻辑表达式组合为单个表达式,且该表达式仅当所有组件表达式为真时才为真,则表达式之间要用AND连接。
_要将几个逻辑表达式组合为单个表达式,且只要其中一个组件表达式为真时,该表达式即为真,则表达式之间要用OR连接。
_要转化逻辑表达式的结果,请在其前面指定NOT。
NOT优先于AND,AND优先于OR。
但是,可以用任何括弧组合指定处理顺序。
由于ABAP/4将括弧解释为单字,前面或后面必须至少有一个空格。
ABAP/4从左到右处理逻辑表达式。
如果确定组件表达式之一是真或假,就不再执行该组件中其余的比较或检查。
这意味着采取这种方法组织逻辑表达式可以提高性能,就是将经常为假的比较放置在AND链的开头,而将费时的比较,如字符串查找放等到最后。
DATA:
FTYPEFVALUE'100.00',
N(3)TYPENVALUE'123',
C(3)TYPECVALUE'456'.
WRITE'Thefollowinglogicalexpressionistrue:
'.
IF(CLTN)AND(NGTF).
WRITE:
/'(',C,'lt',N,')AND(',N,'gt',F,')'.
ELSE.
WRITE:
/'(',C,'ge',N,')OR(',N,'le',F,')'.
ENDIF.
这产生如下输出:
下列逻辑表达式为真:
(456ge123)OR(123le1.000000000000000E+02)
在本例中,在IF语句中使用逻辑表达式。
如果逻辑表达式为真,则将其在屏幕上显示出来。
如果为假,则屏幕上出现相反的表达式。
7–10编程分支和循环
可以在程序中定义条件和无条件分支和循环。
为此,ABAP/4提供了几个在下列主题中描述的语句。
分支
循环
7–11使用IF的条件分支
IF语句允许依据条件将程序流转到特定的语句块中。
该语句块包括IF语句及其后面的ELSEIF、ELSE或ENDIF之间的所有命令。
语法
IF.
ELSEIF.
ELSEIF.
.....
ELSE.
ENDIF.
如果第一个条件是真,系统将执行所有语句直到第一个语句块结束,然后继续处理ENDIF语句之后的程序。
要采用选择性条件,可以使用ELSEIF语句。
如果第一个条件是假,系统使用与IF语句一样的方式处理后面的ELSEIF语句。
如果IF或ELSEIF条件都为假,则执行ELSE开始的语句块。
最后的语句块必须用ENDIF结束。
要用公式表达IF和ELSEIF语句中的条件,可以使用任何编程逻辑表达式(页7–2)描述的逻辑表达式。
ABAP/4允许无限地嵌套IF-ENDIF语句块,但是必须在相同的处理块中终止。
换句话说,就是IF-ENDIF块不能包含事件关键字。
DATA:
TEXT1(30)VALUE'Thisisthefirsttext',
TEXT2(30)VALUE'Thisisthesecondtext',
TEXT3(30)VALUE'Thisisthethirdtext',
STRING(5)VALUE'eco'.
IFTEXT1CSSTRING.
WRITE/'Condition1isfulfilled'.