SAP CA01/CA02 创建及更新工艺路线BAPI

本文介绍了在使用BAPICPCC_S_TASK_LIST_MAINTAIN处理Routing时,如何设置参数以实现创建和更改功能,包括task_maintain_mode、sequence_no、活动号变更和物料任务分配等关键要素。
该文章已生成可运行项目,

前言

最近需要做一个routing的批导,初步查过资料后,发现下面几个BAPI:

BAPI_ROUTING_CREATE:最常用的BAPI,只支持创建,没有对应的CHANGE BAPI;

ROUTING_MAINTAIN:不支持创建,只支持更改;

CPCC_S_TASK_LIST_MAINTAIN:同时支持创建及更改。

刚好项目上的需求是既需要创建也需要变更,所以简单测试了下CPCC_S_TASK_LIST_MAINTAIN该如何传参来支持创建及更新。

2024.04.02更新:末尾追加CA02添加新工序时如何传参。

 2024.04.22更新:末尾追加CA02删除工序时如何传参。


正文

一开始写批导函数的时候,使用的是ROUTING_MAINTAIN,发现该函数没有提供task_maintain_mode参数,所以无法进行创建routing,但是里面调用的函数CPCC_S_TASK_LIST_MAINTAIN是支持这个参数的,所以就改用该函数来实现routing的创建及变更,关于函数的一些说明,也可以查看官方note:1558192。

测试的时候发现有几个小的注意点:

  1. task_maintain_mode(C创建,M变更,D删除);
  2. 如果是变更,需要给对应结构中的FLAG_BAR_POINTER字段赋值(如果有);
  3. sequence_no需要赋值000000;
  4. 工序字段operations-activity,如果要变更工序的编号(PLPO-VORNR),比如将10改为20,则需要给activity赋值为20,activity_old赋值为10,同时给activity打上'X'标记,否则无需打'X'标记,不然程序会判定以activity_old的值去找历史数据,如果未给activity_old传值的话就会报错;
  5. material_task_allocations结构是将物料工厂和工序绑定,需要传值,否则MAPL表中不会有数据。 

工序相关底表

MAPL:分配工序给物料

PLKO:工序表头

PLAS:工序选择 

PLPO :工序明细


测试源码

*&---------------------------------------------------------------------*
*& Form FRM_ROUTING_MAINTAIN
*&---------------------------------------------------------------------*
*& Using BAPI to maintain routing
*&---------------------------------------------------------------------*
FORM frm_routing_maintain USING us_req  TYPE zprppsrouting_in
                       CHANGING cs_resp TYPE zprbcsrest_out.

  DATA:
    lv_maintain_mode   TYPE cp_task_list_maint_mode,
    lv_flag_bar        TYPE cp_task_list_maint_pointer,
    lv_change_no       TYPE cps_task_list_maint_hdr-change_no,
    lv_key_date        TYPE cps_task_list_maint_hdr-key_date,
    lv_task_list_group TYPE cps_task_list_maint_hdr-task_list_group,
    lv_group_counter   TYPE cps_task_list_maint_hdr-group_counter,
    lv_material        TYPE cps_task_list_maint_hdr-material,
    lv_plant           TYPE cps_task_list_maint_hdr-plant,
    ls_task            TYPE cps_task_list_maint_tsk,
    ls_task_x          TYPE cps_task_list_maint_tsk_x,
    lv_bom_usage       TYPE stlan,
    lt_material_task   TYPE cpt_task_list_maint_mtk,
    ls_material_task   TYPE cps_task_list_maint_mtk,
    lt_material_task_x TYPE cpt_task_list_maint_mtk_x,
    ls_material_task_x TYPE cps_task_list_maint_mtk_x,
    lt_operations      TYPE cpt_task_list_maint_opr,
    ls_operations      TYPE cps_task_list_maint_opr,
    lt_operations_x    TYPE cpt_task_list_maint_opr_x,
    ls_operations_x    TYPE cps_task_list_maint_opr_x,
    lt_return          TYPE bapiret2_t,
    ls_return          TYPE bapiret2.

* Head data
  lv_change_no       = us_req-head-aennr.
  lv_key_date        = us_req-head-datuv.
  lv_task_list_group = us_req-head-plnnr.
  lv_group_counter   = us_req-head-plnal.
  lv_material        = us_req-head-matnr.
  lv_plant           = us_req-head-werks.

  IF us_req-head-plnnr IS INITIAL.
    lv_maintain_mode = 'C'.
  ELSE.
    lv_maintain_mode = 'M'.
  ENDIF.

  IF us_req-head-verwe IS NOT INITIAL.
    ls_task-task_list_usage     = us_req-head-verwe.
    ls_task_x-task_list_usage   = abap_true.
  ENDIF.

  IF us_req-head-werks IS NOT INITIAL.
    ls_task-plant               = us_req-head-werks.
    ls_task_x-plant             = abap_true.
  ENDIF.

  IF us_req-head-statu IS NOT INITIAL.
    ls_task-task_list_status    = us_req-head-statu.
    ls_task_x-task_list_status  = abap_true.
  ENDIF.

  IF us_req-head-plnme IS NOT INITIAL.
    ls_task-task_measure_unit   = us_req-head-plnme.
    ls_task_x-task_measure_unit = abap_true.
  ENDIF.

  IF us_req-head-ktext IS NOT INITIAL.
    ls_task-description         = us_req-head-ktext.
    ls_task_x-description       = abap_true.
  ENDIF.

  IF us_req-head-loekz_plko IS NOT INITIAL.
    ls_task-del_flag            = us_req-head-loekz_plko.
    ls_task_x-del_flag          = abap_true.
  ENDIF.

  ls_task-lot_size_to         = '99999999'.
  ls_task_x-lot_size_to       = abap_true.

  IF lv_maintain_mode = 'C'.
    CLEAR ls_task_x.

*   Material routing assignment
    ls_material_task-maintain_mode = lv_maintain_mode.
    ls_material_task-material      = us_req-head-matnr.
    ls_material_task-plant         = us_req-head-werks.
    APPEND ls_material_task TO lt_material_task.
  ENDIF.

* Operations
  LOOP AT us_req-operations INTO DATA(ls_operations_in).
    ls_operations-maintain_mode            = ls_operations_in-maintain_mode.
    ls_operations-sequence_no              = '000000'.

    IF ls_operations_in-maintain_mode = 'M'.
      ADD 1 TO lv_flag_bar.
      ls_operations-flag_bar_pointer = lv_flag_bar.
    ENDIF.

*   If the maintain_mode was 'M', and you set the flag abap_true for it,
*   The system considers the current activity is new value,at the same time,
*   You nedd set the original value for the fields 'ACTIVITY_OLD'
    ls_operations-activity                 = ls_operations_in-vornr.

    IF ls_operations_in-arbpl IS NOT INITIAL.
      ls_operations-work_cntr                = ls_operations_in-arbpl.
      ls_operations_x-work_cntr              = abap_true.
    ENDIF.

    IF us_req-head-werks IS NOT INITIAL.
      ls_operations-plant                    = us_req-head-werks.
      ls_operations_x-plant                  = abap_true.
    ENDIF.

    IF ls_operations_in-steus IS NOT INITIAL.
      ls_operations-control_key              = ls_operations_in-steus.
      ls_operations_x-control_key            = abap_true.
    ENDIF.

    IF ls_operations_in-ktsch IS NOT INITIAL.
      ls_operations-standard_text_key        = ls_operations_in-ktsch.
      ls_operations_x-standard_text_key      = abap_true.
    ENDIF.

    IF ls_operations_in-ltxa1 IS NOT INITIAL.
      ls_operations-description              = ls_operations_in-ltxa1.
      ls_operations_x-description            = abap_true.
    ENDIF.

    IF ls_operations_in-vgw01 IS NOT INITIAL.
      ls_operations-std_unit_01              = ls_operations_in-vge01.
      ls_operations_x-std_unit_01            = abap_true.
      ls_operations-std_value_01             = ls_operations_in-vgw01.
      ls_operations_x-std_value_01           = abap_true.
    ENDIF.

    IF ls_operations_in-vgw02 IS NOT INITIAL.
      ls_operations-std_unit_02              = ls_operations_in-vge01.
      ls_operations_x-std_unit_02            = abap_true.
      ls_operations-std_value_02             = ls_operations_in-vgw02.
      ls_operations_x-std_value_02           = abap_true.
    ENDIF.

    IF ls_operations_in-vgw03 IS NOT INITIAL.
      ls_operations-std_unit_03              = ls_operations_in-vge01.
      ls_operations_x-std_unit_03            = abap_true.
      ls_operations-std_value_03             = ls_operations_in-vgw03.
      ls_operations_x-std_value_03           = abap_true.
    ENDIF.

    IF ls_operations_in-vgw04 IS NOT INITIAL.
      ls_operations-std_unit_04              = ls_operations_in-vge01.
      ls_operations_x-std_unit_04            = abap_true.
      ls_operations-std_value_04             = ls_operations_in-vgw04.
      ls_operations_x-std_value_04           = abap_true.
    ENDIF.

    IF ls_operations_in-vgw05 IS NOT INITIAL.
      ls_operations-std_unit_05              = ls_operations_in-vge01.
      ls_operations_x-std_unit_05            = abap_true.
      ls_operations-std_value_05             = ls_operations_in-vgw05.
      ls_operations_x-std_value_05           = abap_true.
    ENDIF.

    IF ls_operations_in-vgw06 IS NOT INITIAL.
      ls_operations-std_unit_06              = ls_operations_in-vge01.
      ls_operations_x-std_unit_06            = abap_true.
      ls_operations-std_value_06             = ls_operations_in-vgw06.
      ls_operations_x-std_value_06           = abap_true.
    ENDIF.

    IF ls_operations_in-bmsch IS NOT INITIAL.
      ls_operations-base_quantity            = ls_operations_in-bmsch.
      ls_operations_x-base_quantity          = abap_true.
    ENDIF.

    IF ls_operations_in-meinh IS NOT INITIAL.
      ls_operations-operation_measure_unit   = ls_operations_in-meinh.
      ls_operations_x-operation_measure_unit = abap_true.
    ENDIF.

    IF ls_operations_in-umren IS NOT INITIAL.
      ls_operations-denominator              = ls_operations_in-umren.
      ls_operations_x-denominator            = abap_true.
    ENDIF.

    IF ls_operations_in-umrez IS NOT INITIAL.
      ls_operations-nominator                = ls_operations_in-umrez.
      ls_operations_x-nominator              = abap_true.
    ENDIF.

    IF ls_operations_in-infnr IS NOT INITIAL.
      ls_operations-info_rec                 = ls_operations_in-infnr.
      ls_operations_x-info_rec               = abap_true.
    ENDIF.

    IF ls_operations_in-ekorg IS NOT INITIAL.
      ls_operations-purch_org                = ls_operations_in-ekorg.
      ls_operations_x-purch_org              = abap_true.
    ENDIF.

    IF ls_operations_in-plifz IS NOT INITIAL.
      ls_operations-plnd_delry               = ls_operations_in-plifz.
      ls_operations_x-plnd_delry             = abap_true.
    ENDIF.

    IF ls_operations_in-sortl IS NOT INITIAL.
      ls_operations-sorted_by                = ls_operations_in-sortl.
      ls_operations_x-sorted_by              = abap_true.
    ENDIF.

    IF ls_operations_in-matkl IS NOT INITIAL.
      ls_operations-matl_group               = ls_operations_in-matkl.
      ls_operations_x-matl_group             = abap_true.
    ENDIF.

    IF ls_operations_in-ckselkz IS NOT INITIAL.
      ls_operations-cost_relevant            = ls_operations_in-ckselkz.
      ls_operations_x-cost_relevant          = abap_true.
    ENDIF.

    IF ls_operations_in-sakto IS NOT INITIAL.
      ls_operations-cost_elem                = ls_operations_in-sakto.
      ls_operations_x-cost_elem              = abap_true.
    ENDIF.

    IF ls_operations_in-frdlb IS NOT INITIAL.
      ls_operations-ext_proc_with_subcontract_ind   = ls_operations_in-frdlb.
      ls_operations_x-ext_proc_with_subcontract_ind = abap_true.
    ENDIF.

    APPEND ls_operations TO lt_operations.
    APPEND ls_operations_x TO lt_operations_x.

    CLEAR:
      ls_operations,
      ls_operations_x.
  ENDLOOP.

**********************************************************************
* Function 'ROUTING_MAINTAIN' can't import maintain_mode,you can only
* use it to modify routing,if you wan't create & change routing,you
* can use below function.
**********************************************************************
  CALL FUNCTION 'CPCC_S_TASK_LIST_MAINTAIN'
    EXPORTING
      change_no                   = lv_change_no
      key_date                    = lv_key_date
      task_list_type              = 'N'
      task_list_group             = lv_task_list_group
      group_counter               = lv_group_counter
      material                    = lv_material
      plant                       = lv_plant
      task_maintain_mode          = lv_maintain_mode
      task                        = ls_task
      task_x                      = ls_task_x
*     APPLICATION                 =
*     BOM_USAGE                   =
    TABLES
      material_task_allocations   = lt_material_task
      material_task_allocations_x = lt_material_task_x
*     SEQUENCES                   =
*     SEQUENCES_X                 =
      operations                  = lt_operations
      operations_x                = lt_operations_x
*     SUBOPERATIONS               =
*     SUBOPERATIONS_X             =
*     PRODUCTION_RESOURCES_TOOLS  =
*     PRODUCTION_RESOURCES_TOOLS_X       =
*     COMPONENT_ALLOCATIONS       =
*     COMPONENT_ALLOCATIONS_X     =
*     INSPECTION_CHARACTERISTICS  =
*     INSPECTION_CHARACTERISTICS_X       =
*     INSPECTION_VALUES           =
*     INSPECTION_VALUES_X         =
*     REFERENCED_OPERATIONS       =
*     TEXT                        =
*     TEXT_ALLOCATIONS            =
      return                      = lt_return
*     SEGMENT_TASK_MAINTAIN       =
    .

  LOOP AT lt_return INTO ls_return
    WHERE type CA 'EAX'.

    cs_resp-msgty = 'E'.
    CONCATENATE cs_resp-msgtx ls_return-message INTO cs_resp-msgtx.
  ENDLOOP.

  IF cs_resp-msgtx IS INITIAL.
    cs_resp-msgty = 'S'.

    LOOP AT lt_return INTO ls_return
      WHERE type = 'S'
        AND ( number = '059' OR number = '068' ).

      cs_resp-msgtx = ls_return-message.
      EXIT.
    ENDLOOP.

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.

ENDFORM.

当需要调用BAPI创建新工序时传参如下:

 


删除工序传参:

 

 

本文章已经生成可运行项目
<think>我们正在讨论SAP创建工艺路线的方法。根据引用内容,工艺路线描述了生产过程中所需的工序和作业定额参数,用于成本核算等。创建工艺路线通常在物料主数据维护完成后进行。 从引用[2]中可以看到,SAP提供了BAPI:`BAPI_ROUTING_CREATE`来创建工艺路线。使用这个BAPI需要准备相应的数据表,如操作(operation)、文本(text)等。 创建工艺路线有两种主要方法: 1. 通过前台事务码(如CA01)手工创建 2. 通过BAPI编程创建 下面我将详细说明这两种方法: ### 方法1:使用事务码CA01手工创建工艺路线 **步骤:** 1. 输入事务码`CA01`进入创建工艺路线界面 2. 输入物料号和工作计划(Work Scheduling)视图中的工厂代码 3. 输入工艺路线的组计数器(Group Counter),通常从01开始 4. 按回车进入工序编辑界面 5. 逐行添加工序: - 输入工序号(如0010, 0020等) - 输入工作中心(Work Center) - 输入控制码(Control Key,如PP01表示标准生产订单) - 维护标准工时(如机器时间、人工时间等) - 可选:维护组件分配(即BOM中的物料在哪些工序被消耗) 6. 保存后系统生成工艺路线号 > **注意**:创建工艺路线前需确保工作中心已存在(通过CR01创建)且物料主数据已维护[^1]。 ### 方法2:使用BAPI编程创建工艺路线(引用[2]示例) 使用函数模块`BAPI_ROUTING_CREATE`通过ABAP程序创建。主要步骤: 1. **准备输入数据表**: - `OPERATION` 表:存储操作数据(工序) - `COMPONENTALLOCATION` 表:存储组件分配(物料组件与工序的关系) - `TEXT` 表:存储文本描述 - `TEXTALLOCATION` 表:存储文本分配关系 2. **调用BAPI**: ```abap CALL FUNCTION 'BAPI_ROUTING_CREATE' EXPORTING testrun = space " 空格表示正式创建,'X'表示测试 bomusage = '1' " BOM用途,1表示生产 IMPORTING group = lv_group " 返回的工艺路线组 groupcounter = lv_groupcounter " 返回的组计数器 TABLES operation = lt_operation " 工序表 componentallocation = lt_component " 组件分配表 textallocation = lt_text_allocation " 文本分配表 text = lt_text " 文本表 return = lt_return. " 返回消息表 ``` 3. **检查返回值并提交**: ```abap READ TABLE lt_return WITH KEY type = 'E'. IF sy-subrc <> 0. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. ENDIF. ``` ### 关键数据结构说明 | 表名 | 字段示例 | 说明 | |---------------------|------------------------|--------------------------| | `OPERATION` | OPERATION = '0010' | 工序号 | | | WORK_CNTR = 'WC_001' | 工作中心 | | | CONTROL_KEY = 'PP01' | 控制码 | | `COMPONENTALLOCATION`| ITEM_NODE = '0001' | 组件在BOM中的节点号 | | | OPERATION = '0010' | 分配到的工序号 | | `TEXT` | TEXT_ID = 'GRP' | 文本ID(如GRP表示组文本)| | | TEXT_LINE = '注释文本' | 文本内容 | > **注意**:使用BAPI创建需确保所有外键(如工作中心、BOM)已存在[^2]。 ### 创建工艺路线的前提条件 1. 物料主数据已维护(事务码MM01) 2. 工作中心已创建(事务码CR01) 3. 如需分配组件,则BOM必须存在(事务码CS01) ### 相关问题 §§相关问题§§ 1. SAP中如何修改已存在的工艺路线? 2. 如何通过BAPI批量创建工艺路线? 3. 工艺路线中的控制码(Control Key)有哪些类型? 4. 如何将工艺路线与生产版本关联? </think>### SAP创建工艺路线的方法详解 在SAP创建工艺路线有两种主要方式,根据引用内容说明如下: #### 方法1:事务码前台操作(手工创建) 1. **进入创建界面** 事务码 `CA01` - 输入物料号(Material) - 输入工厂代码(Plant) - 组计数器(Group Counter)自动生成或手动指定 2. **维护工序数据** ```ABAP | 工序号 | 工作中心 | 控制码 | 标准工时 | 准备时间 | 机器时间 | |--------|----------|--------|----------|----------|----------| | 0010 | WC_100 | PP01 | 1.5小时 | 0.5小时 | 1小时 | | 0020 | WC_200 | PP03 | 2小时 | 0.2小时 | 1.8小时 | ``` - **控制码**决定工序类型(如PP01=生产,PP02=检验) - 双击工序可维护详细参数(成本中心、作业类型等)[^1] 3. **关联组件分配(可选)** 在工序界面点击"组件分配",将BOM物料分配到具体工序: ```ABAP OPERATION 0010: COMPONENT1 - QTY 2 PC COMPONENT2 - QTY 1 PC ``` 4. **保存激活** - 点击保存按钮(Ctrl+S) - 系统生成工艺路线号(格式: 物料号+工厂+组计数器) #### 方法2:BAPI编程创建(批量处理) 引用[2]提供了核心函数: ```ABAP DATA: lt_operation TYPE TABLE OF bapi_operation, lt_component TYPE TABLE OF bapi_component_allocation. * 填充工序数据 APPEND VALUE #( operation = '0010' work_cntr = 'WC_100' control_key = 'PP01' base_quantity = 1 " 基准数量 activity = 'LABOR' " 作业类型 std_value = 1.5 " 标准工时 ) TO lt_operation. * 填充组件分配 APPEND VALUE #( operation = '0010' component = 'MAT-001' item_qty = 2 ) TO lt_component. * 调用BAPI创建 CALL FUNCTION 'BAPI_ROUTING_CREATE' EXPORTING material = 'FG-1000' plant = '1000' TABLES operation = lt_operation componentallocation = lt_component return = lt_return. * 提交事务 IF NOT line_exists( lt_return[ type = 'E' ] ). CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'. ENDIF. ``` > 关键参数说明: > - `control_key`必须匹配后台配置(OPJH) > - `base_quantity`应与生产版本批量匹配[^1] > - 组件分配需已存在有效BOM(CS01) ### 前提条件 1. **基础数据就绪** - 物料主数据MRP视图已维护(MM01) - 工作中心已创建(CR01) - 成本中心/作业类型配置正常(KP26) 2. **权限要求** 需具备以下权限对象: - `C_CRTD_AB` (工艺路线创建) - `C_WKCTR_2` (工作中心访问) 3. **版本控制** - 新建工艺路线默认状态为"1"(已创建) - 需执行`CA80`发布后状态变为"4"(已释放)方可被生产订单使用 ### 最佳实践 - **批量创建**:结合`LSMW`或`BDC`实现历史数据迁移 - **变更管理**:修改后使用`CA02`创建新组计数器,确保旧订单不受影响 - **集成验证**:创建后运行`CKC1`检查工艺路线-BOM一致性 --- ### 相关问题
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DeveloperMrMeng

觉得有用的佛系投币哦

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

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

打赏作者

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

抵扣说明:

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

余额充值