ABAP Programming Language 的内容主要有:
1.数据类型与数据对象
2.内表和内表结构(Internal Table)
3.数据流控制语句
4.模块化(Modularization)
FORM
form ... endform. 是用来封装一段代码的。
perform ... . 是用来调用这段代码的。
并不是创建函数,创建函数是SE37。form ... endform里面的代码可以看成是私有的,其它程序调用不了,而函数是被其它程序调用的。
创建方法是用SE24。
这个和函数还有点不太一样,在ABAP开发中函数又叫Function Module(功能模块)。
INCLUDE
该语句的主要作用是使别的结构体中的组件全部包括进来成为自己的组件。
TYPES BEGIN OF struc_type.
TYPES comp ...
TYPES comp TYPE struc_type BOXED. "参照另一结构类型
INCLUDE { {TYPE struc_type} | {STRUCTURE struc} } "将另一结构包括进来
[AS name [RENAMING WITH SUFFIX suffix]].
TYPES END OF struc_type.
INCLUDE { {TYPE struc_type} | {STRUCTURE struc} }
[AS name [RENAMING WITH SUFFIX suffix]].
该语句只能用在定义结构的BEGIN OF与 END OF之间。作用是将结构类型struc_type与结构变量struc的所有组件字段拷贝到当前结构定义的指定位置,INCLUDE就是将可以重复使用的东西先做好,再包含进来。
AS name:给包含进来的结构类型(或结构变量)取一个别名,这样就可以通过结构组件符(-)来选取这个结构类型(或结构变量)
RENAMING WITH SUFFIX suffix:如果include进来的结构类型(或结构变量)的组件字段与现有的重复,则可以使用此选项重命名include进来的结构类型(或结构变量)的各组件字段名,具体做法只是在原来组件名后加上了指定的后缀suffix。
function exporting importing
- 进入FUNCTION MODULE BUILDER的事务代码SE37
- 在FUNCTION MODULE BUILDER创建窗口中选择菜单“转到->函数组->创建组”创建FUNCTION GROUP
- FUNCTION MODULE创建与FUNCTION MODULE调用是相返的。创建时的IMPORTING对应调用时的EXPORTING。反之亦然。
SAP ABAP FUNCTION MODULE与其它语言中的函数(或方法)的比较:
- 在FUNCTION
MODULE定义时,IMPORTING相当于定义其它语言函数(或方法)的输入参数,exporting相当于定义其它语言函数(或方法)的输出参
数,EXCEPTIONS相当于定义其它的函数(或方法)异常,CHANGING是其它语言所没有的它也是表示将实参传递给形参,但是它还有一个很特殊的
应用就是在方法调用完成后用于将形参传递给实参。
- 在FUNCTION MODULE调用时。EXPORTING用于定义将实参传递给形参(相当其它语言函数调用的输入参数),IMPORTING用于将参数传递给实能(相当其它语言函数调用的输出参数)。
创建:
FUNCTION z_integer_add.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(INPUT_1) TYPE I
*" REFERENCE(INPUT_2) TYPE I
*" EXPORTING
*" REFERENCE(OUTPUT) TYPE I
*"----------------------------------------------------------------------
output = input_1 + input_2.
ENDFUNCTION.
调用:
DATA: sum TYPE i,int1 TYPE i VALUE 3,int2 TYPE i VALUE 4.
CALL FUNCTION 'Z_INTEGER_ADD'
EXPORTING
input_1 = int1
input_2 = int2
IMPORTING
output = sum.
IF sy-subrc = 0 .
WRITE: / sum.
ENDIF.
- 在FUNCTION
MODULE定义时,IMPORTING相当于定义其它语言函数(或方法)的输入参数,exporting相当于定义其它语言函数(或方法)的输出参
数,EXCEPTIONS相当于定义其它的函数(或方法)异常,CHANGING是其它语言所没有的它也是表示将实参传递给形参,但是它还有一个很特殊的
应用就是在方法调用完成后用于将形参传递给实参。
举个例子:假如你写的应用程序Z_XXX中调用了一个function module,你需要在你自己的应用程序中有类似代码如下:
CALL FUNCTION 'ZGET_ADR_FUNCTION'
IMPORTING
xx = xx
xx = xx
EXPORTING
lv_matnr = lv_matobject
lv_class = 'SAFETY'
lv_classtype = '001'
TABLES"
objectdata = gt_objectdata[].
其中exporting是你从你的应用程序中 传给你要调用的function的参数,importing是你调用的function返回给你程序的参数。如果你看function的代码,那么它的 importing参数就是你写的应用程序中的exporting参数,反之亦然。
关于funcation 中 tables 的用法。exporting 和importing都是flat类型的数据(structure或者单独的变量,必须使flat类型,不能是内表类型),而tables中的参数都必须 是内表类型,并且tables是可以既做输入参数又做输出参数的。
数据流控制语句
1)使用IF语句实现分支
[Syntax]
IF <condition1>.
<statement block>.
ELSEIF <condition2>.
<statement block>.
ELSE.
<statement block>
ENDIF.
[For Example]
DATA xx TYPE N VALUE 6.
IF xx = 5.
WRITE: / 'The value of xx is',5.
ELSEIF xx = 6.
WRITE: / 'The value of xx is',6.
ELSE.
WRITE: / 'The value of xx is',7.
ENDIF.
2)使用CASE...WHEN...ENDCASE语句实现分支
[Syntax]
CASE <f>.
WHEN <f1>.
<statement block>.
WHEN <f2>.
<statement block>.
WHEN ...
WHEN OTHERS.
<statement block>.
ENDCASE.
[For Example]
DATA xx TYPE N VALUE 8.
CASE xx.
WHEN 5.
WRITE: / 'The value of xx is',5.
WHEN 6.
WRITE: / 'The value of xx is',6.
WHEN 7.
WRITE: / 'The value of xx is',7.
WHEN OTHERS.
WRITE: / 'The value of xx is',8.
ENDCASE.
3)使用LOOP...ENDLOOP语句实现循环控制
LOOP语句通常用于实现内表数据的循环读取及操作。
[For Example]
LOOP AT itab.
WRITE:itab.
ENDLOOP.
4)使用DO语句实现内部循环次数控制。
DO 语句可以指定循环次数。
[Syntax]
DO.
[<n> TIMES]
[VARYING <f> FROM <f1> NEXT <f2>].
<statement block>
ENDDO.
注:
n:可以是数字或者变量,如果n是0或者负数,系统不执行该循环。
TIMES:循环次数。
VARYING:选项在每次循环中给变量<f>重新赋值。
使用DO语句时要避免死循环,如果不使用TIMES选项,则在语句块中至少包含一个EXIT、STOP、REJECT语句,以使系统能退出循环。
[For Example]
DO 5 TIMES.
WRITE:/ 'This Index is',SY-INDEX.
ENDDO.
DO语句内部还可以实现多层嵌套,为了保证程序可读性,建议嵌套最多不要超过6层。
[For Example]
DATA do_index TYPE N.
DO 5 TIMES.
do_index = SY-INDEX.
WRITE:/ 'This Index is',do_index.
DO 2 TIMES.
WRITE:/ 'First Index Loop is',do_index, 'The Next Index Loop is',SY-INDEX.
ENDDO.
ENDDO.
执行结果如下图:
5)使用WHILE条件循环
[Syntax]
WHILE <condition> [VARY <f> FROM <f1> NEXT <f2>].
<statement block>
ENDWHILE.
循环终止CONTINUE、CHECK、EXIT
[For Example]
无条件终止循环(CONTINUE):
DATA while_index TYPE N VALUE 0.
WHILE while_index < 5.
while_index = while_index + 1.
IF while_index = 3.
CONTINUE.
ENDIF.
WRITE:/ 'while_index',while_index.
ENDWHILE.
执行结果如下图:
有条件终止循环(CHECK):
DATA while_index TYPE N VALUE 0.
WHILE while_index < 5.
while_index = while_index + 1.
CHECK while_index BETWEEN 2 AND 5.
WRITE:/ 'The while_index is',while_index.
ENDWHILE.
执行结果:
完全终止循环(EXIT):
DATA while_index TYPE N VALUE 0.
WHILE while_index < 5.
while_index = while_index + 1.
IF while_index = 3.
EXIT.
ENDIF.
执行结果:
6)使用ONCHANGE实现循环内部数据管控
当循环的数值发生变动时,可以用表达式ONCHNAGE来触发数值变动事件。
[For Example]
DATA while_index TYPE N VALUE 0.
WHILE while_index < 5.
while_index = while_index + 1.
DO 2 TIMES.
ON CHANGE OF while_index.
WRITE:/ 'The while_index has change value is',while_index.
ENDON.
WRITE:/ 'SY-INDEX=',SY-INDEX.
ENDDO.
ENDWHILE.
执行结果如下图:
ABAP吐槽!!!
学了一段时间的ABAP语法,真是对ABAP很多的语法设计无力吐槽, 今天实在忍不住了,我要吐槽!!!
ABAP的语法肯定是一个庞大团队设计的,很多地方混乱/臃肿/不明所以,和我学过其他的语言如C/C++/Java/Python/VB相比,语法真是一坨屎!!!有意思的是我列举的其他语言都是一个或几个人设计的,而ABAP,肯定是一个团队设计的.我估算ABAP基本语法是一个团队,屏幕逻辑流语法是一个团队,ABAP Object是一个团队,加上人员更迭,规范不严才导致现在这些显而易见的问题.
ABAP的混乱
Function和Method的参数是极好的例子,简直非人类.import/export/importing/exporting/exception/exceptions,关键字真尼玛多啊! BUT! 不要看import就是import喔,它也可能是export,定义函数是import就是'import',调用时呢,importing就是'export'.意义相反噢,不要搞错了.从这一处的混乱可以大致猜测定义Function和调用Function的语法是由两拨人发明的,都是从自己的角度考虑问题.碰到关键字动词要考虑ing,碰到名称要考虑加不加s,真是痛苦,感觉自己不是在编程,而是在复习英语.
ABAP语法和屏幕逻辑流语法不兼容也是一个鲜活的例子.逻辑流常用的process有PBO和PAI,在PBO或PAI里调用module达到模块化的目的.调用module的是屏幕逻辑流语法,定义实现module用ABAP语法.
还有空格问题也比较混乱,不记住基本都会用错,小括号两侧要不要加空格,减号-两侧要不要加空格都是有讲究的.具体就不细说了,严重影响篇幅.
ABAP的臃肿
ABAP语法中很少用到中括号或大括号(或者说没有用到?我是没见过),所以一个语法块的开始与结束就需要用end喽.而一个事件块的结束又没有end喔,当心了.
关键字暴多!ABAP的语法离了关键字完全没法活啊,极难找到哪条语句里面没有关键字啊(看了标准教程得知每条语句第一个单词必为关键字!),这些关键字还大写,还特么没有简写, 读起来用起来暴费劲! 最尼玛关键的是ABAP自带的旧版编辑器竟然没有关键字提示,不得不一个个手输啊,关键字definition/inheriting/implementation可真够长的!新版编辑器倒是提供关键字提示功能了. 可是! 可是! 用新版编辑器打开旧版编辑器创建的代码, 竟然乱码!!我靠,第一次碰到英文也乱码,public能给你整成pu /n blic,CLASS能格式化为cl /n ass,唉, 无力吐槽, 这是不是同一家公司的产品?!?!
整体语法太依赖关键字,入门虽简单但是熟悉了后会觉得很繁琐.举个栗子: 调用对象中的函数不是go_obj->create(),而是CALL METHOD go_obj->create,可是又有CALL METHOD go_obj->create(f)这样的用法,既混乱又臃肿.
在面向过程的ABAP中到处都是全局变量,为了区分所有变量的范围,在变量命名时不得人工添加gt_gs_lt_ls_gv_lv_这些前缀以增加代码可读性.
ABAP的不明所以
缩写没有规范.我是没感觉到有什么规律,大部分都只能碰到一个查一下再记住,没有什么特别的缩写规律.比如说DDIC是Data Dictionary的缩写,ALV是ABAP List Viewer的缩写,tab一般是table的缩写,ref是reference的缩写.PF-status这个缩写我一直都不知道全称是什么,苦恼. 还有slis,slvc,lvc,cl,kkb什么的,都是不知全称的.
合写就更混乱了,table name可能合写为table_name/tabname/tablename,field catalog可能合写为fieldcatalog/fieldcat. 这些混乱的用法就导致碰到一个没见过的词时经常不明所以,搞不定确切含义.同时在使用没用过的功能时不能按规律的猜测,必须翻看文档,否则极易用错.