ABAP模块化:宏、子例程和函数模块

⚡ 智能摘要

ABAP 中的模块化将一系列语句封装成一个可重用的单元,主程序只需调用该单元即可。本页解释了宏、包含程序、子例程、函数模块和函数组,并提供了每种技术的语法、示例和选择标准。

  • 🧩 核心原则: 模块化单元的生成方式如同其源代码实际存在于调用程序中一样,因此结构得到改善,而无需付出运行时成本。
  • 宏: 使用 DEFINE 和 END-OF-DEFINITION 定义,只能在定义它的程序内部使用,并且只能在定义行之后使用。
  • 📄 包含程序: 它不带任何参数接口,其存在的唯一目的就是在多个程序之间共享源代码,例如长数据声明。
  • 🔁 子程序: 使用 FORM 和 ENDFORM 声明,使用 PERFORM 调用,适用于在单个程序内本地重用的逻辑。
  • 🧱 功能模块: 一个系统级例程,具有用于导入、导出、更改表参数和异常的类型化接口。
  • 📦 职能组: 一个容器,其全局数据由其中的每个函数模块共享,并由其 TOP 和 UXX 包含自动生成。
  • 🧭 评选规则: 对于本地简写,选择宏;对于本地逻辑,选择子程序;对于需要在系统中重用的例程,选择函数模块。

ABAP中的模块化

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.

= 子程序的名称

= 正在传递的参数

子程序的类型

  1. 全内走线
    • 在被调用的同一程序中定义的子程序。
    • 可以访问主 ABAP/4 程序中声明的所有数据对象。
  2. 外置
    • 在所调用的程序之外定义的子程序。
    • 需要使用选择或在内存的公共部分声明数据对象。

调用子程序

内部子程序

PERFORM <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 中的 PERFORM … ENDFORM)。
  • 递归调用也是可能的。
  • 要定义本地数据,请在 FORM 之后使用 DATA 语句。每次进入子程序时,都会重新创建数据(使用初始值)并在结束时释放(从堆栈中)。
  • 要定义子程序中使用的全局数据,请在 FORM 后使用 LOCAL 语句。输入子程序时会保存这些值,然后在结束时释放(从堆栈中)

💡提示: 在 ABAP 对象中,子例程已被视为过时的做法。新的开发应该将可重用的逻辑放在类的方法中,并在需要远程或系统级接口时使用函数模块。

功能模块

功能模块是任何人都可以使用的通用 ABAP/4 例程。事实上,有大量的标准功能模块可用。

功能模块被组织成功能组:逻辑相关功能的集合。功能模块始终属于功能组。

句法-

FUNCTION <function module>

<Statements>

ENDFUNCTION.

与功能模块相关的重要信息

  • 行政部
  • 导入/更改/导出参数。
  • 表参数/异常。
  • 文件记录
  • 源代码——L U01。是函数组
  • 全球数据 – L TOP.功能组的全局数据 - 可跨功能组中的功能模块访问。
  • 主要程序 – SAP大号. 包含该函数组的所有包含文件的列表

调用功能模块

要调用功能模块,请使用 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 个字符。
  • 当创建功能组或功能模块时,主程序和包含程序会自动生成。
  • 函数组封装数据。

如何创建函数组

  1. 转到事务 SE80。
  2. 在下拉菜单中选择程序。
  3. 写下您要创建的函数组的名称。通常,用户创建的函数组以“Z”开头。例如 – . 按 Enter 键。
  4. 请注意,如果用户选中创建 TOP 包含的选项,则默认创建 TOP 包含。

如何创建功能模块

  1. 创建一个函数组(例如“ZCAL”)。
  2. 创建函数模块,设置属性(函数组、应用程序、简短文本和流程类型),然后保存。
  3. 包含文件“LZCALU01”将包含第一个功能模块的源代码。
  4. 包含文件“LZCALTOP”将包含全局数据。
  5. 主程序“SAP“LZCAL” 包含
    • 全局数据包含文件“LZCALTOP”
    • 功能模块包含文件“LZCALUXX”
    • 用户定义包含文件“LZCALF..”、 “LZCALO..” 和“LZCALI..”
  6. 定义接口参数和异常
  7. 编写源代码
  8. 激活功能模块
  9. 功能模块测试 – 单项测试与调试
  10. 记录并发布功能模块

如何选择合适的模块化技术

这四种技术之间存在重叠,因此最终决定取决于重用范围以及是否需要参数接口。

技术 重用范围 参数接口 最适合用于
定义行之后的一个程序 位置占位符 &1 至 &9 简短的重复语句、冗长的计算、复杂的 WRITE 输出
包含程序 任何命名包含的程序 没有 共享数据声明和共享源代码
子程序(FORM) 本地或外部,使用 PERFORM … IN PROGRAM 使用、更改、表格 同一程序内频繁重复使用的逻辑
功能模块 整个系统,包括远程通话 导入、导出、更改、表、异常 应用程序之间共享的例程,并封装在函数组中。

一条简短的规则涵盖了大多数情况:在同一程序内部使用宏来实现简写,使用包含文件来实现共享声明,使用子例程来实现局部逻辑,而当例程需要能够从系统中的任何位置调用时,则使用函数模块。这就是 ABAP 模块化的全部内容。

常见问题

宏在生成时展开,并且只能在定义它的程序内部运行。子程序是一个具有类型化参数接口的实际过程,也可以使用 PERFORM 函数从另一个程序调用。

处理类型设置为“远程启用模块”的函数模块可以从另一个模块调用。 SAP 系统或外部应用程序都会调用此函数。其参数必须按值传递,异常情况将作为系统故障处理。

由于宏在生成之前就已经展开,因此无法在调试器中单步执行。如果需要逐行调试,请将逻辑移至子程序或方法中,并尽量将宏限制在简短的语句中。

ABAP 开发工具内置的 AI 代码助手可以根据简单的描述自动生成函数模块框架、参数接口和异常处理规则。开发人员仍然需要审核逻辑、激活模块并在传输前进行测试。

人工智能工具会扫描程序,检测重复的代码块,并建议应该在何处删除子程序、方法或函数模块。trac泰德。该建议加快了重构速度,但仍然需要进行单元测试以确认行为是否一致。

总结一下这篇文章: