ABAP 采购订单增强(屏幕增强与逻辑增强)

一、采购订单屏幕增强,主要涉及增强点SMOD MM06E005或者BADI ME_GUI_PO_CUST,

本次示例使用增强SMOD MM06E005,BADI ME_GUI_PO_CUST可参考SAP标准示例(SE18->转到->示例代码->显示)。

1、抬头屏幕增强

① 在结构CI_EKKODB和CI_EKKODBX中添加字段

②在函数组XM06生成屏幕0101,并绘制屏幕,其中输入输出框建议给组1赋值,以便控制屏幕是否可输入,如下图所示

 ③ 修改屏幕逻辑流,控制是否可输入必须添加,其余搜索帮助或者增加描述字段可根据需求添加

设置字段可否编辑、显示与隐藏PBO事件代码可添加在INCLUDE ZXM06ZZZ中,代码如下:

MODULE status_0101 OUTPUT.
* SET PF-STATUS 'xxxxxxxx'.
* SET TITLEBAR 'xxx'.
  CASE gv_trtyp_c.
    WHEN 'A'.
      LOOP AT SCREEN.
        IF gv_trtyp_c = 'A'.
          screen-input  = 0.
          MODIFY SCREEN.
        ENDIF.
      ENDLOOP.
    WHEN 'V'.
      IF sy-tcode = 'ME29N'.
        CLEAR: lv_kzfae.
        SELECT SINGLE kzfae INTO @lv_kzfae
          FROM t16fb
          WHERE frgke = @ekko-frgke.
        IF sy-subrc = 0 AND lv_kzfae = 1.
          LOOP AT SCREEN.
            screen-input  = 0.
            MODIFY SCREEN.
          ENDLOOP.
        ENDIF.
      ENDIF.
    WHEN OTHERS.
  ENDCASE.

  LOOP AT SCREEN.
    IF screen-group1 = 'G1'.
      AUTHORITY-CHECK OBJECT 'YMM_GJ_EKO'
                          ID 'EKORG' FIELD ekko-ekorg
                          ID 'ACTVT' FIELD '01'.
      IF sy-subrc <> 0.
        screen-active = 0.
        MODIFY SCREEN.

        ASSIGN (screen-name) TO FIELD-SYMBOL(<fs_any>).
        IF sy-subrc = 0.
          CLEAR <fs_any>.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDLOOP.

ENDMODULE.

④将值传递到屏幕使用函数出口EXIT_SAPMM06E_006,控制屏幕字段可否编辑变量gv_trtyp_c(事务类型)定义在INCLUDE ZXM06TOP中,赋值也在此函数中:

 ⑤将屏幕值传回使用函数出口EXIT_SAPMM06E_008:

 2、行项目屏幕增强

① 在结构CI_EKPODB和CI_EKPODBX中添加字段

 

 ②行项目同抬头类似,在函数组XM06生成屏幕0111,并绘制屏幕,如下图所示

 ③ 修改屏幕逻辑流,控制是否可输入必须添加,其余搜索帮助或者增加描述字段可根据需求添加

MODULE status_0111 OUTPUT.
* SET PF-STATUS 'xxxxxxxx'.
* SET TITLEBAR 'xxx'.

  CASE gv_aktyp_c.
    WHEN 'A'.
      LOOP AT SCREEN.
        screen-input  = 0.
        MODIFY SCREEN.
      ENDLOOP.
    WHEN 'V'.
      IF sy-tcode = 'ME29N'.
        SELECT SINGLE kzfae INTO @DATA(lv_kzfae)
          FROM t16fb
          WHERE frgke = @ekko-frgke.
        IF sy-subrc = 0 AND lv_kzfae = 1.
          LOOP AT SCREEN.
            screen-input  = 0.
            MODIFY SCREEN.
          ENDLOOP.
        ENDIF.
      ENDIF.
    WHEN OTHERS.
  ENDCASE.



  IF sy-tcode = 'ME21N' OR sy-tcode = 'ME22N' OR sy-tcode = 'ME29N'
                        OR ( sy-tcode = 'ME23N' AND gv_aktyp_c = 'V' ).
    AUTHORITY-CHECK OBJECT 'Z_SYC_PUR'
                       ID 'ACTVT' FIELD '02'.
    IF sy-subrc <> 0.
      IF NOT ekpo_ci-zzsyst IS INITIAL.
        "MESSAGE e000(zmm) WITH '您没有修改外围系统同步订单的权限'.
        LOOP AT SCREEN.
          screen-input  = 0.
          MODIFY SCREEN.
        ENDLOOP.
      ELSE.
        LOOP AT SCREEN.
          IF screen-group1 = 'G1'.
            screen-input  = 0.
            MODIFY SCREEN.
          ENDIF.
        ENDLOOP.
      ENDIF.
    ENDIF.
  ENDIF.

ENDMODULE.

④将值传递到屏幕使用函数出口EXIT_SAPMM06E_016:

 ⑤将屏幕值传回使用函数出口EXIT_SAPMM06E_018:

二、采购订单逻辑增强,主要是对增强点 ME_PROCESS_PO_CUST进行增强实施,

check方法如下代码所示:

METHOD if_ex_me_process_po_cust~check.

    INCLUDE mm_messages_mac.

    DATA: l_head      TYPE mepoheader,
          l_item      TYPE mepoitem,
          items       TYPE purchase_order_items,
          item_obj    TYPE purchase_order_item,
          account     TYPE purchase_order_accountings,
          account_obj TYPE purchase_order_accounting,
          ls_account  TYPE mepoaccounting,   "科目分配字段结构.
          lv_type     TYPE char1.

**  sy-tcode = 'ME21N' OR sy-tcode = 'ME22N' OR sy-tcode = 'ME29N' .
    CHECK NOT im_header IS INITIAL.

    l_head = im_header->get_data( ).   "获取抬头
    items  = im_header->get_items( ) . "获取行项目

****根据抬头输入的公司代码BUKRS,取表YTGYLCONF02取值
****国际:如果取到的ZBUS_LINE='3’,则检查利润中心,并且
****      如果采购渠道或船(次)号为空,则报错“请检查采购渠道、船(次)号必须输入”,
****      如果合同号或净额结算为空,则警告“请检查合同号、净额结算是否需要输入”
****船舶:如果取到的ZBUS_LINE='4’,则警告“请检查船(次)号、合同号是否需要输入”
    SELECT SINGLE ybus_line
      INTO @DATA(lv_busline)
      FROM ytgylconf02
     WHERE bukrs = @l_head-bukrs.
    IF sy-subrc = 0.
      IF lv_busline = '3'.
        IF l_head-zzcgqd IS INITIAL OR l_head-zzaufnr IS INITIAL.
          mmpur_business_obj_id l_head-id.
          mmpur_context mmcnt_context_badi.
          mmpur_message_forced 'E' 'ZMM' '010' space space space space.
          ch_failed = 'X'.
        ENDIF.

        IF l_head-zzhth IS INITIAL OR l_head-zzjejs IS INITIAL.
          MESSAGE w013(zmm).
          mmpur_business_obj_id l_head-id.
          mmpur_context mmcnt_context_badi.
          mmpur_message_forced 'W' 'ZMM' '013' space space space space.
        ENDIF.

        LOOP AT items INTO item_obj.
          l_item = item_obj-item->get_data(  ).
          IF l_item-knttp = 'I'.
            account = item_obj-item->get_accountings(  ).
            LOOP AT account INTO account_obj.
              ls_account = account_obj-accounting->get_data(  ).
              IF ls_account-prctr IS INITIAL OR ls_account-prctr = '9999999999'.
                mmpur_business_obj_id l_item-id.
                mmpur_context mmcnt_context_badi.
                mmpur_message_forced 'E' 'ZMM' '012' '行项目' l_item-ebelp space space.
                CALL METHOD item_obj-item->invalidate( ).
                ch_failed = 'X'.
              ENDIF.
              CLEAR: ls_account.
            ENDLOOP.
          ENDIF.

          CLEAR: item_obj,
                 l_item,
                 account.
        ENDLOOP.
      ELSEIF lv_busline = '4'.
        IF l_head-zzaufnr IS INITIAL OR l_head-zzhth IS INITIAL.
          MESSAGE w011(zmm).
          mmpur_business_obj_id l_head-id.
          mmpur_context mmcnt_context_badi.
          mmpur_message_forced 'W' 'ZMM' '011' space space space space.
        ENDIF.
      ENDIF.
    ENDIF.

****校验船(次)号的内部订单类型是否为XA18
    IF l_head-zzaufnr IS NOT INITIAL.
      SELECT SINGLE auart
        INTO @DATA(lv_auart)
        FROM aufk
       WHERE aufnr = @l_head-zzaufnr.
      IF sy-subrc <> 0 OR lv_auart <> 'XA18'.
        mmpur_business_obj_id l_head-id.
        mmpur_context mmcnt_context_badi.
        mmpur_message_forced 'E' 'ZMM' '009' space space space space.
        ch_failed = 'X'.
      ENDIF.
    ENDIF.

ENDMETHOD.

 其中有几点注意点:

1. 使用宏 mmpur_message_forced 将消息添加至消息弹框中。

2. 添加消息之前需指定是抬头消息还是行项目消息,使用宏 mmpur_business_obj_id 指定。

3. 增强的消息使用宏 mmpur_context 设置context值为常量 mmcnt_context_badi(12),因为维护SAP标准字段与增强字段所走的代码逻辑不一致,清空消息则是根据context值,所以如果不特殊赋值则可能context值当前为 mmcnt_context_default(5),如果仅仅修改增强字段则不会清空context值为 mmcnt_context_default(5)的消息,那即使校验通过原先的消息依然存在。

4. 此方法如果使用了Message语句抛出消息,但并不会在前台看到。。。

所以所以,用户提了个需求,说他们操作习惯不点检查,这样很容易忽略警告消息,希望在任一屏幕回车时候能看到消息。如果仅仅是增强屏幕回车则可以直接在增强屏幕添加PAI事件,但需求是标准屏幕回车也要触发,这又由于仅修改增强子屏幕的字段值与标准屏幕的处理逻辑不一样,而且没有回车没有用户出口或者BADI增强点,最终在我费了九牛二虎之力后确定了一个都会走的隐式增强点:类 CL_SCREEN_VIEW_MM 方法 PAI_FINISHED,代码如下:

METHOD PAI_FINISHED.
* ...
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""$"$\SE:(1) Class CL_SCREEN_VIEW_MM, Method PAI_FINISHED, End                                                                                                 A
*$*$-Start: (1)---------------------------------------------------------------------------------$*$*
ENHANCEMENT 1  YENH_MEPO_CHECK.    "active version
  DATA: ls_ekko    TYPE ekko,
        lv_busline TYPE ytgylconf02-ybus_line.

  IF ( sy-tcode = 'ME21N' OR sy-tcode = 'ME22N' ) AND sy-ucomm = ''.
    ASSIGN ('(SAPLMEPO)EKKO') TO FIELD-SYMBOL(<fs_ekko>).
    IF sy-subrc = 0 AND <fs_ekko> IS ASSIGNED.
      MOVE-CORRESPONDING <fs_ekko> TO ls_ekko.

*     根据抬头输入的公司代码BUKRS,取表YTGYLCONF02取值
*     国际:如果取到的ZBUS_LINE='3’,则检查利润中心,并且
*           如果采购渠道或船(次)号为空,则报错“请检查采购渠道、船(次)号必须输入”,
*           如果合同号或净额结算为空,则警告“请检查合同号、净额结算是否需要输入”
*     船舶:如果取到的ZBUS_LINE='4’,则警告“请检查船(次)号、合同号是否需要输入”
      SELECT SINGLE ybus_line
        INTO lv_busline
        FROM ytgylconf02
       WHERE bukrs = ls_ekko-bukrs.
      IF sy-subrc = 0.
        IF lv_busline = '3'.
          IF ls_ekko-zzhth IS INITIAL OR ls_ekko-zzjejs IS INITIAL.
            MESSAGE s013(zmm) DISPLAY LIKE 'W'.
          ENDIF.

          IF ls_ekko-zzcgqd IS INITIAL OR ls_ekko-zzaufnr IS INITIAL.
            MESSAGE s010(zmm) DISPLAY LIKE 'E'.
          ENDIF.
        ELSEIF lv_busline = '4'.
          IF ls_ekko-zzaufnr IS INITIAL OR ls_ekko-zzhth IS INITIAL.
            MESSAGE s011(zmm) DISPLAY LIKE 'W'.
          ENDIF.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.

ENDENHANCEMENT.
*$*$-End:   (1)---------------------------------------------------------------------------------$*$*
ENDMETHOD.

这里需注意由于不能让屏幕灰色显示,所以这消息需要定义成S类型,使用DISPLAY LIKE其他消息类型显示。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值