程序类型与模块化
程序类型与模块化 (★★)
#abap-basics #program-structure
ABAP 程序结构
每个 ABAP 程序由四个结构部分组成。实际包含哪些部分取决于程序类型。
1 | +=============================================+ |
📌处理块是不可分割的
处理块是一个不可分割的程序单元,必须连续编写。ABAP 中恰好有三种处理块类型。
处理块类型
| 类型 | 引入方式 | 结束方式 | 调用方 |
|---|---|---|---|
| 事件块 | 事件关键字(如 START-OF-SELECTION) |
由下一个处理块关键字隐式结束 | ABAP 运行时环境 |
| 对话模块 | MODULE ... ENDMODULE |
显式 ENDMODULE |
运行时环境在屏幕处理期间(流逻辑) |
| 过程 | FORM ... ENDFORM、FUNCTION ... 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-PROGRAM、INITIALIZATION、START-OF-SELECTION、GET、END-OF-SELECTION
屏幕相关事件(可执行程序、函数组和模块池可用):
- Dynpro:
PBO、PAI、POH、POV - 选择屏幕:
AT SELECTION-SCREEN OUTPUT、AT SELECTION-SCREEN - 列表:
TOP-OF-PAGE、END-OF-PAGE、AT LINE-SELECTION、AT USER-COMMAND
📌面向对象的程序类型限制子程序
子程序(
FORM)不允许在类池、接口池或类型池中使用。包含程序(Include Programs)
包含程序将 ABAP 源代码拆分为独立的仓库对象。它们不能有引导语句,也不能独立生成。
1 | 函数组 ZFG_EXAMPLE (FUNCTION-POOL) |
包含程序命名规范
| 后缀 | 内容 | 示例 |
|---|---|---|
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(如 F01、F02) |
相关笔记
- 数据类型与数据对象 — 程序中的数据声明
- Open SQL 基础 — 可执行程序的数据库访问
- 程序调用 — 通过 SUBMIT 和 CALL TRANSACTION 调用程序
- 运行时与内存管理 — 程序类型与内存的关系
- [[_posts/SAP_MM/SCM500_采购流程/00-仪表盘/学习地图]] — 完整学习地图