- SAP ABAP 教程
- SAP ABAP - 首页
- SAP ABAP - 概述
- SAP ABAP - 环境
- SAP ABAP - 屏幕导航
- SAP ABAP - 基本语法
- SAP ABAP - 数据类型
- SAP ABAP - 变量
- SAP ABAP - 常量和字面量
- SAP ABAP - 运算符
- SAP ABAP - 循环控制
- SAP ABAP - 决策
- SAP ABAP - 字符串
- SAP ABAP - 日期和时间
- SAP ABAP - 数据格式化
- SAP ABAP - 异常处理
- SAP ABAP - 字典
- SAP ABAP - 数据域
- SAP ABAP - 数据元素
- SAP ABAP - 表
- SAP ABAP - 结构
- SAP ABAP - 视图
- SAP ABAP - 搜索帮助
- SAP ABAP - 锁对象
- SAP ABAP - 模块化
- SAP ABAP - 子程序
- SAP ABAP - 宏
- SAP ABAP - 函数模块
- SAP ABAP - 包含程序
- SAP ABAP - Open SQL 概述
- SAP ABAP - Native SQL 概述
- SAP ABAP - 内部表
- SAP ABAP - 创建内部表
- ABAP - 填充内部表
- SAP ABAP - 复制内部表
- SAP ABAP - 读取内部表
- SAP ABAP - 删除内部表
- SAP ABAP - 面向对象
- SAP ABAP - 对象
- SAP ABAP - 类
- SAP ABAP - 继承
- SAP ABAP - 多态性
- SAP ABAP - 封装
- SAP ABAP - 接口
- SAP ABAP - 对象事件
- SAP ABAP - 报表编程
- SAP ABAP - 对话编程
- SAP ABAP - 智能表单
- SAP ABAP - SAPscript
- SAP ABAP - 用户出口
- SAP ABAP - 用户出口
- SAP ABAP - 业务附加功能 (Business Add-Ins)
- SAP ABAP - Web Dynpro
- SAP ABAP 有用资源
- SAP ABAP - 问答
- SAP ABAP 快速指南
- SAP ABAP - 有用资源
- SAP ABAP - 讨论
SAP ABAP 快速指南
SAP ABAP - 概述
ABAP 代表高级业务应用程序编程 (Advanced Business Application Programming),一种第四代语言 (4GL)。目前,它与 Java 一起被定位为 SAP 应用服务器编程的主要语言。
让我们从 SAP 系统的高级架构开始。典型 SAP 系统的三层客户端/服务器架构如下所示。
**表示层**由任何可用于控制 SAP 系统的输入设备组成。这可以是 Web 浏览器、移动设备等等。所有中央处理都在**应用服务器**中进行。应用服务器本身不仅仅是一个系统,它可以是处理系统的多个实例。服务器与通常保存在单独服务器上的**数据库层**进行通信,这主要是出于性能原因以及安全原因。系统各层之间会进行通信,从表示层到数据库,然后沿链向上返回。
**注意** - ABAP 程序在应用服务器级别运行。软件的技术分发与其物理位置无关。这意味着基本上所有三个级别都可以安装在一台计算机上,或者每个级别可以安装在不同的计算机或服务器上。
ABAP 程序驻留在 SAP 数据库中。它们在运行时系统的控制下执行,运行时系统是 SAP 内核的一部分。运行时系统处理所有 ABAP 语句,控制流程逻辑并响应用户事件。
因此,与 C++ 和 Java 不同,ABAP 程序不存储在单独的外部文件中。在数据库中,ABAP 代码存在两种形式:
可以使用 ABAP 工作台工具查看和编辑的**源代码**。
**生成的代码**,这是一种二进制表示。如果您熟悉 Java,则此生成的代码有点类似于 Java 字节码。
运行时系统可以被认为是虚拟机,类似于 Java 虚拟机。ABAP 运行时系统的一个关键组件是数据库接口,它将数据库无关语句 (Open SQL) 转换为底层数据库 (Native SQL) 可以理解的语句。SAP 可以与各种数据库一起工作,并且相同的 ABAP 程序可以在所有这些数据库上运行。
SAP ABAP - 环境
报表是熟悉一般 ABAP 原则和工具的一个很好的起点。ABAP 报表用于许多领域。在本节中,我们将看到编写简单的 ABAP 报表是多么容易。
你好,ABAP
让我们从常见的“Hello World”示例开始。
每个 ABAP 语句都以 ABAP 关键字开头,以句点结尾。关键字之间必须至少有一个空格。使用一行还是多行对于 ABAP 语句来说并不重要。
您需要使用 ABAP 编辑器输入代码,它是随 SAP NetWeaver Application Server ABAP(也称为“AS ABAP”)提供的 ABAP 工具的一部分。
“AS ABAP”是一个具有自己的数据库、ABAP 运行时环境和 ABAP 开发工具(如 ABAP 编辑器)的应用服务器。“AS ABAP”提供了一个独立于硬件、操作系统和数据库的开发平台。
使用 ABAP 编辑器
**步骤 1** - 启动事务 SE38 以导航到 ABAP 编辑器(下一节中讨论)。让我们开始创建一个报表,它是许多 ABAP 对象之一。
**步骤 2** - 在编辑器的初始屏幕上,在 PROGRAM 输入字段中指定报表的名称。您可以将其名称指定为 ZHELLO1。前面的 Z 对名称很重要。Z 确保您的报表位于客户命名空间中。
客户命名空间包含所有以 Y 或 Z 开头的对象。当客户或合作伙伴创建对象(如报表)时,始终使用它来区分这些对象与 SAP 的对象,并防止与对象发生名称冲突。
**步骤 3** - 您可以使用小写字母键入报表名称,但编辑器会将其更改为大写。因此,ABAP 对象的名称“不”区分大小写。
**步骤 4** - 指定报表名称后,单击“创建”按钮。将弹出 ABAP:程序属性弹出窗口,您将在其中提供有关报表的更多信息。
**步骤 5** - 选择“可执行程序”作为报表类型,输入标题“我的第一个 ABAP 报表”,然后选择“保存”继续。接下来将弹出“创建对象目录条目”窗口。选择“本地对象”按钮,弹出窗口将关闭。
您可以通过在 REPORT 语句下方输入下面的 WRITE 语句来完成您的第一个报表,以便完整的报表仅包含如下所示的两行:
REPORT ZHELLO1. WRITE 'Hello World'.
启动报表
我们可以使用键盘 (Ctrl + S) 或保存图标(命令字段右侧)来保存报表。ABAP 开发在 AS ABAP 中进行。
启动报表与保存报表一样简单。单击“激活”按钮(启动图标左侧),然后使用“直接处理”图标或 F8 功能键启动报表。“我的第一个 ABAP 报表”标题以及输出“Hello World”也将显示。以下是输出:
My First ABAP Report Hello World
只要您不激活新的报表或激活对现有报表的更改,它与它们的使用者就无关。这在中央开发环境中很重要,在该环境中,您可能正在处理其他开发人员在其项目中使用的对象。
查看现有代码
如果您查看“程序”字段并双击值 ZHELLO1,ABAP 编辑器将显示您的报表代码。这称为“向前导航”。双击对象的名称会在相应的工具中打开该对象。
SAP ABAP - 屏幕导航
为了理解 SAP ABAP,您需要了解登录、ABAP 编辑器、注销等基本屏幕。本章重点介绍屏幕导航和标准工具栏功能。
登录屏幕
登录到 SAP 服务器后,SAP 登录屏幕将提示您输入用户 ID 和密码。您需要提供有效的用户 ID 和密码并按 Enter 键(用户 ID 和密码由系统管理员提供)。以下是登录屏幕。
工具栏图标
以下是 SAP 屏幕工具栏。
**菜单栏** - 菜单栏是对话框窗口的顶行。
**标准工具栏** - 此工具栏中提供了大多数标准功能,例如页面顶部、页面底部、页面上移、页面下移和保存。
**标题栏** - 标题栏显示您当前所在的应用程序/业务流程的名称。
**应用程序工具栏** - 这里提供了特定于应用程序的菜单选项。
**命令字段** - 我们可以在不浏览菜单事务的情况下启动应用程序,并且一些逻辑代码被分配给业务流程。在命令字段中输入事务代码以直接启动应用程序。
ABAP 编辑器
您可以启动事务 SE38(在命令字段中输入 SE38)以导航到 ABAP 编辑器。
标准键和图标
**退出键**用于退出程序/模块或注销。它们还用于返回到上次访问的屏幕。
以下是 SAP 中使用的标准退出键,如图像所示。
以下是检查、激活和处理报表的选项。
注销
完成工作后,始终养成从 ABAP 编辑器或/和从 SAP 系统注销的良好习惯。
SAP ABAP - 基本语法
语句
ABAP 源程序由注释和 ABAP 语句组成。ABAP 中的每个语句都以关键字开头,以句点结尾,并且 ABAP “不”区分大小写。
程序中的第一行非注释行以 REPORT 字开头。报表始终是创建的任何可执行程序的第一行。该语句后跟先前创建的程序名称。然后用句点结束该行。
语法为:
REPORT [Program_Name]. [Statements…].
这允许语句在编辑器中占用任意多行。例如,REPORT 可能如下所示:
REPORT Z_Test123_01.
语句由命令和任何变量和选项组成,以句点结尾。只要句点出现在语句的结尾,就不会出现问题。正是这个句点标志着语句的结束位置。
让我们编写代码。
在 REPORT 语句下面的行上,只需键入此语句:Write ‘ABAP 教程’。
REPORT Z_Test123_01. Write 'This is ABAP Tutorial'.
**编写语句时要考虑的四件事**:
write 语句将引号中的内容写入输出窗口。
ABAP 编辑器会将所有文本转换为大写,但文本字符串除外,文本字符串用单引号括起来。
与一些较旧的编程语言不同,ABAP 不关心语句在一行中从何处开始。您可以利用这一点,并通过使用缩进表示代码块来提高程序的可读性。
ABAP 对语句的布局没有限制。也就是说,可以在一行上放置多个语句,或者一个语句可以跨越多行。
冒号表示法
如果每个语句的开头都相同,则可以将连续语句链接在一起。这是通过冒号 (:) 运算符和逗号完成的,它们用于终止各个语句,就像句点结束普通语句一样。
下面是一个可以节省一些按键操作的程序示例:
WRITE 'Hello'. WRITE 'ABAP'. WRITE 'World'.
使用冒号表示法,可以这样改写:
WRITE: 'Hello', 'ABAP', 'World'.
与任何其他 ABAP 语句一样,布局无关紧要。这是一个同样正确的语句:
WRITE: 'Hello', 'ABAP', 'World'.
注释
内联注释可以通过两种方法之一在程序中的任何位置声明:
整行注释通过在行的第一位放置一个星号 (*) 来指示,在这种情况下,系统认为整行都是注释。注释不需要用句点结束,因为它们不能跨越多行:
* This is the comment line
部分行注释通过在语句后输入双引号 (“) 来指示。双引号后的所有文本都被系统视为注释。您不需要用句点结束部分行注释,因为它们不能跨越多行:
WRITE 'Hello'. "Here is the partial comment
注意 - ABAP 编辑器不会将注释代码大写。
抑制空格
NO-ZERO 命令位于 DATA 语句之后。它抑制包含空格的数字字段的所有前导零。输出通常更容易让用户阅读。
示例
REPORT Z_Test123_01. DATA: W_NUR(10) TYPE N. MOVE 50 TO W_NUR. WRITE W_NUR NO-ZERO.
以上代码产生以下输出:
50
注意 - 没有 NO-ZERO 命令,输出为:0000000050
空行
SKIP 命令有助于在页面上插入空行。
示例
消息命令如下:
WRITE 'This is the 1st line'. SKIP. WRITE 'This is the 2nd line'.
上述消息命令产生以下输出:
This is the 1st line This is the 2nd line
我们可以使用 SKIP 命令插入多行空行。
SKIP number_of_lines.
输出将是按行数定义的几行空行。SKIP 命令还可以将光标定位在页面上的所需行上。
SKIP TO LINE line_number.
此命令用于动态向上和向下移动页面上的光标。通常,此命令之后会出现 WRITE 语句,以将输出放在所需行上。
插入行
ULINE 命令会自动在输出中插入一条横线。也可以控制线的长度和位置。语法很简单:
ULINE.
示例
消息命令如下:
WRITE 'This is Underlined'. ULINE.
以上代码产生以下输出:
This is Underlined (and a horizontal line below this).
消息
MESSAGE 命令显示在程序开始时 REPORT 语句中指定的消息 ID 定义的消息。消息 ID 是一个 2 个字符的代码,用于定义程序在使用 MESSAGE 命令时将访问的 1000 条消息集。
消息编号从 000 到 999。每个编号都与最多 80 个字符的消息文本相关联。调用消息编号时,将显示相应的文本。
以下是与 Message 命令一起使用的字符:
消息 | 类型 | 后果 |
---|---|---|
E | 错误 | 消息出现,应用程序在其当前点停止。如果程序在后台模式下运行,则作业将被取消,并且消息将记录在作业日志中。 |
W | 警告 | 消息出现,用户必须按 Enter 键才能继续应用程序。在后台模式下,消息将记录在作业日志中。 |
I | 信息 | 将打开一个包含消息文本的弹出窗口,用户必须按 Enter 键才能继续。在后台模式下,消息将记录在作业日志中。 |
A | 异常终止 | 此消息类将取消用户当前使用的交易。 |
S | 成功 | 这会在屏幕底部提供一条信息消息。显示的信息性质积极,仅供用户反馈。消息不会以任何方式妨碍程序。 |
X | 中止 | 此消息将中止程序并生成 ABAP 短转储。 |
错误消息通常用于阻止用户执行他们不应该执行的操作。警告消息通常用于提醒用户其操作的后果。信息消息为用户提供有用的信息。
示例
当我们为消息 ID AB 创建消息时,MESSAGE 命令 - MESSAGE E011 会给出以下输出:
EAB011 This report does not support sub-number summarization.
SAP ABAP - 数据类型
在 ABAP 中编程时,我们需要使用各种变量来存储各种信息。变量只不过是保留的内存位置以存储值。这意味着当您创建变量时,您会在内存中保留一些空间。您可能希望存储各种数据类型的信息,例如字符、整数、浮点数等。根据变量的数据类型,操作系统会分配内存并决定可以在保留的内存中存储什么。
基本数据类型
ABAP 为程序员提供了丰富的固定长度和可变长度数据类型。下表列出了 ABAP 基本数据类型:
类型 | 关键字 |
---|---|
字节字段 | X |
文本字段 | C |
整数 | I |
浮点数 | F |
压缩数字 | P |
文本字符串 | STRING |
可以使用一个或多个名称修改某些字段和数字,如下所示:
- 字节
- 数值
- 字符型
下表显示了数据类型、存储内存中值所需的内存大小以及可以在此类变量中存储的最小值和最大值。
类型 | 典型长度 | 典型范围 |
---|---|---|
X | 1 字节 | 任何字节值 (00 到 FF) |
C | 1 个字符 | 1 到 65535 |
N(数值文本字段) | 1 个字符 | 1 到 65535 |
D(字符型日期) | 8 个字符 | 8 个字符 |
T(字符型时间) | 6 个字符 | 6 个字符 |
I | 4 字节 | -2147483648 到 2147483647 |
F | 8 字节 | 2.2250738585072014E-308 到 1.7976931348623157E+308 正数或负数 |
P | 8 字节 | [-10^(2len -1) +1] 到 [+10^(2len -1) 1] (其中 len = 固定长度) |
STRING | 变量 | 任何字母数字字符 |
XSTRING(字节字符串) | 变量 | 任何字节值 (00 到 FF) |
示例
REPORT YR_SEP_12. DATA text_line TYPE C LENGTH 40. text_line = 'A Chapter on Data Types'. Write text_line. DATA text_string TYPE STRING. text_string = 'A Program in ABAP'. Write / text_string. DATA d_date TYPE D. d_date = SY-DATUM. Write / d_date.
在这个例子中,我们有一个类型为 C 的字符字符串,预定义长度为 40。STRING 是一种可以用于任何可变长度字符字符串(文本字符串)的数据类型。对于固定长度不重要的字符型内容,通常应使用类型 STRING 数据对象。
以上代码产生以下输出:
A Chapter on Data Types A Program in ABAP 12092015
DATE 类型用于存储日期信息,可以存储八位数字,如上所示。
复杂类型和引用类型
复杂类型分为结构类型和表类型。在结构类型中,基本类型和结构(即嵌入在结构中的结构)组合在一起。您可以只考虑基本类型的分组。但是您必须了解结构嵌套的可用性。
当基本类型组合在一起时,可以将数据项作为分组数据项访问,也可以访问单个基本类型数据项(结构字段)。表类型在其他编程语言中更被称为数组。数组可以是简单数组或结构数组。在 ABAP 中,数组称为内部表,与其他编程语言相比,它们可以以多种方式声明和操作。下表显示了内部表的特征参数。
序号 | 参数和描述 |
---|---|
1 | 行类型 内部表的一行可以是基本类型、复杂类型或引用类型。 |
2 | 键 指定一个字段或一组字段作为内部表的键,用于标识表行。键包含基本类型的字段。 |
3 | 访问方法 描述 ABAP 程序如何访问单个表条目。 |
引用类型用于引用类的实例、接口和运行时数据项。ABAP OOP 运行时类型服务 (RTTS) 允许在运行时声明数据项。
SAP ABAP - 变量
变量是用于在程序分配的内存区域中存储值的命名数据对象。顾名思义,用户可以借助 ABAP 语句更改变量的内容。ABAP 中的每个变量都有一个特定类型,该类型决定变量内存的大小和布局;可以存储在该内存中的值的范围;以及可以应用于变量的操作集。
必须在使用变量之前声明所有变量。变量声明的基本形式为:
DATA <f> TYPE <type> VALUE <val>.
此处<f>指定变量的名称。变量的名称最多可以包含 30 个字符。<type>指定变量的类型。任何具有完全指定技术属性的数据类型都称为<type>。<val>指定<f>变量的初始值。如果您定义基本固定长度变量,则 DATA 语句会自动使用类型特定的初始值填充变量的值。<val>的其他可能值可以是文字、常量或显式子句,例如 Is INITIAL。
以下是变量声明的有效示例。
DATA d1(2) TYPE C. DATA d2 LIKE d1. DATA minimum_value TYPE I VALUE 10.
在上段代码中,d1 是 C 类型的变量,d2 是 d1 类型的变量,minimum_value 是 ABAP 整数类型 I 的变量。
本章将解释 ABAP 中可用的各种变量类型。ABAP 中有三种变量:
- 静态变量
- 引用变量
- 系统变量
静态变量
静态变量在子例程、函数模块和静态方法中声明。
生命周期与声明的上下文相关联。
使用“CLASS-DATA”语句,您可以在类中声明变量。
“PARAMETERS”语句可用于声明与选择屏幕上的输入字段链接的基本数据对象。
您还可以使用“SELECT-OPTIONS”语句声明与选择屏幕上的输入字段链接的内部表。
以下是命名变量时使用的约定:
不能使用“t”和“,”等特殊字符来命名变量。
预定义数据对象的名称不能更改。
变量的名称不能与任何 ABAP 关键字或子句相同。
变量的名称必须传达变量的含义,无需进一步注释。
连字符保留用于表示结构的组件。因此,您应该避免在变量名称中使用连字符。
下划线字符可用于分隔复合词。
此程序演示如何使用 PARAMETERS 语句声明变量:
REPORT ZTest123_01. PARAMETERS: NAME(10) TYPE C, CLASS TYPE I, SCORE TYPE P DECIMALS 2, CONNECT TYPE MARA-MATNR.
此处,NAME 表示 10 个字符的参数,CLASS 指定具有默认字节大小的整数类型参数,SCORE 表示具有最多两位小数的值的压缩类型参数,CONNECT 指的是 ABAP 字典的 MARA-MATNF 类型。
以上代码产生以下输出:
引用变量
声明引用变量的语法为:
DATA <ref> TYPE REF TO <type> VALUE IS INITIAL.
REF TO 附加项声明引用变量 ref。
REF TO 后的规范指定引用变量的静态类型。
静态类型限制了 <ref> 可以引用的对象集。
引用变量的动态类型是它当前引用的数据类型或类。
静态类型总是比动态类型更通用或相同。
TYPE 附加用于创建绑定引用类型并作为起始值,并且在 VALUE 附加之后只能指定 IS INITIAL。
示例
CLASS C1 DEFINITION. PUBLIC SECTION. DATA Bl TYPE I VALUE 1. ENDCLASS. DATA: Oref TYPE REF TO C1 , Dref1 LIKE REF TO Oref, Dref2 TYPE REF TO I . CREATE OBJECT Oref. GET REFERENCE OF Oref INTO Dref1. CREATE DATA Dref2. Dref2→* = Dref1→*→Bl.
在上面的代码片段中,声明了一个对象引用 Oref 和两个数据引用变量 Dref1 和 Dref2。
这两个数据引用变量都是完全类型的,可以使用解引用运算符 →* 在操作数位置进行解引用。
系统变量
ABAP 系统变量可从所有 ABAP 程序访问。
这些字段实际上是由运行时环境填充的。
这些字段中的值指示系统在任何给定时间点的状态。
您可以在 SAP 的 SYST 表中找到系统变量的完整列表。
SYST 结构的各个字段可以使用“SYST-”或“SY-”访问。
示例
REPORT Z_Test123_01. WRITE:/'SY-ABCDE', SY-ABCDE, /'SY-DATUM', SY-DATUM, /'SY-DBSYS', SY-DBSYS, /'SY-HOST ', SY-HOST, /'SY-LANGU', SY-LANGU, /'SY-MANDT', SY-MANDT, /'SY-OPSYS', SY-OPSYS, /'SY-SAPRL', SY-SAPRL, /'SY-SYSID', SY-SYSID, /'SY-TCODE', SY-TCODE, /'SY-UNAME', SY-UNAME, /'SY-UZEIT', SY-UZEIT.
以上代码产生以下输出:
SY-ABCDE ABCDEFGHIJKLMNOPQRSTUVWXYZ SY-DATUM 12.09.2015 SY-DBSYS ORACLE SY-HOST sapserver SY-LANGU EN SY-MANDT 800 SY-OPSYS Windows NT SY-SAPRL 700 SY-SYSID DMO SY-TCODE SE38 SY-UNAME SAPUSER SY-UZEIT 14:25:48
SAP ABAP - 常量和字面量
字面量是在程序源代码中创建的未命名数据对象。它们完全由其值定义。您无法更改字面量的值。常量是使用声明语句静态创建的命名数据对象。常量通过为其赋值来声明,该值存储在程序的内存区域中。在程序执行期间,不能更改分配给常量的值。这些固定值也可以视为字面量。字面量有两种类型:数字和字符。
数字字面量
数字字面量是数字序列,可以带有前缀符号。在数字字面量中,没有小数分隔符,也没有尾数和指数表示法。
以下是一些数字字面量的示例:
183. -97. +326.
字符字面量
字符字面量是 ABAP 程序源代码中用单引号括起来的字母数字字符序列。用引号括起来的字符字面量具有预定义的 ABAP 类型 C,并被描述为文本字段字面量。用“反引号”括起来的字面量具有 ABAP 类型 STRING,并被描述为字符串字面量。字段长度由字符数定义。
注意 - 在文本字段字面量中,尾随空格将被忽略,但在字符串字面量中将被考虑在内。
以下是一些字符字面量的示例。
文本字段字面量
REPORT YR_SEP_12. Write 'Tutorials Point'. Write / 'ABAP Tutorial'.
字符串字段字面量
REPORT YR_SEP_12. Write `Tutorials Point `. Write / `ABAP Tutorial `.
以上两种情况下的输出相同:
Tutorials Point ABAP Tutorial
注意 - 当我们尝试更改常量的值时,可能会发生语法或运行时错误。在类的声明部分或接口中声明的常量属于该类或接口的静态属性。
CONSTANTS 语句
我们可以借助 CONSTANTS 语句声明命名数据对象。
语法如下:
CONSTANTS <f> TYPE <type> VALUE <val>.
CONSTANTS 语句类似于 DATA 语句。
<f> 指定常量的名称。TYPE <type> 表示名为 <f> 的常量,它继承与现有数据类型 <type> 相同的技术属性。VALUE <val> 为声明的常量名 <f> 分配初始值。
注意 - 我们应该在 CONSTANTS 语句中使用 VALUE 子句。“VALUE”子句用于在声明常量时为其分配初始值。
我们有三种类型的常量,例如基本常量、复杂常量和引用常量。以下语句显示了如何使用 CONSTANTS 语句定义常量:
REPORT YR_SEP_12. CONSTANTS PQR TYPE P DECIMALS 4 VALUE '1.2356'. Write: / 'The value of PQR is:', PQR.
输出为:
The value of PQR is: 1.2356
这里它指的是基本数据类型,被称为基本常量。
以下是复杂常量的示例:
BEGIN OF EMPLOYEE, Name(25) TYPE C VALUE 'Management Team', Organization(40) TYPE C VALUE 'Tutorials Point Ltd', Place(10) TYPE C VALUE 'India', END OF EMPLOYEE.
在上面的代码片段中,EMPLOYEE 是一个由 Name、Organization 和 Place 字段组成的复杂常量。
以下语句声明一个常量引用:
CONSTANTS null_pointer TYPE REF TO object VALUE IS INITIAL.
我们可以使用常量引用进行比较,或者将其传递给过程。
SAP ABAP - 运算符
ABAP 提供了一套丰富的运算符来操作变量。所有 ABAP 运算符都分为四类:
- 算术运算符
- 比较运算符
- 位运算符
- 字符字符串运算符
算术运算符
算术运算符与在代数中使用的运算符一样,用于数学表达式。以下列表描述了算术运算符。假设整数变量 A 保持 20,变量 B 保持 40。
序号 | 算术运算符和说明 |
---|---|
1 | +(加法) 将运算符两侧的值相加。例如:A + B 将得到 60。 |
2 | -(减法) 从左操作数中减去右操作数。例如:A - B 将得到 -20。 |
3 | *(乘法) 将运算符两侧的值相乘。例如:A * B 将得到 800。 |
4 | /(除法) 将左操作数除以右操作数。例如:B / A 将得到 2。 |
5 | MOD(模) 将左操作数除以右操作数并返回余数。例如:B MOD A 将得到 0。 |
示例
REPORT YS_SEP_08. DATA: A TYPE I VALUE 150, B TYPE I VALUE 50, Result TYPE I. Result = A / B. WRITE / Result.
以上代码产生以下输出:
3
比较运算符
让我们讨论不同操作数的各种比较运算符。
序号 | 比较运算符和说明 |
---|---|
1 | =(相等性测试)。替代形式为 EQ。 检查两个操作数的值是否相等,如果相等,则条件变为真。例如 (A = B) 为假。 |
2 | <>(不相等性测试)。替代形式为 NE。 检查两个操作数的值是否相等。如果值不相等,则条件变为真。例如 (A <> B) 为真。 |
3 | >(大于测试)。替代形式为 GT。 检查左操作数的值是否大于右操作数的值。如果是,则条件变为真。例如 (A > B) 为假。 |
4 | <(小于测试)。替代形式为 LT。 检查左操作数的值是否小于右操作数的值。如果是,则条件变为真。例如 (A < B) 为真。 |
5 | >=(大于或等于)替代形式为 GE。 检查左操作数的值是否大于或等于右操作数的值。如果是,则条件变为真。例如 (A >= B) 为假。 |
6 | <=(小于或等于测试)。替代形式为 LE。 检查左操作数的值是否小于或等于右操作数的值。如果是,则条件变为真。例如 (A <= B) 为真。 |
7 | a1 BETWEEN a2 AND a3(区间测试) 检查 a1 是否位于 a2 和 a3 之间(包含)。如果是,则条件变为真。例如 (A BETWEEN B AND C) 为真。 |
8 | IS INITIAL 如果变量的内容没有改变并且已自动分配其初始值,则条件变为真。例如 (A IS INITIAL) 为假 |
9 | IS NOT INITIAL 如果变量的内容已更改,则条件变为真。例如 (A IS NOT INITIAL) 为真。 |
注意 - 如果变量的数据类型或长度不匹配,则会执行自动转换。在比较不同数据类型的两个值时,会对一个或两个值执行自动类型调整。转换类型由数据类型和数据类型的优先级顺序决定。
优先级顺序如下:
如果一个字段的类型为 I,则另一个字段将转换为类型 I。
如果一个字段的类型为 P,则另一个字段将转换为类型 P。
如果一个字段的类型为 D,则另一个字段将转换为类型 D。但 C 和 N 类型不会转换,它们直接进行比较。类型 T 也类似。
如果一个字段的类型为 N,另一个字段的类型为 C 或 X,则两个字段都将转换为类型 P。
如果一个字段的类型为 C,另一个字段的类型为 X,则 X 类型将转换为 C 类型。
示例 1
REPORT YS_SEP_08. DATA: A TYPE I VALUE 115, B TYPE I VALUE 119. IF A LT B. WRITE: / 'A is less than B'. ENDIF
以上代码产生以下输出:
A is less than B
示例 2
REPORT YS_SEP_08. DATA: A TYPE I. IF A IS INITIAL. WRITE: / 'A is assigned'. ENDIF.
以上代码产生以下输出:
A is assigned.
位运算符
ABAP 还提供一系列位逻辑运算符,可用于构建布尔代数表达式。位运算符可以使用括号等组合成复杂的表达式。
序号 | 位运算符和说明 |
---|---|
1 | BIT-NOT 一元运算符,它将十六进制数中的所有位翻转到相反的值。例如,将此运算符应用于具有位级值 10101010(例如 'AA')的十六进制数将给出 01010101。 |
2 | BIT-AND 此二元运算符使用布尔 AND 运算符逐位比较每个字段。 |
3 | BIT-XOR 二元运算符,使用布尔 XOR(异或)运算符逐位比较每个字段。 |
4 | BIT-OR 二元运算符,使用布尔 OR 运算符逐位比较每个字段。 |
例如,下表是真值表,它显示了对字段 A 和字段 B 中包含的两个位值应用布尔 AND、OR 或 XOR 运算符时生成的值。
字段 A | 字段 B | AND | OR | XOR |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
字符字符串运算符
以下是一些字符字符串运算符:
序号 | 字符字符串运算符和说明 |
---|---|
1 | CO(仅包含) 检查 A 是否仅由 B 中的字符组成。 |
2 | CN(不只包含) 检查 A 是否包含 B 中不存在的字符。 |
3 | CA(包含任何) 检查 A 是否至少包含 B 的一个字符。 |
4 | NA(不包含任何) 检查 A 是否不包含 B 的任何字符。 |
5 | CS(包含字符串) 检查 A 是否包含字符字符串 B。 |
6 | NS(不包含字符串) 检查 A 是否不包含字符字符串 B。 |
7 | CP(包含模式) 它检查 A 是否包含 B 中的模式。 |
8 | NP(不包含模式) 它检查 A 是否不包含 B 中的模式。 |
示例
REPORT YS_SEP_08. DATA: P(10) TYPE C VALUE 'APPLE', Q(10) TYPE C VALUE 'CHAIR'. IF P CA Q. WRITE: / 'P contains at least one character of Q'. ENDIF.
以上代码产生以下输出:
P contains at least one character of Q.
SAP ABAP - 循环控制
您可能需要多次执行代码块的情况。通常,语句是按顺序执行的:函数中的第一个语句首先执行,然后是第二个语句,依此类推。
编程语言提供各种控制结构,允许更复杂的执行路径。一个循环语句允许我们多次执行语句或语句组,以下是在大多数编程语言中循环语句的一般形式。
ABAP 编程语言提供以下类型的循环来处理循环需求。
序号 | 循环类型和说明 |
---|---|
1 | WHILE 循环
当给定条件为真时,重复语句或语句组。它在执行循环体之前测试条件。 |
2 | DO 循环
DO 语句可用于重复特定任务特定次数。 |
3 | 嵌套循环
您可以在任何其他 WHILE 或 DO 循环内使用一个或多个循环。 |
循环控制语句
循环控制语句将其执行从正常顺序更改。ABAP 包含允许循环过早结束的控制语句。它支持以下控制语句。
序号 | 控制语句和说明 |
---|---|
1 | CONTINUE
使循环跳过其主体的其余部分并开始下一个循环。 |
2 | CHECK
如果条件为假,则CHECK后的剩余语句将被忽略,系统开始下一轮循环。 |
3 | EXIT
完全终止循环,并将执行转移到循环后紧跟的语句。 |
SAP ABAP - 决策
决策结构包含一个或多个条件,由程序进行评估或测试,以及如果条件确定为真则要执行的语句(一个或多个),以及可选的,如果条件确定为假则要执行的其他语句。
以下是大多数编程语言中典型的决策结构的一般形式:
ABAP编程语言提供以下类型的决策语句。
序号 | 语句与描述 |
---|---|
1 | IF语句
IF语句由一个逻辑表达式和一个或多个语句组成。 |
2 | IF...Else语句
IF语句后面可以跟一个可选的ELSE语句,当表达式为假时执行。 |
3 | 嵌套IF语句
可以在另一个IF或ELSEIF语句内使用一个IF或ELSEIF语句。 |
4 | CASE控制语句
当我们需要比较两个或多个字段或变量时,使用CASE语句。 |
SAP ABAP - 字符串
字符串在ABAP编程中被广泛使用,是一系列字符。
我们使用数据类型C变量来存储字母数字字符,最小1个字符,最大65,535个字符。默认情况下,这些字符左对齐。
创建字符串
以下声明和初始化创建一个包含单词“Hello”的字符串。字符串的大小正好是单词“Hello”中字符的数量。
Data my_Char(5) VALUE 'Hello'.
下面的程序是创建字符串的示例。
REPORT YT_SEP_15. DATA my_Char(5) VALUE 'Hello'. Write my_Char.
以上代码产生以下输出:
Hello
字符串长度
为了查找字符字符串的长度,我们可以使用STRLEN语句。STRLEN()函数返回字符串中包含的字符数。
示例
REPORT YT_SEP_15. DATA: title_1(10) VALUE 'Tutorials', length_1 TYPE I. length_1 = STRLEN( title_1 ). Write: / 'The Length of the Title is:', length_1.
以上代码产生以下输出:
The Length of the Title is: 9
ABAP支持各种操作字符串的语句。
序号 | 语句与用途 |
---|---|
1 | CONCATENATE 将两个字符串连接起来形成第三个字符串。 |
2 | CONDENSE 此语句删除空格字符。 |
3 | STRLEN 用于查找字段的长度。 |
4 | REPLACE 用于替换字符。 |
5 | SEARCH 在字符字符串中运行搜索。 |
6 | SHIFT 用于将字符串的内容向左或向右移动。 |
7 | SPLIT 用于将字段的内容拆分为两个或多个字段。 |
以下示例使用了一些上述语句:
示例
REPORT YT_SEP_15. DATA: title_1(10) VALUE 'Tutorials', title_2(10) VALUE 'Point', spaced_title(30) VALUE 'Tutorials Point Limited', sep, dest1(30), dest2(30). CONCATENATE title_1 title_2 INTO dest1. Write: / 'Concatenation:', dest1. CONCATENATE title_1 title_2 INTO dest2 SEPARATED BY sep. Write: / 'Concatenation with Space:', dest2. CONDENSE spaced_title. Write: / 'Condense with Gaps:', spaced_title. CONDENSE spaced_title NO-GAPS. Write: / 'Condense with No Gaps:', spaced_title.
以上代码产生以下输出:
Concatenation: TutorialsPoint Concatenation with Space: Tutorials Point Condense with Gaps: Tutorials Point Limited Condense with No Gaps: TutorialsPointLimited
注意:
在连接的情况下,“sep”在字段之间插入一个空格。
CONDENSE语句删除字段之间的空格,但只保留1个字符的空格。
“NO-GAPS”是CONDENSE语句的可选附加项,它删除所有空格。
SAP ABAP - 日期和时间
ABAP隐式引用格里高利历,在世界大部分地区有效。我们可以将输出转换为特定国家的日历。日期是相对于日历精确到某一天、一周或一个月的时间。时间是相对于一天精确到秒或分的时间。ABAP始终以24小时制保存时间。输出可以具有特定国家的格式。日期和时间通常被解释为当前时区有效的本地日期。
ABAP提供两种内置类型来处理日期和时间:
- D数据类型
- T数据类型
以下是基本格式:
DATA: date TYPE D, time TYPE T. DATA: year TYPE I, month TYPE I, day TYPE I, hour TYPE I, minute TYPE I, second TYPE I.
这两种类型都是固定长度的字符类型,分别采用YYYYMMDD和HHMMSS的形式。
时间戳
除了这些内置类型外,其他两种类型TIMESTAMP和TIMESTAMPL在许多标准应用程序表中用于以UTC格式存储时间戳。下表显示了ABAP中可用的基本日期和时间类型。
序号 | 数据类型与描述 |
---|---|
1 | D 一种内置的固定长度日期类型,格式为YYYYMMDD。例如,值20100913表示2010年9月13日。 |
2 | T 一种内置的固定长度时间类型,格式为HHMMSS。例如,值102305表示上午10:23:05。 |
3 | TIMESTAMP(类型P – 长度8,无小数位) 此类型用于表示YYYYMMDDhhmmss形式的短时间戳。例如,值20100913102305表示2010年9月13日上午10:23:05。 |
4 | TIMESTAMPL(类型P – 长度11,小数位7) TIMESTAMPL以YYYYMMDDhhmmss,mmmuuun的形式表示长时间戳。这里附加的数字“mmmuuun”表示秒的几分之一。 |
当前日期和时间
以下代码片段检索当前系统日期和时间。
REPORT YR_SEP_15. DATA: date_1 TYPE D. date_1 = SY-DATUM. Write: / 'Present Date is:', date_1 DD/MM/YYYY. date_1 = date_1 + 06. Write: / 'Date after 6 Days is:', date_1 DD/MM/YYYY.
以上代码产生以下输出:
Present Date is: 21.09.2015 Date after 6 Days is: 27.09.2015
变量date_1被赋值为当前系统日期SY-DATUM的值。接下来,我们将日期值增加6。在ABAP中的日期计算方面,这意味着我们将日期对象的日分量增加了6天。ABAP运行时环境足够智能,可以在日期值达到月末时进行翻转。
时间计算类似于日期计算。以下代码使用基本时间算术将当前系统时间增加75秒。
REPORT YR_SEP_15. DATA: time_1 TYPE T. time_1 = SY-UZEIT. Write /(60) time_1 USING EDIT MASK 'Now the Time is: __:__:__'. time_1 = time_1 + 75. Write /(60) time_1 USING EDIT MASK 'A Minute and a Quarter from Now, it is: __:__:__'.
以上代码产生以下输出:
Now the Time is 11:45:05 A Minute and a Quarter from Now, it is: 11:46:20
使用时间戳
您可以使用GET TIME STAMP检索当前系统时间并将其存储在时间戳变量中,如下面的代码所示。GET TIME STAMP语句根据所使用的时间戳数据对象的类型,以长格式或短格式存储时间戳。时间戳值使用UTC标准编码。
REPORT YR_SEP_12. DATA: stamp_1 TYPE TIMESTAMP, stamp_2 TYPE TIMESTAMPL. GET TIME STAMP FIELD stamp_1. Write: / 'The short time stamp is:', stamp_1 TIME ZONE SY-ZONLO. GET TIME STAMP FIELD stamp_2. Write: / 'The long time stamp is:', stamp_2 TIME ZONE SY-ZONLO.
以上代码产生以下输出:
The short time stamp is: 18.09.2015 11:19:40 The long time stamp is: 18.09.2015 11:19:40,9370000
在上面的示例中,我们使用WRITE语句的TIME ZONE附加项显示时间戳。此附加项根据指定时区的规则格式化时间戳的输出。系统字段SY-ZONLO用于显示用户首选项中配置的本地时区。
SAP ABAP - 数据格式化
ABAP提供了各种格式化选项来格式化程序的输出。例如,您可以创建一个包含不同颜色或格式样式的各种项目的列表。
WRITE语句是用于在屏幕上显示数据的格式化语句。WRITE语句有不同的格式化选项。WRITE语句的语法为:
WRITE <format> <f> <options>.
在此语法中,<format>表示输出格式规范,它可以是正斜杠(/),表示从新行开始显示输出。除了正斜杠外,格式规范还包括列号和列长度。例如,WRITE/04(6)语句显示新行从第4列开始,列长度为6,而WRITE 20语句显示当前行第20列。参数<f>表示数据变量或编号文本。
下表描述了用于格式化的各种子句:
序号 | 子句与描述 |
---|---|
1 | LEFT-JUSTIFIED 指定输出左对齐。 |
2 | CENTERED 表示输出居中。 |
3 | RIGHT-JUSTIFIED 指定输出右对齐。 |
4 | UNDER <g> 输出直接在字段<g>下方开始。 |
5 | NO-GAP 指定拒绝字段<f>后的空格。 |
6 | USING EDIT MASK <m> 表示格式模板<m>的规范。不使用编辑掩码:这指定在ABAP字典中指定的格式模板被停用。 |
7 | NO-ZERO 如果字段只包含零,则用空格代替。 |
以下是数字类型字段的格式化选项:
序号 | 子句与描述 |
---|---|
1 | NO-SIGN 指定屏幕上不显示前导符号。 |
2 | EXPONENT <e> 指定在类型F(浮点字段)中,指数在<e>中定义。 |
3 | ROUND <r> 类型P字段(打包数字数据类型)首先乘以10**(-r),然后四舍五入到整数值。 |
4 | CURRENCY <c> 表示根据存储在TCURX数据库表中的货币<c>值进行格式化。 |
5 | UNIT <u> 指定小数位数根据类型P的T006数据库表中指定的<u>单位固定。 |
6 | DECIMALS <d> 指定必须在小数点后显示<d>位数字。 |
例如,下表显示了日期字段的不同格式化选项:
格式化选项 | 示例 |
---|---|
DD/MM/YY | 13/01/15 |
MM/DD/YY | 01/13/15 |
DD/MM/YYYY | 13/01/2015 |
MM/DD/YYYY | 01/13/2015 |
DDMMYY | 130115 |
MMDDYY | 011315 |
YYMMDD | 150113 |
这里,DD代表两位数的日期,MM代表两位数的月份,YY代表两位数的年份,YYYY代表四位数的年份。
让我们来看一个实现上述一些格式化选项的ABAP代码示例:
REPORT ZTest123_01. DATA: n(9) TYPE C VALUE 'Tutorials', m(5) TYPE C VALUE 'Point'. WRITE: n, m. WRITE: / n, / m UNDER n. WRITE: / n NO-GAP, m. DATA time TYPE T VALUE '112538'. WRITE: / time, /(8) time Using EDIT MASK '__:__:__'.
以上代码产生以下输出:
Tutorials Point Tutorials Point TutorialsPoint 112538 11:25:38
SAP ABAP - 异常处理
异常是在程序执行期间出现的问题。当发生异常时,程序的正常流程被打断,程序应用程序异常终止,这是不推荐的,因此需要处理这些异常。
异常提供了一种将控制从程序的一部分转移到另一部分的方法。ABAP异常处理基于三个关键字:RAISE、TRY、CATCH和CLEANUP。假设一个块会引发异常,一个方法使用TRY和CATCH关键字的组合捕获异常。TRY-CATCH块放置在可能生成异常的代码周围。以下是使用TRY-CATCH的语法:
TRY. Try Block <Code that raises an exception> CATCH Catch Block <exception handler M> . . . . . . . . . CATCH Catch Block <exception handler R> CLEANUP. Cleanup block <to restore consistent state> ENDTRY.
RAISE:引发异常以指示已发生某些异常情况。通常,异常处理程序尝试修复错误或查找替代解决方案。
TRY:TRY块包含要处理异常的应用程序代码。此语句块按顺序处理。它可以包含进一步的控制结构和过程或其他ABAP程序的调用。它后面是一个或多个catch块。
CATCH:程序在程序中要处理问题的地方使用异常处理程序捕获异常。CATCH关键字表示捕获异常。
CLEANUP:每当TRY块中发生未被同一TRY-ENDTRY结构的处理程序捕获的异常时,都会执行CLEANUP块的语句。在CLEANUP子句中,系统可以将对象恢复到一致状态或释放外部资源。也就是说,可以为TRY块的上下文执行清理工作。
引发异常
可以在方法、函数模块、子例程等的任何点引发异常。异常可以以两种方式引发:
由ABAP运行时系统引发的异常。
例如Y = 1 / 0。这将导致类型为CX_SY_ZERODIVIDE的运行时错误。
由程序员引发的异常。
同时引发并创建异常对象。第一种情况是在已存在的异常对象上引发异常。语法为:RAISE EXCEPTION exep。
捕获异常
使用处理器来捕获异常。
让我们来看一段代码片段:
DATA: result TYPE P LENGTH 8 DECIMALS 2, exref TYPE REF TO CX_ROOT, msgtxt TYPE STRING. PARAMETERS: Num1 TYPE I, Num2 TYPE I. TRY. result = Num1 / Num2. CATCH CX_SY_ZERODIVIDE INTO exref. msgtxt = exref→GET_TEXT( ). CATCH CX_SY_CONVERSION_NO_NUMBER INTO exref. msgtxt = exref→GET_TEXT( ).
在上面的代码片段中,我们尝试将 Num1 除以 Num2,并将结果存储在一个浮点型变量中。
可能会产生两种类型的异常。
数字转换错误。
除以零异常。处理器捕获 CX_SY_CONVERSION_NO_NUMBER 异常和 CX_SY_ZERODIVIDE 异常。这里使用异常类的 GET_TEXT( ) 方法获取异常的描述。
异常的属性
以下是异常的五个属性和方法:
序号 | 属性和描述 |
---|---|
1 | Textid 用于定义异常的不同文本,也影响 get_text 方法的结果。此属性可以存储原始异常,允许您构建异常链。 |
2 | 上一页 此属性可以存储原始异常,允许您构建异常链。 |
3 | get_text 根据系统的语言返回异常的文本表示形式(字符串)。 |
4 | get_longtext 返回异常文本表示形式的长格式(字符串)。 |
5 | get_source_position 给出引发异常的程序名称和行号。 |
示例
REPORT ZExceptionsDemo. PARAMETERS Num_1 TYPE I. DATA res_1 TYPE P DECIMALS 2. DATA orf_1 TYPE REF TO CX_ROOT. DATA txt_1 TYPE STRING. start-of-selection. Write: / 'Square Root and Division with:', Num_1. write: /. TRY. IF ABS( Num_1 ) > 150. RAISE EXCEPTION TYPE CX_DEMO_ABS_TOO_LARGE. ENDIF. TRY. res_1 = SQRT( Num_1 ). Write: / 'Result of square root:', res_1. res_1 = 1 / Num_1. Write: / 'Result of division:', res_1. CATCH CX_SY_ZERODIVIDE INTO orf_1. txt_1 = orf_1→GET_TEXT( ). CLEANUP. CLEAR res_1. ENDTRY. CATCH CX_SY_ARITHMETIC_ERROR INTO orf_1. txt_1 = orf_1→GET_TEXT( ). CATCH CX_ROOT INTO orf_1. txt_1 = orf_1→GET_TEXT( ). ENDTRY. IF NOT txt_1 IS INITIAL. Write / txt_1. ENDIF. Write: / 'Final Result is:', res_1.
在这个例子中,如果数字大于 150,则引发异常 CX_DEMO_ABS_TOO_LARGE。对于数字 160,上述代码会产生以下输出。
Square Root and Division with: 160 The absolute value of number is too high Final Result is: 0.00
SAP ABAP - 字典
如您所知,SQL 可以分为两部分:
- DML(数据操纵语言)
- DDL(数据定义语言)
DML 部分包含查询和更新命令,例如 SELECT、INSERT、UPDATE、DELETE 等,ABAP 程序处理 SQL 的 DML 部分。DDL 部分包含 CREATE TABLE、CREATE INDEX、DROP TABLE、ALTER TABLE 等命令,ABAP Dictionary 处理 SQL 的 DDL 部分。
ABAP Dictionary 可以被视为元数据(即关于数据的数据),它与数据库维护的元数据一起驻留在 SAP 数据库中。Dictionary 用于创建和管理数据定义,以及创建表、数据元素、域、视图和类型。
ABAP Dictionary 中的基本类型
ABAP Dictionary 中的基本类型如下:
数据元素通过定义数据类型、长度和可能的十进制位数来描述基本类型。
结构,其组件可以具有任何类型。
表类型描述内部表的结构。
Dictionary 环境中的各种对象可以在 ABAP 程序中引用。Dictionary 被称为全局区域。Dictionary 中的对象对所有 ABAP 程序都是全局的,ABAP 程序中的数据可以通过引用这些 Dictionary 全局对象来声明。
Dictionary 支持用户定义类型的定义,这些类型用于 ABAP 程序中。它们还定义数据库对象(如表、视图和索引)的结构。当这些对象被激活时,它们的 Dictionary 定义会在底层数据库中自动创建相应的对象。Dictionary 还提供编辑工具(如搜索帮助)和锁定工具(如锁定对象)。
Dictionary 任务
ABAP Dictionary 实现以下功能:
- 强制数据完整性。
- 管理数据定义,避免冗余。
- 与 ABAP 开发工作台的其他部分紧密集成。
示例
任何复杂的自定义类型都可以从 Dictionary 中的 3 种基本类型构建。客户数据存储在一个名为“Customer”的结构中,其组件为 Name、Address 和 Telephone,如下图所示。Name 也是一个结构,其组件为 First name 和 Last name。这两个组件都是基本的,因为它们的类型由数据元素定义。
组件 Address 的类型由一个结构定义,其组件也是结构,而 Telephone 组件由表类型定义,因为一个客户可以拥有多个电话号码。类型用于 ABAP 程序,也用于定义函数模块的接口参数类型。
SAP ABAP - 数据域
在 ABAP Dictionary 中定义数据的三个基本对象是域、数据元素和表。域用于表字段的技术定义(如字段类型和长度),而数据元素用于语义定义(简短描述)。数据元素描述域在特定业务环境中的含义。它主要包含字段帮助和屏幕上的字段标签。
域分配给数据元素,数据元素又分配给表字段或结构字段。例如,MATNR 域(CHAR 物料号)分配给数据元素,如 MATNR_N、MATNN 和 MATNR_D,这些数据元素又分配给许多表字段和结构字段。
创建域
在创建新的域之前,请检查是否存在任何现有域具有表字段所需的相同技术规范。如果是这样,我们应该使用该现有域。让我们讨论创建域的过程。
步骤 1 - 转到事务 SE11。
步骤 2 - 在 ABAP Dictionary 的初始屏幕中选择域单选按钮,并输入域的名称,如下图所示。单击“创建”按钮。您可以在客户命名空间下创建域,对象的名称始终以“Z”或“Y”开头。
步骤 3 - 在域维护屏幕的短文本字段中输入描述。在本例中,它是“客户域”。注意 - 在输入此属性之前,您无法输入任何其他属性。
步骤 4 - 在“定义”选项卡的“格式”块中输入数据类型、字符数和小数位数。按输出长度键,它会提出并显示输出长度。如果您覆盖建议的输出长度,则在激活域时可能会看到警告。如果需要,您可以填写“转换例程”、“符号”和“小写”字段。但这些始终是可选属性。
步骤 5 - 选择“值范围”选项卡。如果域仅限于具有固定值,则输入固定值或区间。如果系统必须在定义引用此域的字段的外键时提出此表作为检查表,则定义值表。但所有这些都是可选属性。
步骤 6 - 保存您的更改。“创建对象目录条目”弹出窗口出现并要求输入包。您可以输入您正在使用的包名称。如果您没有任何包,您可以在对象导航器中创建它,或者您可以使用“本地对象”按钮保存您的域。
步骤 7 - 激活您的域。单击激活图标(火柴图标)或按 CTRL + F3 激活域。出现一个弹出窗口,列出当前处于非活动状态的 2 个对象,如下图所示:
步骤 8 - 在此步骤中,需要激活名为 ZSEP_18 的标记为“DOMA”的顶部条目。由于此条目已突出显示,请单击绿色勾号按钮。此窗口将消失,状态栏将显示消息“对象已激活”。
如果在激活域时出现错误消息或警告,则会自动显示激活日志。激活日志显示有关激活流程的信息。您也可以使用“实用程序(M)”→“激活日志”调用激活日志。
SAP ABAP - 数据元素
数据元素描述 ABAP 数据字典中的各个字段。它们是复杂类型的最小不可分割单元,用于定义表字段的类型、结构组件或表的行类型。有关表字段含义的信息以及有关编辑相应屏幕字段的信息可以分配给数据元素。此信息会自动提供给所有引用数据元素的屏幕字段。数据元素描述基本类型或引用类型。
创建数据元素
在创建新的数据元素之前,您需要检查是否存在任何现有数据元素具有表字段所需的相同语义规范。如果是这样,您可以使用该现有数据元素。您可以将数据元素分配给预定义类型、域或引用类型。
以下是创建数据元素的过程:
步骤 1 - 转到事务 SE11。
步骤 2 - 在 ABAP Dictionary 的初始屏幕中选择数据类型单选按钮,并输入数据元素的名称,如下所示。
步骤 3 - 单击“创建”按钮。您可以在客户命名空间下创建数据元素,对象的名称始终以“Z”或“Y”开头。
步骤 4 - 在出现具有三个单选按钮的“创建类型”弹出窗口上,选中“数据元素”单选按钮。
步骤 5 - 单击绿色勾号图标。您将被定向到数据元素的维护屏幕。
步骤 6 - 在数据元素维护屏幕的短文本字段中输入描述。在本例中,它是“客户数据元素”。注意 - 在输入此属性之前,您无法输入任何其他属性。
步骤 7 - 为数据元素分配类型。您可以通过选中基本类型来创建一个基本数据元素,或者通过选中引用类型来创建一个引用数据元素。您可以在“基本类型”中将数据元素分配给域或预定义类型,在“引用类型”中分配给“引用类型名称”或“对预定义类型的引用”。
步骤 8 - 在“字段标签”选项卡中输入短文本、中文本、长文本和标题的字段。您可以按 Enter 键,这些标签的长度将自动生成。
步骤 9 - 保存您的更改。“创建对象目录条目”弹出窗口出现并要求输入包。您可以输入您正在使用的包名称。如果您没有任何包,您可以在对象导航器中创建它,或者您可以使用“本地对象”按钮保存您的数据元素。
步骤 10 - 激活您的数据元素。单击激活图标(火柴图标)或按 CTRL + F3 激活数据元素。出现一个弹出窗口,列出当前处于非活动状态的 2 个对象,如下图所示。
步骤 11 - 在此步骤中,需要激活名为 Z_CUST 的标记为“DTEL”的顶部条目。由于此条目已突出显示,请单击绿色勾号按钮。此窗口将消失,状态栏将显示消息“对象已激活”。
如果在激活数据元素时出现错误消息或警告,则会自动显示激活日志。激活日志显示有关激活流程的信息。您也可以使用“实用程序(M)”→“激活日志”调用激活日志。
SAP ABAP - 表
可以在 ABAP Dictionary 中独立于数据库定义表。当在 ABAP Dictionary 中激活表时,其字段的类似副本也会在数据库中创建。在 ABAP Dictionary 中定义的表会自动转换为与数据库兼容的格式,因为表的定义取决于 SAP 系统使用的数据库。
表可以包含一个或多个字段,每个字段都定义了其数据类型和长度。存储在表中的大量数据分布在表中定义的多个字段之间。
表字段类型
一张表由多个字段组成,每个字段包含多个元素。下表列出了表字段的不同元素:
序号 | 元素及描述 |
---|---|
1 | 字段名 这是赋予字段的名称,最多可包含 16 个字符。字段名可以由数字、字母和下划线组成,但必须以字母开头。 |
2 | 键标志 确定字段是否属于键字段。 |
3 | 字段类型 为字段分配数据类型。 |
4 | 字段长度 字段中可以输入的字符数。 |
5 | 小数位数 定义允许在小数点后出现的数字位数。此元素仅用于数字数据类型。 |
6 | 简短文本 描述相应字段的含义。 |
在 ABAP 字典中创建表
步骤 1 − 转到事务 SE11,选择“数据库表”单选按钮,并输入要创建的表的名称。在本例中,我们输入了名称 ZCUSTOMERS1。单击“创建”按钮。“字典:维护表”屏幕出现。此处默认选中“交付和维护”选项卡。
步骤 2 − 在“简短描述”字段中输入解释性简短文本。
步骤 3 − 单击“交付类”字段旁边的搜索帮助图标。选择“A [应用表(主数据和事务数据)]”选项。
步骤 4 − 从“数据浏览器/表视图维护”下拉菜单中选择“允许显示/维护”选项。“字典:维护表”屏幕出现。
步骤 5 − 选择“字段”选项卡。出现包含与“字段”选项卡相关的选项的屏幕。
步骤 6 − 在“字段”列中输入表字段的名称。字段名可以包含字母、数字和下划线,但必须始终以字母开头,并且长度不能超过 16 个字符。
要创建的字段也必须具有数据元素,因为它们从定义的数据元素中获取属性,例如数据类型、长度、小数位数和简短文本。
步骤 7 − 如果要将字段作为表键的一部分,请选择“键”列。让我们创建诸如 CLIENT、CUSTOMER、NAME、TITLE 和 DOB 等字段。
步骤 8 − 第一个字段非常重要,它标识记录关联的客户端。输入“Client”作为字段,输入“MANDT”作为数据元素。系统会自动填写数据类型、长度、小数位数和简短描述。“Client”字段通过选中“键”框被设置为键字段。
步骤 9 − 下一个字段是“Customer”。选中该复选框以将其设为键字段,并输入新的数据元素“ZCUSTNUM”。单击“保存”按钮。
步骤 10 − 由于数据元素“ZCUSTNUM”尚不存在,因此必须创建它。双击新的数据元素,“创建数据元素”窗口出现。对此回答“是”,然后出现“维护数据元素”窗口。
步骤 11 − 在“简短描述”区域中输入“客户编号”。应为新的数据元素定义名为“域”的基本数据类型。因此,输入“ZCUSTD1”,双击它并同意保存所做的更改。选择“是”以创建域,并在“简短描述”框中键入域的描述。
“定义”选项卡会自动打开。第一个字段是“数据类型”。
步骤 12 − 单击框内并从下拉菜单中选择“NUMC”类型。在“字符数”字段中输入数字 8(最多 8 个字符),并在“小数位数”区域中输入 0。必须选择 8 的输出长度,然后按 Enter。“NUMC”字段的描述必须重新出现,以确认这是一个有效的条目。
步骤 13 − 单击“保存”按钮并激活对象。
步骤 14 − 按 F3 返回“维护/更改数据元素”屏幕。根据以下快照创建四个字段标签。之后,保存并激活元素。
步骤 15 − 按返回按钮返回表维护屏幕。“客户”列具有正确的数据类型、长度、小数位数和简短描述。这表示成功创建了数据元素以及使用的域。
同样,我们需要创建三个附加字段,例如 NAME、TITLE 和 DOB。
步骤 16 − 从工具栏中选择“技术设置”。为“数据类”选择 APPL0,为“大小”类别字段选择第一个大小类别 0。对于缓冲选项,必须选择“不允许缓冲”。
步骤 17 − 单击“保存”。返回表并激活它。出现以下屏幕。
表“ZCUSTOMERS1”已激活。
SAP ABAP - 结构
结构是由任何数据类型的组件组成的数据库对象,这些组件一个接一个地存储在内存中。
结构对于绘制屏幕字段以及操作由离散数量的字段定义的一致格式的数据非常有用。
结构在运行时可能只有一个记录,但表可以有多个记录。
创建结构
步骤 1 − 转到事务 SE11。
步骤 2 − 单击屏幕上的“数据类型”选项。输入名称“ZSTR_CUSTOMER1”并单击“创建”按钮。
步骤 3 − 在下一个屏幕中选择“结构”选项并按 Enter。您可以看到“维护/更改结构”向导。
步骤 4 − 输入以下快照中所示的简短描述。
步骤 5 − 输入组件(字段名)和组件类型(数据元素)。
注意:此处组件名称根据 SAP 建议以 Z 开头。让我们使用我们已在数据库表中创建的数据元素。
步骤 6 − 提供所有组件和组件类型后,需要保存、检查和激活。
出现以下屏幕:
步骤 7 − 由于“ZSTR_CUSTOMER1”已突出显示,因此单击绿色勾号按钮。此窗口消失,状态栏将显示消息“已激活”。
结构现在已激活,如下面的快照所示:
SAP ABAP - 视图
视图仅像数据库表一样起作用。但它不会占用存储空间。视图类似于虚拟表——一个没有任何物理存在的表。视图是通过组合包含有关应用程序对象的的信息的一个或多个表的數據来创建的。使用视图,您可以表示表中包含的数据的子集,或者您可以将多个表连接到单个虚拟表中。
与应用程序对象相关的數據通过使用数据库视图分布在多个表中。它们使用内部联接条件来连接不同表的数据。维护视图用于显示和修改存储在应用程序对象中的数据。每个维护视图都与其关联的维护状态相关联。
我们使用投影视图来屏蔽不需要的字段,并在表中仅显示相关字段。投影视图必须在一个透明表上定义。投影视图恰好包含一个表。我们不能为投影视图定义选择条件。
创建视图
步骤 1 − 在 ABAP 字典的初始屏幕上选择“视图”单选按钮。输入要创建的视图的名称,然后单击“创建”按钮。我们输入视图的名称为 ZVIEW_TEST。
步骤 2 − 选择视图类型时选择投影视图单选按钮,然后单击“复制”按钮。“字典:更改视图”屏幕出现。
步骤 3 − 在“简短描述”字段中输入简短描述,并在“基本表”字段中输入要使用的表的名称,如下面的快照所示。
步骤 4 − 单击“表字段”按钮,以将 ZCUSTOMERS1 表的字段包含到投影视图中。
步骤 5 − 出现“从表 ZCUSTOMERS1 中选择字段”屏幕。选择您希望包含在投影视图中的字段,如下面的快照所示。
步骤 6 − 单击“复制”按钮后,“字典:更改视图”屏幕上将显示投影视图的所有选定字段。
步骤 7 − 选择“维护状态”选项卡以定义访问方法。选择“只读”单选按钮,并从“数据浏览器/表视图维护”的下拉菜单中选择“允许显示/维护(受限制)”选项。
步骤 8 − 保存并激活它。在“字典:更改视图”屏幕上,选择“实用程序(M) > 内容”以显示 ZVIEW_TEST 的选择屏幕。
步骤 9 − 单击“执行”图标。投影视图的输出将显示在以下屏幕截图中。
表 ZCUSTOMERS1 包含 5 个字段。此处显示的字段为 3 个(客户端、客户编号和名称),包含 4 个条目。客户编号从 100001 到 100004,带有相应的名称。
SAP ABAP - 搜索帮助
搜索帮助是 ABAP 字典的另一个存储库对象,用于以列表形式显示字段的所有可能值。此列表也称为命中列表。您可以从此命中列表中选择要输入字段的值,而不是手动输入值,这既费时又容易出错。
创建搜索帮助
步骤 1 − 转到事务 SE11。选择搜索帮助的单选按钮。输入要创建的搜索帮助的名称。让我们输入名称 ZSRCH1。单击“创建”按钮。
步骤 2 − 系统将提示要创建的搜索帮助类型。选择基本搜索帮助(默认为)。将出现以下屏幕截图所示的创建基本搜索帮助的屏幕。
步骤 3 − 在选择方法中,我们需要指示我们的数据源是表还是视图。在本例中,它恰好是一个表。该表是 ZCUSTOMERS1。它从选择列表中选择。
步骤 4 − 输入选择方法后,下一个字段是对话框类型。这控制限制性对话框的外观。有一个包含三个选项的下拉列表。让我们选择“立即显示值”选项。
步骤 5 − 接下来的参数区域。对于每个搜索帮助参数或字段,必须根据要求输入这些列字段。
搜索帮助参数 − 这是来自数据源的字段。表中的字段列在选择列表中。参与搜索帮助的字段将被输入,每行一个字段。让我们包含两个字段 CUSTOMER 和 NAME。这两个字段参与的方式在其余列中指示。
导入 − 此字段是一个复选框,用于指示搜索帮助参数是否为导入参数。导出或导入是针对搜索帮助的。
导出 − 此字段是一个复选框,用于指示搜索帮助参数是否为导出参数。导出将是将字段值从选择列表传输到屏幕字段。
LPos − 其值控制搜索帮助参数或字段在选择列表中的物理位置。如果输入值 1,则该字段将出现在选择列表的第一个位置,依此类推。
SPos − 它控制搜索帮助参数或字段在限制性对话框中的物理位置。如果输入值为 1,则该字段将出现在限制性对话框的第一个位置,以此类推。
数据元素 − 默认情况下,每个搜索帮助参数或字段都会分配一个数据元素,该数据元素已在数据源(表或视图)中分配给它。此数据元素名称显示在显示模式中。
步骤 6 − 执行一致性检查并激活搜索帮助。按 F8 执行。“测试搜索帮助 ZSRCH1”屏幕将显示如下屏幕截图所示。
步骤 7 − 让我们在客户的“准备输入”屏幕字段中输入数字 100004。按 Enter。
显示客户编号 100004 和姓名“STEPHEN”。
SAP ABAP - 锁对象
锁定对象是 ABAP Dictionary 提供的一项功能,用于同步多个程序对同一数据的访问。数据记录借助特定程序访问。锁定对象用于在 SAP 中避免在数据库中插入或更改数据时出现不一致的情况。必须在锁定对象中定义其数据记录需要锁定的表及其关键字段。
锁定机制
以下是使用锁定机制完成的两个主要功能:
程序可以与其他程序通信,告知其正在读取或更改的数据记录。
程序可以防止自己读取刚刚被另一个程序更改的数据。
程序首先生成一个锁定请求。然后,此请求转到排队服务器,并在锁定表中创建锁定。排队服务器设置锁定,程序最终可以访问数据。
创建锁定对象
步骤 1 − 转到事务代码 SE11。将打开以下屏幕。
步骤 2 − 单击“锁定对象”单选按钮。输入以 E 开头的锁定对象名称,然后单击“创建”按钮。这里我们使用 EZLOCK12。
步骤 3 − 输入简短描述字段,然后单击“表”选项卡。
步骤 4 − 在“名称”字段中输入表名,并将锁定模式选择为“写锁定”。
步骤 5 − 单击“锁定参数”选项卡,将出现以下屏幕。
步骤 6 − 保存并激活。将自动生成 2 个功能模块。要检查功能模块,可以使用“转到”→“锁定模块”。
步骤 7 − 单击“锁定模块”,将打开以下屏幕。
锁定对象已成功创建。
包含在锁定对象中的表的关键字段称为锁定参数,它们用作功能模块中的输入参数。这些参数用于设置和删除锁定对象定义生成的锁定。
SAP ABAP - 模块化
最好使程序尽可能自包含且易于阅读。只需尝试将大型复杂的任务分解成更小、更简单的任务,方法是将每个任务放在其各自的模块中,开发人员可以在没有其他干扰的情况下专注于这些任务。
在 SAP ABAP 环境中,模块化涉及将程序组织成模块化单元,也称为逻辑块。即使在创建程序期间和随后的维护周期中,它也能减少冗余并提高程序的可读性。模块化还可以实现相同代码的可重用性。ABAP 已使开发人员必须进行模块化,即比基于 OOPS 的语言(具有相对更多内置模块化功能)更相对地组织程序。一旦完成、调试等一个小型的模块化代码部分,就不必再返回到它,开发人员可以继续关注其他问题。
ABAP 程序由称为模块化处理块的处理块组成。它们是:
从程序外部和 ABAP 运行时环境(即事件块和对话框模块)调用的处理块。
从 ABAP 程序调用的处理块。
除了使用处理块进行模块化之外,源代码模块还用于通过宏和包含程序对源代码进行模块化。
源代码级别的模块化:
- 局部宏
- 全局包含程序
通过从 ABAP 程序调用的处理块进行模块化:
- 子例程
- 功能模块
模块化源代码意味着将一系列 ABAP 语句放在模块中。可以根据用户的需求在程序中调用模块化的源代码。源代码模块增强了 ABAP 程序的可读性和可理解性。创建单独的源代码模块还可以防止一次又一次地重复编写相同的语句,这反过来又使第一次阅读代码的人更容易理解。
SAP ABAP - 子程序
子例程是可重用的代码段。它是程序中的一个模块化单元,其中函数以源代码的形式封装。您可以将程序的一部分分页到子例程中,以便更好地概述主程序,并多次使用相应的语句序列,如下面的图所示。
我们有程序 X,其中包含 3 个不同的源代码块。每个块都具有相同的 ABAP 语句。基本上,它们是相同的代码块。为了使此代码更易于维护,我们可以将代码封装到子例程中。我们可以在程序中根据需要多次调用此子例程。可以使用 Form 和 EndForm 语句定义子例程。
以下是子例程定义的一般语法。
FORM <subroutine_name>. <statements> ENDFORM.
我们可以使用 PERFORM 语句调用子例程。控制跳转到子例程 <subroutine_name> 中的第一个可执行语句。遇到 ENDFORM 时,控制跳转回 PERFORM 语句后面的语句。
示例
步骤 1 − 转到事务代码 SE80。打开现有程序,然后右键单击程序。在本例中,它是“ZSUBTEST”。
步骤 2 − 选择“创建”,然后选择“子例程”。在字段中写入子例程名称,然后单击“继续”按钮。子例程名称为“Sub_Display”,如下面的屏幕截图所示。
步骤 3 − 在 FORM 和 ENDFORM 语句块中编写代码。子例程已成功创建。
我们需要包含 PERFORM 语句来调用子例程。让我们看看代码:
REPORT ZSUBTEST. PERFORM Sub_Display. * Form Sub_Display * --> p1 text * <-- p2 text FORM Sub_Display. Write: 'This is Subroutine'. Write: / 'Subroutine created successfully'. ENDFORM. " Sub_Display
步骤 4 − 保存、激活并执行程序。上述代码产生以下输出:
Subroutine Test: This is Subroutine Subroutine created successfully
因此,使用子例程使您的程序更面向函数。它将程序的任务分解成子函数,以便每个子例程负责一个子函数。您的程序变得更容易维护,因为对函数的更改通常只需要在子例程中实现。
SAP ABAP - 宏
如果我们想在一个程序中多次重用同一组语句,我们需要将它们包含在一个宏中。例如,宏对于长计算或编写复杂的 WRITE 语句很有用。我们只能在定义宏的程序中使用宏。宏定义应该在程序中使用宏之前发生。
宏是基于占位符设计的。占位符就像 C 语言中的指针。您可以在 DEFINE...END-OF-DEFINITION 语句中定义宏。
以下是宏定义的基本语法:
DEFINE <macro_name>. <statements> END-OF-DEFINITION. ...... <macro_name> [<param1> <param2>....].
在调用宏之前,必须先定义它。<param1>…. 替换 ABAP 语句中包含的宏定义中的占位符 &1...。
宏定义中的占位符最大数量为九个。也就是说,当程序执行时,SAP 系统会将宏替换为适当的语句,并且占位符 &1、&2……&9 将被参数 param1、param2……param9 替换。我们可以在另一个宏中调用宏,但不能调用同一个宏。
示例
转到事务代码 SE38。创建一个新的程序 ZMACRO_TEST,以及简短文本字段中的描述,以及适当的属性,例如类型和状态,如下面的屏幕截图所示:
以下是代码:
REPORT ZMACRO_TEST. DEFINE mac_test. WRITE: 'This is Macro &1'. END-OF-DEFINITION. PARAMETERS: s1 type C as checkbox. PARAMETERS: s2 type C as checkbox. PARAMETERS: s3 type C as checkbox default 'X'. START-OF-SELECTION. IF s1 = 'X'. mac_test 1. ENDIF. IF s2 = 'X'. mac_test 2. ENDIF. IF s3 = 'X'. mac_test 3. ENDIF.
我们有 3 个复选框。执行程序时,让我们选择 S2 复选框。
以上代码产生以下输出:
A Macro Program This is Macro 2
如果选择所有复选框,则代码将产生以下输出:
A Macro Program This is Macro 1 This is Macro 2 This is Macro 3
SAP ABAP - 函数模块
功能模块构成了 SAP 系统的主要部分,因为多年来 SAP 一直使用功能模块对代码进行模块化,从而允许代码本身、其开发人员以及其客户重用代码。
功能模块是包含一组可重用语句以及导入和导出参数的子程序。与包含程序不同,功能模块可以独立执行。SAP 系统包含多个预定义的功能模块,可以从任何 ABAP 程序中调用。功能组充当许多逻辑上属于一起的功能模块的容器。例如,HR 工资系统的功能模块将组合到一个功能组中。
要查看如何创建功能模块,必须探索功能构建器。您可以使用事务代码 SE37 找到功能构建器。只需键入部分功能模块名称和通配符即可演示如何搜索功能模块。键入 *amount*,然后按 F4 键。
搜索结果将显示在新窗口中。功能模块显示在蓝色背景的行中,其功能组显示在粉红色行中。您可以使用对象导航器屏幕(事务代码 SE80)进一步查看功能组 ISOC。您可以看到功能组中包含的功能模块列表以及其他对象。让我们考虑功能模块 SPELL_AMOUNT。此功能模块将数字转换为文字。
创建新程序
步骤 1 − 转到事务代码 SE38 并创建一个名为 Z_SPELLAMOUNT 的新程序。
步骤 2 − 输入一些代码,以便可以设置参数,在其中可以输入值并传递给功能模块。此处的文本元素 text-001 读取“输入值”。
步骤 3 − 要编写此代码,请使用 CTRL+F6。之后,将出现一个窗口,其中“调用函数”是列表中的第一个选项。在文本框中输入“spell_amount”,然后单击“继续”按钮。
步骤 4 − 一些代码会自动生成。但是我们需要增强 IF 语句,以包含向屏幕写入消息的代码,例如“函数模块返回的值:sy-subrc”,并添加 ELSE 语句,以便在函数模块成功时输出正确的结果。这里,必须设置一个新变量来保存从函数模块返回的值。让我们将其称为“result”。
以下是代码:
REPORT Z_SPELLAMOUNT. data result like SPELL. selection-screen begin of line. selection-screen comment 1(15) text-001. parameter num_1 Type I. selection-screen end of line. CALL FUNCTION 'SPELL_AMOUNT' EXPORTING AMOUNT = num_1 IMPORTING IN_WORDS = result. IF SY-SUBRC <> 0. Write: 'Value returned is:', SY-SUBRC. else. Write: 'Amount in words is:', result-word. ENDIF.
步骤 5 − 函数模块返回的变量称为 IN_WORDS。在程序中设置相应的变量“result”。使用 LIKE 语句引用名为 SPELL 的结构来定义 IN_WORDS。
步骤 6 − 保存、激活并执行程序。输入如下屏幕截图所示的值,然后按 F8。
以上代码产生以下输出:
Spelling the Amount Amount in words is: FIVE THOUSAND SIX HUNDRED EIGHTY
SAP ABAP - 包含程序
包含程序是用于模块化源代码的全局存储库对象。它们允许您在不同的程序中使用相同的源代码。包含程序还可以帮助您井然有序地管理复杂的程序。为了在另一个程序中使用包含程序,我们使用以下语法:
INCLUDE <program_name>.
INCLUDE 语句的效果与将包含程序
编写包含程序代码时,有一些限制:
- 包含程序不能调用自身。
- 包含程序必须包含完整的语句。
以下是创建和使用包含程序的步骤:
步骤 1 − 在 ABAP 编辑器中创建要包含的程序 (Z_TOBEINCLUDED)。要在 ABAP 编辑器中包含的代码为:
PROGRAM Z_TOBEINCLUDED. Write: / 'This program is started by:', SY-UNAME, / 'The Date is:', SY-DATUM, / 'Time is', SY-UZEIT.
步骤 2 − 将程序的类型设置为 INCLUDE 程序,如下面的屏幕截图所示。
步骤 3 − 单击“保存”按钮,并将程序保存在名为 ZINCL_PCKG 的包中。
步骤 4 − 创建另一个程序,其中必须使用程序 Z_TOBEINCLUDED。这里我们创建了另一个名为 Z_INCLUDINGTEST 的程序,并将程序的类型指定为可执行程序。
步骤 5 − Z_INCLUDINGTEST 程序的编码使用 INCLUDE 语句包含 Z_TOBEINCLUDED 程序,如下面的代码所示。
REPORT Z_INCLUDINGTEST. INCLUDE Z_TOBEINCLUDED.
步骤 6 − 保存、激活并执行程序。
以上代码产生以下输出:
This program is started by: SAPUSER The Date is: 06.10.2015 Time is 13:25:11
SAP ABAP - Open SQL 概述
开放式 SQL 指的是 ABAP 语句的子集,这些语句能够直接访问当前 AS ABAP 中心数据库中的数据。开放式 SQL 语句将所有数据库系统都支持的 SQL 数据操作语言功能映射到 ABAP 中。
开放式 SQL 语句在数据库接口的开放式 SQL 接口中转换为特定于数据库的 SQL。然后,它们被传输到数据库系统并执行。开放式 SQL 语句可用于访问在 ABAP 字典中声明的数据库表。默认情况下访问 AS ABAP 的中心数据库,也可以通过辅助数据库连接访问其他数据库。
每当在 ABAP 程序中使用这些语句中的任何一个时,务必检查执行的操作是否成功。如果尝试将记录插入数据库表但未正确插入,则必须了解这一点,以便在程序中采取适当的操作。这可以使用已经使用的系统字段 SY-SUBRC 来完成。当语句成功执行时,SY-SUBRC 字段将包含值 0,因此可以对此进行检查,如果出现该值,则可以继续执行程序。
DATA 语句用于声明工作区。让我们将其命名为“wa_customers1”。与其为此声明一种数据类型,不如声明构成表的多个字段。最简单的方法是使用 LIKE 语句。
INSERT 语句
这里声明的 wa_customers1 工作区与 ZCUSTOMERS1 表类似,具有相同的结构,但本身不成为表。此工作区只能存储一条记录。声明后,可以使用 INSERT 语句将工作区及其保存的记录插入表中。这里的代码将读取为“INSERT ZCUSTOMERS1 FROM wa_customers1”。
必须用一些数据填充工作区。使用 ZCUSTOMERS1 表中的字段名。这可以通过前向导航、双击代码中的表名或打开新会话并使用事务 SE11 来完成。然后可以将表的字段复制并粘贴到 ABAP 编辑器中。
以下是代码片段:
DATA wa_customers1 LIKE ZCUSTOMERS1. wa_customers1-customer = '100006'. wa_customers1-name = 'DAVE'. wa_customers1-title = 'MR'. wa_customers1-dob = '19931017'. INSERT ZCUSTOMERS1 FROM wa_customers1.
然后可以使用 CHECK 语句,如下所示。这意味着如果记录正确插入,系统将声明这一点。如果没有,则将显示不等于零的 SY-SUBRC 代码。以下是代码片段:
IF SY-SUBRC = 0. WRITE 'Record Inserted Successfully'. ELSE. WRITE: 'The return code is ', SY-SUBRC. ENDIF.
检查程序,保存,激活代码,然后测试它。输出窗口应显示为“记录插入成功”。
CLEAR 语句
CLEAR 语句允许清除字段或变量,以便在其位置插入新数据,从而允许重复使用它。CLEAR 语句通常用于程序中,它允许多次使用现有字段。
在之前的代码片段中,工作区结构已填充数据以创建要插入 ZCUSTOMERS1 表的新记录,然后执行验证检查。如果要插入新记录,必须使用 CLEAR 语句,以便可以使用新数据再次填充它。
UPDATE 语句
如果要同时更新表中的一条或多条现有记录,则使用 UPDATE 语句。与 INSERT 语句类似,声明一个工作区,填充程序执行时要放入记录中的新数据。此处将更新先前使用 INSERT 语句创建的记录。只需编辑 NAME 和 TITLE 字段中存储的文本。然后在新的一行上,使用与 INSERT 语句相同的结构,这次使用 UPDATE 语句,如下面的代码片段所示:
DATA wa_customers1 LIKE ZCUSTOMERS1. wa_customers1-customer = '100006'. wa_customers1-name = 'RICHARD'. wa_customers1-title = 'MR'. wa_customers1-dob = '19931017'. UPDATE ZCUSTOMERS1 FROM wa_customers1.
执行 UPDATE 语句后,您可以查看 ABAP 字典中的数据浏览器,以查看记录是否已成功更新。
MODIFY 语句
MODIFY 语句可以被认为是 INSERT 和 UPDATE 语句的组合。它可以用来插入新记录或修改现有记录。它遵循与前两个语句类似的语法,从输入工作区的数据中修改记录。
执行此语句时,将检查所涉及的关键字段与表中的关键字段。如果已存在具有这些关键字段值的记录,则将对其进行更新。如果没有,则将创建一个新记录。
以下是创建新记录的代码片段:
CLEAR wa_customers1. DATA wa_customers1 LIKE ZCUSTOMERS1. wa_customers1-customer = '100007'. wa_customers1-name = 'RALPH'. wa_customers1-title = 'MR'. wa_customers1-dob = '19910921'. MODIFY ZCUSTOMERS1 FROM wa_customers1.
在此示例中,使用 CLEAR 语句以便可以将新条目放入工作区,然后添加客户(编号)100007。由于这是一个新的、唯一的关键字段值,因此将插入一条新记录,并将执行另一个验证检查。
执行此操作并在数据浏览器中查看数据后,将为客户编号 100007 (RALPH) 创建一条新记录。
以上代码产生以下输出(表内容):
SAP ABAP - Native SQL 概述
术语“原生 SQL”指的是所有可以静态传输到数据库接口的原生 SQL 接口的语句。原生 SQL 语句不属于 ABAP 的语言范围,也不遵循 ABAP 语法。ABAP 仅包含用于隔离可以列出原生 SQL 语句的程序部分的语句。
在原生 SQL 中,主要可以使用特定于数据库的 SQL 语句。这些语句从原生 SQL 接口到数据库系统几乎没有更改就被传输并执行。可以使用相关数据库的完整 SQL 语言范围,并且不需要在 ABAP 字典中声明已寻址的数据库表。还有一小部分 SAP 特定的原生 SQL 语句,这些语句由原生 SQL 接口以特定方式处理。
要使用原生 SQL 语句,必须在它前面加上 EXEC SQL 语句,并在后面加上 ENDEXEC 语句。
语法如下:
EXEC SQL PERFORMING <form>. <Native SQL statement> ENDEXEC.
这些语句定义了 ABAP 程序中的一个区域,可以在其中列出一种或多种原生 SQL 语句。输入的语句将传递到原生 SQL 接口,然后按如下方式处理:
所有对已寻址数据库系统的程序接口有效的 SQL 语句都可以在 EXEC 和 ENDEXEC 之间列出,特别是 DDL(数据定义语言)语句。
这些 SQL 语句从原生 SQL 接口传递到数据库系统,基本上没有改变。语法规则由数据库系统指定,尤其是数据库对象的区分大小写规则。
如果语法允许在各个语句之间使用分隔符,则可以在 EXEC 和 ENDEXEC 之间包含多个原生 SQL 语句。
可以在 EXEC 和 ENDEXEC 之间指定 SAP 特定的原生 SQL 语言元素。这些语句不会直接从原生 SQL 接口传递到数据库,而是会进行适当的转换。
示例
SPFLI 是一个标准的 SAP 表,用于存储航班时刻信息。这取决于版本和发布级别,可在 R/3 SAP 系统中使用。当您将表名 SPFLI 输入相关 SAP 事务(例如 SE11 或 SE80)时,您可以查看此信息。您还可以使用这两个事务查看此数据库表中包含的数据。
REPORT ZDEMONATIVE_SQL. DATA: BEGIN OF wa, connid TYPE SPFLI-connid, cityfrom TYPE SPFLI-cityfrom, cityto TYPE SPFLI-cityto, END OF wa. DATA c1 TYPE SPFLI-carrid VALUE 'LH'. EXEC SQL PERFORMING loop_output. SELECT connid, cityfrom, cityto INTO :wa FROM SPFLI WHERE carrid = :c1 ENDEXEC. FORM loop_output. WRITE: / wa-connid, wa-cityfrom, wa-cityto. ENDFORM.
以上代码产生以下输出:
0400 FRANKFURT NEW YORK 2402 FRANKFURT BERLIN 0402 FRANKFURT NEW YORK
SAP ABAP - 内部表
内部表实际上是一个临时表,它包含正在执行的 ABAP 程序的记录。内部表仅在 SAP 程序的运行时存在。它们用于使用 ABAP 语言处理大量数据。当您需要从数据库表中检索数据时,需要在 ABAP 程序中声明一个内部表。
内部表中的数据存储在行和列中。每一行称为行,每一列称为字段。在内部表中,所有记录都具有相同的结构和键。使用索引或键访问内部表的各个记录。由于内部表一直存在到关联程序执行完毕为止,因此当程序执行终止时,内部表的记录将被丢弃。因此,内部表可以用作临时存储区或临时缓冲区,可以在其中根据需要修改数据。这些表仅在运行时占用内存,而不是在声明时占用内存。
内部表只在程序运行时存在,因此在编写代码时,必须以程序能够使用的方式来构造内部表。您会发现内部表的操作方式与结构相同。主要区别在于结构只有一行,而内部表可以根据需要拥有任意多行。
内部表可以由多个字段组成,这些字段对应于表的列,就像在ABAP字典中使用多个字段创建表一样。关键字段也可以与内部表一起使用,并且在创建这些内部表时,它们提供了更大的灵活性。使用内部表,可以指定非唯一键,允许存储任意数量的非唯一记录,并允许根据需要存储重复记录。
内部表的大小或包含的行数不是固定的。内部表的大小会根据与内部表关联的程序的需求而变化。但建议尽可能保持内部表的小型化。这样做是为了避免系统在处理海量数据时运行缓慢。
内部表用于多种目的:
它们可以用来保存计算结果,这些结果可以在程序的后面部分使用。
内部表还可以保存记录和数据,以便快速访问这些数据,而无需从数据库表中访问这些数据。
它们非常通用。可以使用任意数量的其他已定义结构来定义它们。
示例
假设用户想要从一个或多个大型表中创建一个包含各种客户联系号码的列表。用户首先创建一个内部表,从客户表中选择相关数据,然后将数据放入内部表中。其他用户可以直接访问和使用此内部表来检索所需的信息,而无需编写数据库查询来在程序运行时执行每个操作。
SAP ABAP - 创建内部表
使用DATA语句声明内部表。程序必须知道表从哪里开始和结束。因此,使用BEGIN OF语句,然后声明表名。之后,使用OCCURS附加项,后跟一个数字,这里为0。OCCURS告诉SAP正在创建内部表,而0表示它最初不包含任何记录。它将在填充数据时扩展。
语法如下:
DATA: BEGIN OF <internal_tab> Occurs 0,
让我们在新的一行上创建字段。例如,创建“name”字段,声明为LIKE ZCUSTOMERS1-name。创建另一个名为“dob”的字段,LIKE ZCUSTOMERS1-dob。最初将内部表中的字段名称与在其他地方创建的其他字段名称相同是有用的。最后,使用“END OF <internal_tab>.”声明内部表的结束,如下面的代码所示:
DATA: BEGIN OF itab01 Occurs 0, name LIKE ZCUSTOMERS1-name, dob LIKE ZCUSTOMERS1-dob, END OF itab01.
这里“itab01”在SAP中创建临时表时常用作简写。OCCURS子句用于通过声明表的字段来定义内部表的主体。当使用OCCURS子句时,可以指定一个数值常量“n”来根据需要确定额外的默认内存。OCCUR 0子句使用的默认内存大小为8 KB。现在创建了内部表的结构,可以编写代码来用记录填充它。
可以使用或不使用标题行来创建内部表。要创建带标题行的内部表,请在内部表的定义中,在OCCURS子句之前使用BEGIN OF子句或在OCCURS子句之后使用WITH HEADER LINE子句。要创建不带标题行的内部表,请在不使用BEGIN OF子句的情况下使用OCCURS子句。
您还可以使用TYPES语句创建一个内部表作为局部数据类型(仅在当前程序上下文中使用的的数据类型)。此语句使用TYPE或LIKE子句引用现有表。
创建内部表作为局部数据类型的语法如下:
TYPES <internal_tab> TYPE|LIKE <internal_tab_type> OF <line_type_itab> WITH <key> INITIAL SIZE <size_number>.
这里<internal_tab_type>指定内部表<internal_tab>的表类型,<line_type_itab>指定内部表行的类型。在TYPES语句中,可以使用TYPE子句将内部表的行类型指定为数据类型,并使用LIKE子句将行类型指定为数据对象。指定内部表键是可选的,如果用户没有指定键,则SAP系统将定义一个具有任意键的表类型。
INITIAL SIZE <size_number> 通过为其分配初始内存量来创建内部表对象。在前面的语法中,INITIAL SIZE子句为size_number表行预留内存空间。每当声明内部表对象时,表的大小都不属于表的 数据类型。
注意 - 当第一次填充内部表时,消耗的内存要少得多。
示例
步骤1 - 通过执行SE38事务代码打开ABAP编辑器。出现ABAP编辑器的初始屏幕。
步骤2 - 在初始屏幕中,输入程序名称,选择“源代码”单选按钮,然后单击“创建”按钮以创建新程序。
步骤3 - 在“ABAP:程序属性”对话框中,在“标题”字段中输入程序的简短描述,从“属性”组框中的“类型”下拉菜单中选择“可执行程序”选项。单击“保存”按钮。
步骤4 - 在ABAP编辑器中编写以下代码。
REPORT ZINTERNAL_DEMO. TYPES: BEGIN OF CustomerLine, Cust_ID TYPE C, Cust_Name(20) TYPE C, END OF CustomerLine. TYPES mytable TYPE SORTED TABLE OF CustomerLine WITH UNIQUE KEY Cust_ID. WRITE:/'The mytable is an Internal Table'.
步骤5 - 像往常一样保存、激活和执行程序。
在此示例中,mytable是一个内部表,并在Cust_ID字段上定义了一个唯一键。
以上代码产生以下输出:
The mytable is an Internal Table.
SAP ABAP - 填充内部表
在内部表中,填充包括选择、插入和追加等功能。本章重点介绍INSERT和APPEND语句。
INSERT 语句
INSERT语句用于将单行或多行插入内部表。
以下是将单行添加到内部表的语法:
INSERT <work_area_itab> INTO <internal_tab> INDEX <index_num>.
在此语法中,INSERT语句在internal_tab内部表中插入新行。可以使用work_area_itab INTO表达式在internal_tab参数之前插入新行。当使用work_area_itab INTO表达式时,新行取自work_area_itab工作区并插入到internal_tab表中。但是,当不使用work_area_itab INTO表达式插入行时,该行取自internal_tab表的标题行。
当使用INDEX子句将新行插入内部表时,插入行之后行的索引号将加1。如果内部表包含<index_num> - 1行,则新行将添加到表的末尾。当SAP系统成功将一行添加到内部表时,SY-SUBRC变量将设置为0。
示例
以下是一个使用insert语句的示例程序。
REPORT ZCUSLIST1. DATA: BEGIN OF itable1 OCCURS 4, F1 LIKE SY-INDEX, END OF itable1. DO 4 TIMES. itable1-F1 = sy-index. APPEND itable1. ENDDO. itable1-F1 = -96. INSERT itable1 INDEX 2. LOOP AT itable1. Write / itable1-F1. ENDLOOP. LOOP AT itable1 Where F1 ≥ 3. itable1-F1 = -78. INSERT itable1. ENDLOOP. Skip. LOOP AT itable1. Write / itable1-F1. ENDLOOP.
以上代码产生以下输出:
1 96- 2 3 4 1 96- 2 78- 3 78- 4
在上面的示例中,DO循环追加包含数字1到4的4行。标题行组件itable1-F1的值已赋值为-96。Insert语句将标题行作为新行插入到第3行之前的正文中。现有的第3行在插入后变为第4行。LOOP AT语句从内部表中检索F1值大于或等于3的行。在每一行之前,Insert语句从其标题行插入新行。在插入之前,F1组件已更改为包含-78。
在执行每个insert语句之后,系统会重新索引插入行下方的所有行。当您在大型内部表的顶部附近插入行时,这会引入开销。如果您需要将多行插入大型内部表,请准备另一个包含要插入行的表,并使用插入行。
在itable1的循环中插入itable1内的新的行时,它不会立即影响内部表。它实际上在下一个循环传递中生效。在当前行之后插入一行时,表在ENDLOOP处重新索引。sy-tabix递增,下一个循环处理sy-tabix指向的行。例如,如果您在第二个循环传递中并且您在第3行之前插入一条记录。当执行endloop时,新行变为第3行,旧的第3行变为第4行,依此类推。Sy-tabix递增1,下一个循环传递处理新插入的记录。
APPEND语句
APPEND语句用于向现有内部表添加单行。此语句从工作区复制单行,并将其插入内部表中最后一行之后。工作区可以是标题行或任何其他与内部表行结构相同的字段字符串。以下是用于向内部表追加单行的APPEND语句的语法:
APPEND <record_for_itab> TO <internal_tab>.
在此语法中,<record_for_itab>表达式可以用可转换为行类型的<work_area_itab>工作区或INITIAL LINE子句来表示。如果用户使用<work_area_itab>工作区,则SAP系统会向<internal_tab>内部表添加新行,并用工作区的内容填充它。INITIAL LINE子句追加空白行,其中包含表结构中每个字段的初始值。在每个APPEND语句之后,SY-TABIX变量包含追加行的索引号。
向具有非唯一键的标准表和已排序表追加行,无论表中是否已存在具有相同键的行,其工作方式都相同。换句话说,可能会出现重复条目。但是,如果用户尝试向具有唯一键的已排序表添加重复条目,或者用户通过向其追加行来违反已排序表的排序顺序,则会发生运行时错误。
示例
REPORT ZCUSLIST1. DATA: BEGIN OF linv Occurs 0, Name(20) TYPE C, ID_Number TYPE I, END OF linv. DATA table1 LIKE TABLE OF linv. linv-Name = 'Melissa'. linv-ID_Number = 105467. APPEND linv TO table1. LOOP AT table1 INTO linv. Write: / linv-name, linv-ID_Number. ENDLOOP.
以上代码产生以下输出:
Melissa 105467
SAP ABAP - 复制内部表
当我们从具有标题行的内部表读取记录时,该记录将从表本身移动到标题行。然后,程序将使用标题行。创建新记录时也是如此。它是您使用的标题行,新记录从中发送到表体本身。
为了复制记录,我们可以使用 SELECT 语句选择表中的所有记录,然后使用 MOVE 语句将记录从原始表移动到新的内部表中对应的字段。
以下是 MOVE 语句的语法:
MOVE <table_field> TO <internal_tab_field>.
示例
REPORT ZCUSLIST1. TABLES: ZCUSTOMERS1. DATA: BEGIN OF itab01 Occurs 0, name LIKE ZCUSTOMERS1-name, dob LIKE ZCUSTOMERS1-dob, END OF itab01. Select * FROM ZCUSTOMERS1. MOVE ZCUSTOMERS1-name TO itab01-name. MOVE ZCUSTOMERS1-dob TO itab01-dob. ENDSELECT. Write: / itab01-name, itab01-dob.
以上代码产生以下输出:
MARGARET 02.11.1994
SELECT 循环一次填充一个字段,使用 MOVE 语句将数据从一个表的字段移动到另一个表的字段。在上面的例子中,MOVE 语句用于将 ZCUSTOMERS1 表的内容移动到内部表中对应的字段。您可以只用一行代码完成此操作。您可以使用 MOVECORRESPONDING 语句。
以下是 MOVECORRESPONDING 语句的语法:
MOVE-CORRESPONDING <table_name> TO <internal_tab>.
它告诉系统将 ZCUSTOMERS1 的字段数据移动到 itab01 中对应的字段。
示例
REPORT ZCUSTOMERLIST. TABLES: ZCUSTOMERS1. DATA: Begin of itab01 occurs 0, customer LIKE ZCUSTOMERS1-customer, name LIKE ZCUSTOMERS1-name, title LIKE ZCUSTOMERS1-title, dob LIKE ZCUSTOMERS1-dob, END OF itab01. SELECT * from ZCUSTOMERS1. MOVE-Corresponding ZCUSTOMERS1 TO itab01. APPEND itab01. ENDSELECT. LOOP AT itab01. Write: / itab01-name, itab01-dob. ENDLOOP.
以上代码产生以下输出:
MARK 21.05.1981 JAMES 14.08.1977 AURIELE 19.06.1990 STEPHEN 22.07.1985 MARGARET 02.11.1994
这是因为两者都有匹配的字段名。使用此语句时,需要确保两个字段的数据类型和长度匹配。这之前已经通过 LIKE 语句完成了。
SAP ABAP - 读取内部表
我们可以使用 READ TABLE 语句的以下语法读取表的行:
READ TABLE <internal_table> FROM <work_area_itab>.
在此语法中,<work_area_itab> 表达式表示与 <internal_table> 表的行类型兼容的工作区。我们可以使用 WITH KEY 子句在 READ 语句中指定搜索键,但不能指定表键,如下面的语法所示:
READ TABLE <internal_table> WITH KEY = <internal_tab_field>.
这里,内部表的整行用作**搜索键**。表的整行内容与 <internal_tab_field> 字段的内容进行比较。如果 <internal_tab_field> 字段的值与表的行类型不兼容,则根据表的行类型转换这些值。搜索键允许您在没有结构化行类型的内部表中查找条目,即行是单个字段或内部表类型的情况。
READ 语句的以下语法用于使用 COMPARING 子句指定工作区或字段符号:
READ TABLE <internal_table> <key> INTO <work_area_itab> [COMPARING <F1> <F2>...<Fn>].
使用 COMPARING 子句时,将结构化行类型的指定表字段 <F1>、<F2>……<Fn> 与工作区的对应字段进行比较,然后再进行传输。如果指定了 ALL FIELDS 子句,则 SAP 系统会比较所有组件。当 SAP 系统根据键找到条目时,SY-SUBRC 变量的值设置为 0。此外,如果比较字段的内容不同,或者 SAP 系统找不到条目,则 SY-SUBRC 变量的值设置为 2 或 4。但是,无论比较的结果如何,只要 SAP 系统找到条目,就会将条目复制到目标工作区。
示例
REPORT ZREAD_DEMO. */Creating an internal table DATA: BEGIN OF Record1, ColP TYPE I, ColQ TYPE I, END OF Record1. DATA mytable LIKE HASHED TABLE OF Record1 WITH UNIQUE KEY ColP. DO 6 Times. Record1-ColP = SY-INDEX. Record1-ColQ = SY-INDEX + 5. INSERT Record1 INTO TABLE mytable. ENDDO. Record1-ColP = 4. Record1-ColQ = 12. READ TABLE mytable FROM Record1 INTO Record1 COMPARING ColQ. WRITE: 'SY-SUBRC =', SY-SUBRC. SKIP. WRITE: / Record1-ColP, Record1-ColQ.
以上代码产生以下输出:
SY-SUBRC = 2 4 9
在上面的例子中,mytable 是哈希表类型的内部表,Record1 是工作区,ColP 是唯一键。最初,mytable 填充了六行,其中 ColP 字段包含 SY-INDEX 变量的值,ColQ 字段包含 (SY-INDEX + 5) 值。
Record1 工作区填充了 ColP 和 ColQ 字段的值分别为 4 和 12。READ 语句使用 COMPARING 子句比较 ColP 键字段的值与 Record1 工作区中的值后读取表的行,然后将读取的行内容复制到工作区。SY-SUBRC 变量的值显示为 2,因为当 ColP 字段中的值为 4 时,ColQ 中的值不是 12,而是 9。
SAP ABAP - 删除内部表
DELETE 语句用于从内部表中删除一个或多个记录。内部表的记录通过指定表键或条件,或通过查找重复条目来删除。如果内部表具有非唯一键并包含重复条目,则删除表中的第一个条目。
以下是使用 DELETE 语句从内部表中删除记录或行的语法:
DELETE TABLE <internal_table> FROM <work_area_itab>.
在上述语法中,<work_area_itab> 表达式是一个工作区,它应该与 <internal_table> 内部表的类型兼容。删除操作是基于可以从工作区组件中获取的默认键执行的。
您还可以使用以下语法在 DELETE TABLE 语句中显式指定表键:
DELETE TABLE <internal_table> WITH TABLE KEY <K1> = <F1>………… <Kn> = <Fn>.
在此语法中,<F1>、<F2>……<Fn> 是内部表的字段,<K1>、<K2>……<Kn> 是表的键字段。DELETE 语句用于根据表达式 <K1> = <F1>、<K2> = <F2>……<Kn> = <Fn> 删除 <internal_table> 表的记录或行。
**注意** - 如果 <F1>、<F2>……<Fn> 字段的数据类型与 <K1>、<K2>……<Kn> 键字段不兼容,则 SAP 系统会自动将其转换为兼容的格式。
示例
REPORT ZDELETE_DEMO. DATA: BEGIN OF Line1, ColP TYPE I, ColQ TYPE I, END OF Line1. DATA mytable LIKE HASHED TABLE OF Line1 WITH UNIQUE KEY ColP. DO 8 TIMES. Line1-ColP = SY-INDEX. Line1-ColQ = SY-INDEX + 4. INSERT Line1 INTO TABLE mytable. ENDDO. Line1-ColP = 1. DELETE TABLE mytable: FROM Line1, WITH TABLE KEY ColP = 3. LOOP AT mytable INTO Line1. WRITE: / Line1-ColP, Line1-ColQ. ENDLOOP.
以上代码产生以下输出:
2 6 4 8 5 9 6 10 7 11 8 12
在这个例子中,mytable 有两个字段,ColP 和 ColQ。最初,mytable 填充了八行,其中 ColP 包含值 1、2、3、4、5、6、7 和 8。ColQ 包含值 5、6、7、8、9、10、11 和 12,因为 ColP 值每次递增 4。
DELETE 语句用于删除 mytable 中 ColP 键字段的值为 1 或 3 的行。删除后,mytable 的 ColP 字段包含值 2、4、5、6、7 和 8,如输出所示。ColQ 字段包含值 6、8、9、10、11 和 12。
SAP ABAP - 面向对象
面向对象简化了软件设计,使其更容易理解、维护和重用。**面向对象编程**(OOP) 代表了编写软件的一种不同思维方式。OOP 的优点在于其简单性。OOP 的表达能力使其更容易按时交付高质量的软件组件。
由于解决方案是根据现实世界中的对象设计的,程序员和业务分析师更容易交换关于使用通用领域语言的设计的想法和信息。这些改进的沟通有助于揭示隐藏的需求,识别风险,并提高正在开发的软件的质量。面向对象的方法侧重于表示现实世界抽象或具体事物的对象。这些对象由它们的特征和属性定义,这些特征和属性由它们的内部结构和它们的属性(数据)来表示。这些对象的行为由方法(即功能)来描述。
让我们比较一下过程式编程和面向对象编程:
特性 | 过程式方法 | 面向对象方法 |
---|---|---|
重点 | 重点在于任务。 | 重点在于执行这些任务的事物。 |
模块化 | 程序可以划分为称为函数的较小程序。 | 程序被组织成类和对象,功能被嵌入到类的成员函数中。 |
数据安全 | 大多数函数共享全局数据。 | 数据可以隐藏,外部资源无法访问。 |
可扩展性 | 修改和扩展现有功能比较耗时。 | 可以根据需要轻松添加新的数据和函数。 |
ABAP 最初是作为过程式语言开发的(类似于早期的过程式编程语言,如 COBOL)。但是,ABAP 现在已经通过引入 ABAP Objects 适应了面向对象范式的原则。ABAP 中的面向对象概念,例如类、对象、继承和多态性,与其他现代面向对象语言(如 Java 或 C++)的基本相同。
随着面向对象的成型,每个类都承担特定的角色分配。这种分工有助于简化整体编程模型,允许每个类专注于解决手头问题的特定部分。这样的类具有高内聚性,并且每个类的操作以某种直观的方式紧密相关。
面向对象的主要特性是:
- 有效的编程结构。
- 可以很好地模拟现实世界的实体。
- 强调数据安全和访问。
- 最大限度地减少代码冗余。
- 数据抽象和封装。
SAP ABAP - 对象
对象是一种特殊的变量,具有独特的特性和行为。对象的特性或属性用于描述对象的状态,而行为或方法则表示对象执行的操作。
对象是类的模式或实例。它代表一个现实世界的实体,例如一个人,或一个编程实体,例如变量和常量。例如,账户和学生是现实世界实体的例子。但是,计算机的硬件和软件组件是编程实体的例子。
对象具有以下三个主要特征:
- 具有状态。
- 具有唯一的标识。
- 可能会也可能不会显示行为。
对象的状态可以描述为一组属性及其值。例如,银行账户具有一组属性,例如账户号码、姓名、账户类型、余额以及所有这些属性的值。对象的举动是指其属性在一段时间内发生的变化。
每个对象都有一个唯一的标识,可用于将其与其他对象区分开来。两个对象可能表现出相同的行为,它们可能具有也可能不具有相同的状态,但它们永远不会具有相同的标识。两个人可能有相同的姓名、年龄和性别,但他们并不相同。同样,对象的标识在其整个生命周期中永远不会改变。
对象可以通过发送消息相互交互。对象包含数据和用于操作数据的代码。对象也可以在类的帮助下用作用户定义的数据类型。对象也称为类类型的变量。定义类后,您可以创建任意数量属于该类的对象。每个对象都与创建它的类类型的数据相关联。
创建对象
对象创建通常包括以下步骤:
创建一个引用变量来引用类。其语法为:
DATA: <object_name> TYPE REF TO <class_name>.
从引用变量创建一个对象。其语法为:
CREATE Object: <object_name>.
示例
REPORT ZDEMO_OBJECT. CLASS Class1 Definition. Public Section. DATA: text1(45) VALUE 'ABAP Objects.'. METHODS: Display1. ENDCLASS. CLASS Class1 Implementation. METHOD Display1. Write:/ 'This is the Display method.'. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA: Class1 TYPE REF TO Class1. CREATE Object: Class1. Write:/ Class1->text1. CALL METHOD: Class1->Display1.
以上代码产生以下输出:
ABAP Objects. This is the Display method.
SAP ABAP - 类
类用于指定对象的表单,它将数据表示和用于操作该数据的方法组合成一个简洁的包。类中的数据和函数称为**类的成员**。
类定义和实现
定义类时,定义数据类型的蓝图。这实际上并没有定义任何数据,但它确实定义了类名的含义、类的对象将包含的内容以及可以对这样的对象执行的操作。也就是说,它定义了对象的抽象特性,例如属性、字段和特性。
以下语法显示了如何定义类:
CLASS <class_name> DEFINITION. .......... .......... ENDCLASS.
类定义以关键字 CLASS 后跟类名、DEFINITION 和类体开头。类的定义可以包含类的各种组件,例如属性、方法和事件。当我们在类声明中声明方法时,必须在类实现中包含方法实现。以下语法显示了如何实现类:
CLASS <class_name> IMPLEMENTATION. ........... .......... ENDCLASS.
**注意** - 类的实现包含其所有方法的实现。在 ABAP Objects 中,类的结构包含属性、方法、事件、类型和常量等组件。
属性
属性是类的字段,可以具有任何数据类型,例如 C、I、F 和 N。它们在类声明中声明。这些属性可以分为两类:实例属性和静态属性。**实例属性**定义对象的特定实例状态。不同对象的属性状态不同。实例属性使用 DATA 语句声明。
静态属性定义了类的公共状态,该状态由类的所有实例共享。也就是说,如果您更改类的一个对象的静态属性,则更改也对类的所有其他对象可见。静态属性的声明使用 CLASS-DATA 语句。
方法
方法是表示类中对象行为的函数或过程。类的这些方法可以访问类的任何属性。方法的定义也可以包含参数,以便在调用方法时可以向这些参数提供值。方法的定义在类声明中声明,并在类的实现部分实现。METHOD 和 ENDMETHOD 语句用于定义方法的实现部分。以下语法显示了如何实现方法:
METHOD <m_name>. .......... .......... ENDMETHOD.
在此语法中,<m_name> 表示方法的名称。注意 - 可以使用 CALL METHOD 语句调用方法。
访问属性和方法
类组件可以在公共、私有或受保护的可见性部分中定义,这些部分控制如何访问这些组件。私有可见性部分用于拒绝从类外部访问组件。此类组件只能从类内部(例如方法)访问。
在公共可见性部分中定义的组件可以从任何上下文访问。默认情况下,类的所有成员都是私有的。实际上,我们在私有部分定义数据,在公共部分定义相关方法,以便可以从类外部调用它们,如下面的程序所示。
在类中公共部分声明的属性和方法可以被该类和程序的任何其他类、子类访问。
当在类中受保护部分声明属性和方法时,只有该类和子类(派生类)可以访问它们。
当在类中私有部分声明属性和方法时,只有该类可以访问它们,任何其他类都不能访问。
示例
Report ZAccess1. CLASS class1 Definition. PUBLIC Section. Data: text1 Type char25 Value 'Public Data'. Methods meth1. PROTECTED Section. Data: text2 Type char25 Value 'Protected Data'. PRIVATE Section. Data: text3 Type char25 Value 'Private Data'. ENDCLASS. CLASS class1 Implementation. Method meth1. Write: / 'Public Method:', / text1, / text2, / text3. Skip. EndMethod. ENDCLASS. Start-Of-Selection. Data: Objectx Type Ref To class1. Create Object: Objectx. CALL Method: Objectx→meth1. Write: / Objectx→text1.
以上代码产生以下输出:
Public Method: Public Data Protected Data Private Data Public Data
静态属性
静态属性用 CLASS-DATA 语句声明。所有对象或实例都可以使用类的静态属性。静态属性可以直接使用类名访问,例如 class_name⇒name_1 = 'Some Text'。
示例
以下是一个程序,我们想打印带有行号 4 到 8 次的文本。我们定义一个类 class1,在公共部分声明 CLASS-DATA(静态属性)和一个方法。在实现类和方法之后,我们直接在 Start-Of-Selection 事件中访问静态属性。然后,我们只需创建类的实例并调用方法。
Report ZStatic1. CLASS class1 Definition. PUBLIC Section. CLASS-DATA: name1 Type char45, data1 Type I. Methods: meth1. ENDCLASS. CLASS class1 Implementation. Method meth1. Do 4 Times. data1 = 1 + data1. Write: / data1, name1. EndDo. Skip. EndMethod. ENDCLASS. Start-Of-Selection. class1⇒name1 = 'ABAP Object Oriented Programming'. class1⇒data1 = 0. Data: Object1 Type Ref To class1, Object2 Type Ref To class1. Create Object: Object1, Object2. CALL Method: Object1→meth1, Object2→meth1.
以上代码产生以下输出:
构造函数
构造函数是在创建对象或访问类的组件时自动调用的特殊方法。每当创建对象时,构造函数都会被触发,但我们需要调用一个方法来触发常规方法。在下面的示例中,我们声明了两个公共方法 method1 和构造函数。这两个方法都有不同的操作。创建类的对象时,构造函数方法会触发其操作。
示例
Report ZConstructor1. CLASS class1 Definition. PUBLIC Section. Methods: method1, constructor. ENDCLASS. CLASS class1 Implementation. Method method1. Write: / 'This is Method1'. EndMethod. Method constructor. Write: / 'Constructor Triggered'. EndMethod. ENDCLASS. Start-Of-Selection. Data Object1 Type Ref To class1. Create Object Object1.
以上代码产生以下输出:
Constructor Triggered
方法中的 ME 运算符
当您在类的公共部分声明任何类型的变量时,可以在任何其他实现中使用它。可以在公共部分声明具有初始值的变量。我们可以在方法内部再次声明该变量,并赋予不同的值。当我们在方法内部写入变量时,系统将打印更改后的值。要反映变量的先前值,我们必须使用“ME”运算符。
在这个程序中,我们声明了一个公共变量 text1 并初始化了一个值。我们再次声明了相同的变量,但用不同的值实例化了它。在方法内部,我们使用“ME”运算符写入该变量以获取先前初始化的值。通过直接声明,我们得到更改后的值。
示例
Report ZMEOperator1. CLASS class1 Definition. PUBLIC Section. Data text1 Type char25 Value 'This is CLASS Attribute'. Methods method1. ENDCLASS. CLASS class1 Implementation. Method method1. Data text1 Type char25 Value 'This is METHOD Attribute'. Write: / ME→text1, / text1. ENDMethod. ENDCLASS. Start-Of-Selection. Data objectx Type Ref To class1. Create Object objectx. CALL Method objectx→method1.
以上代码产生以下输出:
This is CLASS Attribute This is METHOD Attribute
SAP ABAP - 继承
面向对象编程中最重要概念之一是继承。继承允许我们根据另一个类来定义一个类,这使得创建和维护应用程序更容易。这也提供了重用代码功能和加快实现速度的机会。
创建类时,程序员无需编写全新的数据成员和方法,而是可以指定新类应该继承现有类的成员。这个现有类称为基类或超类,新类称为派生类或子类。
一个类的对象可以获取另一个类的属性。
派生类继承超类的的数据和方法。但是,它们可以覆盖方法并添加新方法。
继承的主要优点是可重用性。
继承关系使用类定义语句的“INHERITING FROM”附加项指定。
语法如下:
CLASS <subclass> DEFINITION INHERITING FROM <superclass>.
示例
Report ZINHERITAN_1. CLASS Parent Definition. PUBLIC Section. Data: w_public(25) Value 'This is public data'. Methods: ParentM. ENDCLASS. CLASS Child Definition Inheriting From Parent. PUBLIC Section. Methods: ChildM. ENDCLASS. CLASS Parent Implementation. Method ParentM. Write /: w_public. EndMethod. ENDCLASS. CLASS Child Implementation. Method ChildM. Skip. Write /: 'Method in child class', w_public. EndMethod. ENDCLASS. Start-of-selection. Data: Parent Type Ref To Parent, Child Type Ref To Child. Create Object: Parent, Child. Call Method: Parent→ParentM, child→ChildM.
以上代码产生以下输出:
This is public data Method in child class This is public data
访问控制和继承
派生类可以访问其基类的所有非私有成员。因此,超类成员不应被子类的成员函数访问,应该在超类中声明为私有。我们可以按谁可以访问它们来总结不同的访问类型:
访问 | 公共 | 受保护 | 私有 |
---|---|---|---|
相同类 | 是 | 是 | 是 |
派生类 | 是 | 是 | 否 |
类外 | 是 | 否 | 否 |
从超类派生类时,可以通过公共、受保护或私有继承进行继承。继承类型由如上所述的访问说明符指定。我们几乎不使用受保护或私有继承,但公共继承是常用的。使用不同类型的继承时,会应用以下规则。
公共继承 - 从公共超类派生类时,超类的公共成员成为子类的公共成员,超类的受保护成员成为子类的受保护成员。超类的私有成员永远无法直接从子类访问,但可以通过调用超类的公共和受保护成员来访问。
受保护继承 - 从受保护超类派生类时,超类的公共和受保护成员成为子类的受保护成员。
私有继承 - 从私有超类派生类时,超类的公共和受保护成员成为子类的私有成员。
在子类中重新定义方法
超类的方法可以在子类中重新实现。重新定义方法的一些规则:
继承方法的重新定义语句必须与原始方法的定义位于同一部分。
如果重新定义方法,则无需在子类中再次输入其接口,只需输入方法的名称。
在重新定义的方法中,可以使用 super 引用访问直接超类的组件。
伪引用 super 只能在重新定义的方法中使用。
示例
Report Zinheri_Redefine. CLASS super_class Definition. Public Section. Methods: Addition1 importing g_a TYPE I g_b TYPE I exporting g_c TYPE I. ENDCLASS. CLASS super_class Implementation. Method Addition1. g_c = g_a + g_b. EndMethod. ENDCLASS. CLASS sub_class Definition Inheriting From super_class. Public Section. METHODS: Addition1 Redefinition. ENDCLASS. CLASS sub_class Implementation. Method Addition1. g_c = g_a + g_b + 10. EndMethod. ENDCLASS. Start-Of-Selection. Parameters: P_a Type I, P_b TYPE I. Data: H_Addition1 TYPE I. Data: H_Sub TYPE I. Data: Ref1 TYPE Ref TO sub_class. Create Object Ref1. Call Method Ref1→Addition1 exporting g_a = P_a g_b = P_b Importing g_c = H_Addition1. Write:/ H_Addition1.
执行 F8 后,如果我们输入值 9 和 10,则上述代码会产生以下输出:
Redefinition Demo 29
SAP ABAP - 多态性
多态性这个术语字面意思是“多种形式”。从面向对象的角度来看,多态性与继承一起工作,使得继承树中的各种类型可以互换使用。也就是说,当存在类层次结构并且它们通过继承相关联时,就会发生多态性。ABAP 多态性意味着对方法的调用将导致执行不同的方法,具体取决于调用方法的对象类型。
以下程序包含一个抽象类“class_prgm”,2 个子类(class_procedural 和 class_OO)以及一个测试驱动程序类“class_type_approach”。在此实现中,类方法“start”允许我们显示编程类型及其方法。如果您仔细观察方法“start”的签名,您会发现它接收类型为 class_prgm 的导入参数。但是,在 Start-Of-Selection 事件中,此方法在运行时使用 class_procedural 和 class_OO 类型的对象被调用。
示例
Report ZPolymorphism1. CLASS class_prgm Definition Abstract. PUBLIC Section. Methods: prgm_type Abstract, approach1 Abstract. ENDCLASS. CLASS class_procedural Definition Inheriting From class_prgm. PUBLIC Section. Methods: prgm_type Redefinition, approach1 Redefinition. ENDCLASS. CLASS class_procedural Implementation. Method prgm_type. Write: 'Procedural programming'. EndMethod. Method approach1. Write: 'top-down approach'. EndMethod. ENDCLASS. CLASS class_OO Definition Inheriting From class_prgm. PUBLIC Section. Methods: prgm_type Redefinition, approach1 Redefinition. ENDCLASS. CLASS class_OO Implementation. Method prgm_type. Write: 'Object oriented programming'. EndMethod. Method approach1. Write: 'bottom-up approach'. EndMethod. ENDCLASS. CLASS class_type_approach Definition. PUBLIC Section. CLASS-METHODS: start Importing class1_prgm Type Ref To class_prgm. ENDCLASS. CLASS class_type_approach IMPLEMENTATION. Method start. CALL Method class1_prgm→prgm_type. Write: 'follows'. CALL Method class1_prgm→approach1. EndMethod. ENDCLASS. Start-Of-Selection. Data: class_1 Type Ref To class_procedural, class_2 Type Ref To class_OO. Create Object class_1. Create Object class_2. CALL Method class_type_approach⇒start Exporting class1_prgm = class_1. New-Line. CALL Method class_type_approach⇒start Exporting class1_prgm = class_2.
以上代码产生以下输出:
Procedural programming follows top-down approach Object oriented programming follows bottom-up approach
ABAP 运行时环境在导入参数 class1_prgm 的赋值期间执行隐式缩小转换。此功能有助于泛型地实现“start”方法。与对象引用变量关联的动态类型信息允许 ABAP 运行时环境动态地将方法调用与对象引用变量指向的对象中定义的实现绑定。例如,“class_type_approach”类中方法“start”的导入参数“class1_prgm”是指向抽象类型,该类型永远无法自行实例化。
每当使用具体的子类实现(例如 class_procedural 或 class_OO)调用该方法时,class1_prgm 引用参数的动态类型就会绑定到这些具体类型之一。因此,对方法“prgm_type”和“approach1”的调用指的是 class_procedural 或 class_OO 子类中提供的实现,而不是 class “class_prgm”中提供的未定义的抽象实现。
SAP ABAP - 封装
封装是面向对象编程 (OOP) 的一个概念,它将数据及其操作数据的函数绑定在一起,并防止外部干扰和误用。数据封装导致了重要的 OOP 概念数据隐藏。封装是将数据与其使用的函数捆绑在一起的机制,而数据抽象是仅公开接口并向用户隐藏实现细节的机制。
ABAP 通过创建称为类的用户定义类型来支持封装和数据隐藏的属性。如前所述,类可以包含私有、受保护和公共成员。默认情况下,在类中定义的所有项目都是私有的。
接口封装
封装实际上意味着一个属性和方法可以在不同的类中修改。因此,数据和方法可以具有不同的形式和逻辑,这些形式和逻辑可以隐藏到单独的类中。
让我们考虑一下基于接口的封装。当我们需要在不同的类中创建具有不同功能的一种方法时,就使用接口。这里方法的名称不需要改变。相同的方法必须在不同的类实现中实现。
示例
下面的程序包含一个接口inter_1。我们声明了一个属性和一个方法method1。我们还定义了两个类,例如Class1和Class2。因此,我们必须在这两个类的实现中实现方法'method1'。我们在不同的类中以不同的方式实现了方法'method1'。在程序开始处,我们为两个类创建了两个对象Object1和Object2。然后,我们通过不同的对象调用该方法,以获得在不同类中声明的功能。
Report ZEncap1. Interface inter_1. Data text1 Type char35. Methods method1. EndInterface. CLASS Class1 Definition. PUBLIC Section. Interfaces inter_1. ENDCLASS. CLASS Class2 Definition. PUBLIC Section. Interfaces inter_1. ENDCLASS. CLASS Class1 Implementation. Method inter_1~method1. inter_1~text1 = 'Class 1 Interface method'. Write / inter_1~text1. EndMethod. ENDCLASS. CLASS Class2 Implementation. Method inter_1~method1. inter_1~text1 = 'Class 2 Interface method'. Write / inter_1~text1. EndMethod. ENDCLASS. Start-Of-Selection. Data: Object1 Type Ref To Class1, Object2 Type Ref To Class2. Create Object: Object1, Object2. CALL Method: Object1→inter_1~method1, Object2→inter_1~method1.
以上代码产生以下输出:
Class 1 Interface method Class 2 Interface method
封装类对外部世界的依赖性不大。此外,它们与外部客户端的交互是通过稳定的公共接口来控制的。也就是说,封装类及其客户端是松散耦合的。在大多数情况下,具有明确定义接口的类可以插入另一个上下文。如果设计正确,封装类将成为可重用的软件资产。
设计策略
我们大多数人都通过痛苦的经验了解到,除非我们真的需要公开类成员,否则默认情况下应将其设置为私有。这只是良好的封装。这种智慧最常应用于数据成员,也同样适用于所有成员。
SAP ABAP - 接口
与ABAP中的类类似,接口充当对象的數據類型。接口的组成部分与类的组成部分相同。与类的声明不同,接口的声明不包含可见性部分。这是因为在接口声明中定义的组件始终集成在类的公共可见性部分。
当两个相似的类具有相同名称的方法但功能彼此不同时,使用接口。接口可能看起来类似于类,但在接口中定义的功能是在类中实现的,以扩展该类的范围。接口连同继承特性为多态性提供了基础。这是因为在接口中定义的方法可以在不同的类中表现出不同的行为。
以下是创建接口的通用格式:
INTERFACE <intf_name>. DATA..... CLASS-DATA..... METHODS..... CLASS-METHODS..... ENDINTERFACE.
在此语法中,<intf_name>表示接口的名称。DATA和CLASSDATA语句可分别用于定义接口的实例和静态属性。METHODS和CLASS-METHODS语句可分别用于定义接口的实例和静态方法。由于接口的定义不包含实现类,因此在接口的声明中不需要添加DEFINITION子句。
注意 - 接口的所有方法都是抽象的。它们已完全声明,包括其参数接口,但在接口中未实现。所有想要使用接口的类都必须实现接口的所有方法。否则,该类将成为抽象类。
我们在类的实现部分使用以下语法:
INTERFACE <intf_name>.
在此语法中,<intf_name>表示接口的名称。请注意,此语法必须在类的公共部分使用。
以下语法用于在类的实现内部实现接口的方法:
METHOD <intf_name~method_m>. <statements>. ENDMETHOD.
在此语法中,<intf_name~method_m>表示<intf_name>接口方法的全名。
示例
Report ZINTERFACE1. INTERFACE my_interface1. Methods msg. ENDINTERFACE. CLASS num_counter Definition. PUBLIC Section. INTERFACES my_interface1. Methods add_number. PRIVATE Section. Data num Type I. ENDCLASS. CLASS num_counter Implementation. Method my_interface1~msg. Write: / 'The number is', num. EndMethod. Method add_number. ADD 7 TO num. EndMethod. ENDCLASS. CLASS drive1 Definition. PUBLIC Section. INTERFACES my_interface1. Methods speed1. PRIVATE Section. Data wheel1 Type I. ENDCLASS. CLASS drive1 Implementation. Method my_interface1~msg. Write: / 'Total number of wheels is', wheel1. EndMethod. Method speed1. Add 4 To wheel1. EndMethod. ENDCLASS. Start-Of-Selection. Data object1 Type Ref To num_counter. Create Object object1. CALL Method object1→add_number. CALL Method object1→my_interface1~msg. Data object2 Type Ref To drive1. Create Object object2. CALL Method object2→speed1. CALL Method object2→my_interface1~msg.
以上代码产生以下输出:
The number is 7 Total number of wheels is 4
在上例中,my_interface1是包含'msg'方法的接口的名称。接下来,定义并实现了两个类num_counter和drive1。这两个类都实现了'msg'方法以及定义其各自实例行为的特定方法,例如add_number和speed1方法。
注意 - add_number和speed1方法特定于各个类。
SAP ABAP - 对象事件
事件是在类中定义的一组结果,用于触发其他类中的事件处理程序。触发事件时,我们可以调用任意数量的事件处理程序方法。触发器与其处理程序方法之间的链接实际上是在运行时动态确定的。
在正常的函数调用中,调用程序确定需要调用对象的哪个方法或类的哪个方法。由于并非为每个事件都注册了固定的处理程序方法,因此在事件处理的情况下,处理程序方法确定需要触发的事件。
类的事件可以通过使用RAISE EVENT语句来触发同一类的事件处理程序方法。对于事件,可以使用FOR EVENT子句在同一类或不同类中定义事件处理程序方法,如下面的语法所示:
FOR EVENT <event_name> OF <class_name>.
与类的方法类似,事件可以具有参数接口,但它只有输出参数。输出参数由RAISE EVENT语句传递给事件处理程序方法,该语句将其作为输入参数接收。事件通过使用SET HANDLER语句在程序中动态地与其处理程序方法链接。
当事件被触发时,应该在所有处理类中执行相应的事件处理程序方法。
示例
REPORT ZEVENT1. CLASS CL_main DEFINITION. PUBLIC SECTION. DATA: num1 TYPE I. METHODS: PRO IMPORTING num2 TYPE I. EVENTS: CUTOFF. ENDCLASS. CLASS CL_eventhandler DEFINITION. PUBLIC SECTION. METHODS: handling_CUTOFF FOR EVENT CUTOFF OF CL_main. ENDCLASS. START-OF-SELECTION. DATA: main1 TYPE REF TO CL_main. DATA: eventhandler1 TYPE REF TO CL_eventhandler. CREATE OBJECT main1. CREATE OBJECT eventhandler1. SET HANDLER eventhandler1→handling_CUTOFF FOR main1. main1→PRO( 4 ). CLASS CL_main IMPLEMENTATION. METHOD PRO. num1 = num2. IF num2 ≥ 2. RAISE EVENT CUTOFF. ENDIF. ENDMETHOD. ENDCLASS. CLASS CL_eventhandler IMPLEMENTATION. METHOD handling_CUTOFF. WRITE: 'Handling the CutOff'. WRITE: / 'Event has been processed'. ENDMETHOD. ENDCLASS.
以上代码产生以下输出:
Handling the CutOff Event has been processed
SAP ABAP - 报表编程
报表是以组织结构形式呈现的数据。许多数据库管理系统都包含一个报表编写器,使您可以设计和生成报表。SAP应用程序支持报表创建。
经典报表是通过在循环内使用WRITE语句中的输出数据创建的。它们不包含任何子报表。SAP还提供一些标准报表,例如用于跨客户端复制表的RSLTCOP和用于显示实例参数的RSPARAM。
这些报表只有一个屏幕作为输出。我们可以使用各种事件,例如INITIALIZATON & TOP-OF-PAGE来创建经典报表,并且每个事件在创建经典报表期间都有其自身的意义。每个事件都与特定用户操作相关联,并且仅在用户执行该操作时才触发。
下表描述了事件和描述:
序号 | 事件 & 描述 |
---|---|
1 | INITIALIZATON 在显示选择屏幕之前触发。 |
2 | AT SELECTION-SCREEN 在处理选择屏幕上的用户输入后触发。此事件在程序执行之前验证用户输入。处理用户输入后,选择屏幕保持活动状态。 |
3 | START-OF-SELECTION 仅在选择屏幕处理结束后触发;也就是说,当用户单击选择屏幕上的“执行”图标时。 |
4 | END-OF-SELECTION 在执行START-OF-SELECTON事件中的最后一个语句后触发。 |
5 | TOP-OF-PAGE 由第一个WRITE语句触发,以在新页面上显示数据。 |
6 | END-OF-PAGE 触发以在报表的页面末尾显示文本。请注意,此事件是创建报表时的最后一个事件,应与REPORT语句的LINE-COUNT子句结合使用。 |
示例
让我们创建一个经典报表。我们将使用ABAP编辑器中的一系列语句来显示存储在标准数据库MARA(包含一般物料数据)中的信息。
REPORT ZREPORT2 LINE-SIZE 75 LINE-COUNT 30(3) NO STANDARD PAGE HEADING. Tables: MARA. TYPES: Begin of itab, MATNR TYPE MARA-MATNR, MBRSH TYPE MARA-MBRSH, MEINS TYPE MARA-MEINS, MTART TYPE MARA-MTART, End of itab. DATA: wa_ma TYPE itab, it_ma TYPE STANDARD TABLE OF itab. SELECT-OPTIONS: MATS FOR MARA-MATNR OBLIGATORY. INITIALIZATION. MATS-LOW = '1'. MATS-HIGH = '500'. APPEND MATS. AT SELECTION-SCREEN. . IF MATS-LOW = ' '. MESSAGE I000(ZKMESSAGE). ELSEIF MATS-HIGH = ' '. MESSAGE I001(ZKMESSAGE). ENDIF. TOP-OF-PAGE. WRITE:/ 'CLASSICAL REPORT CONTAINING GENERAL MATERIAL DATA FROM THE TABLE MARA' COLOR 7. ULINE. WRITE:/ 'MATERIAL' COLOR 1, 24 'INDUSTRY' COLOR 2, 38 'UNITS' COLOR 3, 53 'MATERIAL TYPE' COLOR 4. ULINE. END-OF-PAGE. START-OF-SELECTION. SELECT MATNR MBRSH MEINS MTART FROM MARA INTO TABLE it_ma WHERE MATNR IN MATS. LOOP AT it_ma into wa_ma. WRITE:/ wa_ma-MATNR, 25 wa_ma-MBRSH, 40 wa_ma-MEINS, 55 wa_ma-MTART. ENDLOOP. END-OF-SELECTION. ULINE. WRITE:/ 'CLASSICAL REPORT HAS BEEN CREATED' COLOR 7. ULINE. SKIP.
以上代码生成的输出包含来自标准表MARA的一般物料数据:
SAP ABAP - 对话编程
对话框编程处理多个对象的发展。所有这些对象都与主程序分层链接,并且按顺序执行。对话框程序开发利用ABAP工作台中的工具。这些工具与标准SAP应用程序开发中使用的工具相同。
以下是对话框程序的主要组成部分:
- 屏幕
- 模块池
- 子例程
- 菜单
- 事务
工具集
应通过对象浏览器(事务:SE80)开发对话框程序,以便所有对象都链接到主程序,而无需显式指向每个对象。高级导航技术增强了从一个对象移动到另一个对象的过程。
屏幕由屏幕属性、屏幕布局、字段和流程逻辑组成。模块池包含放置在对话框程序的包含程序中的模块化语法。这些模块可以由流程逻辑调用,该流程逻辑由对话框处理器处理。
创建新的对话框程序
步骤1 - 在事务SE80中,从下拉列表中选择“程序”,并为您的自定义SAP程序输入Z名称,例如“ZSCREENEX”。
步骤2 - 按Enter键,选择“With TOP INCL”,然后单击“是”按钮。
步骤3 - 为您的顶级包含程序输入名称“ZSCRTOP”,然后单击绿色勾号。
步骤4 - 在属性屏幕中,只需输入标题并单击保存按钮。
向对话框程序添加屏幕
步骤1 - 要向程序添加屏幕,请右键单击程序名称,然后选择“创建”→“屏幕”选项。
步骤2 - 输入屏幕编号“0211”,然后单击绿色勾号。
步骤3 - 在下一个屏幕中,输入简短标题,设置为普通屏幕类型,然后单击顶部应用程序工具栏上的保存按钮。
屏幕布局和添加“Hello World”文本
步骤1 - 单击应用程序工具栏中的布局按钮,将出现屏幕绘制器窗口。
步骤2 - 添加文本字段并输入一些文本,例如“Hello World”。
步骤3 - 保存并激活屏幕。
创建事务
步骤1 - 要为您的程序创建事务代码,只需右键单击程序名称,然后选择“创建”→“事务”选项,并输入事务代码“ZTRANEX”。
步骤2 - 输入事务文本、程序和您刚刚创建的屏幕(ZSCREENEX和0211),并在“GUI支持”部分选中“SAPGUI for Windows”复选框。
执行程序
保存并激活所有内容。您可以执行程序。程序执行时,您输入的文本将显示在屏幕上,如下面的屏幕截图所示。
SAP ABAP - 智能表单
SAP Smart Forms工具可用于打印和发送文档。此工具可用于开发表单、PDF文件、电子邮件和互联网文档。该工具提供了一个接口来构建和维护表单的布局和逻辑。SAP还提供了一些用于业务流程的表单,例如那些用于客户关系管理 (CRM)、销售和分销 (SD)、财务会计 (FI) 和人力资源 (HR) 的表单。
此工具允许您使用简单的图形工具来修改表单,而无需使用任何编程工具。这意味着没有编程知识的用户可以轻松地为业务流程配置这些表单数据。
在Smart Form中,数据是从静态表和动态表中检索的。表标题和小计由触发的事件指定,然后在最终输出之前对数据进行排序。Smart Form允许您合并图形,这些图形可以作为表单的一部分显示,也可以作为背景显示。您也可以在打印表单时根据需要隐藏背景图形。
SAP系统中提供的一些标准Smart Forms示例如下:
SF_EXAMPLE_01代表包含客户航班预订的表格输出的发票。
SF_EXAMPLE_02代表类似于SF_EXAMPLE_01的发票,但包含小计。
SF_EXAMPLE_03指定类似于SF_EXAMPLE_02的发票,但在应用程序程序中可以选择多个客户。
创建表单
让我们使用SAP Smart Forms工具创建一个表单。在本教程中,您还将学习如何在Smart Form中添加节点以及如何测试表单。这里我们首先创建SF_EXAMPLE_01表单的副本。SF_EXAMPLE_01表单是SAP系统中提供的标准Smart Form。
步骤 1 − 智能表单构建器是用于构建智能表单的主要界面。它位于 SAP 智能表单的初始屏幕上。我们需要在命令字段中输入“SMARTFORMS”事务代码以打开 SAP 智能表单的初始屏幕。在此屏幕上,在“表单”字段中输入表单名称 SF_EXAMPLE_01。
步骤 2 − 选择智能表单→复制或单击“复制”图标以打开“复制表单或文本”对话框。
步骤 3 − 在“目标对象”字段中,输入新表单的名称。名称必须以字母 Y 或 Z 开头。在本例中,表单的名称为“ZSMM1”。
步骤 4 − 单击“继续”图标或在“复制表单或文本”对话框中按 ENTER 键,以便创建 ZSMM1 表单作为预定义表单 SF_EXAMPLE_01 的副本。
步骤 5 − 单击“保存”图标。表单的名称将显示在 SAP 智能表单初始屏幕上的“表单”字段中。
步骤 6 − 单击 SAP 智能表单初始屏幕上的“创建”按钮。ZSMM1 表单将显示在表单构建器中。
步骤 7 − 将创建具有主窗口的第一个草稿页。新表单的所有组件都基于预定义表单 SF_EXAMPLE_01。您只需单击导航菜单中的节点即可查看其内容。
在表单中创建文本节点
步骤 1 − 在 SAP 表单构建器屏幕的更改模式下打开表单,然后右键单击“第一页”节点中的“主窗口”选项,并从上下文菜单中选择“创建”→“文本”。
步骤 2 − 将“文本”字段中的文本修改为“My_Text”,将“含义”字段中的文本修改为“Text_Demo”。在表单构建器中心框架的文本编辑框中输入文本“Hello TutorialsPoint.....”,如下图所示:
步骤 3 − 单击“保存”按钮保存节点。
步骤 4 − 分别单击“激活”和“测试”图标来激活和测试节点。将显示函数构建器的初始屏幕。
步骤 5 − 单击“激活”和“执行”图标来激活和测试函数模块。函数模块的参数将显示在函数构建器的初始屏幕上。
步骤 6 − 单击“执行”图标执行函数模块。将出现“打印”对话框。
步骤 7 − 将输出设备指定为“LP01”,然后单击“打印预览”按钮。
以上步骤将产生以下输出:
SAP ABAP - SAPscript
SAP 系统的 SAPscript 工具可用于构建和管理业务表单,例如发票和采购订单。SAPscript 工具提供了许多模板,在很大程度上简化了业务表单的设计。
SAP 系统附带标准 SAPscript 表单,这些表单随 SAP 标准客户端(通常为客户端 000)一起交付。以下是随客户端 000 一起交付的标准 SAPscript 表单的一些示例:
序号 | 表单名称和说明 |
---|---|
1 | RVORDER01 销售订单确认单 |
2 | RVDELNOTE 装箱单 |
3 | RVINVOICE01 发票 |
4 | MEDRUCK 采购订单 |
5 | F110_PRENUM_CHCK 预编号支票 |
SAPscript 表单的结构包含两个主要组件:
内容 − 这可以是文本(业务数据)或图形(公司徽标)。
布局 − 这由表单内容显示的一组窗口定义。
SAPscript – 表单绘制器工具
表单绘制器工具提供 SAPscript 表单的图形布局和各种操作表单的功能。在下面的示例中,我们将通过复制其布局结构从标准 SAPscript 表单 RVINVOICE01 创建发票表单,并通过访问表单绘制器工具来显示其布局。
步骤 1 − 打开表单绘制器。您可以通过导航 SAP 菜单或使用 SE71 事务代码来请求屏幕。
步骤 2 − 在表单绘制器请求屏幕中,分别在“表单”和“语言”字段中输入 SAPscript 表单的名称和语言。让我们分别在这些字段中输入“RVINVOICE01”和“EN”。
步骤 3 − 在“子对象”组框中选择“页面布局”单选按钮。
步骤 4 − 选择“实用程序”→“从客户端复制”以创建 RVINVOICE01 表单的副本。“在客户端之间复制表单”屏幕将出现。
步骤 5 − 在“在客户端之间复制表单”屏幕中,在“表单名称”字段中输入表单的原始名称“RVINVOICE01”,在“源客户端”字段中输入源客户端号“000”,在“目标表单”字段中输入目标表单的名称“ZINV_01”。确保其他设置保持不变。
步骤 6 − 接下来,单击“在客户端之间复制表单”屏幕中的“执行”图标。“创建对象目录条目”对话框将出现。单击“保存”图标。
ZINV_01 表单将从 RVINVOICE01 表单复制,并在“在客户端之间复制表单”屏幕中显示,如下面的快照所示:
步骤 7 − 单击两次后退图标,然后导航回到表单绘制器:请求屏幕,其中包含已复制表单 ZINV_01 的名称。
步骤 8 − 单击“显示”按钮后,“表单 ZINV_01:第一页布局”窗口和“表单:更改页面布局:ZINV_01”屏幕将出现,如下面的屏幕截图所示。
步骤 9 − “表单 ZINV_01:第一页布局”窗口显示表单的初始布局。表单的布局包含五个窗口:HEADER、ADDRESS、INFO、INFO1 和 MAIN。这些窗口的描述可以在 PC 编辑器中访问。
例如,只需选择 MAIN 窗口并单击“表单:更改页面布局:ZINV_01”屏幕中的“文本”图标,您就可以查看所有边距值,如下面的屏幕截图所示:
SAP ABAP - 用户出口
客户出口可以被认为是 SAP 标准程序的挂钩。我们不需要访问密钥来编写代码,也不需要修改 SAP 标准程序。这些出口没有任何功能,它们是空的。可以添加业务逻辑以满足各种客户需求。但是,并非所有程序都提供客户出口。
标准事务的客户出口
以下是关于标准事务的查找客户出口的步骤。让我们确定 MM01(物料主数据创建)中可用的客户出口。
步骤 1 − 转到事务 MM01,并通过转到菜单栏→系统→状态来识别 MM01 的程序名称,如上面的屏幕截图所示。
步骤 2 − 从弹出屏幕获取程序名称。程序名称为“SAPLMGMM”。
步骤 3 − 转到事务 SE38,输入程序名称并单击“显示”。
步骤 4 − 导航到转到→属性,并找出此程序名称的包。
包名称为“MGA”。
步骤 5 − 转到通常用于识别客户出口的事务代码 SMOD。导航到实用程序→查找(或)您也可以直接在事务代码 SMOD 上按 Ctrl + F。
步骤 6 − 转到“查找出口”屏幕后,输入我们之前获得的包名称,然后按 F8(执行)按钮。
以上步骤将产生以下输出,其中列出了物料主数据创建中可用的出口。
SAP ABAP - 用户出口
如果标准 SAP 抽取器未提供预期的功能或所需的功能(例如授权或时间检查),则在抽取中使用用户出口。用户出口通常用于销售和分销 (SD) 模块。SAP 在销售、运输、装运和计费领域提供了许多出口。用户出口旨在在标准 SAP 无法满足所有需求时进行一些更改。
要访问销售各个领域中可用的出口,请使用以下路径转到 IMG:IMG → 销售和分销 → 系统修改 → 用户出口。对销售各个领域中每个出口的文档进行了详尽的解释。
例如,如果您想查找销售凭证处理(合同、报价或销售订单)中的用户出口,请按照上述路径继续展开节点销售中的用户出口→用户出口。单击图标文档以查看销售凭证处理中可用的所有用户出口。
序号 | 用户出口和说明 |
---|---|
1 | USEREXIT_FIELD_MODIFICATION 用于修改屏幕属性。 |
2 | USEREXIT_SAVE_DOCUMENT 在用户单击“保存”时帮助执行操作。 |
3 | USEREXIT_SAVE_DOCUMENT_PREPARE 非常有用,可以检查输入字段,在字段中放入任何值,或向用户显示弹出窗口并确认文档。 |
4 | USEREXIT_MOVE_FIELD_TO_VBAK 当用户标头更改移动到标头工作区时使用。 |
5 | USEREXIT_MOVE_FIELD_TO_VBAP 当用户项目更改移动到 SAP 项目工作区时使用。 |
用户出口与客户出口具有相同的目的,但它们仅适用于 SD 模块。出口实现为对函数模块的调用。用户出口是对 SAP 标准程序的修改。
示例
REPORT ZUSEREXIT1. TABLES: TSTC, TSTCT, TADIR, TRDIR, TFDIR, ENLFDIR, MODSAPT, MODACT. DATA: JTAB LIKE TADIR OCCURS 0 WITH HEADER LINE, field1(30), v_devclass LIKE TADIR-devclass. PARAMETERS: P_TCODE LIKE TSTC-tcode OBLIGATORY. SELECT SINGLE * FROM TSTC WHERE tcode EQ P_TCODE. IF SY-SUBRC EQ 0. SELECT SINGLE * FROM TADIR WHERE pgmid = 'R3TR' AND object = 'PROG' AND obj_name = TSTC-pgmna. MOVE TADIR-devclass TO v_devclass. IF SY-SUBRC NE 0. SELECT SINGLE * FROM TRDIR WHERE name = TSTC-pgmna. IF TRDIR-subc EQ 'F'. SELECT SINGLE * FROM TFDIR WHERE pname = TSTC-pgmna. SELECT SINGLE * FROM ENLFDIR WHERE funcname = TFDIR-funcname. SELECT SINGLE * FROM TADIR WHERE pgmid = 'R3TR' AND object = 'FUGR' AND obj_name EQ ENLFDIR-area. MOVE TADIR-devclass TO v_devclass. ENDIF. ENDIF. SELECT * FROM TADIR INTO TABLE JTAB WHERE pgmid = 'R3TR' AND object = 'SMOD' AND devclass = v_devclass. SELECT SINGLE * FROM TSTCT WHERE sprsl EQ SY-LANGU AND tcode EQ P_TCODE. FORMAT COLOR COL_POSITIVE INTENSIFIED OFF. WRITE:/(19) 'Transaction Code - ', 20(20) P_TCODE, 45(50) TSTCT-ttext. SKIP. IF NOT JTAB[] IS INITIAL. WRITE:/(95) SY-ULINE. FORMAT COLOR COL_HEADING INTENSIFIED ON. WRITE:/1 SY-VLINE, 2 'Exit Name', 21 SY-VLINE , 22 'Description', 95 SY-VLINE. WRITE:/(95) SY-ULINE. LOOP AT JTAB. SELECT SINGLE * FROM MODSAPT WHERE sprsl = SY-LANGU AND name = JTAB-obj_name. FORMAT COLOR COL_NORMAL INTENSIFIED OFF. WRITE:/1 SY-VLINE, 2 JTAB-obj_name HOTSPOT ON, 21 SY-VLINE , 22 MODSAPT-modtext, 95 SY-VLINE. ENDLOOP. WRITE:/(95) SY-ULINE. DESCRIBE TABLE JTAB. SKIP. FORMAT COLOR COL_TOTAL INTENSIFIED ON. WRITE:/ 'No of Exits:' , SY-TFILL. ELSE. FORMAT COLOR COL_NEGATIVE INTENSIFIED ON. WRITE:/(95) 'User Exit doesn’t exist'. ENDIF. ELSE. FORMAT COLOR COL_NEGATIVE INTENSIFIED ON. WRITE:/(95) 'Transaction Code Does Not Exist'. ENDIF. AT LINE-SELECTION. GET CURSOR FIELD field1. CHECK field1(4) EQ 'JTAB'. SET PARAMETER ID 'MON' FIELD sy-lisel+1(10). CALL TRANSACTION 'SMOD' AND SKIP FIRST SCREEN.
在处理过程中,输入事务代码“ME01”并按 F8(执行)按钮。以上代码将产生以下输出:
SAP ABAP - 业务附加功能 (Business Add-Ins)
在某些情况下,需要在软件应用程序中预定义特殊函数以增强各种应用程序的功能。许多 Microsoft Excel 加载项都可以提高 MS Excel 的功能。类似地,SAP 通过提供称为 BADI 的业务附加功能来促进一些预定义的功能。
BADI 是一种增强技术,它使 SAP 程序员、用户或特定行业能够向 SAP 系统中的现有程序添加一些附加代码。我们可以使用标准或自定义逻辑来改进 SAP 系统。必须首先定义 BADI,然后才能实现它以增强 SAP 应用程序。在定义 BADI 时,将创建一个接口。BADI 由此接口实现,而接口又由一个或多个适配器类实现。
BADI 技术在两个方面不同于其他增强技术:
- 增强技术只能实现一次。
- 许多客户可以同时使用此增强技术。
您还可以创建过滤器 BADI,这意味着 BADI 是基于过滤数据的,而增强技术无法实现这一点。在 SAP Release 7.0 中,BADI 的概念已重新定义,目标如下:
通过在 ABAP 语言中添加两个新元素“GET BADI”和“CALL BADI”来增强 SAP 系统中的标准应用程序。
为增强 SAP 系统中的标准应用程序提供更多灵活的功能,例如上下文和过滤器。
创建BADI时,它包含一个接口和其他附加组件,例如菜单增强和屏幕增强的功能代码。创建BADI允许客户在标准SAP应用程序中包含他们自己的增强功能。增强功能、接口和生成的类位于合适的应用程序开发命名空间中。
因此,BADI可以被认为是一种增强技术,它使用ABAP对象在SAP组件中创建“预定义点”。然后,这些预定义点由各个行业解决方案、国家变体、合作伙伴和客户来实现,以满足他们的特定需求。SAP实际上在4.6A版本中引入了BADI增强技术,并且该技术在7.0版本中再次进行了重新实现。
SAP ABAP - Web Dynpro
用于ABAP的Web Dynpro (WD)是由SAP AG开发的SAP标准用户界面技术。它可用于在使用SAP开发工具和概念的SAP ABAP环境中开发基于Web的应用程序。它提供了一个前端Web用户界面,可以直接连接到后端SAP R/3系统,以访问数据和报告功能。
用于ABAP的Web Dynpro由一个运行时环境和一个图形化开发环境组成,该环境具有集成在ABAP工作台(事务:SE80)中的特定开发工具。
Web Dynpro架构
下图显示了Web Dynpro的整体架构:
关于Web Dynpro,需要注意以下几点:
Web Dynpro是SAP NetWeaver的用户界面编程模型。
所有Web Dynpro应用程序都按照模型-视图-控制器(MVC)编程模型进行结构化。
模型定义了与主系统的接口,Web Dynpro应用程序可以访问系统数据。
视图负责在Web浏览器中显示数据。
控制器位于视图和模型之间。控制器格式化要在视图中显示的模型数据。它处理用户进行的用户输入并将其返回给模型。
优势
Web Dynpro为应用程序开发人员提供了以下优势:
使用图形工具可显著减少实施工作量。
通过使用组件实现重用和更好的可维护性。
使用Web Dynpro工具可以轻松更改布局和导航。
支持用户界面可访问性。
完全集成到ABAP开发环境中。
Web Dynpro组件和窗口
组件是Web Dynpro应用程序项目的全局单元。创建Web Dynpro组件是开发新的Web Dynpro应用程序的初始步骤。创建组件后,它充当Web Dynpro对象列表中的节点。您可以在一个组件中创建任意数量的组件视图,并将它们组合到任意数量的相应Web Dynpro窗口中。
每个Web Dynpro组件至少包含一个Web Dynpro窗口。Web Dynpro窗口嵌入在前端Web应用程序中显示的所有视图。窗口在ABAP工作台的窗口编辑器中进行处理。
注意
组件视图显示应用程序的所有管理详细信息,包括描述、创建者的姓名、创建日期和分配的开发包。
Web Dynpro应用程序是ABAP工作台对象列表中的独立对象。窗口和应用程序之间的交互是由给定窗口的接口视图创建的。