ABAP 中的模块化:宏、子例程和函数模块
当您将源代码模块化时,会将一系列 ABAP 语句放入一个模块中。然后,您只需调用该模块,而无需将所有语句都放入主程序中。当程序生成时,模块化单元中的源代码被视为实际物理存在于主程序中。
模块化的必要性
- 改进程序结构。
- 易于阅读代码
- 易于维护代码
- 避免冗余并促进代码重用
各种模块化技术
- 使用宏
- 使用包含文件
- 子例程
- 函数模块
让我们详细了解它们
SAP-ABAP 宏
如果您想在程序中多次重用同一组语句,可以将其包含在宏中。
您只能在定义宏的程序中使用宏,并且只能在其定义之后的程序行中调用宏。
宏对于长时间计算或复杂的 WRITE 语句很有用。
语法
DEFINE <macro_name> 'Macro Statements END-OF-DEFINITION
宏可以使用参数 &N,其中 N = 1,2,3…
示例:-
DATA: number1 TYPE I VALUE 1. DEFINE increment. ADD 1 to &1. WRITE &1. END-OF-DEFINITION. Increment number1. WRITE number1.
输出:2
包含程序
包含程序仅用于模块化源代码,没有参数接口。
包含程序允许您在不同的程序中使用相同的源代码。如果您有想要在不同程序中使用的冗长数据声明,它们会很有用。
语法
Include <include program Name>
注意事项
- 包含程序不能调用自身。
- 包含程序必须包含完整的语句。
示例
INCLUDE ZILX0004. WRITE: / 'User', SY-UNAME,/ 'Date', SY-DATUM. ================================ PROGRAM ZRPM0001. INCLUDE ZILX0004.
子例程
子例程是您可以在任何 ABAP 程序中定义并从任何程序中调用的过程。子例程通常在内部调用,也就是说,它们包含经常在本地使用的代码段或算法。如果您希望某项功能在整个系统中可重用,请使用函数模块。
语法-
FORM <Subroutine> [<pass>]. <Statement block>. ENDFORM.
<子例程> = 子例程的名称
<pass> = 正在传递的参数
子例程的类型
- 内置
- 在被调用的同一程序中定义的子例程。
- 可以访问主 ABAP/4 程序中声明的所有数据对象。
- 外部
- 在被调用程序外部定义的子例程。
- 需要使用 <pass> 选项或在内存的公共部分声明数据对象。
调用子例程
内部子例程
PERFORM <subroutine> [<pass>]
<subroutine> = 子例程的名称
<pass> = 正在传递的参数
主程序中声明的数据自动可用。
外部子例程
PERFORM <subroutine>(<Program>) [<pass>]. PERFORM <subroutine> (<Program>) [<pass>] [IF FOUND]. PERFORM (<subroutine>) IN PROGRAM (<Program>) [<pass>] [IF FOUND]. PERFORM <index> OF <subroutine1> <subroutine2> <subroutine3> [<pass>].
注意事项
- 子例程中允许嵌套调用(即 FORM … ENDFORM 中的 PERFORM)。
- 也可能进行递归调用。
- 要定义局部数据,请在 FORM 之后使用 DATA 语句。每次进入子例程时,数据都会重新创建(带有初始值),并在结束时释放(从堆栈中)。
- 要定义子例程中使用的全局数据,请在 FORM 之后使用 LOCAL 语句。这些值在进入子例程时保存,然后在结束时释放(从堆栈中)
函数模块
函数模块是任何人都可以使用的通用 ABAP/4 例程。事实上,有大量标准函数模块可用。
函数模块被组织成函数组:逻辑相关函数的集合。函数模块始终属于一个函数组。
语法-
FUNCTION <function module> <Statements> ENDFUNCTION.
与函数模块相关的重要信息
- 管理
- 导入/更改/导出参数。
- 表参数/异常。
- 文档
- 源代码 – L<fgrp>U01。<fgrp> 是函数组
- 全局数据 – L<fgrp>TOP。函数组的全局数据 – 在函数组中的函数模块之间可访问。
- 主程序 – SAPL<fgrp>。包含该函数组所有包含文件的列表
调用函数模块
要调用函数模块,请使用 CALL FUNCTION 语句
CALL FUNCTION <module> [EXPORTING f1 = a 1.... f n = a n] [IMPORTING f1 = a 1.... f n = a n] [CHANGING f1 = a 1.... f n = a n] [TABLES f1 = a 1.... f n = a n] [EXCEPTIONS e1 = r 1.... e n = r n [ERROR_MESSAGE = r E] [OTHERS = ro]].
函数组
函数组是函数模块的容器。事实上,有大量标准函数组。
函数组中的所有函数模块都可以访问该组的全局数据。
与可执行程序(类型 1)和 模块池(类型 M)一样,函数组可以包含屏幕、选择屏幕和列表。
注意事项
- 函数组无法执行。
- 函数组的名称最长可达 26 个字符。
- 当您创建函数组或函数模块时,主程序和包含程序会自动生成。
- 函数组封装数据。
如何创建函数组
- 转到事务 SE80。
- 在下拉列表中选择程序。
- 写入您要创建的函数组的名称。通常,用户创建的函数组以“Z”开头。例如 – <Z_FUNCTION_GROUP_NAME>。按回车键。
- 请注意,如果用户勾选创建 TOP 包含的选项,则默认创建 TOP 包含。
如何创建函数模块
- 创建函数组(例如“ZCAL”)。
- 创建函数模块,设置属性(例如函数组、应用程序、简短文本和处理类型)并保存。
- 包含文件“LZCALU01”将包含第一个函数模块的源代码。
- 包含文件“LZCALTOP”将包含全局数据。
- 主程序“SAPLZCAL”包含
- 全局数据包含文件“LZCALTOP”
- 函数模块包含文件“LZCALUXX”
- 用户定义的包含文件“LZCALF..”、“LZCALO..”和“LZCALI..”
- 定义接口参数和异常
- 编写源代码
- 激活函数模块
- 测试函数模块 – 单独测试和调试
- 文档化和发布函数模块
这就是 ABAP 模块化的全部内容。