SAP_ABAP_MM_BAPI清单案例教程——采购申请_BAPI_PR_CREATE_ME51N

以下是一个不使用CLASS的ABAP程序,通过BAPI `BAPI_PR_CREATE_MULTI_ITEM` 批量创建采购申请,并将成功/失败信息记录到自定义日志表中: ```ABAP REPORT z_create_pr_batch_bapi. * 自定义日志表定义(需提前创建) TABLES: zmm_pr_log. * 选择屏幕 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001. PARAMETERS: p_test TYPE c AS CHECKBOX DEFAULT 'X' USER-COMMAND test, "测试运行 p_commit TYPE c AS CHECKBOX DEFAULT 'X'. "提交标志 SELECTION-SCREEN END OF BLOCK b1. INITIALIZATION. TEXT-001 = '批量创建采购申请选项'. * 内部表定义 DATA: gt_pr_items TYPE TABLE OF bapimemory, "采购申请项目数据 gs_pr_item TYPE bapimemory, gt_return TYPE TABLE OF bapiret2, "返回消息 gs_return TYPE bapiret2, gv_pr_no TYPE eban-banfn, "生成的采购申请号 gv_subrc LIKE sy-subrc. * 主程序 START-OF-SELECTION. PERFORM prepare_pr_data. PERFORM create_pr_via_bapi. PERFORM display_result. *&---------------------------------------------------------------------* *& Form PREPARE_PR_DATA *&---------------------------------------------------------------------* * 准备采购申请数据 *----------------------------------------------------------------------* FORM prepare_pr_data. CLEAR gt_pr_items[]. "示例数据1 - 办公用品 gs_pr_item-banfn = ''. "留空表示新建 gs_pr_item-bnfpo = '00010'. gs_pr_item-bsart = 'NB'. "采购申请类型 gs_pr_item-matnr = 'MAT001'. "物料编号 gs_pr_item-menge = '10'. "数量 gs_pr_item-meins = 'EA'. "单位 gs_pr_item-werks = '1000'. "工厂 gs_pr_item-lgort = '0001'. "库存地点 gs_pr_item-afnam = sy-uname. "申请人 gs_pr_item-badat = sy-datum. "申请日期 gs_pr_item-ekgrp = '001'. "采购组 APPEND gs_pr_item TO gt_pr_items. CLEAR gs_pr_item. "示例数据2 - IT设备 gs_pr_item-banfn = ''. gs_pr_item-bnfpo = '00020'. gs_pr_item-bsart = 'NB'. gs_pr_item-matnr = 'MAT002'. gs_pr_item-menge = '5'. gs_pr_item-meins = 'EA'. gs_pr_item-werks = '1000'. gs_pr_item-lgort = '0001'. gs_pr_item-afnam = sy-uname. gs_pr_item-badat = sy-datum. gs_pr_item-ekgrp = '002'. APPEND gs_pr_item TO gt_pr_items. CLEAR gs_pr_item. ENDFORM. " PREPARE_PR_DATA *&---------------------------------------------------------------------* *& Form CREATE_PR_VIA_BAPI *&---------------------------------------------------------------------* * 通过BAPI创建采购申请 *----------------------------------------------------------------------* FORM create_pr_via_bapi. CLEAR: gt_return[], gv_pr_no, gv_subrc. "调用BAPI创建采购申请 CALL FUNCTION 'BAPI_PR_CREATE_MULTI_ITEM' EXPORTING pr_header = VALUE bapimepoheader( "抬头数据(可选) pr_type = 'NB' "采购申请类型 doc_date = sy-datum purch_org = '1000' "采购组织 pur_group = '001' "采购组 company = '1000' "公司代码 ) IMPORTING number = gv_pr_no "返回的采购申请号(仅单申请时有效) TABLES pr_items = gt_pr_items "项目数据 return = gt_return. "返回消息 "分析返回结果 PERFORM analyze_bapi_result. "记录日志 PERFORM write_log. "提交或回滚 IF p_commit = 'X' AND gv_subrc = 0. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. WRITE: / '数据已提交'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. WRITE: / '数据未提交(测试模式或发生错误)'. ENDIF. ENDFORM. " CREATE_PR_VIA_BAPI *&---------------------------------------------------------------------* *& Form ANALYZE_BAPI_RESULT *&---------------------------------------------------------------------* * 分析BAPI执行结果 *----------------------------------------------------------------------* FORM analyze_bapi_result. READ TABLE gt_return INTO gs_return WITH KEY type = 'E'. IF sy-subrc = 0. gv_subrc = 4. "显示所有错误消息 LOOP AT gt_return INTO gs_return WHERE type = 'E' OR type = 'A'. MESSAGE ID gs_return-id TYPE gs_return-type NUMBER gs_return-number WITH gs_return-message_v1 gs_return-message_v2 gs_return-message_v3 gs_return-message_v4. ENDLOOP. ELSE. gv_subrc = 0. "显示成功消息 LOOP AT gt_return INTO gs_return WHERE type = 'S'. MESSAGE ID gs_return-id TYPE gs_return-type NUMBER gs_return-number WITH gs_return-message_v1 gs_return-message_v2 gs_return-message_v3 gs_return-message_v4. ENDLOOP. ENDIF. ENDFORM. " ANALYZE_BAPI_RESULT *&---------------------------------------------------------------------* *& Form WRITE_LOG *&---------------------------------------------------------------------* * 写入日志表 *----------------------------------------------------------------------* FORM write_log. DATA: lv_log_id TYPE char30. "生成日志ID CONCATENATE sy-datum sy-uzeit sy-uname INTO lv_log_id. "处理每个项目 LOOP AT gt_pr_items INTO gs_pr_item. CLEAR zmm_pr_log. zmm_pr_log-log_id = lv_log_id. zmm_pr_log-log_date = sy-datum. zmm_pr_log-log_time = sy-uzeit. zmm_pr_log-user_name = sy-uname. zmm_pr_log-pr_item = gs_pr_item-bnfpo. zmm_pr_log-matnr = gs_pr_item-matnr. zmm_pr_log-menge = gs_pr_item-menge. zmm_pr_log-werks = gs_pr_item-werks. "确定状态和消息 IF gv_subrc = 0. zmm_pr_log-status = 'S'. "成功 zmm_pr_log-message = '采购申请项目创建成功'. "获取实际创建的采购申请号(多项目时需从返回消息中解析) READ TABLE gt_return INTO gs_return WITH KEY type = 'S' id = 'MM' number = '601'. IF sy-subrc = 0. CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = gs_return-message_v1 IMPORTING output = zmm_pr_log-pr_no. ENDIF. ELSE. zmm_pr_log-status = 'E'. "错误 "收集错误消息 LOOP AT gt_return INTO gs_return WHERE row = sy-tabix. CONCATENATE zmm_pr_log-message gs_return-message INTO zmm_pr_log-message SEPARATED BY space. ENDLOOP. ENDIF. "写入日志 INSERT zmm_pr_log. IF sy-subrc <> 0. WRITE: / '日志写入失败:', zmm_pr_log-pr_item. ENDIF. ENDLOOP. "批量提交日志 IF p_commit = 'X'. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF. ENDFORM. " WRITE_LOG *&---------------------------------------------------------------------* *& Form DISPLAY_RESULT *&---------------------------------------------------------------------* * 显示处理结果 *----------------------------------------------------------------------* FORM display_result. WRITE: / '处理完成,详细结果请查看日志表ZMM_PR_LOG'. WRITE: / '日志ID:', lv_log_id. "显示概览 DATA: lv_success TYPE i, lv_fail TYPE i. SELECT COUNT(*) FROM zmm_pr_log WHERE log_id = lv_log_id AND status = 'S'. lv_success = sy-dbcnt. SELECT COUNT(*) FROM zmm_pr_log WHERE log_id = lv_log_id AND status = 'E'. lv_fail = sy-dbcnt. WRITE: / '成功项目:', lv_success, / '失败项目:', lv_fail. ENDFORM. " DISPLAY_RESULT ``` --- ### **关键功能说明** #### **1. BAPI调用核心逻辑** ```ABAP CALL FUNCTION 'BAPI_PR_CREATE_MULTI_ITEM' EXPORTING pr_header = VALUE bapimepoheader( "可选抬头数据 pr_type = 'NB' doc_date = sy-datum ) IMPORTING number = gv_pr_no "返回的采购申请号(单申请时有效) TABLES pr_items = gt_pr_items "项目数据 return = gt_return. "返回消息 ``` #### **2. 数据准备** - 使用内部表`gt_pr_items`(类型为`BAPIMEMORY`)准备项目数据 - 关键字段: - `BANFN`:留空表示新建 - `BNFPO`:项目号(需唯一) - `BSART`:采购申请类型(如NB标准采购申请) - `MATNR`/`MENGE`/`MEINS`:物料信息 - `WERKS`/`LGORT`:工厂和库存地点 #### **3. 结果处理** - 通过`gt_return`表分析执行结果: ```ABAP READ TABLE gt_return INTO gs_return WITH KEY type = 'E'. IF sy-subrc = 0. "存在错误 ENDIF. ``` #### **4. 日志记录** - 自定义日志表`ZMM_PR_LOG`记录处理结果 - 关键字段: - `LOG_ID`:处理批次ID - `PR_NO`:生成的采购申请号 - `STATUS`:处理状态(S/E) - `MESSAGE`:处理消息 --- ### **增强建议** 1. **从Excel导入数据**: ```ABAP " 使用OLE或ABAP2XLSX读取Excel数据 DATA: lt_excel_data TYPE TABLE OF zexcel_structure. " 填充gt_pr_items LOOP AT lt_excel_data INTO ls_excel_data. MOVE-CORRESPONDING ls_excel_data TO gs_pr_item. APPEND gs_pr_item TO gt_pr_items. ENDLOOP. ``` 2. **多申请处理**: ```ABAP " 按工厂/采购组分组创建不同申请 SORT gt_pr_items BY werks ekgrp. DATA: lv_current_group TYPE char20. LOOP AT gt_pr_items INTO gs_pr_item. AT NEW werks. " 新建申请组 ENDAT. " 添加到当前申请 AT END OF werks. " 提交当前申请组 ENDAT. ENDLOOP. ``` 3. **账户分配处理**: ```ABAP " 在项目数据中添加账户分配 gs_pr_item-account_assignment = 'X'. gs_pr_item-kostl = '1000'. "成本中心 gs_pr_item-sakto = '0000400000'. "总账科目 ``` 4. **增强错误处理**: ```ABAP " 解析返回消息获取具体错误 LOOP AT gt_return INTO gs_return WHERE row = sy-tabix. CASE gs_return-id. WHEN 'MM'. CASE gs_return-number. WHEN '601'. "成功消息 WHEN '602'. "错误消息 ENDCASE. ENDCASE. ENDLOOP. ``` --- ### **常见问题处理** 1. **BAPI返回消息解析**: - 成功消息:`MM 601`(采购申请XXX已创建) - 常见错误: - `MM 602`:必输字段缺失 - `MM 603`:物料主数据不存在 2. **性能优化**: ```ABAP " 批量处理时显示进度 DATA: lv_total TYPE i, lv_count TYPE i. DESCRIBE TABLE gt_pr_items LINES lv_total. LOOP AT gt_pr_items INTO gs_pr_item. lv_count = sy-tabix. CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' EXPORTING percentage = lv_count * 100 / lv_total text = '正在处理项目...'. " 处理逻辑 ENDLOOP. ``` 3. **字段验证**: ```ABAP " 在调用BAPI前验证必输字段 LOOP AT gt_pr_items INTO gs_pr_item. IF gs_pr_item-matnr IS INITIAL. MESSAGE '物料编号不能为空' TYPE 'E'. EXIT. ENDIF. ENDLOOP. ``` --- ### **部署注意事项** 1. **日志表创建**: - 使用SE11创建透明表`ZMM_PR_LOG` - 关键字段:`LOG_ID`, `PR_NO`, `STATUS`, `MESSAGE` 2. **权限控制**: ```ABAP AUTHORITY-CHECK OBJECT 'M_BEST_EKO' ID 'ACTVT' FIELD '01' "创建权限 ID 'EKORG' FIELD '1000'. IF sy-subrc <> 0. MESSAGE '无采购申请创建权限' TYPE 'E'. ENDIF. ``` 3. **测试建议**: - 先使用`p_test = 'X'`运行,不提交数据 - 检查日志表中的模拟结果 - 确认无误后取消测试模式 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SAP社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值