网上有关SUBMIT实现程序调用的例子稍显复杂,本文给出一个SUBMIT的小示例程序(代码见文末),实现了最简单的程序间调用及返回值,以及SAP官方文档中相关内容的翻译、解释。
本文链接:http://www.cnblogs.com/hhelibeb/p/5802398.html
转载请注明
SUBMIT - 短参考
语法
SUBMIT {rep|(name)} [USING SELECTION-SCREEN dynnr] [VIA SELECTION-SCREEN] [USING SELECTION-SET variant] [USING SELECTION-SETS OF PROGRAM prog] [WITH SELECTION-TABLE rspar] { [WITH sel1 { {{EQ|NE|CP|NP|GE|LT|LE|GT} dobj [SIGN sign]} | {[NOT] BETWEEN dobj1 AND dobj2 [SIGN sign]} | {IN rtab} }] [WITH sel2 { {{EQ|NE|CP|NP|GE|LT|LE|GT} dobj [SIGN sign]} | {[NOT] BETWEEN dobj1 AND dobj2 [SIGN sign]} | {IN rtab} }] ... } [WITH FREE SELECTIONS texpr] [LINE-SIZE width] [LINE-COUNT page_lines] { [EXPORTING LIST TO MEMORY] | [TO SAP-SPOOL SPOOL PARAMETERS pri_params [ARCHIVE PARAMETERS arc_params] WITHOUT SPOOL DYNPRO] } [[USER user] VIA JOB job NUMBER n] [AND RETURN].
效果
调用一个可执行程序。
附加项:
- {rep|(name)}
使用rep静态地指定一个程序,或者使用name动态地指定
- USING SELECTION-SCREEN dynnr
指定要访问的选择屏幕dynnr,如不使用该条目,系统调用标准选择屏幕。
- VIA SELECTION-SCREEN
显示被调用的选择屏幕。如不使用该条目,选择屏幕过程(selection screen processing)将会在后台发生。
- USING SELECTION-SET variant
选择屏幕使用变式
- USING SELECTION-SETS OF PROGRAM prog
指定使用的变式的程序
- WITH SELECTION-TABLE rspar
选择屏幕使用内表rspar中的值,内表的行结构为RSPARAMS或者RSPARAMS_255
- WITH sel1 ... WITH sel2 ...
传入单独的参数和条件值(selection criteria ) sel1, sel2....给选择屏幕:
- {EQ|NE|CP|NP|GE|LT|LE|GT} dobj [SIGN sign] - 传输一个单值和相关的操作符,以及selection table中SIGN列的设定
- [NOT] BETWEEN dobj1 AND dobj2 [SIGN sign] - 传输一个从dobj1到dobj2之间的区间和可选的操作符NOT,以及selection table中SIGN列的设定
- in rtab - 传输一个Range Table rtab
tips: Range Table
*--------------------------------------------------------------------------------------
Range Table 为系统标准内表的一种,结构与 Selection Table 一致,由 SIGN, OPTION, LOW, HIGH和条件值字段组成;
可以通过 TYPE RANGE OF 语句或 RANGES 关键字定义 Range Table。
Range Table 常用于Open SQL语句中的条件筛选,可以优化取数效率与程序性能。
*--------------------------------------------------------------------------------------
- WITH FREE SELECTIONS texpr
通过一个内表texpr向选择屏幕提供基于逻辑数据库的动态选择,内表texpr的类型是RSDS类型组中的RSDS_TEXPR
- LINE-SIZE width
使用width设置程序访问的Basic List的行宽
tips: Basic List
*--------------------------------------------------------------------------------------
Basic List: list screen的一种.
在START-OF-SELECTION事件处理块中,用WRITE语句向列表缓冲区(List Buffer)输出要显示的内容。
当该事件结束的时候,所有在列表缓冲区中的内容将被显示到一个基本列表屏幕(Basic List)上。
*--------------------------------------------------------------------------------------
- LINE-COUNT page_lines
使用设置程序访问的Basic List的页包含的行数
- EXPORTING LIST TO MEMORY
将程序访问的Basic List以行类型为ABAPLIST的内表形式保存到ABAP Memory中
- TO SAP-SPOOL
为程序访问的basic list创建一个spool request,并带有以下参数:
- SPOOL PARAMETERS pri_params - 打印参数,保存在类型为PRI_PARAMS的结构pri_params中
- ARCHIVE PARAMETERS arc_params - 归档参数,保存在类型为ARC_PARAMS的结构arc_params中
- WITHOUT SPOOL DYNPRO - 阻止打印对话框
- [USER user] VIA JOB job NUMBER n
待补充
- AND RETURN
效果:
AND RETURN通过运行时环境决定了在程序被调用后的访问对象:
- 没有AND RETURN关键字的时候,伴随着SAP LUW的退出,被访问程序的内部会话在访问队列的相同位置替代了访问程序的内部会话。一旦程序访问结束,系统返回到调用程序开始的位置 。SUBMIT上系统字段SY-CALLD复制调用程序的值。
- AND RETURN关键字在一个新的内部会话中运行程序。调用程序和当前的SAO LUW会保持存在。被调用程序运行它自己的SAP LUW。一旦程序访问结束,程序将继续执行SUBMIT语句之后的内容。
tips: SAP LUW, SY-CALLD
*--------------------------------------------------------------------------------------
SAP LUW:SAP logical unit of work(LUW)是一个逻辑单位,我们把需要完成的工作分成一个个独立的单元(LUW),每个单元包含若干操作,这些操作要么完全执行,要么完全不执行(all-or-nothing principle)。相应地,数据库层面存在更小的单元Database LUW。
SY-CALLD: 在一个调用序列中的第一个程序里为空字符串,否则为值“X”。在调用using CALL TRANSACTION,CALL DIALOG或 者SUBMIT ... AND RETURN后变为“X”。如果程序以LEAVE TO TRANSACTION或者从一个屏幕事务开始的话,则为空。使用SUBMIT(没有AND RETURN)时设定为调用它的程序的值。
*---------------------------------------------------------------------------------------
注:
- 如果在一个submit里依然有注册在当前的SAP LUW中的程序,且没有 AND RETURN,SAP LUW会在不掉用的情况下退出或者回滚程序。已注册的更新函数模块(update function modules) 保留在数据库中,但是不能再被运行。为了防止这种情形,你可以在程序调用前显式的执行语句COMMIT WORK或者ROLLBACK WORK。
- 带有AND RETURN的SUBMIT语句开启了一个新的SAP LUW,但是注意这并不会自动开启一个新的database LUW。这意味着在这个SAP LUW中使用语句 CALL FUNCTION IN UPDATE TASK或者CALL FUNCTION IN BACKGROUND TASK in the tables VB... or ARFCSSTATE and ARFCSDATA. 进行数据库会回滚全部登记项。在某些情况下,被调用程序的ROLLBACK WORK语句也会影响到暂停的SAP LUW。为了防止这点,必须在程序被调用前显式地运行database commit。这个问题不会在本地模式更新中发生。
tips: 本地模式
*---------------------------------------------------------------------------------------
更新数据库的几种模式:异步模式、同步模式、本地模式。
*---------------------------------------------------------------------------------------
异常:
- ·原因:未找到指定程序
运行时错误:LOAD_PROGRAM_NOT_FOUND
- 原因:尝试使用SIGN传输一个无效的选择值
运行时错误:SUBMIT_WRONG_SIGN
- 原因:指定程序不是一个report
运行时错误:SUBMIT_WRONG_TYPE
tips: 程序类型
*--------------------------------------------------------------------------------------
1 REPORT(报表)
M PROGRAM(屏幕程序)
F FUNCTION-POOL(函数组)
K CLASS-POOL(类组)
J CLASS-POOL(接口组)
T TYPE-POOL(类型池)
*--------------------------------------------------------------------------------------
- 原因:尝试向报表参数传输一个以上的值
运行时错误:SUBMIT_IMPORT_ONLY_PARAMETER
- 原因:尝试使用WITH sel IN itab传输一个没有和选择相适应的结构的表
运行时错误:SUBMIT_IN_ITAB_ILL_STRUCTURE
- 原因:尝试传输一个不能被转换为选择屏幕目标字段的参数
运行时错误: SUBMIT_PARAM_NOT_CONVERTIBLE
- 原因:被调用程序存在语法错误
运行时错误: SYNTAX_ERROR
程序示例:
示例包含3个程序,CALL, CALL_A和CALL_B,我们将使用CALL调用后两者。
其中,CALL_A和CALL_B均为独立可运行的REPORT程序,带有标准选择屏幕,可以将输入的数值计算后输出到屏幕。
在CALL程序中,我们可以在选择屏幕输入一个值,运行后,分别调用CALL_A和CALL_B进行数值处理,并显示在CALL的结果屏幕中,主程序代码如下:
1 REPORT ztestcall. 2 3 CONSTANTS: g_memory(30) VALUE ‘JACKYTEST‘."定义MEMORY ID 4 CONSTANTS: g_memoryb(30) VALUE ‘JACKYTESTB‘. 5 6 DATA: return_a TYPE i, 7 return_b TYPE i. 8 9 DATA: selectable LIKE TABLE OF rsparams. "选择参数内表 10 DATA: selectline LIKE LINE OF selectable. 11 12 13 SELECTION-SCREEN BEGIN OF BLOCK blk. 14 PARAMETERS: p_value TYPE i. 15 SELECTION-SCREEN END OF BLOCK blk. 16 17 18 INITIALIZATION. 19 20 START-OF-SELECTION. 21 22 selectline-selname = ‘P_VALUE‘. "选择屏幕字段名 23 selectline-kind = ‘P‘. "选择模式PARAMETER,如果是多选,设为S 24 selectline-low = p_value. "传递值 25 APPEND selectline TO selectable. 26 27 28 SUBMIT ztestcall_a WITH SELECTION-TABLE selectable AND RETURN. "调用程序后返回 29 IMPORT vala TO return_a FROM MEMORY ID g_memory. "取出ABAP内存中的数据 30 FREE MEMORY ID g_memory. "释放MEMORY ID 31 32 SUBMIT ztestcall_b WITH SELECTION-TABLE selectable AND RETURN. 33 IMPORT valb TO return_b FROM MEMORY ID g_memoryb. 34 FREE MEMORY ID g_memoryb. 35 36 SKIP. 37 38 WRITE: ‘程序call_A的运行结果是 参数 + 1 = ‘ , return_a . 39 WRITE: / ‘程序call_B的运行结果是 参数 * 3 = ‘ , return_b .
接下来是被调用的CALL_A和CALL_B,内容基本一致
1 REPORT ZTESTCALL_A. 2 3 DATA vala TYPE i. 4 CONSTANTS: g_memory(30) VALUE ‘JACKYTEST‘. 5 6 SELECTION-SCREEN BEGIN OF BLOCK BLk1. 7 PARAMETERS: p_value TYPE i. 8 SELECTION-SCREEN END OF BLOCK blk1. 9 10 INITIALIZATION. 11 12 START-OF-SELECTION. 13 14 VALA = p_value + 1. 15 16 IF SY-CALLD = ‘X‘. "判断程序是否处于被调用状态 17 18 EXPORT VALA FROM VALA TO MEMORY ID g_memory. 19 20 ELSE. 21 22 WRITE VALA. 23 24 ENDIF.
1 REPORT ztestcall_b. 2 3 DATA valb TYPE i. 4 CONSTANTS: g_memoryb(30) VALUE ‘JACKYTESTB‘. 5 6 SELECTION-SCREEN BEGIN OF BLOCK blk1. 7 PARAMETERS: p_value TYPE i. 8 SELECTION-SCREEN END OF BLOCK blk1. 9 10 INITIALIZATION. 11 12 START-OF-SELECTION. 13 14 valb = p_value * 3. 15 16 IF sy-calld <> ‘X‘. 17 18 WRITE valb. 19 20 ELSE. 21 22 EXPORT valb FROM valb TO MEMORY ID g_memoryb. "数据存储到ABAP内存 23 24 ENDIF.
运行CALL程序,输入数字2:
点击运行,直接显示两个程序的计算结果:
原创内容,转载请注明本文链接。