子程序

子程序 (★★★)

#abap #abap-modularization

概览表

方面 详情
定义 FORM name USING ... CHANGING ...
调用 PERFORM name USING ... CHANGING ...
作用范围 仅在当前程序中局部有效
参数 USING(输入),CHANGING(双向)

定义与调用

1
2
3
4
5
6
7
8
9
10
11
12
13
" 定义
FORM calc_percentage USING pv_act TYPE i
pv_max TYPE i
CHANGING cv_result TYPE decfloat16.
IF pv_max = 0.
cv_result = 0.
ELSE.
cv_result = pv_act / pv_max * 100.
ENDIF.
ENDFORM.

" 调用
PERFORM calc_percentage USING gv_act gv_max CHANGING gv_result.

参数传递

类型 方向 传递方式
USING 输入到子程序 引用传递(默认)或值传递
CHANGING 双向 引用传递(默认)或值结果传递
⚠️默认引用传递
默认情况下,参数通过引用传递。子程序可以直接修改调用者的数据。为防止这种情况,在 FORM 定义中使用 VALUE()。

形式参数与实际参数

  • 形式参数:在 FORM 语句中定义(如 pv_act
  • 实际参数:在 PERFORM 调用中传递(如 gv_actual_value

子程序中的全局与局部数据

1
2
3
4
5
6
程序(全局作用域)
├── gv_global ← 可在 FORM 中访问
├── FORM example.
│ ├── pv_param(形式参数) ← 仅在 FORM 中
│ └── lv_local (DATA) ← 仅在 FORM 中
└── ENDFORM.
⚠️遮蔽规则
如果子程序中的局部数据对象与全局数据对象同名,则在该子程序内部,局部变量会遮蔽全局变量。

为什么优先使用局部类而非子程序

  1. 通过 IMPORTING/EXPORTING/CHANGING/RETURNING 实现更好的封装
  2. 不直接访问全局程序数据
  3. 与 ABAP Objects 兼容
  4. 现代异常处理(基于类的异常)

考试/测试模式

场景/关键词 答案
“子程序的参数类型?” 仅 USING 和 CHANGING
“可以从另一个程序调用子程序吗?” 技术上可以,但不应该这样做(违反封装原则)
“遮蔽规则?” 同名局部变量会隐藏全局变量
“子程序的更好替代方案?” 局部类方法

相关笔记