导图社区 SAP-ABAP开发
《SAP ABAP开发技术详解:语法手册》 对SAP ABAP开发所需的基础技术(ABAP编程语言概述,ABAP字典,ABAP语法解析)做了详尽的介绍,包括ABAP语言特性、ABAP数据字典各元素的介绍及用途、ABAP语法中各关键字的说明以及相关示例。
编辑于2022-07-12 12:21:42微信小程序开发知识整理,系统地介绍了微信小程序开发的基础知识,帮助开发者更好地理解和掌握小程序开发的要点和流程。
SpringFramework技术的介绍,SpringFramework,通常简称为Spring,是一个开源的企业级Java应用程序框架,由Rod Johnson创建,并于2004年首次发布。Spring Framework的主要目标是简化企业级Java开发,提高开发效率和应用程序的可维护性。
Maven的特性以及使用部署方法,Maven介绍:Maven是一款为Java项目构建管理、依赖管理的工具(软件),使用Maven可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。
社区模板帮助中心,点此进入>>
微信小程序开发知识整理,系统地介绍了微信小程序开发的基础知识,帮助开发者更好地理解和掌握小程序开发的要点和流程。
SpringFramework技术的介绍,SpringFramework,通常简称为Spring,是一个开源的企业级Java应用程序框架,由Rod Johnson创建,并于2004年首次发布。Spring Framework的主要目标是简化企业级Java开发,提高开发效率和应用程序的可维护性。
Maven的特性以及使用部署方法,Maven介绍:Maven是一款为Java项目构建管理、依赖管理的工具(软件),使用Maven可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。
SAP ABAP语言基础
一、 ABAP语言基础
1. 概述
ABAP语言是整个SAP系统的基础开发工具和技术平台,包含事件驱动(Evet-Driven)、机制和模块化技术(Modularization)、完整的面向对象概念及实现方法(Object Oriented)等
2. ABAP程序结构
ABAP程序的源代码结构主要包括数据定义、处理块两部分
数据定义:整个程序中可见的全局数据类型和数据对象、选择屏幕元素以及ABAP Object中自定义的类和接口
处理块(Processing Blocks):是ABAP的主要结构单元,定义程序在不同状态下执行的具体功能,在编译运行中,每一块都是一个独立的实体。数据(包括选择屏幕元素)定义和声明语句是独立于任何处理块的,其他的所有语句都必须隶属于某个处理块
1. ABAP程序包含的3中类型的处理块
(1) 事件块(Event Blocks):每一个事件都需要有一个时间关键字引导,并单独构成一个语句,其后续语句隶属于该关键字代表的时间块,知道下一个关键字出现为止,包括报表事件、列表事件、屏幕事件等
1||| 初始化:INITIALIATION
2||| 数据选择开始:START-OF-SELECTION
3||| 列表行选择:ATLINE-SELECTION
4||| 屏幕输出前处理:PROCESS BEFORE OUTPUT
5||| 屏幕输入后处理:PROCESS AFTER INPUT
(2) 对话模块(Dialog Modules):开始和结束都有相关的关键字作为标志,是相对独立的程序单元
(3) 过程(Procedures):代码部分的开始和结束都有相关的关键字,也是相对独立的程序单元。过程包括功能模块和子程序,以及对象中的类方法。可以被其它的模块调用,实现程序模块化和代码复用
2. 处理块调用
处理块是程序代码模块,也是运行期间的单元,其具体出现的顺序与其在程序代码中的先后顺序无关
3. 事件驱动
在各种处理块中,系统对事件块的调用过程有其特殊性:其调用总是与某事件地发生相关,也称为事件的触发
4. 处理块与工作过程
通过调度机(Dispather)把应用程序的各个代码模块分解成许多对话步骤,并通过工作过程(Work Processes,是系统的软件元素)在系统的应用层的虚拟机上进行处理,这保证了ABAP程序运行时的系统硬件平台无关性
3. ABAP程序类型
ABAP/4语言开发的程序主要分为应用程序和其他程序两种
(1) 应用程序类型
1||| 可执行程序(Executable Program,类型代码1):整个程序由Report关键字语句进行引导,可以包含自定义的屏幕,在ABAP编辑器中进行编辑,并可直接在ABAP编辑器中执行。此外,还可以通过Submit语句或者分配报表事务代码来运行
2||| 模块池(Module pool,类型代码M):出案件时由系统自动生成,由PROGRAM关键字进行引导,一般包含程序自定义的屏幕和对话模块,必须通过事务代码运行
3||| 报表程序:报表程序用于分析数据库表中的数据,分析的结果可显示在屏幕上或发送到打印机上。逻辑数据库支持报表程序,它是一种特殊的ABAP/4程序,使开发者不必编码即可对所有的数据库进行访问
4||| 对话程序:对话程序组织为包含对话模块的模块池。每个动态程序(由一个屏幕及其流逻辑组成的“动态程序”)都基于一个ABAP/4对话程序。流逻辑包含对ABAP/4对话模块的调用
习惯上,应用程序往往是按照报表程序和对话程序(又称动态程序、事务程序)进行划分的。在可执行程序中可以处理报表事件,也可以加入屏幕和对话模块,而模块池程序一般只用于事务程序的设计
(2) 其他程序类型
其他程序不能直接执行,但这种类型的程序可以作为代码容器,为ABAP程序提供各种各样的模块化代码单元。主要有以下几种类型
1||| 功能组(Function groups,类型代码F):由Function-pool语句引导,包含一个或多个功能模块,可包含自己的屏幕,一般不能直接运行功能。功能模块是模块化的代码段,不能用来直接执行,而需要在普通程序中调用
2||| ABAP类库(Class pools,类型代码K):由Class-pool语句引导,是系统ABAP对象类和多个局域类。类库在ABAP工作台工具Class Builder进行创建
3||| ABAP接口库(Interface pools,类型代码J):由Interface-pool语句引导,与类型K程序相似,用于定义ABAP对象的接口,可被人以全局类和局部类实现,不能直接运行
4||| 子程序池(Subroutine pools,类型代码S):由Program语句引导,包含一个或者多个程序代码模块或类方法,允许被普通程序调用,不可包含自定义的用户屏幕,在ABAP编辑器中进行编辑
5||| 类型组(Type Groups,无类型代码):由Type-pool语句引导,在数据字典中定义,不包含任何屏幕和处理块,用于定义全局数据类型
6||| 包含程序(Include Programs,类型代码I):不需要任何语句引导,也无需包含完整的处理块。无需独立编译,包含程序只是代码复用,在ABAP/4中编辑,可直接插入其他程序中。包含程序可通过Include语句被多个程序引用,与其他程序之间不存在参数接口
4. ABAP语言特性
(1) 具备多种元素
1||| 各种类型和结构的声明元素
2||| 数据制作的操作元素
3||| 控制程序流的控制元素
4||| 反映外部事件的事件元素
(2) 支持多语言
文本摘要根据程序代码分别存储。开发人员可以随时在不改变程序代码的情况下更改、转换和维护文本摘要
(3) ABAP/4支持商业数据类型和操作。开发人员可使用特殊日期和时间字段进行计算。系统会自动提供必须的类型转换
(4) ABAP/4提供功能处理字符串
(5) ABAP/4可通过OpenSQL工具直接访问数据库表
(6) ABAP/4允许自定义及处理内部表。内部表只在允许在运行程序时存在,并对底层数据库进行帮助处理,以及完成建立程序中的复杂数据结构
(7) ABAP/4允许自定义及调用子程序。通过调用指定程序的子程序,使得参数能够以各种方式从子程序传递或传递给子程序
(8) ABAP/4具备功能模块这种特殊的子程序。开发人员可以自己创建及维护功能模块,还可以对调用程序和子程序之间的功能模块明确定义一个或多个数据接口,他们能够以调用程序的独立模式进行单独测试
二、 数据定义
1. 概述
数据类型和数据对象是ABAP/4类型概念的基本组件,二者均可由用户声明和维护。这与其他编程语言,如C、FORTRAN或PASCAL不同,在这些语言中用户可以声明数据对象,但仅限于预定义的数据类型。而在ABAP/4中,可以使用与标准数据声明相似的语法处理数据类型,而与数据对象无关。特殊程序以外的数据类型集中存储也是可能的
2. 数据类型和数据对象基础
(1) 数据类型(包括基本数据类型或结构化数据类型)
1||| 数据类型是数据对象的类型
2||| 数据类型不占用物理内存
3||| 数据类型描述数据对象的技术属性
在ABAP/4程序中按结构和定义对数据类型分类。一般划分为
1||| 基本的(非结构化的)或结构化的
2||| 预定义的或用户定义的
其中ABAP/4程序中的基本数据类型主要包括
C
默认大小:1
有效大小:1-65535
初始值:空值
说明:字母、数字、字符
I
默认大小:4
有效大小:4
初始值:0
说明:整型
D
默认大小:8
有效大小:8
初始值:‘00000000’
说明:日期(格式:YYYYMMDD)
N
默认大小:1
有效大小1-65535
初始值‘00...0’
说明:数字文本
F
默认大小:8
有效大小:8
初始值:0
说明:浮点数
P
默认大小:8
有效大小:1-16
初始值:0
说明:压缩号
T
默认大小:6
有效大小:6
初始值‘000000’
说明:时间(格式:HHMMSS)
X
默认大小:1
有效大小:1-65535
初始值:‘00’
说明:十六进制
(2) 数据对象(文字、变量、常量等)
1||| 数据对象是程序在运行时使用的物理单元
2||| 每个数据对象都有分配给它的特定数据类型
3||| 每个数据对象占据一定的物理内存
4||| ABAP/4程序根据数据对象的数据类型处理数据对象
在ABAP/4程序中,可以使用以下几种数据对象
1||| 内部数据对象:创建内部数据对象供在特定的程序中使用,但在该程序之外无效
2||| 外部数据对象:外部数据对象独立于程序。不能直接使用外部数据对象,但能将其赋值到内部数据对象,并在完成后将它们回写。可以在整个系统环境中全局使用外部数据对象。
tips:ABAP/4程序将外部数据对象保存在ABAP/4词典中定义的表中。要从程序内部访问该数据,须通过TABLES语句对表进行定义
3||| 系统定义的数据对象:除了用户定义的数据对象外,还有一些数据对象由系统自动定义
4||| 特殊数据对象:ABAP/4程序中还包括一些具有特殊特征的数据对象
参数:指链接到选择屏幕的变量,它可以在程序启动后接收及传送数值
选择标准:用于制定数值范围的特殊内表,它与选择屏幕相链接
(3) 在创建一个程序的开始,必须声明要使用的全部数据对象。声明过程中还必须给数据对象分配相应的属性,其中最重要的属性就是数据类型。在ABAP/4程序开发的过程中,可以使用与其他程序语言类似的预定义数据类型,或者使用用户自己定义的数据类型。ABAP/4程序分为3个层次级的数据类型和对象
ABAP/4程序字典中定义的独立于程序的数据
独立程序中要全局使用的内部数据
单独过程(子程序和功能模块)中要局部使用的数据
(4) 用户定义的基本数据类型完全是以预定义的基本数据类型为基础的。要定义自己的基本数据类型,需要在程序开发中通过使用TYPES语句来定义,如下所示
TYPES: NUM TYPE I, LENGTH TYPE P DECIMALS 2, ID(3) TYPE C.
通过TYPES语句,将字段NUM定义为I整形数值;将字段LENGTH定义为小数点后两位的P类型;将字段ID号定义为长度为3的C字符类型
3. 创建数据类型和数据对象
在ABAP/4程序中创建数据对象和数据类型必须通过声明语句。一般来说,在声明语句中定义数据对象的数据类型采用以下两种方式
1||| 直接声明方式。例如A TYPE<datatype>,通过TYPE选项可直接将数据类型<datatype>分配给已声明的数据对象
2||| 间接声明方式。例如B LIKE<dataobject>,通过LIKE选项可将另一个数据对象<dataobject>的数据类型分配给已声明的数据对象
在ABAP/4程序中可使用数据声明语句静态创建数据对象,也可以利用操作语句动态创建数据对象。用于静态创建数据对象和数据类型的关键字如下所示
1||| DATA语句
用于创建变量
2||| CONSTANTS语句
用于创建常量
3||| STATICS语句
用于创建变量,这些变量在程序运行期间一直存在,但仅在过程中可见
4||| TABLES语句
用于创建表工作区
5||| TYPES语句
用于创建用户定义的数据类型
4. 语法使用
1||| DATA语句
(1) 语法1:DATA <f>【(<length>)]<type>[<value>][<decimals>]
其中<f>是为变量进行命名,变量名<f>最长可以达30个字符;<length><type>是指定变量的“数据类型”和”变量的长度“;<value>为变量指定初始值;<decimals>是当变量有小数位的时候指定小数位位数
(2) 语法2:DATA<f>LIKE<g>
在使用LIKE参数时,根据与数据对象<g>完全相同的类型和结构创建字段<f>,此语法可将任何数据对象用于<g>;
例如:DATA NUM1 TYPE P. DATA NUM2 LIKE NUM1.
(3) 语法3:DATA<f>......VALUE<val>
词语发通过DATA命令将字段<f>的初始值设为<val>,其中<val>可以是常量
(4) 语法4: DATA:BEGIN OF <abcd>, <component declaration>, ......... END OF <abcd>
这些语句定义了字段串ABCD,在语法<component declaration>中,可以指定长度、类型、初始值或小数位数具体如下
DATA:BEGIN OF ABC, NAME(20) TYPE C, STREET(20) TYPE C, NUMBER TYPE P, END OF ADDRESS.
2||| CONSTANTS语句
在编写ABAP/4程序时,如果要频繁地使用某常量,可以利用CONSTANTS语句,将其声明为具有固定值的变量
语法:CONSTANTS <c>[<length>]<type><value>[<decimals>].
如果要将字段串定义为常量,则如下所示: CONSTANTS:BEGIN OF <abcd>, <conponent declaration>, ............ END OF <abcd>.
tips:对于CINSTANTS语句,必须使用<value>参数,而在DATA语句中此参数是可选的。另外,利用<value>参数指定的初始值,在程序的执行期间不能更改
3||| STATICS语句
在开发过程中,如果要在过程的运行时间之外扔保留某变量的数值,可在该过程中利用STATICS语句定义该变量。STATICS语句是DATA语句的变异
语法:STATICS<a>[<length>]<TYPE>[<value>][<decimals>].
如果要在程序中多次调用某过程,对于利用STATICS定义的变量,过程总是使用该变量的最新值,而不能从过程外部定址静态变量
4||| TYPES语句
使用TYPES语句可以创建用户定义的基本数据类型和结构化数据类型。对于由TYPES 语句定义的数据类型,可以按与使用预定义数据类型声明数据对象相同的方法使用
语法:TYPES<a>[<length>]<type>[<decimals>].
在该语句中定义了数据类型<a>。那么如果要定义结构化的数据类型,则需要通过以下语法: TYPES: BEGIN OF <abc>, <component declaration>, ..................... END OF <abc>.
tips:由于没有与数据类型相关联的内存,所以无法在TYPES语句中使用<value>参数。因此,TYPES语句不能给数据类型分配值
三、 ABAP开发基础
1. 创建新程序及其属性
1||| 创建新程序
要创建一个新的ABAP/4程序,首先要想好给这个程序起什么名字。一般来说,程序名只要设置在8个字符内都是允许的,但是还得注意以下规范
i. 程序不得使用特殊字符,包括下划线、空格等符号
ii. 报表程序(Yaxxxxxx或Zaxxxxxx):一般以Y或Z作为首字母,然后用应用程序区的分类字母替换a,用任何有效字符替换x
iii. 其他ABAP/4程序(SAPMYxxx或SAPMZxxx):使用有效字符替换x
命名完程序名后,下面就要进入到ABAP程序的编辑界面。打开编辑器的具体步骤如下
1||| 在SAP系统菜单中选择“工具->ABAP/4工作台”菜单,或在命令栏中输入SE38命令,出现“ABAP编辑器:初始屏幕”界面,如图1所示
图1
2||| 在“程序”字段中输入要创建的程序名,然后单击创建按钮,系统会弹出“程序属性设置”对话框,要求开发人员设置程序的相关属性,如图2所示。程序属性决定程序属于哪种应用程序,以及程序所链接的逻辑数据库
图2
3||| 首先需要在“程序属性设置”对话框中的“Title”文本框输入程序标题。创建完标题以后,再进行程序类型的设置。如果创建报表程序,则在“类型”字段中选择“可执行程序”选项;如果创建模块存储,则在“类型”字段中选择“模块池”选项。设置完成后,接着在“应用程序”字段中为应用程序输入分类字母,例如财务会计程序就输F
4||| 所有属性设置完成后,单机保存按钮以保存属性,系统弹出“维护对象目录条目”对话框,如图3所示,在这个对话框中可以输入开发类和开发负责人员。完成后单击保存开发类并返回“ABAP/4:程序属性”屏幕,然后单击返回按钮,离开屏幕。如果要直接转到ABAP/4编辑器,选择“转向->源代码”即可
图3
5||| 对于某些程序初始界面有筛选条件的字段,可以在图1中选择“文本元素”选项然后单击修改按钮,系统会弹出“文本要素”编辑界面,如图4所示,在此界面中选择“Selection texts”选项页即可针对筛选条件字段进行文本描述的编辑
图4
6||| 如果对于已经创建完的程序要更改标题,也可以在图1中选择“ABAP/4编辑器初始屏幕”中的“属性”选项,然后单击修改按钮即可重新进入到“程序属性设置”页面
2||| 重要的程序属性
(1) 类型
除了“可执行程序”和“模块池”之外,还应该注意类型I(include程序)。包含程序是个独立的程序,它有两个主要特征。首先,它包含程序代码,不同的程序都可以使用该代码。其次,它用于模块化程序源代码,该代码分成逻辑相关部分,其中每个部分都存储在不同的包含程序中。包含程序用于改善源代码的可读性并有助于维护
(2) 应用程序
“应用程序”字段包括应用程序的缩写,例如财务会计可缩写为F。此字段可以使系统能将程序分配给适当的业务区
(3) 开发类
开发类对系统之间进行传输非常重要。执行传输任务时,可将分配给某个开发类的工作台对象组合起来。如果用户在某组中工作,可将程序分配给现有开发类或创建新的开发类。但也可以通过选择“ABAP编辑器:初始屏幕”界面上的“程序->其他对象”更改已分配给程序的开发类,如图5所示
图5
(4) 应用程序中的逻辑数据库
这些属性决定报表应该使用哪个逻辑数据库去检索数据,以及逻辑数据库属于哪个应用程序。应用程序中的数据库名称必须名称必须是唯一的。如果报表程序直接读取数据,而未使用逻辑数据库,就应该像通常一样指定应用程序,但必须将“逻辑数据库”字段置为空
2. 编写程序及检查
I. 在“ABAP:程序属性”界面上选择“转向->源代码”或“源代码”
II. 选择“源代码”选项后,单击“ABAP编辑器:初始屏幕”界面上的创建按钮,进入“ABAP/4编辑器编辑程序”界面啊。此时系统会自动输入第一个ABAP/4语句,例如: REPORT<reportname> or PROGRAM<programname>。 这里的<report/programname>,系统一般会自动使用在“ABAP编辑器:初始屏幕”界面上输入的名称,如图6所示。语句REPORT或PROGRAM语句有不同的参数,如LINE-SIZE、LINE-COUNT或NOSTAN-DARDPAGEHEADING。这些参数主要适用于报表程序,用来分析数据并输出结果列表
图6
III. 在编辑器中开始书输入程序代码。完成编辑后单击“检查”按钮进行程序的语法检查。系统会自动扫描程序代码,以寻找语法错误及不相容处。如果检查出错误,在编辑器的下方会出现消息报告,有可能的话,系统还会提示建议解决方案或更改操作,如图7所示
图7
IV. 编辑完程序后,单击保存按钮将源程序的文本存储在程序库中
V. 同样,如果要对程序进行修改,在“ABAP编辑器:初始屏幕”界面的“程序”字段中输入要更改的程序名称,选择“源代码”选项并单击“显示”或“修改”按钮即可
3. 分配事务代码给程序
程序创建完成,如果要运行程序,必须要给程序分配一个事务代码才能通过命令栏或者菜单运行程序,步骤如下
1||| 在“ABAP/4开发工作台”界面上选择“开发->其它工具->事务”选项(或者直接在命令栏输入SE93命令),进入“维护事务界面,如图8所示
图8
2||| 填入事务名称并选择创建按钮,然后在对话界面上选择”报表事务“的选项。同时在”建立事务“界面中填入所需条目的”事务文本“和”程序“,最后单击保存按钮将事务代码保存在开发类中,如图9所示
图9
4. 程序测试及运行
开发及分配事务代码完成以后,则需要对程序进行测试,以及检查代码是否能够正确运行
1||| 在”ABAP编辑器:初始屏幕“的”程序“字段中输入要更改的程序名称,然后单击”ABAP/4编辑器编辑程序“界面上的”执行“按钮
2||| 系统执行该程序,如同从”ABAP编辑器:初始屏幕“界面中启动的一样。例如,创建报表程序之后,则首先出现从中输入条件的选择界面,然后是结果列表
5. 程序语法元素
ABAP/4编程语言包括下列元素类型
(1) 语句
示例:PROGRAM TEST. WRITE ‘Frist Program’.
该示例中的语句是通过关键字PROGRAM和WRITE写入的。定义了TEST程序,并在程序中写入了‘First Program’的文本
(2) 关键字
关键字是语句的第1个词,它决定整个语句的意义。有以下4种不同类型的关键字
1||| 活动性关键字:这些关键字定义数据类型,或者说明程序可以访问的数据对象,例如TYPES、DATA、TABLES。系统只在生成程序期间处理说明性关键字。一般来说,所有的说明性关键字都是在程序开头的“说明部分”中去指定
2||| 事件关键字:这些关键字在ABAP/4程序中定义处理块。处理块是当特定事件发生时进行处理的语句组。示例如下:AT SELECTION SCREEN 、START-OF-SELECTION、ATUSER-COMMAND
3||| 控制关键字:控制关键字按照特定条件控制ABAP/4程序流。示例如下:IF、WHILE、CASE
4||| 操作关键字:当事件或者条件发生时,操作关键字开始处理相关数据。示例如下:WRITE、MOVE、ADD
(3) 注释
注释是卸载ABAP/4程序语句之间,用来向读者解释其程序或者模块功能的文本摘要。注释由系统定义的特殊字符标记“*”号来作为引导。一个好的程序一定要有丰富的注释去帮助其他用户理解和更改程序,示例如下
*********************************************** * PROGRAM SAPMTZST * * LAST CHANGE BY RITA DIGIT,01/01/2000 * * PURPOSE : DEMONSTRATION *
四、 结构控制
ABAP/4程序具有特定结构的不同语句的顺序。可以在语句间插入注释。分开的但相似的语句顺序可以组成链语句。常用的结构主要有以下几种
(1) 语句结构
ABAP/4没有格式限制,可以按照任意自由格式输入语句。既可以缩排语句、在一行中写几条语句,也可以一条语句跨越几行。但是,在语句中必须至少要使用一个空格分开词,系统本身也将行结束符解释为空格。例如: PROGRAM SAPMZTST . WRITE ' This is a file ' . 也可以编成一行:PROGRAM SAPMTEST. WRITE 'This is a file'. 或者是: PROGRAM SAPMTEST. WRITE 'This is a file'.
虽然可以跨行写编码,但是从程序规范性的角度来说,应该尽量使用规范的格式,以提高程序的可读性,而避免使用复杂格式
(2) 注释结构
注释结构在程序的任意位置插入注释行,一般程序中可使用以下两种方法标明注释
1||| 如果要将整行变为注释,则在行开始处输入星号(*)
2||| 如果要将某行的一部分变为注释,则在注释之前输入双引号("),系统将由双引号标明的注释解释为空格 示例如下: PROGRAM TEST. *The following line contains a WRITE file. WRITE 'First Program'. " Output on List
示例中,程序的第2行是不执行的注释,注释由行开始处的*标明;程序的第3行,"之后全部都是注释,并且不被程序执行
(3) 连接相似语句(链语句)
ABAP/4编程语言运行将带有相同起始部分的连续语句作为链语句。要连接分开的语句,只要写一次相同部分,并且在其后设置冒号”:“,冒号后列出语句的其余部分并用逗号(,)分开,并在最后结尾设置句号”。“作为系统链的结束处
示例: WRITE SPFLI-TEST01. WRITE SPFLI-TEST02. WRITE SPFLI-TEST03. 通过链语句修改后: WRITE: SPFLI-TEST01 , SPFLI-TEST02 , SPFLI-TEST03 .
在链语句中,冒号将语句的开始部分与可变部分分开,可以在冒号(或逗号之前或之后插入任意个空格)
五、 使用内表
在ABAP/4程序中,表格是系统中的关键数据结构。长期使用的数据都是存储在关系数据库表格中。但除了数据库表格,还可以创建仅在程序运行时间内存在的内表。ABAP/4程序提供了针对内表的不同操作,例如搜索、附加、插入或删除行等。 内表中的行数并不固定。根据需求,系统可实时增加内表的大小。如果想将某个数据库表格读入内表,也不必事先知道数据库表格的大小。该特征项使得内表使用起来十分方便,同时还支持动态编程。 ABAP/4程序还支持使用内表在数据库表格的子集上进行表格计算。例如,可以将数据库表格的某个部分读入内表,然后可以从内表中计算总和或生成次序表。内表关键字有以下两种类型
1||| 自定义关键字:使用READ语句从内表中读取行时,可以指定自定义关键字
2||| 缺省关键字:根据定义,内表的关键字段是非数字(类型F、I和P)和非内表的字段。这些关键字段形成内表的标准关键字。要获得带嵌套结构(包含字段串作为组件的表格行)的内表标准关键字,系统将子结构分为基本字段层次
访问内表
内表是按行进行访问的。必须使用某个工作区域作为与表格互相传输数据的接口。 从内表中读取数据时,已定址的表格行内容覆盖工作区域的内容,然后可以在程序中引用工作区域的内容,将数据写入内表时,必须首先在工作区域(系统可以将数据传输给内表)中输入数据。 为了避免不一致,最好是工作区域与内表行有相同的数据类型。创建与内表兼容的工作区域的一种安全步骤,是在说明内表和工作区域时使用相同的数据类型。在该环境中,可以区分ABAP/4中两种类型的内表的差别
1||| 带表头行的内表:如果创建带表头行的内表,系统自动创建与内表行数据类型相同的工作区域。该工作区域称为表头行或表格工作区域,对内表的作用与由TABLES语句创建的数据库表格工作区域相同。表格工作区域和内表本身同名
2||| 不带表头行的内表:不带表头行的内表没有可以隐式使用的表格工作区域。要访问没有表头行的内表,必须在相应的ABAP/4语句中显式指定工作区域。决定创建的内表是否带表头行时,必须考虑是否喜欢隐式还是显式用于内表访问的工作区域
创建内表
创建内表时,可以决定是先用TYPES语句创建内表数据类型,然后再创建具有该类型的数据对象,还是直接使用DATA语句创建内表数据对象。或者决定创建带表头行的内表数据对象,以及创建不带表头行的内表数据对象
1||| 创建内表数据类型:要创建内表数据类型,需要使用TYPES语句。 语法:TYPES <t> <type> OCCURS <n>.
该语句通过使用TYPES语句的OCCURS选项创建一个内表数据类型<t>。内表中行的数据类型在<type>中指定。要指定行的数据类型,可以使用TYPE或者LIKE参数 通过使用LIKE参数引用ABAP/4词典中定义的对象,可以创建内表。其行结构与存储在词典中的对象相同,且反应数据库表格的结构,在读取和处理数据库表格时这种结构非常重要。<n>指定行的初始号,将第1行写入用类型<t>创建的内表数据对象之后,就为指定行保留了内存。如果添加到内表中的行比<n>指定的要多,则自动扩展保留的内存;如果内存中没有足够的空间可用于内表,则将其写入缓冲区或磁盘
2||| 创建内表数据对象:创建内表数据对象,对于用新的行结构创建的表格,则必须要有表头行。如果是用另一个表格来创建内表,则要通过引用现有内表数据类型或数据对象来创建内表数据对象,可使用DATA语句, 语法:DATA <f> <type> [WITH HEADER LINE]. 通过使用TYPE或LIKE,可以使用<type>选项来引用表格数据类型或表格数据对象,将数据对象<f>说明为结构相同的内表。如果使用WITH HEADER LINE 选项,创建的内表则带工作区域<f>
3||| 通过引用结构来创建内表:要通过引用现有行结构创建内表数据对象,则要使用DATA语句的另外一种语法结构, 语法:DATA <f> <type> OCCURS <n> [WITH HEADER LINE].
4||| 创建带新结构的内表:要创建既不引用现有对象,也不引用现有行结构的内表数据对象,则可以使用DATA语句, 语法: DATA:BEGIN OF <f> OCCURS <n> , <component declaration>, ....................................... END OF <f>.
在这里定义内表<f>并在<component declaration>中说明其行组件。除OCCURS参数外,语法与定义字段串相同。该语句通常用于创建表格工作区域<f>,因此,其作用与先创建字段串<f>,然后再创建与该字段串行结构相同的内表<f>相同。其中参数<n>用于制定行的初始号。将第1行写入用类型<t>创建的内表数据对象之后,就为指定行保留了内存。如果添加到内表中的行比<n>指定的要多,则自动扩展保留的内存;如果内存中没有足够的空间可用于内表,则将其写入缓冲区或磁盘
使用内表
1||| 内表填充
(1) 要填充内表,既可逐行添加数据,也可复制另一个表格的内容
I. 如果是逐行填充内表,可以使用APPEND、COLLECT或INSERT语句
II. 如果要将内表仅用于存储数据,出于性能方面的考虑,建议使用APPEND。而且APPEND语句还可用于创建序列清单
III. 如果要计算数字字段之和,或要确保内表中没有出现重复条目,建议使用COLLECT语句,它可以根据标准关键字处理行
IV. 如果要在内表现有行之前插入新行,建议使用INSERT语句
V. 如果要将内表内容复制到另一个内表中,建议使用APPEND、INSERT或MOVE等语句的变式
VI. 如果要将内表行附加到另一个内表中,建议使用APPEND语句的变式
VII. 如果要将内表行插入另一个内表中,建议使用INSERT语句的变式
VIII. 如果要将内表条目内容复制到另一个内表中,并覆盖该目标表格,建议使用MOVE语句
(2) 附加行
如果要将行附加到内表中,需要使用APPEND语句,语法: APPEND [<wa> TO | INITIAL LINE TO] <itab> .此语句将新行附加到内表<itab>中,并且通过使用<wa>TO选项,指定要附加的源区域<wa>。对于带表头行的表格,可以忽略TO选项,这样,表格工作区域就成了源区域。在这里也可以使用INITIAL LINE TO选项替代<wa>TO,将用其类型的正确值初始化的行添加到表格中
由于APPEND不考虑是否存在标准关键字相同的行,所以有可能出现相同条目
(3) 插入行
如果要在内表行之前插入新行,需要使用INSERT语句,语法: INSERT[<wa> INTO | INITIAL LINE INTO] <itab> [INDEX <idx> ]. 该语句通过使用INTO选项指定想插入的源区域<wa>。如果表格有表头行,则可忽略INTO选项。这样,表格工作区域就成了源区域。同时也可以使用INITIAL LINE INTO选项替代<wa>INTO,将用其类型的正确值初始化的行添至表格中。如果使用INDEX选项,则将新行插入到有索引<idx>的行之前。插入之后,新条目索引为<idx>,下行索引加1;如果表格包含<idx>-1条目,系统将新条目附加到最后的现有表格之后;如果表格条目小于<idx>-1,系统无法插入条目并将SY-SUBRC设置为4.如果操作成功,将SY-SUBRC设置为0。如果使用不带INDEX选项的INSERT语句,系统只能在LOOP-ENDLOOP循环内通过在当前行前插入新条目来处理它
(4) 附加内表行
如果要将部分或全部内表附加到另一个内表中,则需要使用APPEND语句,语法: APPEND LINES OF <itab1> [FROM <n1> ] [TO <n2>] TO <itab2> . 如果没有FROM和TO选项,该语句将整个表格ITAB1附加到ITAB2中。如果使用这些选项,则可通过索引<n1>或<n2>指定ITAB1中要附加的第一或最后一行。 如果要将部分或全部内表插入到另一个内表中,则需要使用INSERT语句,语法: INSERT LINES OF <itab1> [FROM <n1> ] [ TO <n2> ] INTO <itab2> [INDEX <idx> ]. 如果没有FROM和TO选项,该语句将整个表格ITAB1附加到ITAB2中。如果使用这些选项,则可通过索引<n1>或<n2>指定ITAB1中要附加的第一或最后一行。如果使用INDEX选项,则将新行插入到有索引<idx>的行之前。如果使用不带INDEX选项的INSERT语句,系统只能在LOOP-ENDLOOP循环内通过在当前行(例如,其索引在SY-TABIX中返回的行)之前插入新条目来处理它
(5) 复制内表
如果想一次将内表的全部内容复制到另一内表中,则需要使用MOVE语句或赋值操作符(=),语法如下: MOVE <itab1> TO <itab2> .或者 <itab2> = <itab1> . 也可进行多重赋值,例如: <itab4> = <itab3> = <itab2> = <itab1> .
2||| 读取内表
在程序中要读取内表的内容以便进一步操作,可以使用LOOP或READ语句。其中使用LOOP语句可逐行读取内表,使用READ语句则选定单行,还可以使用DESCRIBE语句确定内表属性
(1) 逐行读取内表:要将内表读入工作区域,可以使用LOOP语句编一个循环。语法: LOOP AT <itab> [INTO <wa>] [FROM <n1>] [TO <n2>] [WHERE <condition>] . ............ ENDLOOP . 这里用INTO选项指定目标区域<wa>。如果表格有表头行,则可忽略INTO选项。这样,表格工作区域就成了目标区域。逐行将内表<itab>读入<wa>或表格工作区域<itab>。对于读取的每一行,系统都以LOOP作为开始,以ENDLOOP作为结束,还可以用控制关键字AT在LOOP-ENDLOOP块内控制语句块流。 在语句块内,系统字段SY-TABIX包含当前行的索引。处理完表格的所有行之后循环结束。在ENDLOOP语句之后,如果至少读取了一行,则将系统字段SY-SUBRC设置为0。否则,将其设置为4。 另外,还可以使用FROM、TO或WHERE选项限制要在循环中进行处理的行数。
i. 使用FORM选项,可以用<n1>指定要读取的第一行
ii. 使用TO选项,可以用<n2>指定要读取的最后一行
iii. 使用WHERE选项,可以指定<condition>的任何逻辑表达式。第一个操作数必须时内表行结构的组件。如果在循环中使用控制关键字AT,则不能使用WHERE选项
(2) 用索引读取单行
要用索引从内表中读取单行,可使用READ语句,语法: READ TABLE <itab> [INTO <wa> ] INDEX <idx> . 用INTO选项指定目标区域<wa>。系统用索引<idx>从表格<itab>中读取行,这比关键字访问表格要快。如果找到有指定索引的条目,则将系统字段SY-SUBRC设置为0,而且SY-TABIX包含该行的索引,否则SY-SUBRC包含非0值
(3) 用自定义关键字读取行
如果要从有自定义关键字的内表中读取单行,则需要使用READ语句的WITHKEY选项,语法: READ TABLE <itab> [INTO <wa>] WITH KEY <key> [BINARYSEARCH] . 用INTO选项可以指定目标区域。如果表格有表头行,可忽略INTO选项。这样,表格工作区域旧城了目标区域。系统读取<itab>中匹配<key>中所定义的关键字的第一个条目。如果找到有适当关键字的条目,则将系统字段SY-SUBRC设置为0,并且SY-TABIX包含该行的索引。否则,将SY-SUBRC设置为非0值
3||| 更改内表行
在程序中要修改已填充的内表内容,可以使用更改行、删除行的方法
(1) 用MODIFY更改行
语法: MODIFY <itab> [FROM <wa>] [INDEX <idx>]. 用FROm选项中指定的工作区域<wa>代替<itab>中的行。如果表头有表头行,则可忽略FROM选项。这样表格工作区域就代替行
(2) 用WRITETO更改行
语法: WRITE <f> [ + <O1> ] [(<l1>)] TO <itab> [ + <O2>] [(<l2>)] INDEX <idx>. 将字段f中偏移量为o1、长度为l1部分的内容复制到索引为idx的表格中,覆盖偏移量为o2、长度为l2的部分。请注意,即使对于由表头行的表格,带INDEX选项的WRITETO语句也不访问表格工作区域,而是访问表格的某一行
(3) 用索引删除行
语法: DELETE <itab>[FROM <wa>] [INDEX <idx>] .
4||| 初始化内表
(1) 初始化没有表头的内表,语法: REFRESH <itab> . 该语句将内表重置为填充它以前的状态,这意味着表格将不包含任何行
(2) 如果使用没有表格工作区域的内表,使用CLEAR语句代替REFRESH语句,语法: CLEAR <itab> .
(3) 如果使用有表头行的内表,CLEAR语句如重置为缺省值,则仅清除表格工作区域。如重置整个内表而不清除表格工作区域,则可使用REFRESH语句或CLEAR语句,语法: CLEAR <itab> 【】. 内表名称后的方括号指内表体
(4) 使用REFRESH或CLEAR初始化内表后系统保持在内存中保留的空间。可以用FREE语句释放内存,语法如下: FREE <itab> . 也可使用FREE语句重置内表,并直接释放内存,而不必先使用REFRESH或CLEAR。与REFRESH一样,FREE在表格体上,而不再表格工作区域上工作。在FREE语句之后,可以再次定位内表。这样,系统就会再次保留内存空间
六、 简单报表开发示例
(1) 程序测试及运行
一般来说,对于纯报表程序,SAP系统会预定义一系列的报表事件
1||| INITIALIZATION:初始化事件,常用来填充选择屏幕的默认值
2||| AT SELECTION-SCREEEN OUTPUT:选择屏幕的PBO事件,显示选择屏幕之前触发
3||| AT SELECTION-SCREEN:选择屏幕的PAI事件,用户在选择屏幕中执行某些功能后触发,通常用来接收用户输入,并给用户出错提示
4||| START-OF-SELECTION:选择开始事件,一般在屏幕处理结束后触发
5||| END-OF-SELECTION:选择结束时间,通常在该事件中输出报表
6||| AT-LINE-SELECTION:交互式报表中,用户选择某行时触发
7||| AT-USER-COMMAND:交互式报表中,用户选择某个功能时触发
8||| TOP-OF-PAGE:页眉控制,每个新页面开始时触发,通常输出页眉、报表标题行
9||| END-OF-PAGE:页脚控制,在当前页结束前触发
(2) 事件处理次序
在ABAP/4程序中,都会对事件设置处理次序,所以一个事件的ABAP代码,总是开始于事件关键字,结束于下一个事件关键字。一般来说,ABAP/4程序中的事件处理次序关键字主要有以下几种(按先后顺序)
1. SELECTION-SCREEN OUTPUT
2. INITIALIZATION
3. AT SELECITON-SCREEN
4. START-OF-SELECTION
5. END-OF-SELECTION
6. LOAD-OF-PROGRAM
(3) 报表格式
在SAP系统中,ABAP/4开发报表的时候都有一个常用的格式,大部分报表都是套用这种格式来进行语句的编排。程序主要包含以下几个部分
1. 程序说明。包括:程序名称、作者、日期等相关信息
2. 关键字Report
3. 数据定义。内表、参数文件都是在这里定义
4. Include部分。指定包含文件
5. 定义选择屏幕。利用SELECT-OPTIONS和PARAMETERS声明多个选择参数,系统会自动产生一个屏幕号为1000的选择屏幕
6. INITIALIZATION事件。完成对选择屏幕参数的默认值填充
7. AT SELECTION-SCREEN事件。对用户的输入参数做校验
8. START-OF-SELECTION事件。在这里完成数据的处理
9. END-OF-SELECTION事件。在这里定义报表的输出
10. 如果报表没有采用ALV的方式输出报表,而是采用WRITE语句输出,则还有TOP-OF-PAGE和END-OF-PAGE事件
(4) 报表选择屏幕
在报表程序开发中,经常需要定义选择屏幕,常用的定义选择屏幕的关键字
1. PARAMETERS。用来定义单值参数
2. SELECT-OPTIONS。用来定义单值、多值、范围参数
3. SELECTION-SCREEN。用来格式化选择屏幕
定义选择屏幕时,用的最多的是SELECT-OPTIONS这个关键字,该参数能够接受单值、多值、范围。实际上,该参数是一个内表,它定义的选择参数能够直接用在Opensql语句中。另外,常用的屏幕格式化语句如下:
1. 在选择屏幕上产生空行:SELECTION-SCREEN SKIP.
2. 定义屏幕块: SELECTION -SCREEN BEGIN OF A WITH FRAME TITLE B. SELECTION-SCREEN END OF A.
(5) 报表屏幕文本
定义完选择屏幕后,测试运行程序。此时,我们看到的只是各个参数的名称,通常还要用文本来替换裸露显示的参数名
选择菜单“转到->文本元素->选择文本”选项;在Text栏中输入希望显示的选择文本。如果参数定义来源于数据字典元素或数据元素,则需要在“Dictionaryref”栏中打上勾,Text栏会自动显示数据字典中定义的文本