ABAP 编程
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
举个例子:假如你写的应用程序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. 这些混乱的用法就导致碰到一个没见过的词时经常不明所以,搞不定确切含义.同时在使用没用过的功能时不能按规律的猜测,必须翻看文档,否则极易用错.
ABAP 编程的更多相关文章
- 如何在SAP Cloud Platform ABAP编程环境里创建一个employee
用ABAP Development Tool登录SAP Cloud Platform ABAP编程环境后,对ABAP项目点击右键,选择属性,从而找到该环境的web访问的url: https://325 ...
- 学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景
最近Jerry写了一系列关于SAP云平台ABAP编程环境的技术文章,这些文章都是围绕着在云上的ABAP编程环境的具体知识点来分享,比如要完成一个具体的开发需求,所需要的编程步骤.这些文章陆续收到一些读 ...
- SAP云平台上的ABAP编程环境里如何消费第三方服务
在ABAP On-Premises环境下,使用ABAP编程消费第三方服务,相信很多ABAP顾问都已经非常熟悉了,无非就是使用CL_HTTP_CLIENT或者CL_REST_HTTP_CLIENT来发送 ...
- SAP官方发布的ABAP编程规范
最近有朋友在公众号后台给我留言,"Jerry啊,你最近写的都是一些SAP研究院里面用到的新技术,能不能写点SAP传统的开发技术比如ABAP相关的东西"? 其实Jerry在刚开始写这 ...
- 在SAP云平台ABAP编程环境上编写第一段ABAP程序
距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP's Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今 ...
- 一些通过SAP ABAP代码审查得出的ABAP编程最佳实践
1. 这两个IF ELSE分支里检测的条件其实逻辑上来说都是同一类,应该合并到一个IF分支里进行检查: It is an expensive operation to open a file in a ...
- 使用ABAP编程实现对微软Office Word文档的操作
SAP ABAP里提供了一个标准的类CL_DOCX_DOCUMENT,提供了本地以".docx"结尾的微软Office word文档的读和写操作. 本文介绍了ABAP类CL_DOC ...
- 如何在SAP云平台ABAP编程环境里创建自己的Z表
选中ABAP包,右键创建一个新的Database Table: 维护表名为ZBOOKING: 表实现的源代码: @EndUserText.label : 'Jerry''s booking' @Aba ...
- 如何在SAP云平台ABAP编程环境里把CDS view暴露成OData服务
Jerry 2016年在学习SAP CDS view时,曾经写过一个CDS view的自学系列,其中有一篇提到了一个很方便的注解: @OData.publish: true 加上这个注解的CDS vi ...
随机推荐
- Windows NAT端口映射
由于有需求进行端口映射,又不想装乱七八糟的软件,Windows本身自带的路由远程访问配置太麻烦,还要两块网卡,坑爹啊. 其实Windows本身命令行支持配置端口映射,条件是已经安装了IPV6,启不启用 ...
- jQuery操作标签
jQuery操作标签 样式操作: 对标签的样式进行修改,那么操作样式的方法是什么? 样式类: addClass();// 添加指定的CSS类名. removeClass();// 移除指定的CSS类名 ...
- python利用socket写一个文件上传
1.先将一张图片拖入‘文件上传’的目录下,利用socket把这张图片写到叫‘yuan’的文件中 2.代码: #模拟服务端 import subprocess import os import sock ...
- [java,2018-01-16] HttpClient发送、接收 json 请求
最近需要用到许多在后台发送http请求的功能,可能需要发送json和xml类型的数据. 就抽取出来写了一个帮助类: 首先判断发送的数据类型是json还是xml: import org.dom4j.Do ...
- centos安装dlib
小心这个错误 c++: 编译器内部错误:已杀死(程序 cc1plus) # 内存不足,可解决的 复制如下命令: yum install cmake python-devel numpy gcc ...
- mongodb对数据库的基本操作
数据库切换 查看当前数据库名称 db 查看所有数据库名称 列出所有在物理上存在的数据库 show dbs 切换数据库 如果数据库不存在,则指向数据库,但不创建,直到插入数据或创建集合时数据库才被创建 ...
- Running a jupyter notebook server
你也许需要服务器运行jupyter notebook 阿里云: https://yq.aliyun.com/articles/98527 关于更安全的证书访问: http://jupyter-note ...
- 从一个异常探索spring autowired 的原理
从一个异常探索autowired 的原理. 首先环境是这样的: public class Boss { @Autowired private Car car; } //@Component 加上这个注 ...
- windows清除访问共享文件夹的登陆信息
https://jingyan.baidu.com/article/c843ea0b70797e77931e4a96.html 当在命令提示窗口输入net use命令时,会显示本机缓存的共享登录信息, ...
- 结构体中string成员的问题
在结构体中定义字符串的成员的时候要注意定义成string有时候,在某些程序中给成员赋值会崩溃,但是不确定到底什么情况会崩溃.运行报错如下: Program received signal SIGSEG ...