目录
ABAP实施常用事务代码SE11和SE80
SE11:对数据库表、视图、域、搜索帮助等基础元素进行定义。
SE80:ABAP开发(函数、程序、增强等)。
ABAP开发的常用工具-调试(DEBUG)。
按照是否由SAP创建,分为标准表和自建表两类。
【标准表】
【自建表】
基本介绍
表中包含字段、字段描述等,字段可以参考数据元素创建(数据元素规定了字段的数据类型、长度、小数位数),也可以不参考数据元素自由定义。
自定义字段,以ZPJZX_NO(配件中心编码)为例, “Z”为默认命名规范(一般非SAP进行开发时使用Z开头进行函数、程序、数据表、结构等的命名,A~W留给SAP,避免与SAP有冲突时被SAP覆盖)。对应的数据元素为ZEZPJZX_NO,Z为命名的开头字母,E为“ELEMENTS”(元素)的首字母,“ZE”标识为自定义的数据元素。
参考百度文库:https://wenku.baidu.com/view/253ddbfaa5e9856a561260da.html。
域
是用来描述一个字段的技术属性的集合,包括数据类型,数据长度,小数点位数以及取值范围等。具有以上技术属性的相同定义的字段可以包含进一个域,那么当域的属性定义发生改变时,一旦域被激活,所有引用它的字段的属性都会对应进行更改。
小数位数是通过数据类型决定是否需要输入,NUMC是数据文本(本质上是文本),所以默认小数位数为0。
需要输入小数位数的数据类型,常见的有QUAN(一般常用于数量)、CURR(货币)等。
【值范围】,类似于EXCEL中的数据校验,可以规定字段可以选择填入的值,并对填写数据进行校验。如果不需要,则不用维护。
数据元素
数据元素是一个数据的类型,包含了这个元素的语义属性,它包含了一些非结构化的数据对象(如表的字段、结构的字段和变量等)的技术属性(域)、屏幕信息(比如字段长、中、短、头标签等),是能够被引用的数据类型的最小单元,比如表或者结构的字段可以参考数据元素,这样可以保证这类特性的数据一致性。同时在ABAP中,数据元素也可以直接用关键字TYPE进行引用,从数据定义的角度来看,数据元素与ABAP最基本的数据类型(如C、I、F等)是同一个层面上。
字段
就是表的列信息,它是物质对象的某一类特征的描述,包含了数据类型信息(数据元素)、字段名、字段描述信息等。ABAP中的字段名只能以字母开始,不能以数字或者汉字开始(中间可以)。ABAP中的字段也可以是一个附属结构的名字,附属结构下的所有字段本身可以作为表格的字段。
搜索帮助
分为基于数据类型输入帮助、用固定值输入帮助、用检查表实现输入帮助
基于数据类型输入帮助,例如日期类型的数据,输入帮助就是日历表
用固定值输入帮助
用检查表实现输入帮助
以基本单位为例,其后台表存储在T006里。
从搜索帮助的配置里就可以看到,检查表为T006
表
是物质对象一系列特征的集合体,既包含特征类(字段)、关键特征(主键),也包含这些特征具体的数据(数据记录)。表是数据库的基础,承载实际数据的最小单元。是对现实物质对象的数据抽象,即数字化。
结构
总结
域(Domain)‐》数据元素(DataElement)‐》字段(Field)‐‐》表(Table)
前面三个都是后面一个的继承前面一个所有的属性,而字段则是表的构成部分。
域和数据元素最大的作用是增加了数据类型的重用性,并且域的取值范围还能起到数据一致性检查的作用,在维护数据记录的时候,能够起到提示的作用。
前三个虽然是继承关系,当时并非必要条件。字段可以引用数据元素,也可以不引用,而直接定义数据字典的基本类型(如CHAR、NUMC、CURR等,和ABAP的基本数据类型还不完全一样,也不能在ABAP代码中直接进行TYPE式引用);数据元素的定义也引用域,也可以不引用域,而直接定义数据字典的基本类型。
另外,SAP中所有的数据字典对象,只有被激活过才能够被其他对象进行引用,此原则也适合SAP其他开发对象。
练习
创建一个自定义表——学生信息表。
需求如下:
操作如下:
创建表
维护字段
1.必须要有MANDT(集团),用于标识每一条数据记录属于哪一个Client,将不同Client之间的数据进行隔离。
2.必须要有一个主键(主键可以是一个字段,也可以是多个字段构成的联合主键)。
维护字段的三种方式
1. 参考现有数据元素
MANDT(集团),参考现有数据元素MANDT,选择数据元素之后,字段的数据类型、长度、小数位数都带过来了:
2. 自定义属性
SID(学号),采用自定义属性,不参考数据元素
3. 参考自定义数据元素
GRADE,参考自定义数据元素Z_GRADE。如果没有提前创建好数据元素,则可以在此处双击进行创建。
保存表
点击上方保存按钮将表进行保存。
弹出窗口有两种方式将表保存,一是选择包,生成传输请求;二是选择【本地对象】,则只保存到本地,不触发传输。自己测试一般选择【本地对象】。
维护表的技术设置
【大小类别】:只是数据处理的一种方式,服务器每次预先留存的表空间,用于表的数据存储,如果不够则会自动扩充。
激活表
这样,一个简单的自建表就创建并激活完毕
查看表
维护一条记录后,使用SE16查看:
SE80集合了SE37、SE38等功能,可以满足ABAP技术的大部分开发需要。
即SE11中的内容,在SE80里也可以进行SE11的操作。
视图只是数据表的另一种展示方式,本身不存储数据,例如做两张及以上表的连接,满足更多查询需求。
SAP有4种视图:数据库视图、维护视图、投影视图和帮助视图。
1、 数据库视图:通过inner join的方式把若干个数据库表连接起来,可以类似的作为一个数据库表在ABAP里使用;
例如:COVP视图,是通过COEP和COBK两张表连接组成的,连接方式是两张表的主键。
2、维护视图:通过outer join的方式把数据表连接起来,可以作为维护表格内容的一种方式,很多配置都是通过维护视图实现的;
3、投影视图:有点类似数据库视图,但是是通过outer join的方式,可以隐藏一些字段内容;
4、帮助视图:用于创建搜索帮助。
函数
函数是包含输入、处理过程和输出的代码块,可以作为一个完整的模块,供程序或其他函数调用,远程调用函数可提供给外部系统使用来与SAP进行交互。
函数的输入
函数的输入可以在【导入】进行定义,也可以在【表】中进行定义。
前台显示
【表】中定义的输入
双击【关联类型】进入明细,可以看到ZRFC_STRU04实际上是一个结构,包含的字段与数据表中的字段属性相同,但是结构只能用于程序运行过程数据的暂时存储和处理,实际并不存储数据。
前台显示
函数的输出
函数的输出可以在【导出】进行定义,同样也可以在【表】中进行定义(与输入的表定义相同)。
函数的过程处理
函数的过程处理,主要是通过【源代码】中的逻辑语言,将输入转化为输出。
函数源代码主要有以下几部分:
FUNCTION声明
声明数据类型和数据对象
处理导入数据
输出导出数据
ENDFUNCTION
FUNCTION声明
功能:声明函数,方便用于其他程序或者函数调用。
调用FUNCTION的语句“CALL
FUNCTION ‘函数名’”。
内表
内表数据对象是实际的内表,可以用数据进行填充。
内表数据类型是用于定义内表数据对象的抽象数据类型。
ABAP中的内表相当于其他程序设计语言中的二维数组,存储多行结构相同的数据。
不同于二维数组,内表在创建后,列结构与列数是固定不变的,而行数是动态增长的。
内表支持循环对每行数据进行操作,也支持整体操作。
内表是具有行和列的表结构。
然而,不同于数据库表,内表仅在程序运行期间在内存中存储数据。
主要用于在程序编写过程中存储临时数据(例如把库存数据从MARD表里取出来,对物料编码一致的进行求和,计算工厂下全部非限制使用库存数量。这个场景下,就需要数据结构来存储MRAD中提取的数据,并且对数据按照物料进行循环汇总。)
可以使用的内表数据类型有:Structure、数据库表、用户自定义数据类型。
工作区、构造和内表的区别
工作区:用来存取数据的,但是只能存取一条数据
内 表: 也是用来存取数据的,但是可以存取多行数据
构 造: 是一种数据类型,用来做参照的。
比如定义一个工作区,这个工作区需要放一些字段,它就需要一种数据类型来做参照,这个参照就是构造。
构造
TYPES: BEGIN OF TY_TEST,
MATNR TYPE MARA-MATNR,
MATKX TYPE MAKT-MAKTX,
END OF TY_TEST.
工作区
DATA: GWA_TEST TYPE TY_TEST.
内表
DATA:GT_TEST TYPE TABLE OF TY-TEST.
DATA和TYPES
功能:声明数据类型和数据对象(数据结构、内表)。数据类型和数据对象是代码中操作的基础单元,必须提前声明,否则代码语言将无法编写。
DATA
定义数据对象(数据结构)。这种数据结构只需要往里填值就可以,不需要进行实例化(也就是不能直接当做数据类型一样使用)。
TYPES
定义数据类型,这种类型可以有一个或多个基础类型或结构来组成。它可以被实例化但是却不能直接接受外部赋值,这点和预定义的数据类型相同。
例如:
DATA: BEGIN OF d, //定义数据结构d,包含stu_id,stu_name,stu_class三个字段
stu_id(9) TYPE c,
stu_name(8) TYPE c,
stu_class(7) TYPE c,
END OF d.
d-stu_id = '0908103101'. //给数据结构中的每个字段赋值
d-stu_name = '司马相如'.
d-stu_class = '信管092'.
WRITE:/ '学号:',d-stu_id. //打印输出每个字段的值
WRITE:/ '姓名:',d-stu_name.
WRITE:/ '班级:',d-stu_class.
----------------------------------
结果:
-------------
学号:0908103101
姓名:司马相如
班级:信管092
ABAP内表声明
1>
TYPES: BEGIN OF line,
field1 TYPE i,
field2 TYPE i,
END OF line. //声明一个数据类型
DATA: ITAB_WA TYPE(LIKE) line. //声明一个内表工作区
DATA: ITAB TYPE(LIKE) line OCCURS 0. //声明一个无工作区的内表
DATA: ITAB TYPE(LIKE) STANDARD TABLE OFline INITIAL SIZE 0. //声明一个有工作区的内表
2>
DATA: BEGIN OF line,
field1 TYPE i,
field2 TYPE i,
END OF line. //声明一个line对象,该对象可以作为工作区使用,用DATA定义的line本身也是一个结构类型,也可再声明一个工作区
DATA: ITAB_WA TYPE(LIKE) line. //声明一个工作区
DATA: ITAB TYPE(LIKE) line OCCURS 0 WITHHEADER LINE. //声明一个带工作区的内表
DATA: ITAB TYPE(LIKE) STANDARD TABLE OF
line INITIAL SIZE 0 WITH HEADER LINE . //声明一个带工作区的内表
SELECT
SELECT MATNR //选择物料字段的值
INTO TABLE @DATA(LT_MATNR) //将取到的值写入表
FROM MARA //从MARA表中读取
FOR ALL ENTRIES IN @LT_TEMP //将读取到的数据与LT_TEMP的数据进行串联
WHERE MATNR = @LT_TEMP-MATNR. //筛选条件为LT_TEMP-MATNR字段
SORT LT_MATNR BY MATNR. //对查询到的数据按照物料编码进行排序
需要多个筛选条件,WHERE后面的多个条件之间使用AND连接
LOOP循环
LOOP循环,其中T_GHXQ是一个导入结构,如下:
*&----数据处理:补前导零
LOOP AT T_GHXQ. //如果没有读取到数据,则跳出此循环
CONDENSE T_GHXQ-PSPID NO-GAPS. //删除字符串中的前导零
CALL FUNCTION 'CONVERSION_EXIT_ABPSN_INPUT' //调用输入转换函数将PSPID(项目编号转化为SAP内部可识别的数据)
EXPORTING INPUT = T_GHXQ-PSPID
IMPORTING OUTPUT = T_GHXQ-PSPID.
CONDENSE T_GHXQ-MATNR NO-GAPS.
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
INPUT = T_GHXQ-MATNR
IMPORTING
OUTPUT = T_GHXQ-MATNR.
"供应商可能为空的,如果空就不做校验,如果不为空就做校验
CONDENSE T_GHXQ-LIFNR NO-GAPS.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = T_GHXQ-LIFNR
IMPORTING
OUTPUT = T_GHXQ-LIFNR.
CONDENSE T_GHXQ-BANFN NO-GAPS. 、
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = T_GHXQ-BANFN
IMPORTING
OUTPUT = T_GHXQ-BANFN.
MODIFY T_GHXQ. //将处理后的数据更新到数据结构T_GHXQ中
ENDLOOP. //结束一次循环
补充说明
1.代码里可以直接使用结构T_GHXQ,实际上已经在代码的开始预先定义好了:
2.CALL FUNCTION ***,代码中用来调用其他函数的语句。
如下,即为物料添加前导零的语句,外部系统通过T_GHXQ传入的物料编码未带前导零,需要补上才可以在SAP里进行识别和处理。
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
INPUT = T_GHXQ-MATNR
IMPORTING
OUTPUT = T_GHXQ-MATNR.
3.SAP里的数据类型对应的域,外部显示的数据和内部存储的数据如果存在差异,则会通过【例程】来进行定义:
双击例程可以查询到转换函数,带INPUT为输入转换函数,带OUTPUT为输出转换函数:
MODIFY
MODIFY兼有UPDATE和INSERT的功能,会自动比较数据是否在要写入的表里存在,来执行UPDATE或INSERT。
"记录日志
CLEAR NUM. //涉及到循环的数据结构,需要在循环前先清空,再使用。
LOOP AT T_GHXQ. "日志行号
NUM = NUM + 1. GV_IFPOS = NUM.
"宏里面没写清空变量的,所以一定要在用宏之前先清空这个工作区
CLEAR GS_ZTMM3009.
MOVE-CORRESPONDING T_GHXQ TO GS_ZTMM3009.
"填充日志内表的宏
INIT_LOG GV_REQDE GV_REQTE GV_REQDT GV_IFSNR
GV_IFPOS GV_MSGID T_RETURN-IFFLG T_RETURN-IFMSG
SY-UNAME.
ENDLOOP.
CLEAR GV_IFPOS. "更新日志到数据库表
PERFORM FRM_MODIFY_LOG TABLES GT_ZTMM3009. //为了保证代码的连续可读性,将可独立成块的代码封装起来,放在整块代码的后面,只在代码中间使用PERFORM进行调用。实际上,在这里把FORM的代码写上也没问题。
GV_ERROR = 'X'. ENDIF.
* 更新日志到数据库表*----------------------------------------------------------------------*
FORM FRM_MODIFY_LOG TABLES PT_ZTMM3009 STRUCTURE ZTMM3009.
IF PT_ZTMM3009[] IS NOT INITIAL.
"更新到日志表
MODIFY ZTMM3009 FROM TABLE PT_ZTMM3009[].
IF SY-SUBRC = 0.
COMMIT WORK AND WAIT. //如果更新表的动作执行成功,则提交任务。
ELSE.
ROLLBACK WORK. //否则回滚操作。
ENDIF.
ENDIF.
ENDFORM.
数据校验
以校验工厂WERKS为例
首先,将有效数据从标准表T001W中读取出来存放到内表LT_WERKS中,此处使用SELECT语句:
使用READ语句,将数据从LT_WERKS读取到LS_WERKS(工作区)中,与T_GHXQ-WERKS(导入数据表)的值进行比较。IF SY-SUBRC<>0,(匹配成功返回值为0,<>0标识匹配失败),则进行提示“工厂未查询到”。
对于输出的处理
APPEND 将数据全部提交给T_RETURN,作为接口的返回结果。
完整的程序,主要分为以下几部分:声明和定义、SELECTION-SCTEEN、INITIALIZATION、START-OF-SCREEN、PERFORM FRM_ALV_DATA。
声明和定义
程序的声明:REPORT ***(程序名)。
数据库表的声明:用于声明程序中使用到的数据库表。
定义程序界面的按钮、状态灯等。
内表和工作区定义
热点链接(点击调转界面)
列颜色(改变ALV报表某一列的颜色)
SELECTION-SCREEN定义选择屏幕
INITIALIZATION选择屏幕初始化
定义选择屏幕各字段的初始值/输入值范围及输入方式
START-OF-SELECTION开始选择屏幕
执行选择屏幕的输入,作为ALV报表显示的输入/筛选条件。
PERFORM FRM_ALV_DATA,ALV显示
通常用PERFORM FRM_ALV_DATA来执行ALV的显示,作为程序的输出。
FRM_ALV_DATA 主要有以下固定部分组成。
ALV报表字段:
这里可以这样写,是因为之前定义了宏:
Web Dynpro是一种标准的SAP
UI技术,允许使用与ABAP工作台集成的原型工具和开发环境来开发Web应用程序。使用原型工具可以减少实施工作量,也可以更好地重用和维护ABAP工作台中的组件。
样例可参考:SAP自开发的请求管理网页平台solmsg。
或者,SOA管理界面:
即事务代码,将程序包成事务代码,可以使用事务代码执行程序(注意:程序ZMMR200和事务代码ZMMR200的区别)。
类似在SE38,输入程序名ZMMR200后,点击执行:
使用SOAMANAGER,对远程调用函数(RFC)进行Webservice配置后,可以生成Webservice地址供外部系统调用,配置后可在【企业服务】-->【服务定义】中查询到。
以RFC函数ZLFR_SAP_TO_HAP供应商主数据同步为例。
进入测试界面的方式:
1、
2、
进入测试界面,输入参数,点击按钮:
进入调试界面:
调试界面抬头分别为四个执行键(一般使用F6进行调试,不会每一行代码都经过,也不会直接运行完,可以有时间来查看字段/表的赋值变化)
1——执行单个步骤,对应F5键(如果代码执行过程中经过调用的其他函数,则会跳转到这个函数内部执行)
2——执行单个代码块,对应F6键(如果代码执行过程中经过调用的其他函数,不会进入该函数,而是直接执行完这个函数)
3——返回上一步,对应F7键
4——执行到下一个断点/如果没有断点则执行完全部逻辑,对应F8键。
对于代码执行经过的字段,可以双击显示字段此时被赋予的值:
对于代码执行经过的表,可以双击显示表此时被赋予的值:
双击右侧的ITAB[],可以看到值的明细(可以看到表ITAB[]中只有一行数据,这是在查询参数中只输入了一个LIFNR=10000050,这样根据LIFNR在表LFA1中只查询到一行数据):
点击【桌面3】,返回原来的调试界面:
经过LOOP循环后, 看下表ITAB[]中发生的变化:
采购组织EKORG和公司代码被赋予了值:
代码走到ENDFUNCTION,调试就结束了
屏幕跳转到测试界面,可以看到ITAB中有一行数据:
点击查看,可以看到和程序调试时看到的ITAB[]中的数据一致