
文章目录SAP 采购订单收货函数实战基于 BAPI_GOODS_MVT_CREATE 的 AI 驱动开发一、需求背景--测试AI功能使用-没有指定具体的业务要求二、技术栈与环境三、过程实现核心踩坑与解决1. 第一步确认对象与类型是否存在2. 使用 ADT 创建函数模块3. 遇到的规则雷区关键经验4. 标准化的成功判断与提交四、最终成果生成对象接口清单开发亮点五、结尾SAP 采购订单收货函数实战基于 BAPI_GOODS_MVT_CREATE 的 AI 驱动开发本文记录一次使用 AI 编程助手在 SAP S/4HANA 系统中从零开发采购收货自定义函数的完整过程涵盖技术选型、开发环境、踩坑过程、最终成果希望对 SAP 开发 AI 提效场景有参考价值。一、需求背景–测试AI功能使用-没有指定具体的业务要求业务需要封装一个可供其他程序复用的采购订单收货函数模块底层调用 SAP 标准 BAPI ——BAPI_GOODS_MVT_CREATE移动类型默认 101。要求放置在现有的 PO 函数组ZFG_COPY_PO下参数风格统一IV_/EV_前缀业务逻辑完善必填校验、默认日期/移动类型、成功判断、RETURN表回传、测试运行控制提交方式标准化使用 BAPI 事务函数提交/回滚而非裸COMMIT WORK。二、技术栈与环境开发过程不是闷头写代码而是基于MCPModel Context Protocol打通 AI 与 SAP 的三层通道通道用途写权限ABAP Development Tools创建/读取/编辑源代码、激活对象✅ 可写Remote Function Call只读查询查表结构等❌ 只读OData系统登录与会话管理中间层开发对象自定义函数Z_MM_GR_PO_GOODSRCPT函数组ZFG_COPY_PO包$TMP关键依赖类型BAPI2017_GM_HEAD_01抬头BAPI2017_GM_CODE代码BAPI2017_GM_ITEM_CREATE项目BAPIRET2返回消息三、过程实现核心踩坑与解决1. 第一步确认对象与类型是否存在按字段名先查再写、禁止猜的原则用RFC 读取数据字典DD03L确认所有 BAPI 结构真实存在BAPIRET2结构存在 —— 返回消息表行类型BAPI2017_GM_ITEM_CREATE结构存在 —— 项目字段PO_NUMBER/PO_ITEM/MOVE_TYPE/PLANT/STGE_LOC/ENTRY_QNT。教训类型名拼写错误是激活失败的主要来源之一。2. 使用 ADT 创建函数模块使用 ADT 的源码写入能力一次性提交完整的FUNCTION ... ENDFUNCTION.块完成对象创建与激活。3. 遇到的规则雷区关键经验在多次激活失败后总结出该套件下的三大避坑点禁止DATA:冒号批量声明ADT 归一化解析器会把DATA: a TYPE x, b TYPE y.误判为函数参数接口从而生成一堆错误的 EXPORTING 参数。必须一行一条DATA x TYPE y.。TABLES 参数类型写法需要一个ET_RETURN TYPE BAPIRET2直接给行类型这一行写STANDARD TABLE OF会被解析器拆错。用行类型由系统自动转内表。Type 名称必须以数据字典为准曾把BAPIRET2误写成BAPIRETAP/bapiretr等触发Type unknown。4. 标准化的成功判断与提交 调用标准 BAPI 执行货物移动 CALL FUNCTION BAPI_GOODS_MVT_CREATE EXPORTING goodsmvt_header ls_header goodsmvt_code ls_code testrun iv_testrun TABLES goodsmvt_item lt_item return lt_ret. 回传 BAPI 返回消息 et_return[] lt_ret[]. 检查是否存在错误/中止类型返回 LOOP AT lt_ret INTO ls_ret WHERE type CA EAX. lv_error X. EXIT. ENDLOOP. 存在错误则标准回滚 IF lv_error X. IF iv_testrun IS INITIAL. CALL FUNCTION BAPI_TRANSACTION_ROLLBACK. ENDIF. ev_success . RETURN. ENDIF. 处理成功标准提交测试运行不提交 ev_success X. IF iv_testrun IS INITIAL. CALL FUNCTION BAPI_TRANSACTION_COMMIT EXPORTING wait X. ENDIF.要点成功判断遍历RETURN表的type含 E/A/X 视为失败提交统一走BAPI_TRANSACTION_COMMIT(WAITX)回滚出错走BAPI_TRANSACTION_ROLLBACK不再直接用 COMMIT WORK》测试运行IV_TESTRUN时不提交只做验证。四、最终成果生成对象对象名称 : Z_MM_GR_PO_GOODSRCPT 所属函数组: ZFG_COPY_PO 所属包 : $TMP 激活状态 : ✓ 成功激活activated true, 无错误 参数数量 : 14接口清单方向参数类型说明IMPORTINGIV_PO_NUMBEREBELN采购订单号必输IV_PO_ITEMEBELP采购订单行项目必输IV_QTYMENGE_D收货数量必输IV_UOMMEINS收货单位IV_PLANTWERKS_D工厂IV_STGE_LOCLGORT_D存储地点IV_MOVE_TYPEBWART移动类型默认 101IV_PSTNG_DATEBUDAT过账日期默认当天IV_HEADER_TXTBKTXT抬头文本IV_TESTRUNXFELD测试运行EXPORTEV_SUCCESSXFELD是否成功EV_MAT_DOCMBLNR物料凭证号EV_MAT_YEARMJAHR物料凭证年度TABLESET_RETURNBAPIRET2BAPI 返回消息开发亮点多通道协作ADT 写、RFC 查、OData 登录三层通道各司其职全程无人为手工录入先查后写所有字段/类型名先经 DDIC 核实杜绝盲猜标准化提交BAPI 事务函数 测试运行处理安全合规注释与格式程序头文档、逐段中文注释、变量前缀规范。五、结尾这次开发说明了一个判断即使是一个小功能 BAPI 封装函数背后也涉及类型名精确性、参数写法兼容、事务提交规范等细节。而借助统一的 MCP 通道AI 可以完成「分析 → 查询 → 编码 → 激活 → 校验」的闭环大幅提升开发效率。如果你也想用类似方式提升 SAP 常规功能的开发体验建议先从「小函数封装 类型字典查询」这类低风险场景入手。最后附上代码function z_mm_gr_po_goodsrcpt. *---------------------------------------------------------------------- **本地接口 * IMPORTING * VALUE(IV_PO_NUMBER) TYPE EBELN * VALUE(IV_PO_ITEM) TYPE EBELP * VALUE(IV_QTY) TYPE MENGE_D * VALUE(IV_UOM) TYPE MEINS OPTIONAL * VALUE(IV_PLANT) TYPE WERKS_D OPTIONAL * VALUE(IV_STGE_LOC) TYPE LGORT_D OPTIONAL * VALUE(IV_MOVE_TYPE) TYPE BWART OPTIONAL * VALUE(IV_PSTNG_DATE) TYPE BUDAT OPTIONAL * VALUE(IV_HEADER_TXT) TYPE BKTXT OPTIONAL * VALUE(IV_TESTRUN) TYPE XFELD OPTIONAL * EXPORTING * VALUE(EV_SUCCESS) TYPE XFELD * VALUE(EV_MAT_DOC) TYPE MBLNR * VALUE(EV_MAT_YEAR) TYPE MJAHR * TABLES * ET_RETURN STRUCTURE BAPIRET2 *---------------------------------------------------------------------- . DATA ls_header TYPE bapi2017_gm_head_01. 货物移动抬头 DATA ls_code TYPE bapi2017_gm_code. 货物移动代码 DATA lt_item TYPE TABLE OF bapi2017_gm_item_create. 货物移动项目表 DATA ls_item LIKE LINE OF lt_item. 货物移动项目行 DATA lt_ret TYPE TABLE OF bapiret2. BAPI返回消息表 DATA ls_ret LIKE LINE OF lt_ret. BAPI返回消息行 DATA lv_move TYPE bwart. 移动类型 DATA lv_error TYPE flag. 错误标记 CLEAR: ev_success, ev_mat_doc, ev_mat_year, et_return. 必填参数校验 IF iv_po_number IS INITIAL OR iv_po_item IS INITIAL OR iv_qty IS INITIAL. RETURN. ENDIF. 设置货物移动代码01收货 ls_code-gm_code 01. 设置抬头过账日期默认当前日期 ls_header-pstng_date sy-datum. IF iv_pstng_date IS NOT INITIAL. ls_header-pstng_date iv_pstng_date. ENDIF. ls_header-header_txt iv_header_txt. 移动类型默认101采购订单收货 lv_move iv_move_type. IF lv_move IS INITIAL. lv_move 101. ENDIF. ls_item-move_type lv_move. 组装BAPI项目字段 ls_item-po_number iv_po_number. ls_item-po_item iv_po_item. ls_item-plant iv_plant. ls_item-stge_loc iv_stge_loc. ls_item-entry_qnt iv_qty. ls_item-entry_uom iv_uom. APPEND ls_item TO lt_item. 调用标准BAPI执行货物移动 CALL FUNCTION BAPI_GOODS_MVT_CREATE EXPORTING goodsmvt_header ls_header goodsmvt_code ls_code testrun iv_testrun TABLES goodsmvt_item lt_item return lt_ret. 回传BAPI返回消息 et_return[] lt_ret[]. 检查是否存在错误/中止类型返回 LOOP AT lt_ret INTO ls_ret WHERE type CA EAX. lv_error X. EXIT. ENDLOOP. 存在错误则标准回滚 IF lv_error X. IF iv_testrun IS INITIAL. CALL FUNCTION BAPI_TRANSACTION_ROLLBACK. ENDIF. ev_success . RETURN. ENDIF. 处理成功标准提交测试运行不提交 ev_success X. IF iv_testrun IS INITIAL. CALL FUNCTION BAPI_TRANSACTION_COMMIT EXPORTING wait X. ENDIF. endfunction.