ABAP:SUBMIT执行其他报表并返回的数据

本文介绍了如何在ABAP中使用SUBMIT...AND RETURN调用标准报表MB5B,以获取库存数据。通过示例展示了调用过程,并将ALV输出保存至内存,便于进一步处理。测试结果显示,获取的库存数据与MB5B报表一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有些情况我们需要取一些标准报表的数据,如果自己重写比较复杂,用SUBMIT … AND RETURN可以调用标准报表并获取获取返回值。

参考:ZEROTEST69

语法:SUBMIT [程序名] WITH [调用程序屏幕的参数名]IN/=  值 AND RETURN

加上 EXPORTING LIST TO MEMORY 将程序返回的alv输出到MEMORY可以用函数取出

网上也有很多类似的例子,这里自己以MB5B测试了一个例子

列子:

 

*&---------------------------------------------------------------------*
*& Report  ZEROTEST69
*& 测试直接取MB5B 历史库存的数据
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zerotest69.
TABLES: t001w,mard,mkpf.
DATA:ls_data TYPE REF TO data.
FIELD-SYMBOLS: <lt_data> TYPE table,
<think>我们有两个需求:1.执行一个ABAP程序(可以是报表程序获取其输出结果(如屏幕输出、ALV格等)。2.在ABAP代码中实现,而不是通过事务码手动执行。在ABAP中,要执行另一个程序捕获其输出,通常有以下几种方法:方法1:使用SUBMIT...ANDRETURN语句,结合导出到内存(EXPORTINGLISTTOMEMORY)-这种方法可以捕获程序的列输出(即传统WRITE语句输出的内容)到内存,然后通过函数'LIST_FROM_MEMORY'读取。-但是,如果目标程序是ALV输出,则这种方法只能捕获列形式的输出,而无法捕获ALV控件的内容。方法2:使用RFC调用(如果目标程序是函数模块或者可以被封装成函数模块)-将目标程序改造成函数模块,然后通过RFC调用获取返回参数。方法3:使用SUBMIT...VIAJOB输出到假脱机,然后读取假脱机内容-将程序提交为后台作业,输出到假脱机(spool),然后通过读取假脱机来获取输出。方法4:使用类CL_SALV_BS_RUNTIME_INFO捕获ALV输出-专门用于捕获ALV输出的方法,通过设置CL_SALV_BS_RUNTIME_INFO来拦截ALV数据。由于问题中没有明确目标程序的类型,我们将分别说明:情况一:目标程序是传统列输出(WRITE语句)情况二:目标程序是ALV输出(REUSE_ALV_GRID_DISPLAY等)我们分别给出两种情况的示例:情况一:捕获列输出(WRITE输出)步骤:1.使用SUBMIT程序提交导出列到内存。2.使用函数模块'LIST_FROM_MEMORY'将内存中的列数据读取到内。3.处理内(即程序输出的每一行)。代码示例:```abapDATA:lt_listTYPETABLEOFchar255.SUBMITrsdbruntest"要执行程序名WITHparam='value'"传递参数ANDRETURNEXPORTINGLISTTOMEMORY.CALLFUNCTION'LIST_FROM_MEMORY'TABLESlistobject=lt_listEXCEPTIONSnot_found=1OTHERS=2.IFsy-subrc<>0."处理错误ENDIF."清除内存中的列CALLFUNCTION'FREE_MEMORY'EXPORTINGid='LIST'.```情况二:捕获ALV输出使用类CL_SALV_BS_RUNTIME_INFO,步骤:1.在调用目标程序前,设置CL_SALV_BS_RUNTIME_INFO以开始收集数据。2.提交目标程序(使用SUBMIT或直接调用功能模块等)。3.停止收集获取收集到的数据。注意:此方法只适用于使用标准ALV输出的程序。代码示例:```abapDATA:lr_dataTYPEREFTOdata,lr_typeTYPEREFTOcl_salv_bs_runtime_info.FIELD-SYMBOLS:<lt_data>TYPEANYTABLE."创建实例lr_type=cl_salv_bs_runtime_info=>get_instance()."设置模式为获取数据(而不是显示)lr_type->set(EXPORTINGdisplay=abap_false"不显示metadata=abap_falsedata=abap_true)."提交程序(这里假设程序是Z_ALV_DEMO)SUBMITzalv_demoANDRETURN."停止数据收集lr_type->set(EXPORTINGdisplay=abap_falsemetadata=abap_falsedata=abap_false)."获取数据TRY."获取数据引用lr_data=lr_type->get_data().ASSIGNlr_data->*TO<lt_data>.IF<lt_data>ISASSIGNED."现在<lt_data>就是ALV输出的内数据ENDIF.CATCHcx_salv_bs_sc_runtime_info."错误处理ENDTRY.```注意:如果目标程序不是标准ALV程序,或者使用了自定义的屏幕输出,则上述方法可能无效。方法三:通过后台作业和假脱机如果上述方法都不适用,可以考虑将程序提交到后台作业,输出到假脱机,然后读取假脱机内容。但是这种方法较为复杂,且需要处理假脱机的读取权限。步骤:1.使用SUBMIT...VIAJOB将程序提交到后台。2.获取作业号和假脱机号。3.等待作业完成。4.使用函数模块RSPO_RETURN_SPOOLJOB读取假脱机内容。由于这种方法代码较长且需要处理作业状态,这里不展开,仅作为备选方案。总结:-对于简单的列程序,使用SUBMIT...EXPORTINGLISTTOMEMORY和LIST_FROM_MEMORY。-对于ALV程序,使用CL_SALV_BS_RUNTIME_INFO捕获内数据。-其他复杂情况(如交互式程序)可能需要更复杂的方法,甚至修改目标程序以提供接口。注意:执行外部程序时,需要确保该程序在当前用户的执行权限范围内。相关问题:1.如何动态传递参数给被执行程序?2.如何捕获被调用程序中的异常?3.如何处理被调用程序中的选择屏幕参数?4.如果目标程序是事务码(即不是报表程序),如何执行获取结果?我们将针对第一个问题(动态传递参数)给出示例:在SUBMIT语句中,可以通过WITH选择屏幕参数名后面接值来传递参数。例如,如果选择屏幕有参数PARAM1,则可以使用WITHparam1='value'。另外,也可以使用动态指定参数名的方式,例如:```abapDATA:lv_param_nameTYPEstringVALUE'PARAM1',lv_valueTYPEstringVALUE'100'.SUBMITprogram_nameWITH(lv_param_name)=lv_value...```但是注意,参数名必须是选择屏幕上定义的参数名。参考文献:[^1]:ABAP帮助文档:SUBMIT语句[^2]:ABAP帮助文档:CL_SALV_BS_RUNTIME_INFO类[^3]:ABAP帮助文档:LIST_FROM_MEMORY函数模块由于我们无法提供真正的引用链接,因此请参考SAP官方文档或ABAP帮助文档。根据用户提供的引用[1]:调用外部程序的子程序时首先要利用[IFFOUND]语句检查是否存在该子程序。但是请注意,这个引用是关于调用外部程序中的子程序(PERFORM)的,而我们现在讨论的是执行整个程序获取输出。因此,这个引用不直接适用。根据用户提供的引用[2]:关于事务码的创建和程序调用,这里也不直接相关。因此,我们主要依据ABAP标准功能提供上述方法。</think>### ABAP代码执行程序返回结果的实现方法 在ABAP执行另一个程序获取其运行结果,可以通过以下两种主要方法实现: --- ### 方法一:使用 `SUBMIT` 语句捕获列输出 ```abap DATA: lt_output TYPE TABLE OF text255. " 执行目标程序捕获输出 SUBMIT ztarget_program " 要执行程序名 WITH p_param = 'value' " 传递参数 AND RETURN EXPORTING LIST TO MEMORY. " 将输出保存到内存 " 从内存读取输出结果 CALL FUNCTION 'LIST_FROM_MEMORY' TABLES listobject = lt_output EXCEPTIONS not_found = 1 OTHERS = 2. IF sy-subrc = 0. " 处理输出结果 LOOP AT lt_output ASSIGNING FIELD-SYMBOL(<line>). WRITE: / <line>. ENDLOOP. ELSE. MESSAGE '无法获取程序输出' TYPE 'E'. ENDIF. " 清除内存中的列 CALL FUNCTION 'FREE_MEMORY' EXPORTING id = 'LIST'. ``` **关键点说明**: 1. `SUBMIT...AND RETURN` 执行目标程序返回到当前程序 2. `EXPORTING LIST TO MEMORY` 将传统列输出(WRITE语句)保存到内存 3. `LIST_FROM_MEMORY` 函数读取内存中的输出内容 4. 适用于使用传统列输出的程序(非ALV) --- ### 方法二:捕获ALV输出数据 对于使用ALV报表程序,可以通过运行时信息类获取内数据: ```abap DATA: lr_runtime_info TYPE REF TO cl_salv_bs_runtime_info. " 创建运行时信息实例 lr_runtime_info = cl_salv_bs_runtime_info=>get_instance( ). " 设置仅获取数据不显示 lr_runtime_info->set( EXPORTING display = abap_false " 不显示ALV metadata = abap_false data = abap_true ). " 仅获取数据 " 执行目标程序 SUBMIT zalv_program AND RETURN. " 结束数据捕获 lr_runtime_info->set( EXPORTING display = abap_false metadata = abap_false data = abap_false ). " 获取输出数据 TRY. DATA(lr_data) = lr_runtime_info->get_data( ). ASSIGN lr_data->* TO FIELD-SYMBOL(<lt_output>). IF <lt_output> IS ASSIGNED. " 处理ALV数据 ENDIF. CATCH cx_salv_bs_sc_runtime_info. MESSAGE '获取ALV数据失败' TYPE 'E'. ENDTRY. ``` **关键点说明**: 1. `cl_salv_bs_runtime_info` 类用于拦截ALV输出 2. 通过 `set( display = abap_false )` 禁止ALV显示 3. `get_data()` 方法返回结果数据的引用 4. 适用于使用标准ALV函数(如 `REUSE_ALV_GRID_DISPLAY`)的程序 --- ### 方法三:通过后台作业捕获假脱机输出 ```abap " 创建后台作业 CALL FUNCTION 'JOB_OPEN' EXPORTING jobname = 'OUTPUT_CAPTURE' IMPORTING jobcount = lv_jobcount. " 提交程序到后台 SUBMIT ztarget_program VIA JOB 'OUTPUT_CAPTURE' NUMBER lv_jobcount AND RETURN. " 关闭作业 CALL FUNCTION 'JOB_CLOSE' EXPORTING jobcount = lv_jobcount jobname = 'OUTPUT_CAPTURE' strtimmed = abap_true. " 获取假脱机ID DATA: lv_spoolid TYPE rspoid. CALL FUNCTION 'RSPO_RETURN_SPOOLJOB' EXPORTING rqident = lv_jobcount IMPORTING spoolid = lv_spoolid EXCEPTIONS no_such_job = 1. " 读取假脱机内容 CALL FUNCTION 'RSPO_RETURN_SPOOLJOB' EXPORTING spoolid = lv_spoolid complete = abap_true TABLES buffer = lt_output. ``` --- ### 最佳实践建议 1. **输出类型匹配**: - 传统列程序 → 使用方法一 - ALV报表程序 → 使用方法二 - 复杂输出程序 → 使用方法三 2. **参数传递**: ```abap " 动态传递选择屏幕参数 SUBMIT zprogram WITH p_date EQ sy-datum WITH p_werks IN s_plant ... ``` 3. **错误处理**: ```abap SUBMIT zprogram ... EXCEPTIONS program_not_found = 1 OTHERS = 2. IF sy-subrc <> 0. " 错误处理 ENDIF. ``` 4. **权限检查**: ```abap AUTHORITY-CHECK OBJECT 'S_PROGRAM' ID 'P_GROUP' DUMMY ID 'P_ACTION' FIELD 'SUBMIT'. IF sy-subrc <> 0. MESSAGE '无执行权限' TYPE 'E'. ENDIF. ``` --- ### 注意事项 1. 目标程序必须可执行(非对话程序) 2. ALV捕获方法需要目标程序使用标准ALV函数 3. 后台作业方法会产生实际作业记录 4. 需要处理用户会话超时问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值