目录
[二、SUBMIT 的两种调用模式](#二、SUBMIT 的两种调用模式)
[2.1 无返回调用 --- SUBMIT](#2.1 无返回调用 — SUBMIT)
[2.2 调用并返回 --- SUBMIT AND RETURN](#2.2 调用并返回 — SUBMIT AND RETURN)
[3.1 传递 PARAMETERS(单个参数)](#3.1 传递 PARAMETERS(单个参数))
[3.2 传递 SELECT-OPTIONS(单值条件)](#3.2 传递 SELECT-OPTIONS(单值条件))
[3.3 传递选择表(RANGES / SELECT-OPTIONS)](#3.3 传递选择表(RANGES / SELECT-OPTIONS))
[3.4 其他常用 WITH 选项](#3.4 其他常用 WITH 选项)
[四、通过 ABAP 内存传递复杂数据](#四、通过 ABAP 内存传递复杂数据)
[4.1 发送方程序(调用方)](#4.1 发送方程序(调用方))
[4.2 接收方程序(被调用方)](#4.2 接收方程序(被调用方))
[4.3 重要特性](#4.3 重要特性)
[六、判断程序是否被 SUBMIT 调用](#六、判断程序是否被 SUBMIT 调用)
[七、后台执行:SUBMIT VIA JOB](#七、后台执行:SUBMIT VIA JOB)
一、前言
在 ABAP 开发中,我们经常需要在一个程序中调用另一个程序。SUBMIT 语句就是专门用于调用**可执行程序(报表程序,类型 1)**的关键字,它属于 ABAP 中的外部程序调用语句类型。
通过 SUBMIT,开发者可以在一个运行中的程序里启动另一个报表程序,实现程序间的逻辑串联、报表联查与功能复用,是 ABAP 报表开发中最常用的程序间调用手段之一。
注意 :SUBMIT 只能调用类型为 1(可执行程序) 的程序,不能调用模块池程序(类型 M)、函数组或类。
二、SUBMIT 的两种调用模式
2.1 无返回调用 --- SUBMIT
SUBMIT z_simple_program.
使用不带 AND RETURN 的 SUBMIT 时,调用程序将控制权完全移交给被调用程序,被调用程序执行结束后不再返回原程序。
执行特征:
- 调用程序中 SUBMIT 之后的所有语句都不会被执行
- 系统内部会话被调用程序取代
- 相当于 "跳转" 到目标程序运行
示例说明 :假设程序 z_calling_program 中执行了 SUBMIT z_simple_program,那么被调用程序的输出列表会直接显示,而调用程序中 SUBMIT 之后的语句(包括前面的 WRITE 缓冲)都不会输出。
2.2 调用并返回 --- SUBMIT AND RETURN
SUBMIT z_simple_program AND RETURN.
使用 SUBMIT AND RETURN 时,被调用程序执行结束后,控制权会返回 给调用程序,继续执行 SUBMIT 之后的逻辑。
执行特征:
- 被调用程序在新的内部会话中运行
- 运行结束后回到原程序继续执行
- 是实际项目中最常用的模式
调用方式对比:
| 调用类型 | 报表调用语句 | 事务码调用语句 | 是否返回原程序 | 内部会话 |
|---|---|---|---|---|
| 无返回调用 | SUBMIT |
LEAVE TO TRANSACTION |
否 | 替换当前会话 |
| 调用并返回 | SUBMIT AND RETURN |
CALL TRANSACTION |
是 | 新建内部会话 |
三、向被调用程序传递参数
SUBMIT 的核心价值在于可以通过 WITH 选项向目标程序的选择屏幕传递参数,支持单个值、范围值、选择表等多种形式。
3.1 传递 PARAMETERS(单个参数)
直接将值赋给被调用程序的 PARAMETERS 参数:
SUBMIT zmmr022
WITH p_werks = p_werks " 单个参数赋值
WITH p_bukrs = '1000' " 直接写字面量
WITH p_check = abap_true " 复选框参数
AND RETURN.
3.2 传递 SELECT-OPTIONS(单值条件)
对于选择屏幕上的 SELECT-OPTIONS,可以逐行指定 sign、option、low、high:
SUBMIT zmmr022
WITH s_matnr = ls_sto-matnr " 只传 low,默认 EQ
WITH s_charg = ls_sto-charg
AND RETURN.
3.3 传递选择表(RANGES / SELECT-OPTIONS)
对于多值选择条件,使用 WITH <seltab> IN <table> 语法将构造好的选择表整体传递:
* 构造范围表
RANGES s_carrid FOR spfli-carrid.
s_carrid-sign = 'I'.
s_carrid-option = 'EQ'.
s_carrid-low = 'LH'.
APPEND s_carrid.
s_carrid-sign = 'I'.
s_carrid-option = 'BT'.
s_carrid-low = 'AA'.
s_carrid-high = 'AZ'.
APPEND s_carrid.
* 整体传递
SUBMIT z_report WITH s_carrid IN s_carrid AND RETURN.
注意 :使用
RANGES创建的内表虽然结构与 SELECT-OPTIONS 相同,但它们不是选择屏幕的一部分,不能用于逻辑数据库,仅可用于 SUBMIT 的WITH ... IN ...参数传递。
3.4 其他常用 WITH 选项
SUBMIT z_report
WITH s_matnr IN s_matnr " 传递选择表
WITH FREE SELECTIONS texpr " 传递动态选择条件
WITHOUT SPOOL DYNPRO " 跳过假脱机对话框
VIA SELECTION-SCREEN " 先显示选择屏幕再执行
AND RETURN.
- VIA SELECTION-SCREEN:先弹出被调用程序的选择屏幕,用户可修改参数后再执行
- WITHOUT SPOOL DYNPRO:后台打印时跳过假脱机参数对话框
- WITH FREE SELECTIONS:传递动态选择条件(配合 FREE_SELECTIONS_INIT 等函数使用)
四、通过 ABAP 内存传递复杂数据
SUBMIT 的 WITH 选项只能传递选择屏幕参数,无法直接传递复杂内表、深层结构等大数据量内容。此时可以利用 ABAP/4 内存(ABAP Memory)在程序间共享数据。
ABAP/4 内存是分配给当前外部会话的存储区,同一事务内所有通过 CALL 或 SUBMIT 调用的程序都可以访问该内存。
4.1 发送方程序(调用方)
DATA: gv_text TYPE string VALUE 'Hello ABAP Memory'.
DATA: gt_data TYPE STANDARD TABLE OF sbook.
* 填充内表数据
SELECT * FROM sbook INTO TABLE gt_data UP TO 100 ROWS.
* 导出到 ABAP 内存
EXPORT gv_text = gv_text
gt_data = gt_data
TO MEMORY ID 'ZMY_DATA_ID'.
* 调用目标程序
SUBMIT z_receiver_program AND RETURN.
* 调用结束后可清理内存
FREE MEMORY ID 'ZMY_DATA_ID'.
4.2 接收方程序(被调用方)
PROGRAM z_receiver_program.
DATA: gv_text TYPE string.
DATA: gt_data TYPE STANDARD TABLE OF sbook.
* 从 ABAP 内存导入
IMPORT gv_text = gv_text
gt_data = gt_data
FROM MEMORY ID 'ZMY_DATA_ID'.
IF sy-subrc = 0.
WRITE: / '读取成功:', gv_text.
WRITE: / '数据行数:', lines( gt_data ).
ELSE.
WRITE: / '内存数据不存在'.
ENDIF.
4.3 重要特性
1、SY-SUBRC 返回规则:
- 只要指定 ID 的数据簇存在,SY-SUBRC = 0
- 即使簇中某个具体对象不存在,SY-SUBRC 仍为 0,对应目标变量保持原值
- 如果整个 ID 的数据簇不存在,SY-SUBRC = 4
2、内存作用域:
- ABAP Memory 属于外部会话级别,跨内部会话共享
- 同一用户打开的不同窗口(外部会话)之间内存隔离
- 事务结束后内存自动释放,但建议手动 FREE 避免内存残留
3、与 SAP Memory 的区别:
- ABAP Memory :使用
EXPORT/IMPORT TO MEMORY,同一外部会话内有效 - SAP Memory :使用
SET/GET PARAMETER,跨事务、跨会话的用户级内存
五、捕获被调用程序的输出列表
使用 SUBMIT ... EXPORTING LIST TO MEMORY 可以将被调用程序的输出列表保存到内存中,而不直接显示,调用方可以读取并处理该列表。
* 调用程序并将列表导出到内存
SUBMIT z_report
WITH s_matnr IN s_matnr
EXPORTING LIST TO MEMORY
AND RETURN.
* 从内存读取列表
DATA: gt_list TYPE STANDARD TABLE OF abaplist.
CALL FUNCTION 'LIST_FROM_MEMORY'
TABLES
listobject = gt_list
EXCEPTIONS
not_found = 1
OTHERS = 2.
* 将列表转换为文本
DATA: gt_text TYPE STANDARD TABLE OF char255.
CALL FUNCTION 'LIST_TO_ASCI'
TABLES
listasci = gt_text
listobject = gt_list
EXCEPTIONS
empty_list = 1
OTHERS = 2.
适用场景:
- 需要抓取标准报表输出结果进行二次处理
- 后台任务中静默执行报表并提取数据
- 避免弹出多个报表窗口影响用户体验
六、判断程序是否被 SUBMIT 调用
在实际开发中,经常需要区分程序是独立运行 还是被外部调用,从而执行不同的逻辑(例如:被调用时隐藏选择屏幕、跳过某些校验、改变输出格式等)。
使用系统字段 SY-CALLD 判断:
START-OF-SELECTION.
IF sy-calld = abap_true.
" 被外部 SUBMIT / CALL TRANSACTION 调用
gv_background_mode = abap_true.
" 可以跳过某些交互逻辑
ELSE.
" 用户直接运行程序
gv_background_mode = abap_false.
ENDIF.
典型应用场景:
- 被调用时自动跳过选择屏幕直接执行
- 被调用时不显示 ALV 工具栏按钮
- 被调用时直接返回数据而不输出列表
- 根据调用来源调整消息输出方式
七、后台执行:SUBMIT VIA JOB
SUBMIT 支持将目标程序提交到后台作业中异步执行,不阻塞当前程序:
DATA: lv_jobname TYPE tbtcjob-jobname VALUE 'Z_BACKGROUND_JOB',
lv_jobcount TYPE tbtcjob-jobcount.
* 创建后台作业
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = lv_jobname
IMPORTING
jobcount = lv_jobcount
EXCEPTIONS
OTHERS = 1.
* 将程序提交到作业中
SUBMIT z_report
WITH p_werks = '1000'
VIA JOB lv_jobname NUMBER lv_jobcount
AND RETURN.
* 释放作业,立即执行
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = lv_jobcount
jobname = lv_jobname
strtimmed = abap_true
EXCEPTIONS
OTHERS = 1.
这种方式下,被调用程序在后台工作进程中异步运行,当前程序立即继续执行,适用于耗时较长的报表任务。