当前位置: 首页 > news >正文

SAP ABAP开发实战:用GN_DELIVERY_CREATE和BAPI_INB_DELIVERY_CHANGE搞定内部交货单(附完整代码)

SAP ABAP实战:GN_DELIVERY_CREATE与BAPI_INB_DELIVERY_CHANGE在内部交货单开发中的深度应用

当企业供应链系统需要处理跨仓库调拨或生产补料时,内部交货单(Inbound Delivery)的高效创建与修改直接影响物流效率。作为ABAP开发者,我们常面临如何在保证系统稳定性的前提下快速实现业务需求的挑战。本文将深入解析两个核心函数模块——GN_DELIVERY_CREATEBAPI_INB_DELIVERY_CHANGE的实战应用场景,通过完整代码示例展示从采购订单生成交货单到后续修改的全流程解决方案。

1. 内部交货单技术选型:BAPI对比与选择逻辑

在VL31N事务码的底层实现中,系统提供了多种创建内部交货单的技术路径。经过实际项目验证,我们发现不同BAPI在字段完整性、执行效率和异常处理方面存在显著差异:

函数模块字段丰富度执行效率错误处理适用场景
GN_DELIVERY_CREATE完善复杂业务场景
BAPI_DELIVERYPROCESSING基础简单快速创建
BBP_INB_DELIVERY_CREATE存在缺陷不推荐生产环境使用

关键选择依据

  • 当需要完整控制交货单的各个业务字段(如批次、生产日期、特殊库存标识)时,GN_DELIVERY_CREATE是不二之选
  • 对于简单的测试场景或快速原型开发,轻量级的BAPI_DELIVERYPROCESSING_EXEC可能更合适
  • 涉及供应商批次管理或特殊移动类型时,必须使用GN_DELIVERY_CREATE的扩展参数结构

实际项目中曾遇到使用BBP_INB_DELIVERY_CREATE创建的交付单无法冲销的问题,后来通过增强LE_SHP_DELIVERY_PROC的CHANGE_DELIVERY_HEADER方法才解决。这种隐性缺陷使得该BAPI不适合关键业务流程。

2. GN_DELIVERY_CREATE的实战应用详解

下面是通过采购订单创建内部交货单的完整示例代码,重点解析关键参数和业务逻辑:

DATA: lt_komdlgn TYPE TABLE OF komdlgn, ls_komdlgn TYPE komdlgn, lt_vbfs TYPE TABLE OF vbfs, lt_vbls TYPE TABLE OF vbls. " 从采购订单获取源数据 SELECT SINGLE * FROM ekpo WHERE ebeln = '4500001299' AND ebelp = '000020' INTO @DATA(gs_po_item). " 构建交货单创建参数 ls_komdlgn-lfart = 'EL'. " 交货类型 ls_komdlgn-vgtyp = 'V'. " 参考凭证类型 ls_komdlgn-kzazu = 'X'. " 订单组合标识(关键参数) ls_komdlgn-lfdat = sy-datum. " 交货日期 ls_komdlgn-wadat = sy-datum. " 发货日期 ls_komdlgn-vgbel = gs_po_item-ebeln. " 采购订单号 ls_komdlgn-vgpos = gs_po_item-ebelp. " 采购订单行号 ls_komdlgn-matnr = gs_po_item-matnr. " 物料编号 ls_komdlgn-werks = gs_po_item-werks. " 工厂 ls_komdlgn-lgort = gs_po_item-lgort. " 库存地点 ls_komdlgn-lfimg = '1'. " 交货数量 ls_komdlgn-vrkme = gs_po_item-meins. " 销售单位 ls_komdlgn-meins = gs_po_item-meins. " 基本单位 ls_komdlgn-lichn = 'BATCH001'. " 供应商批次 APPEND ls_komdlgn TO lt_komdlgn. " 调用BAPI创建交货单 CALL FUNCTION 'GN_DELIVERY_CREATE' EXPORTING vbsk_i = VALUE #( mandt = sy-mandt ernam = sy-uname erdat = sy-datum ) IMPORTING vbsk_e = DATA(es_vbsk) TABLES xkomdlgn = lt_komdlgn xvbfs = lt_vbfs xvbls = lt_vbls. " 错误处理逻辑 LOOP AT lt_vbfs INTO DATA(ls_vbfs) WHERE msgty CA 'EAX'. " 记录错误日志 MESSAGE ID ls_vbfs-msgid TYPE ls_vbfs-msgty NUMBER ls_vbfs-msgno WITH ls_vbfs-msgv1 ls_vbfs-msgv2 ls_vbfs-msgv3 ls_vbfs-msgv4 INTO DATA(lv_message). ROLLBACK WORK. EXIT. ENDLOOP. IF sy-subrc NE 0. COMMIT WORK. " 获取创建的交货单号 SELECT vbeln FROM likp INTO @DATA(lv_vbeln) WHERE erdat = @sy-datum AND ernam = @sy-uname ORDER BY erzet DESCENDING. EXIT. ENDSELECT. ENDIF.

关键参数解析

  • kzazu:订单组合标识,设置为'X'时,系统会将多个采购订单行项目合并到一个交货单
  • lfdat/wadat:必须保持日期一致性,否则可能导致WM层面处理异常
  • lichn:供应商批次字段,在医药、化工等行业尤为重要

3. BAPI_INB_DELIVERY_CHANGE的进阶使用技巧

交货单创建后的修改操作同样充满挑战,特别是数量调整和批次变更场景。以下示例展示如何安全修改交货单:

DATA: ls_header TYPE bapiibdlvhdrchg, ls_headerx TYPE bapiibdlvhdrctrlchg, lt_item TYPE TABLE OF bapiibdlvitemchg, lt_itemx TYPE TABLE OF bapiibdlvitemctrlchg, lt_return TYPE TABLE OF bapiret2. " 获取原始交货单数据 SELECT SINGLE * FROM lips WHERE vbeln = '800000123' AND posnr = '000010' INTO @DATA(ls_lips). " 设置修改参数 ls_header-deliv_numb = '800000123'. ls_headerx-deliv_numb = '800000123'. " 行项目修改 APPEND VALUE #( deliv_numb = '800000123' deliv_item = '000010' dlv_qty = '5' " 新数量 sales_unit = ls_lips-vrkme fact_unit_nom = 1 " 单位转换因子 fact_unit_denom = 1 ) TO lt_item. " 修改控制标识 APPEND VALUE #( deliv_numb = '800000123' deliv_item = '000010' chg_delqty = 'X' " 修改数量标识 chg_batch = 'X' " 修改批次标识 ) TO lt_itemx. " 调用修改BAPI CALL FUNCTION 'BAPI_INB_DELIVERY_CHANGE' EXPORTING header_data = ls_header header_control = ls_headerx TABLES item_data = lt_item item_control = lt_itemx return = lt_return. " 检查执行结果 LOOP AT lt_return INTO DATA(ls_return) WHERE type CA 'EAX'. " 错误处理 ROLLBACK WORK. EXIT. ENDLOOP. IF sy-subrc NE 0. COMMIT WORK AND WAIT. ENDIF.

修改操作注意事项

  1. 数量修改时需要同时维护fact_unit_nomfact_unit_denom单位转换因子
  2. 批次修改前需确认物料是否启用了批次管理
  3. 删除操作需设置header_control-dlv_del = 'X'
  4. 部分字段(如移动类型)创建后不可修改

4. 异常处理与性能优化实战建议

在批量处理场景下,合理的错误处理和性能调优至关重要。以下是经过生产验证的最佳实践:

错误处理机制

  • GN_DELIVERY_CREATE返回的lt_vbfs表必须检查'E'和'A'类型消息
  • BAPI_INB_DELIVERY_CHANGE的返回表需遍历检查TYPE字段
  • 关键业务操作建议实现自动重试机制

性能优化技巧

" 批量处理优化示例 LOOP AT lt_po_items INTO DATA(ls_po). " 1. 使用FOR ALL ENTRIES减少DB查询 IF lt_mara IS INITIAL. SELECT matnr, meins FROM mara FOR ALL ENTRIES IN @lt_po_items WHERE matnr = @lt_po_items-matnr INTO TABLE @lt_mara. ENDIF. " 2. 使用内存缓存减少重复计算 ASSIGN lt_mara[ matnr = ls_po-matnr ] TO FIELD-SYMBOL(<fs_mara>). IF sy-subrc = 0. ls_komdlgn-meins = <fs_mara>-meins. ENDIF. " 3. 分批提交控制 IF sy-index MOD 50 = 0. COMMIT WORK AND WAIT. REFRESH: lt_komdlgn. ENDIF. ENDLOOP.

单元测试建议

  1. 创建测试专用物料主数据
  2. 模拟不同工厂/库存地点组合
  3. 测试边界条件(如零数量、极大数量)
  4. 验证冲销场景的可行性

在最近参与的汽车零部件项目中,我们通过优化GN_DELIVERY_CREATE的调用频率(从单条处理改为50条批量处理),使夜间批量作业的执行时间从4小时缩短到35分钟。关键点在于合理控制COMMIT的频率和批量大小。

http://www.jsqmd.com/news/906990/

相关文章:

  • 霸王茶姬API接口开发
  • ABAQUS二次开发实战脚本包:17个章节的可运行Python案例(含.py/.pyc/odb/inp)
  • LX51链接器解决8051分页应用中的IMPROPER FIXUP错误
  • 别再只看准确率了!用Python手把手教你计算混淆矩阵、精准率与召回率(附完整代码)
  • 2026 年 5 月基金从业备考指南:刷题 APP 与小程序实测对比 - 讲清楚了
  • 一维卷积(1DCNN)的权重矩阵到底长啥样?深度拆解MATLAB与Keras的实现差异
  • Python 开发者三分钟接入 Taotoken 调用 GPT 与 Claude 模型
  • 基于Arduino与传感器的智能干湿垃圾分类系统设计与实现
  • 2026 年 5 月基金从业刷题攻略:在线平台与每日一练 APP 深度测评 - 讲清楚了
  • PHP 新手入门路线图,从环境搭建到像程序员一样思考
  • 粉笔和中公哪个好?公考报班看课程、题库、模考和学习节奏
  • 算力筑基,场景破界 | 倍联德全场景算力研讨会圆满落幕
  • 从金融资产收益率到互联网用户时长:手把手教你用对数正态分布建模实际数据(含MATLAB/Python代码)
  • 数学建模竞赛避坑指南:用最小二乘法做回归预测,这些统计检验你做了吗?
  • UE4SS深度解析:从游戏脚本系统到跨平台构建的完整指南
  • SQLite 删除表
  • 从‘乱码’中学习:深入浅出图解BART模型的5种去噪预训练任务
  • AI时代,物流行业为什么越来越需要“系统能力”?物流行业一直是高度依赖流程协同的行业。从:仓储配送客服数据调度到:订单管理售后处理供应链协同背后都需要复杂的系统支持
  • Webfunny用户分群功能详解:精准筛选与管理用户群体的利器
  • 当密码不是MD5:手把手教你用Burp+jsEncrypter搞定前端自定义加密爆破
  • 用ATMEGA328微控制器改造老式电话,实现DTMF信号生成与智能扩展
  • 保姆级教程:用Unity UGUI搞定坦克大战的摇杆控制与动态血条UI
  • 华为健康数据转换终极指南:3步解锁运动数据自由
  • 别再一键删除了!聊聊Source Map泄露的正确修复姿势:从Vue/React到Webpack配置
  • 从`.txt`到`.npy`:一个数据科学新手的踩坑实录与格式升级指南
  • Abaqus 仿真与 AI 融合实战入门
  • Microsoft Visual Studio快捷键大全
  • 告别‘无效分区表’!保姆级教程:用U盘给Ubuntu 20.04分区(GPT+UEFI版)
  • 银河麒麟aarch64如何高效做数据分析?分享一款内网离线数据分析利器
  • ImageMagick:跨平台图像处理工具套件