SAP ABAP 当标准BAPI或事务无法指定用户名执行的处理办法

@


需求

有时我们会面对某一标准事务或bapi需要以特定账户执行,以财务的过账、冲销举例,过账时可以在header中填写用户名指定创建人,这里不做阐述。

如果面对BAPI_ACC_DOCUMENT_REV_POST这样用于冲销且没有指定用户名字段的BAPI,但又需要冲销到指定用户名下,有以下方法

1.远程调用RFC的方式

2.创建SE38程序 通过调用后台作业的方式指定用户名执行


一、远程调用RFC的方式

1.SM59配置

新建ABAP类型连接


指定client和用户名

注意系统是否为Unicode

连接测试通过即可

2.指定用户需要满足以下条件

①.未被锁定
②.有S_RFCACL和S_RFC权限

3.创建远程RFC

BAPI调用成功后需要在当前luw中调用commit。

FUNCTION zbapi_acc_document_rev_post.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(REVERSAL) LIKE  BAPIACREV STRUCTURE  BAPIACREV
*"     VALUE(BUS_ACT) LIKE  BAPIACHE09-BUS_ACT
*"  EXPORTING
*"     VALUE(OBJ_TYPE) LIKE  BAPIACREV-OBJ_TYPE
*"     VALUE(OBJ_KEY) LIKE  BAPIACREV-OBJ_KEY
*"     VALUE(OBJ_SYS) LIKE  BAPIACREV-OBJ_SYS
*"  TABLES
*"      RETURN STRUCTURE  BAPIRET2
*"----------------------------------------------------------------------

  DATA:lv_error TYPE char1.

  CALL FUNCTION 'BAPI_ACC_DOCUMENT_REV_POST'
    EXPORTING
      reversal = reversal
      bus_act  = bus_act
    IMPORTING
      obj_type = obj_type
      obj_key  = obj_key
      obj_sys  = obj_sys
    TABLES
      return   = return.

  LOOP AT return[] INTO DATA(ls_return) WHERE type EQ 'E'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.

  IF lv_error IS NOT INITIAL.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'
*     IMPORTING
*       RETURN        =
      .
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'
*       IMPORTING
*       RETURN        =
      .
  ENDIF.

ENDFUNCTION.

实现代码:


*首先判断destination是否存在
CALL FUNCTION 'CAT_CHECK_RFC_DESTINATION'
    EXPORTING
      rfcdestination = 'ZDEST_FOR_TEST'
    IMPORTING
      msgv1          = lv_msg1
      msgv2          = lv_msg2
      rfc_subrc      = lv_subrc.


      CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
        IMPORTING
          own_logical_system = lv_system.
      ls_reversal-obj_type   = 'BKPFF'.
      ls_reversal-obj_key    = ls_bkpf-awkey.
      ls_reversal-obj_key_r  = ls_bkpf-awkey.
      ls_reversal-comp_code  = ls_bkpf-bukrs.
      ls_reversal-obj_sys = lv_system .
      ls_reversal-pstng_date = gs_date-zcxdate.

      CALL FUNCTION 'ZBAPI_ACC_DOCUMENT_REV_POST'  "  使用带commit远程rfc
        DESTINATION 'ZDEST_FOR_XGF'   " 使用HELPDESK冲销
        EXPORTING
          reversal = ls_reversal
          bus_act  = 'RFBU'
        IMPORTING
          obj_key  = lv_obj_key
        TABLES
          return   = lt_return.
      READ TABLE lt_return INTO ls_return WITH KEY type = 'E'.
      IF sy-subrc = 0.
        READ TABLE lt_return INTO ls_return_id WITH KEY number = 361 id = 'F5'.""已被冲销
        IF sy-subrc = 0.
          MESSAGE '凭证号:' && ls_bkpf-awkey && '已冲销' TYPE 'E'.
        ELSE.
          ROLLBACK WORK.
          cv_status = 'E'.
          MESSAGE '凭证冲销失败,凭证号:' && ls_bkpf-awkey TYPE 'E'.
          RETURN.
        ENDIF.
      ELSE.
        cv_status = 'S'.
      ENDIF.

二、创建SE38程序 通过调用后台作业的方式指定用户名执行


submit后跟用户名,程序内代码这里就自己补充啦

代码如下(示例):


*      安排作业  立即执行
      CALL FUNCTION 'JOB_OPEN'
        EXPORTING
          jobname          = lv_name
        IMPORTING
          jobcount         = lv_number
        EXCEPTIONS
          cant_create_job  = 1
          invalid_job_data = 2
          jobname_missing  = 3.
      IF sy-subrc EQ 0.

        SUBMIT zreport WITH SELECTION-TABLE lt_seltab
          USER lv_user AND RETURN
          VIA JOB lv_name NUMBER lv_number.

        IF sy-subrc EQ 0.

          CALL FUNCTION 'JOB_CLOSE'
            EXPORTING
              jobcount  = lv_number
              jobname   = lv_name
              strtimmed = 'X'.  "立即开始
              
        ENDIF.

总结

以上