程序类型与模块化

程序类型与模块化 (★★)

#abap-basics #program-structure

ABAP 程序结构

每个 ABAP 程序由四个结构部分组成。实际包含哪些部分取决于程序类型。

1
2
3
4
5
6
7
8
9
+=============================================+
| 引导语句(Introductory Statement) | <- 第一条语句(展开包含后)
+=============================================+
| 全局声明(Global Declarations) | <- DATA, CONSTANTS, TYPES, CLASS DEF, INTERFACE DEF
+---------------------------------------------+
| 实现(Implementations) | <- 局部类方法实现(CLASS ... IMPLEMENTATION)
+---------------------------------------------+
| 处理块(Processing Blocks) | <- 事件块、对话模块、过程
+=============================================+
📌处理块是不可分割的
处理块是一个不可分割的程序单元,必须连续编写。ABAP 中恰好有三种处理块类型。

处理块类型

类型 引入方式 结束方式 调用方
事件块 事件关键字(如 START-OF-SELECTION 由下一个处理块关键字隐式结束 ABAP 运行时环境
对话模块 MODULE ... ENDMODULE 显式 ENDMODULE 运行时环境在屏幕处理期间(流逻辑)
过程 FORM ... ENDFORMFUNCTION ... ENDFUNCTION、方法 显式结束关键字 从另一个处理块显式调用
💡事件块不能在源代码中调用
事件块只能由 ABAP 运行时环境在程序执行期间特定时间调用。不能通过编程方式调用。

程序类型

引导语句

程序类型 引导语句 说明
可执行程序 REPORT name ... [MESSAGE-ID id]. 可附加列表输出选项
函数组 FUNCTION-POOL name ... [MESSAGE-ID id]. 可附加列表输出选项
模块池 PROGRAM name [MESSAGE-ID id].
子程序池 (无单独语句)
类池(全局类) CLASS-POOL [MESSAGE-ID id]. 由类构建器生成
接口池(全局接口) INTERFACE-POOL. 由类构建器生成
类型池(类型组) TYPE-POOL name.
⚠️引导语句 vs 程序属性
引导语句不一定与程序属性中的程序类型匹配。编辑时只更改附加项,不要更改语句本身,以避免意外行为。

各程序类型允许的全局声明

声明 可执行程序 函数组 模块池 子程序池 类池 接口池 类型池
局部数据类型 是(签名+局部) 是(仅签名)
数据对象
常量 是(仅签名) 是(仅签名)
局部类
局部接口
💡接口池和类型池是纯声明性的
全局接口和类型组仅是数据类型和常量的集合。不能包含数据对象、局部类或局部接口。

各程序类型允许的处理块

处理块 可执行程序 函数组 模块池 子程序池 类池 接口池 类型池
事件块 完整集合 LOAD-OF-PROGRAM LOAD-OF-PROGRAM
对话模块
FORM(子程序)
函数模块
方法

可执行程序事件LOAD-OF-PROGRAMINITIALIZATIONSTART-OF-SELECTIONGETEND-OF-SELECTION

屏幕相关事件(可执行程序、函数组和模块池可用):

  • Dynpro:PBOPAIPOHPOV
  • 选择屏幕:AT SELECTION-SCREEN OUTPUTAT SELECTION-SCREEN
  • 列表:TOP-OF-PAGEEND-OF-PAGEAT LINE-SELECTIONAT USER-COMMAND
📌面向对象的程序类型限制子程序
子程序(FORM)不允许在类池、接口池或类型池中使用。

包含程序(Include Programs)

包含程序将 ABAP 源代码拆分为独立的仓库对象。它们不能有引导语句,也不能独立生成。

1
2
3
4
5
6
7
8
9
10
11
函数组 ZFG_EXAMPLE (FUNCTION-POOL)
|
+-- LZFG_EXAMPLETOP <-- 顶部包含(全局声明,TABLES, TYPES, DATA)
+-- LZFG_EXAMPLEUXX <-- 包含的包含(包含 INCLUDE 语句)
| +-- LZFG_EXAMPLEU01 <-- 函数模块 1
| +-- LZFG_EXAMPLEU02 <-- 函数模块 2
+-- LZFG_EXAMPLEF01 <-- FORM 例程(PERFORM)
+-- LZFG_EXAMPLEF02 <-- 额外的 FORM 例程
+-- LZFG_EXAMPLEO01 <-- PBO 模块
+-- LZFG_EXAMPLEI01 <-- PAI 模块
+-- LZFG_EXAMPLEE01 <-- 事件块

包含程序命名规范

后缀 内容 示例
TOP 全局声明 LZFG_EXAMPLETOP
Uxx 函数模块 LZFG_EXAMPLEU01
Fxx FORM 例程 LZFG_EXAMPLEF01
Oxx PBO 模块 LZFG_EXAMPLEO01
Ixx PAI 模块 LZFG_EXAMPLEI01
Exx 事件块 LZFG_EXAMPLEE01
💡包含程序规则
  • 包含程序必须包含完整语句(不能是部分语句)
  • 包含程序可以集成其他包含程序,但不能包含自身
  • 包含程序不必包含完整的处理块
  • INCLUDE 是除了引导语句之外唯一允许出现在程序顶部的语句
  • 使用报表 RSINCL00 生成包含程序的引用列表

考试/测试模式

关键词/问题 答案
“哪种程序类型不能包含处理块?” 接口池和类型池(纯声明性)
“函数组和模块池可以包含哪个事件?” LOAD-OF-PROGRAM
“函数模块可以在哪里定义?” 仅在函数组中
“子程序可以在类池中使用吗?” 不可以——面向对象程序类型中不允许
“引导语句之前可以出现什么?” INCLUDE 语句
“包含程序需要引导语句吗?” 不需要——它们不能有引导语句
“事件块中的 DATA 语句是局部还是全局?” 始终是全局(常见陷阱)
“什么命名后缀表示 FORM 包含?” Fxx(如 F01F02

相关笔记