SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN

SAP ABAP 顾问(开发工程师)能力模型_Terry谈企业数字化的博客-CSDN博客文章浏览阅读423次。目标:基于对SAP abap 顾问能力模型的梳理,给一年左右经验的abaper 快速成长为三年经验提参考ALV/REPORT|SMARTFROM|SCREEN|OLE|BAPI|BDC|PI|IDOC|RFC|API|WEBSERVICE|Enhancement|UserExits|Badi|Debughttps://blog.csdn.net/java_zhong1990/article/details/132469977


一 背景介绍

1.1  SAP Java Connector (JCo) 是一个用于在 Java 应用程序中访问 SAP 系统的库。它允许 Java 开发人员使用 Java 编程语言来调用 SAP 系统的功能,而无需编写任何 SAP ABAP 代码。

     使用 JCo,您可以:

  1. 在 Java 应用程序中访问 SAP 数据库。
  2. 在 Java 应用程序中调用 SAP 业务功能。
  3. 在 Java 应用程序中读取和写入 SAP 表格。
  4. 在 Java 应用程序中使用 SAP 中间件进行通信。

     JCo 支持以下功能:

  1. 通过 JCo 进行身份验证,使用 Java 程序员的用户凭证登录到 SAP 系统。
  2. 使用 JCo API,通过 Java 程序访问和操作 SAP 系统中的数据。
  3. 使用 JCo 进行数据传输,将数据从 Java 应用程序传输到 SAP 系统,反之亦然。
  4. 使用 JCo 进行远程函数调用 (RFC),在 Java 应用程序中调用 SAP 系统中的函数。
  5. 使用 JCo 进行事务处理,在 Java 应用程序中启动、提交和回滚 SAP 事务。
  6. 使用 JCo 进行批处理,在 Java 应用程序中批量处理 SAP 事务。
  7. 使用 JCo 进行错误处理,在 Java 应用程序中处理从 SAP 系统返回的错误和异常。

2.2 JAVA JCO 都有哪些版本 ?

     SAP JCo 主要有以下版本:

  1. SAP JCo 3.0:这是较早的版本,已经有了基本的功能,可以实现在 Java 应用程序中访问 SAP 系统的数据和业务逻辑。
  2. SAP JCo 3.1:这是 SAP JCo 的最新版本,相比 3.0 版本,它有了一些改进和增强,例如更好的性能、更稳定的连接、更多的功能等。

        除了以上版本,SAP JCo 还提供了 Standalone 版本,这个版本可以用于在外部(非 SAP)Java 应用程序和 AS ABAP 之间建立通信。同时,SAP 还提供了 JCo 的 IDoc 处理组件,可以用于处理 SAP 系统中的 IDoc 文档。

二 环境搭建

1 软件版本

Win10 / 64位系统

JAVA项目 landray  ekp_v15,java jdk 1.8 

SAP系统,S/4 hana

2 部署搭建步骤

2.1  将 sapjco3.dll 加入到c:/windows/SysWOW64/目录 ,或者将 sapjco3.dll 加入到 JDK/bin 目录下.;或者将 sapjco3.dll 加入到 Tomcat/bin ;或者安装SAP GUI750/760客户端都是可以 ,这边直是安装SAP GUI750客户端。

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第1张图片

2.2 再java项目中加入jco JAR,应用到项目中,JAVA的项目技术一般都是非常的老旧,JAR包的管理也并没有用 Maven ,( 新手谨慎进入,特别是OA项目,一入必死无疑 ! )

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第2张图片

三 代码模板

3.1 JAVA 代码模板


package com.landray.kmss.cee.sapcall.util;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;

public class GetSapConn {

    static String ABAP_AS_POOLED = "SAP-RFC_DEV151"; // 所属异构系统 【找sap要】

    private static void createDataFile() {
        Properties properties = new Properties();
        // 测试
        properties.setProperty(DestinationDataProvider.JCO_ASHOST, "");// sap服务器地址, Q120 :192.168.22.34
        properties.setProperty(DestinationDataProvider.JCO_SYSNR, "");// 系统编号,找SAP核对写00就可以了
        properties.setProperty(DestinationDataProvider.JCO_CLIENT, "");// 集团号
        properties.setProperty(DestinationDataProvider.JCO_USER, "");// 帐号
        properties.setProperty(DestinationDataProvider.JCO_PASSWD, "");// 密码
        properties.setProperty(DestinationDataProvider.JCO_LANG, "");// 语言

        String name = ABAP_AS_POOLED;
        String suffix = "jcoDestination";
        File cfg = new File(name + "." + suffix);
        if (!cfg.exists()) {
            try {
                FileOutputStream fos = new FileOutputStream(cfg, false);
                properties.store(fos, "SAP logon parameters:");
                fos.close();
            } catch (Exception e) {
                throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
            }
        }

    }

    public static JCoDestination getJcoConnection() throws JCoException {
        createDataFile();
        return JCoDestinationManager.getDestination(ABAP_AS_POOLED);
    }

}

 数据源连接地址

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第3张图片

private Map doTosap(Map map) {
		Map sapReturnMap = new HashMap();
		
		JCoDestination jCoDestination;
		JCoFunction function = null;
		try {
			jCoDestination = GetSapConn.getJcoConnection();
			function       = jCoDestination.getRepository().getFunctionTemplate("ZSDIF003_1").getFunction();
			JCoStructure struc   = function.getImportParameterList().getStructure("I_DATA");

	        struc.setValue("PARTNER", map.get("FD_STAFF_NO"));      //业务伙伴编号
	        struc.setValue("NAME_ORG1", map.get("FD_NAME"));        //客户名称
	        struc.setValue("BANKN", map.get("FD_PAYROLL_ACCOUNT")); //银行帐户号码
	        struc.setValue("ACCNAME", map.get("FD_PAYROLL_BANK"));  //银行帐户的名称
	        logger.info(struc.toString()); 
	        function.execute(jCoDestination);
	         
	        sapReturnMap.put("TYPE", function.getExportParameterList().getString("E_TYPE")) ;
	        sapReturnMap.put("MESSAGE", function.getExportParameterList().getString("E_MESSAGE")) ;
	        sapReturnMap.put("PARTNER", function.getExportParameterList().getString("E_PARTNER")) ;
	        logger.info(sapReturnMap.toString());
	        return sapReturnMap;
			
		} catch (JCoException e) {
			e.printStackTrace();
		}
         return sapReturnMap;
		
	}

3.2 SAP 代码模板

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第4张图片

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第5张图片 SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第6张图片

SAP_ABAP_JAVA 系统调用SAP系统 RFC , 实战案例之——供应商主数据(员工信息)同步| Java jco | BP| BAPI |RFC_CVI_EI_INBOUND_MAIN_第7张图片

FUNCTION zsdif003_1 .
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(I_DATA) TYPE  ZSSDIF003_1
*"  EXPORTING
*"     VALUE(E_TYPE) TYPE  CHAR1
*"     VALUE(E_MESSAGE) TYPE  CHAR50
*"     VALUE(E_PARTNER) TYPE  BUT000-PARTNER
*"----------------------------------------------------------------------
  "BAPI
  DATA: it_bp_general           TYPE TABLE OF cvis_bp_general      WITH HEADER LINE,
        it_bp_role              TYPE TABLE OF cvis_bp_role         WITH HEADER LINE,
        it_bp_address           TYPE TABLE OF cvis_bp_address      WITH HEADER LINE,
        it_bp_address_usage     TYPE TABLE OF cvis_bp_address_usage    WITH HEADER LINE,
        it_bp_address_teleno    TYPE TABLE OF cvis_bp_address_teleno   WITH HEADER LINE,
        it_bp_tax_number        TYPE TABLE OF cvis_bp_tax_number       WITH HEADER LINE,
        it_bp_address_faxno     TYPE TABLE OF cvis_bp_address_faxno WITH HEADER LINE,
        it_bp_address_email     TYPE TABLE OF cvis_bp_address_email WITH HEADER LINE,
        it_cust_general         TYPE TABLE OF cvis_customer_general WITH HEADER LINE,
        it_cust_sales           TYPE TABLE OF cvis_customer_sales  WITH HEADER LINE,
        it_cust_sales_functions TYPE TABLE OF cvis_customer_sales_func WITH HEADER LINE,
        it_cust_tax_indicator   TYPE TABLE OF cvis_customer_tax_indicator  WITH HEADER LINE,
        it_cust_company         TYPE TABLE OF cvis_customer_company WITH HEADER LINE,
        ct_return               TYPE TABLE OF cvis_bp_return  WITH HEADER LINE.

  DATA:
    ls_cvis_bp_bank_details TYPE          cvis_bp_bank_details, "
    lt_cvis_bp_bank_details LIKE TABLE OF cvis_bp_bank_details. "银行

  DATA: ls_msg TYPE  esp1_message_wa_type,
        lt_msg TYPE  esp1_message_tab_type.
  DATA: lv_error  TYPE  c.
  DATA:l_msg(255) TYPE  c.


  i_data-katr1 = '12'.

  "常规视图
  it_bp_general-run_id      = 1.
  it_bp_general-bpartner    = i_data-partner.     "客户号
  it_bp_general-name1       = i_data-name_org1.   "客户名称 ,传OA的姓名
*  it_bp_general-category    = i_data-type.       "业务伙伴类别
  it_bp_general-category    = '2'.                "业务伙伴类别
  it_bp_general-object_task = 'I'.                "'I'新增 ; 'U'更新
  it_bp_general-grouping    = 'Z902'.             "客户账户组

  APPEND it_bp_general.
  CLEAR  it_bp_general.

  "视图数据
  CLEAR  it_bp_role.
  it_bp_role-run_id   = 1.
  it_bp_role-data_key = 'FLCU00'."客户财务视图
  APPEND it_bp_role.


  DATA:lt_t001 TYPE TABLE OF t001.
  DATA:ls_t001 TYPE t001.
  ls_t001-bukrs = '2010'.
  ls_t001-bukrs = '2030'.
  ls_t001-bukrs = '1000'.
  ls_t001-bukrs = '2020'.
  ls_t001-bukrs = '3010'.
  ls_t001-bukrs = '4220'.
  ls_t001-bukrs = '4240'.
  ls_t001-bukrs = '4260'.
  ls_t001-bukrs = '4270'.
  ls_t001-bukrs = '4280'.
  APPEND ls_t001 TO lt_t001.

  LOOP AT lt_t001 INTO ls_t001.
    "财务视图数据
    it_cust_company-run_id = 1.

    it_cust_company-bukrs  = ls_t001-bukrs.
    it_cust_company-akont  = '1221010300'."统驭科目
    it_cust_company-zterm  = '0001'.      "付款条件
    it_cust_company-zuawa  = '001'.       "排序码

    APPEND it_cust_company.
    CLEAR it_cust_company.
  ENDLOOP.

  it_cust_general-run_id = 1.
  it_cust_general-ktokd  = 'Z902'.  "客户账户组

  APPEND it_cust_general.
  CLEAR  it_cust_general.

  it_bp_address-run_id     = 1.
  it_bp_address-street     = i_data-stras.   "街道/门牌号
  it_bp_address-postl_cod1 = i_data-pstlz.   "邮政编码
  it_bp_address-city       = i_data-ort01.   "城市
  it_bp_address-country    = 'CN'.   "国家
  it_bp_address-region     = i_data-regio.   "省份
  it_bp_address-langu      = 'ZH'.   "语言代码

  APPEND it_bp_address.
  CLEAR  it_bp_address.

*  ls_cvis_bp_bank_details-run_id        = '1'.
*  ls_cvis_bp_bank_details-data_key      = '0001'.       "银行明细标识
*  ls_cvis_bp_bank_details-bank_ctry     = 'CN'.         "银行国家
*
*  ls_cvis_bp_bank_details-bank_key      = '0000000001'. "银行代码
*  ls_cvis_bp_bank_details-bank_acct     = 'bank_no'.    "银行账号
*  ls_cvis_bp_bank_details-bankaccountname = '银行帐户的名称'."银行帐户的名称
*  ls_cvis_bp_bank_details-bank_ref      = '123' .       "参考明细,账号写不下才放尾数在这
*  ls_cvis_bp_bank_details-accountholder = '账号持有人'."账号持有人。
*  APPEND ls_cvis_bp_bank_details TO lt_cvis_bp_bank_details.
*  CLEAR ls_cvis_bp_bank_details.



  CALL FUNCTION 'RFC_CVI_EI_INBOUND_MAIN'
    EXPORTING
      iv_docommit          = 'X'
    TABLES
      it_bp_general        = it_bp_general
      it_bp_role           = it_bp_role
      it_bp_address        = it_bp_address
*     it_bp_address_usage  = it_bp_address_usage
      it_bp_address_teleno = it_bp_address_teleno
      it_cust_general      = it_cust_general
      it_cust_company      = it_cust_company
*     it_bp_bank_details   = lt_cvis_bp_bank_details
      ct_return            = ct_return.



  REFRESH lt_msg .
  CLEAR: lv_error,l_msg .
  LOOP AT ct_return WHERE type EQ 'E' OR type EQ 'A'.
    lv_error = 'X' .

    CLEAR ls_msg .

    MESSAGE ID ct_return-id TYPE ct_return-type NUMBER ct_return-number
         INTO l_msg
         WITH ct_return-message_v1 ct_return-message_v2 ct_return-message_v3 ct_return-message_v4.

    APPEND ls_msg TO lt_msg .

    IF l_msg = ''.
      e_message = e_message  && ';' && l_msg .
    ENDIF.
    e_type = 'E'.
    e_message = l_msg.
  ENDLOOP .


  IF lv_error EQ 'X' ."没有

    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

  ELSE .

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.

    READ TABLE ct_return WITH KEY type = 'S'.
    IF sy-subrc = 0.
      e_partner = ct_return-object_key.
      e_type    = 'S'.
    ENDIF.

  ENDIF.


  IF e_partner IS NOT INITIAL.
    " ---
    DATA: wa_but0bk TYPE but0bk.
    DATA: wa_lfbk TYPE lfbk.
    DATA: l_change TYPE char1.

    DATA: i_bankdetaildata TYPE bapibus1006_bankdetail.
    DATA: e_bankdetailidout TYPE bapibus1006_head-bankdetailid.
    DATA: wa_return TYPE bapiret2,
          it_return LIKE STANDARD TABLE OF wa_return.

    DATA: i_bankdetaildata_x TYPE bapibus1006_bankdetail_x.


    CLEAR: e_bankdetailidout.
    CLEAR: it_return.

    CLEAR: i_bankdetaildata.
    i_bankdetaildata-bank_ctry       = 'CN'."国家
    i_bankdetaildata-bank_key        = '0000000001'."银行代码
    i_bankdetaildata-bank_acct       = i_data-bankn."'6225885919442046'."银行账号
    i_bankdetaildata-accountholder   = ''."账户持有人
    i_bankdetaildata-bankaccountname = i_data-accname."账户名称
*  CLEAR: i_bankdetaildata_x.
*  i_bankdetaildata_x-bank_ctry       = 'X'."国家
*  i_bankdetaildata_x-bank_key        = 'X'."银行代码
*  i_bankdetaildata_x-bank_acct       = 'X'."银行账号
*  i_bankdetaildata_x-accountholder   = 'X'."账户持有人
*  i_bankdetaildata_x-bankaccountname = 'X'."账户名称

    CLEAR: l_change.

*    SELECT SINGLE bkvid   FROM but0bk INTO @DATA(lv_bkvid) WHERE partner EQ @wa_data-partner
*       AND bkvid EQ @wa_data-bkvid.
*    IF sy-subrc = 0.
*      l_change = 'X'.
*    ELSE.
*
*    ENDIF.

    IF l_change = 'X'.
*      CALL FUNCTION 'BAPI_BUPA_BANKDETAIL_CHANGE'
*        EXPORTING
*          businesspartner  = wa_data-partner
*          bankdetailid     = wa_data-bkvid
*          bankdetaildata   = i_bankdetaildata
*          bankdetaildata_x = i_bankdetaildata_x
*        TABLES
*          return           = it_return.
    ELSE.
      CALL FUNCTION 'BAPI_BUPA_BANKDETAIL_ADD'
        EXPORTING
          businesspartner = e_partner
          bankdetailid    = '0001'
          bankdetaildata  = i_bankdetaildata
        IMPORTING
          bankdetailidout = e_bankdetailidout
        TABLES
          return          = it_return.
    ENDIF.

    LOOP AT it_return INTO wa_return WHERE type = 'E'
                                        OR type = 'A'
                                        OR type = 'X'.
      EXIT.
    ENDLOOP.
    IF sy-subrc = 0.
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ELSE.

      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.

    ENDIF.


    UPDATE kna1 SET katr1 = i_data-katr1 WHERE kunnr = e_partner.
    COMMIT WORK.
    " ---
  ENDIF.






ENDFUNCTION.

        业务顾问再设计的时,把员工设置成了客户账户组,正常是设置成供应商账户组,导致SAP标准的BAPI不可用,用该BAPI BAPI_BUPA_BANKDETAIL_ADD 代替 RFC_CVI_EI_INBOUND_MAIN

四 SAP方案

接口1:OA抛到SAP基本视图的字段(员工客户: 基本视图、财务视图、银行账户信息)

序号

字段名称

字段名

备注

1

业务伙伴

BUT000

PARTNER

CEE+OA建的员工工号比如:CEE88888

2

分组

BUT000

BU_GROUP

默认Z902:员工客户

3

名称

BUT000

NAME_ORG1

OA的姓名

4

国家

KNA1

LAND1

用客户号关联

BUT000- PARTNER= KNA1- KUNNR

默认CN

5

地区

KNA1

REGIO

6

语言

KNA1

SPRAS

默认ZH

7

属性1

KNA1

KATR1

默认12

8

银行国家

BUT0BK

BANKS

KNA1- KUNNR= BUT0BK - PARTNER,默认CN

9

银行代码

BUT0BK

BANKL

默认0000000001

10

银行账户

BUT0BK

BANKN

11

银行账号参考补充

BUT0BK

BKREF

当KNBK- BANKN字数超过18位,超过的部分放到该字段

12

银行账户名称

BUT0BK

ACCNAME

13

公司代码

KNB1

BUKRS

需维护2010/2030/1000/2020/3010/4220/4240/4260/4270/4280

14

统驭科目

KNB1

AKONT

默认1221010300

15

排序码

KNB1

ZUAWA

默认001

你可能感兴趣的:(Abap编程,Java编程,SAP,ABAP,JAVA,JCO)