前言
SAP与外部系统进行数据交换的方法众多,如常见的PI、WSDL、HTTP等,如果外部系统是企业内部系统,源码自主,使用RFC也是一种可选的非常方便的方法。
SAP官方提供了标准的SDK,可供其它开发语言进行调用SAP中的RFC。
本文将分别介绍在JAVA、PYTHON、C#/.NET中如何进行编码来调用SAP的RFC方法。
RFC准备
FUNCTION zrfc_say_hello.*"----------------------------------------------------------------------*"*"本地接口:IV_VALUE*" IMPORTING*" VALUE(IV_VALUE) TYPE STRING*" EXPORTING*" VALUE(EV_VALUE) TYPE STRING*" TABLES*" IT_INPUT STRUCTURE T001W*" ET_OUTPUT STRUCTURE T001W*"----------------------------------------------------------------------
ev_value = |Hello { iv_value }! From sap { sy-datum }{ sy-uzeit }|. SELECT * INTO TABLE @et_output FROM t001w UP TO 10 ROWS FOR ALL ENTRIES IN @it_input WHERE werks = @it_input-werks.
ENDFUNCTION.传入一个字符串 IV_VA LUE 和一个 IT_INPUT 内表(只需WERKS字段赋值即可)
返回一个字符串 EV_VA LUE 和一个 ET_OUTPUT 内表
JAVA调用
1. 下载sapjco3.jar包,根据自己系统到SAP官方网站下载(需要SAP账号),或者网上找资源
https://support.sap.com/en/product/connectors.html?anchorId=section_125501632
2\. 创建JAVA项目,引入JAR包
3\. 示例程序
import com.sap.conn.jco.*;import com.sap.conn.jco.ext.DataProviderException;import com.sap.conn.jco.ext.DestinationDataEventListener;import com.sap.conn.jco.ext.DestinationDataProvider;
import java.util.Properties;
import static com.sap.conn.jco.ext.Environment.registerDestinationDataProvider;import static com.sap.conn.jco.ext.Environment.unregisterDestinationDataProvider;
public class saptest {
static String SAP_SERVER = "SAP_SERVER";
public static void main(String[] args) { class MyDestinationDataProvider implements DestinationDataProvider { private final Properties properties;
public MyDestinationDataProvider() {
properties = new Properties(); }
@Override public Properties getDestinationProperties(String s) throws DataProviderException { String host = "xx.xx.xx.xx"; String router = "xxxx"; String clientName = "xxx";//200 String language = "ZH"; String userId = "xxxx"; String password = "xxx"; String system = "xx";//00 properties.clear(); properties.setProperty(DestinationDataProvider.JCO_ASHOST, host); properties.setProperty(DestinationDataProvider.JCO_SAPROUTER, router); properties.setProperty(DestinationDataProvider.JCO_SYSNR, system); properties.setProperty(DestinationDataProvider.JCO_CLIENT, clientName); properties.setProperty(DestinationDataProvider.JCO_USER, userId); properties.setProperty(DestinationDataProvider.JCO_PASSWD, password); properties.setProperty(DestinationDataProvider.JCO_LANG, language); properties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "30"); return properties; }
@Override public boolean supportsEvents() { return false; }
@Override public void setDestinationDataEventListener(DestinationDataEventListener destinationDataEventListener) {
} }
try { MyDestinationDataProvider myProvider = new MyDestinationDataProvider(); registerDestinationDataProvider(myProvider); JCoDestination destination = JCoDestinationManager.getDestination(SAP_SERVER); JCoRepository repos = destination.getRepository(); JCoFunction function = repos.getFunction("ZRFC_SAY_HELLO");//调用SAP接口 JCoParameterList importParameterList = function.getImportParameterList(); importParameterList.setValue("IV_VALUE", "JAVA");//设置入参 JCoParameterList tableParameterList = function.getTableParameterList();//获取表格参数 JCoTable inputTable = tableParameterList.getTable("IT_INPUT"); //获取输入表IT_INPUT的数据参数 for (int i = 0; i < 10; i++) { //往输入表中,给指定字段参数进行赋值 inputTable.appendRow(); inputTable.setRow(i); inputTable.setValue("WERKS", (1000 + i) + ""); } function.execute(destination); JCoParameterList exportParameterList = function.getExportParameterList(); System.out.println(exportParameterList.getString("EV_VALUE"));//获取出参 JCoTable outputTable = tableParameterList.getTable("ET_OUTPUT");//获取输出表ET_OUTPUT的数据 for (int i = 0; i < outputTable.getNumRows(); i++) { outputTable.setRow(i); System.out.println(outputTable.getString("WERKS") + " " + outputTable.getString("NAME1"));//获取输出结果中的两个字段 }
unregisterDestinationDataProvider(myProvider);
} catch (Exception e) { System.out.println(e.getMessage()); } }}
4\. 运行结果
Python调用
1. 下载SAP NetWeaver RFC SDK, 根据自己系统到SAP官方网站下载(需要SAP账号),或者网上找资源
https://support.sap.com/en/product/connectors.html?anchorId=section_125501632,另外根据https://github.com/SAP/PyRFC中的
Requirements介绍设置环境变量。
2\. 安装pyrfc,这个直接使用pip安装就可以了 。
3\. 示例程序
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError, \ ExternalRuntimeError
def get_connection(connmeta=None): try: if not connmeta: connmeta = { 'user': 'xxx', 'passwd': 'xxx', 'ashost': 'xx.xx.xx.xx', 'saprouter': 'xxx', 'sysnr': 'xxx', #00 'client': 'xxx', #200 # 'trace': '3', # optional, in case you want to trace 'lang': 'ZH' } return Connection(**connmeta)
except CommunicationError: print(u"Could not connect to server.") raise except LogonError: print(u"Could not log in. Wrong credentials?") raise except (ABAPApplicationError, ABAPRuntimeError): print(u"An error occurred.") raise
def main(): conn = get_connection() inputTable = [{"WERKS": str(1000 + i)} for i in range(10)] args = {'IV_VALUE': 'PYTHON', 'IT_INPUT': inputTable} try: result = conn.call('ZRFC_SAY_HELLO', **args) print(result["EV_VALUE"]) for row in result["ET_OUTPUT"]: print(row["WERKS"], row["NAME1"]) except ExternalRuntimeError as exc: print(exc.message) conn.close()
if __name__ == "__main__": main()
4\. 运行结果
C#调用
1. 下载sapnco.dll, 根据自己系统到SAP官方网站下载(需要SAP账号),或者网上找资源
https://support.sap.com/en/product/connectors.html?anchorId=section_125501632
2\. 创建C#程序,添加引用。
3\. 示例程序
using System;using SAP.Middleware.Connector;
namespace TEST_RFC{ class Program { static String SAP_SERVER = "SAP_SERVER"; static void Main(string[] args) { IDestinationConfiguration ID = new MyBackendConfig(); RfcDestinationManager.RegisterDestinationConfiguration(ID); RfcDestination prd = RfcDestinationManager.GetDestination(SAP_SERVER); RfcRepository repo; try { repo = prd.Repository; IRfcFunction function = repo.CreateFunction("ZRFC_SAY_HELLO"); //调用函数名 function.SetValue("IV_VALUE", ".NET"); //设置Import的参数 IRfcTable inputTable = function.GetTable("IT_INPUT"); //输入表 RfcStructureMetadata structMeta = inputTable.Metadata.LineType; for (int i = 0; i < 10; i++) { IRfcStructure import = structMeta.CreateStructure(); import.SetValue("
...