SAP RFC 函数创建 Java程序调用 学习总结 一步一步图文并茂

前言

公司即将接到一个项目与SAP有接口。老大让我们搞SAP,首先SAP接触过,但是没玩过开发,本周就专心的在研究这一块.

各种碰壁,SAP的系统让我怎么说呢? 算了,说多了都是泪,下面附上本周学习成果,大家一起探讨一下,ABAP 还得多学学.

Package (tcode:se80)

输入需要创建的 Package ,例:ZTP (之前用T打头测试,貌似不行,大家可以试试)

点  Yes 创建.

输入创建Package的信息.

Table (tcode:se11)

点击Create.

点击保存,弹出选择Package界面

保存即可.

切换到 Fields 选项卡:

一个字段可对应一个数据元素,一个数据元素可对应多个字段.

如上图: ZAGE 数据元素不存在,双击可进入:

提示不存在,则创建.

输入数据类型,长度:

保存,都会提示选择Package,后面就不说了.

激活该数据元素.

回到创建表界面,即可发现数据类型和长度都已显示.

点击 技术设置.

保存即可.

点击 索引.

点击创建索引.

输入索引名字.

选择字段等

保存,激活索引,激活表.

上面忘记设置 Key,选一个字段设置Key即可.

Function Group (tcode:se37)

输入创建Function Group的信息.点击保存后弹出选择 Package 的界面:

选择刚刚创建的 Package :

保存即可.

Function Module (tcode:se37)

Z_TEST_1

点击创建 , 选择函数组.

创建后 , 在Attributes选项卡 选择 Remote 远程调用函数.

这里简单说一下 Import,Export,Tables 三个选项卡

Import 就是需要导入的字段,在SAP的测试运行的时候可以输入该值进行测试,外部程序调用时传值进入,可以理解 Java方法参数.

Export 就是导出字段,程序执行完成后返回字段,可以理解 Java方法返回值,不过可以返回多个.

Tables 可以作为导入、导出, 他的字段为数据结果,其实就是一个复杂参数,比如说外围程序调用要传入一批数据,就可以使用他了,导出一样,可以返回一批数据.

这里我们就使用Table做一个批量上传数据的一个功能,点击 Tables选项卡,定义字段

Parameter Name,参数名,自己定义

Type spec,参数类型 ,普通值使用Type即可,不过在Tables这里一般定义复杂类型,使用Like模拟一个结构对象

Associated Type,使用Like 时输入我们的参考对象,可以是表、视图、元素等.

然后回车即可,第一次回车好像报红,再回车一次就可以了,不知道其它大神有没有遇到过.

点击 Source code 选项卡,进入编码.

小白也不知道复杂的编码,所以只能简单写一下了.

我们的目标是将传入的数据插入到SAP的内表中,编码如下

INSERT ZTAB01 FROM TABLEIMPT.

以上代码就可以啦,将传入的 IMPT 导入到内表中.

先保存,点击Check,无错误激活即可.

然后点击激活.

左下角会提示激活.

然后我们可以测试一下程序是否成功.

进入到输入参数界面,即可看到我们定义的Tables字段.

点击进入编辑数据.

完成编辑后,返回.

点击执行即可.

此为执行结果.

通过 tcode:se11 进入到数据库表查看数据

数据已插入到SAP内表.

Z_TEST_2

数据上传已经完成,这个时候我们做一个数据查询的Function.

同样我们选择 远程调用函数

这个时候我们加一个 Import参数,有选择性的根据条件来查询.

在Tables参数我们加一个返回参数.

设置好后,进入编码 source code.

*判断传入参数是否为空
IF DZNAME = '' .
*为空查询所有数据
SELECT * INTOTABLE OUTT FROM ZTAB01.
ELSE.
SELECT * INTOTABLE OUTT FROM ZTAB01 WHERE ZNAME = DZNAME.
ENDIF.

点击 Check,无问题后,激活测试.

测试时,输入参数显示出来了.

执行后,上图已出结果,点击进入查看明细.

不输入条件时查询.

到此RFC我们就已经创建好了.

Java

准备工具

Eclipse

SapJco.jar

librfc32.dll

sapjcorfc.dll

(以上两个动态连接需要加载,最简单的办法就是放在和Java执行程序放在一起,其实就是JDK环境 bin 目录下)

环境

Window 环境

JDK 1.6 32位

首先准备了一个工具类,连接SAP.

import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.Client;

/**
 * SAP 连接工具类
 * @author berr
 * 2014.11.7
 */
public class SapConn {

	private JCO.Client client; //客户端连接对象
	private JCO.Function function; //RFC Function 对象
	String host,clientId,userName, password,lang, sysnr; //地址,客户端,用户名,密码,语言,系统标识

	public SapConn(){

	}

	/**
	 * 创建连接对象
	 */
	public void connect(){
		client = JCO.createClient(clientId, userName,password,lang,host,sysnr);
		client.connect();
	}

	/**
	 * 断开连接
	 */
	public void disconnect(){
		client.disconnect();
	}

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}

	/**
	 * 注册并获取一个RFC函数
	 * @param reName 注册名称,任意
	 * @param ftName RFC 名称
	 */
	public void regFunction(String reName,String ftName){
		JCO.Repository mRepository = new JCO.Repository(reName,this.client);
		IFunctionTemplate ft = mRepository.getFunctionTemplate(ftName.toUpperCase());
		this.function = ft.getFunction();
	}

	/**
	 * 设置输入参数
	 * @param parameter 参数名
	 * @param value 值
	 */
	public void setImport(String parameter,String value){
		JCO.ParameterList im = this.function.getImportParameterList();
		im.setValue(value,parameter);
	}

	/**
	 * 获取Tables结构对象
	 * @param tableName 参数名称
	 * @return
	 */
	public JCO.Table getTable(String tableName){
		return this.function.getTableParameterList().getTable(tableName);
	}

	/**
	 * 执行当前注册的函数
	 */
	public void execute(){
		this.client.execute(this.function);
	}

	public JCO.Function getFunction() {
		return function;
	}

	public void setFunction(JCO.Function function) {
		this.function = function;
	}

}

这里我们开始准备测试类

测试插入RFC函数,代码如下

import com.sap.mw.jco.JCO;

public class CallInsert {

	public static void main(String[] args) {

		SapConn sc = new SapConn();
		sc.host="192.168.0.140";
		sc.clientId = "001";
		sc.userName = "dev";
		sc.password = "d123456";
		sc.lang = "zh";
		sc.sysnr="000";
		/*以上都是连接SAP需要的信息,登录SAP GUI也需要这些,就不多解释了*/

		sc.connect();//创建连接

		String function1 = "Z_TEST_1";
		sc.regFunction(function1,function1); //注册并获取一个Function

		JCO.Table imt =  sc.getTable("IMPT"); //获取Function 中设置的Tables参数

		for (int i = 0; i < 10; i++) {
			imt.appendRow(); //增加一行
			imt.setValue(i, "ZAGE"); // 设置 ZAGE 值,必须为大写
			imt.setValue("C" + i, "ZNAME");//  设置 ZNAME 值,必须为大写
		}

		sc.execute();

		sc.disconnect();

	}
}

执行成功后,返回SAP查看结果.

测试查询RFC函数,代码如下

import com.sap.mw.jco.JCO;

public class CallQuery {

	public static void main(String[] args) {

		SapConn sc = new SapConn();
		sc.host="192.168.0.140";
		sc.clientId = "001";
		sc.userName = "dev";
		sc.password = "d123456";
		sc.lang = "zh";
		sc.sysnr="000";
		/*以上都是连接SAP需要的信息,登录SAP GUI也需要这些,就不多解释了*/

		String tpl = "name:%s,age:%s";

		sc.connect();//创建连接

		String function1 = "Z_TEST_1";
		sc.regFunction(function1,function1); //注册并获取一个Function

		String zname = "C1";
		sc.setImport("DZNAME",zname); //设置输入参数

		sc.execute();

		JCO.Table imt =  sc.getTable("OUTT"); //获取Function Tables中的数据

		System.out.println("-------根据条件"+zname+"查询-----------");
		do{
			Object name = imt.getValue("ZNAME");
			Object age = imt.getValue("ZAGE");
			System.out.println(String.format(tpl, name,age));

		}while(imt.nextRow());

		System.out.println("-------不根据条件查询-----------");

		sc.regFunction(function1,function1); //注册并获取一个Function
		sc.execute();

		imt =  sc.getTable("OUTT"); //获取Function Tables中的数据

		do{
			Object name = imt.getValue("ZNAME");
			Object age = imt.getValue("ZAGE");
			System.out.println(String.format(tpl, name,age));

		}while(imt.nextRow());

		sc.disconnect();

	}
}

执行结果如下:

以上,简单的RFC程序开发与外部程序调用就完成了,欢迎大家一起交流.

下面再总结一些外部程序调用的异常情况.

动态链接库未加载

Exceptionin thread "main" java.lang.ExceptionInInitializerError:JCO.classInitialize(): Could not load middleware layer'com.sap.mw.jco.rfc.MiddlewareRFC'
JCO.nativeInit():Could not initialize dynamic link library sapjcorfc [no sapjcorfc injava.library.path]. java.library.path[D:\work\wms\jdk1.6.0_26\jre\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;E:/jdk15/BIN/../jre/bin/client;E:/jdk15/BIN/../jre/bin;E:/jdk15/BIN/../jre/lib/i386;d:\app\berr\product\11.2.0\client_1\bin;E:\jdk15\BIN;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;D:\eclipse-jee-indigo-SR2-win32\eclipse;;.]
            atcom.sap.mw.jco.JCO.<clinit>(JCO.java:776)
            at SapConn.connect(SapConn.java:26)
            at CallInsert.main(CallInsert.java:18)

解决方案:将sapjcorfc.dll,librfc32.dll 加载到JDK动态链接库中,最简单的办法及复制到JAVA_HOME/bin目录下.

RFC 未开启远程调用

Exceptionin thread "main" com.sap.mw.jco.JCO$Exception: (104)RFC_ERROR_SYSTEM_FAILURE: The function module "Z_TEST_2" cannot beused for 'remote' calls.
            atcom.sap.mw.jco.rfc.MiddlewareRFC$Client.nativeExecute(NativeMethod)
            at com.sap.mw.jco.rfc.MiddlewareRFC$Client.execute(MiddlewareRFC.java:1242)
            atcom.sap.mw.jco.JCO$Client.execute(JCO.java:3816)
            atcom.sap.mw.jco.JCO$Client.execute(JCO.java:3261)
            at SapConn.execute(SapConn.java:82)
            at CallQuery.main(CallQuery.java:30)

解决方案:开启远程调用即可.

以上,希望大家交流交流! 本人邮箱:[email protected]  ,博客不能上传附件,需要Java源码的可以Email我。

Java 源码已上传 http://download.csdn.net/detail/iberr/8133125.

时间: 2025-01-02 16:51:27

SAP RFC 函数创建 Java程序调用 学习总结 一步一步图文并茂的相关文章

C# 使用 SAP NCO3.0 调用SAP RFC函数接口

C# 使用 SAP NCO3.0 调用SAP RFC函数接口 最近使用C#调用SAP RFC函数,SAP提供了NCO3.0组件. 下载组件安装,之后引用“sapnco.dll”和“sapnco_utils.dll”两个文件. 在程序中 using SAP.Middleware.Connector; 具体看下面代码 使用app.config文件配置注册客户端连接 <?xml version="1.0"?> <configuration> <configSec

【Python】Java程序员学习Python(五)— 函数的定义和使用

不想做一个待宰的羔羊!!!!要自己变得强大.... 函数的定义和使用放在最前边还是有原因的,现在语言趋于通用,基本类型基本都是那些,重点还是学习对象的使用方法,而最根本的还是方法的使用,因此优先介绍,方法的目的还是重用和封装 一.方法的定义 方法的定义使用关键词def来定义,定义格式如下: def 方法名(参数定义): 方法体 方法名:方法名的规范同变量名规范一样 参数定义:比较复杂,后面会进行讲解 冒号:这个类似于Java的{},必不可少 方法体:方法实现的功能在此定义即可 简单的例子: #定

mysql创建 存储过程 并通过java程序调用该存储过程

create table users_ning(id primary key auto_increment,pwd int); insert into users_ning values(id,1234); insert into users_ning values(id,12345); insert into users_ning values(id,12); insert into users_ning values(id,123); CREATE PROCEDURE login_ning(

介绍SAP预留函数创建搜索帮助

紧接上一节介绍的SAP预定义的出口函数F4IF_SHLP_EXIT_EXAMPLE创建搜索帮助, 该函数主要有两个部分: Changing接口的参数属性如下: SHLP:搜索帮助的基础描述,包括搜索帮助的名称.类型以及内部信息等. 以下:1)INTERFACE:会列出该搜索帮助中包含哪些字段及当前使用的是哪个字段. 2)FIELDDESCR:会列出包含字段的具体属性,如字段名称.类型.长度等 3)FIELDPROP:搜索帮助所定义字段的参数设置,如:EXP/IMP/SPos等 4)SELOPT:

Java程序员学习之路

1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基本没有其它任何一本书可以超越它.该书的作者Bruce Eckel在网络上被称为天才的投机者,作者的<Thinking in C++> 在1995年曾获SoftwareDevelopment Jolt Award最佳书籍大奖,<Thinking in Java>被评为1999年Java

Java程序猿学习当中各个阶段的建议

回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议 引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容基本上忘得一干二净,所以写这篇文章其实是很有难度的. 但是,最近问LZ的人实在是太多了,为了避免重复回答,给自己省点力气,干脆就在这里统一回复了. 其实之前LZ写过一篇文章,但是那篇文章更多的是在讨论“面试前该不该刷题”这个

回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议

其实本来真的没打算写这篇文章,主要是我得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.我自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容基本上忘得一干二净,所以写这篇文章其实是很有难度的. 但是,最近问我的人实在是太多了,为了避免重复回答,给自己省点力气,干脆就在这里统一回复了. 其实之前我写过一篇文章,但是那篇文章更多的是在讨论"面试前该不该刷题"这个话题,而这篇文章将会更加聚焦在面试前如何准备,以及工作当中如何学习这个话题上,而

面试?顺谈Java程序员学习中各阶段的建议

第一个问题:阿里面试都问什么? 这个是让LZ最头疼的一个问题,也是群里的猿友们问的最多的一个问题.说实话,LZ只能隐约想起并发.JVM.分布式.TCP/IP协议这些个关键字,具体的问题真的是几乎都没记住.而且就算LZ记住了,也告诉你了,你也背会了,但LZ觉得,在面试中,你被问到一模一样问题的可能性依然很小. 甚至,就算你运气好被问到了,你也照着背下来了,也不一定就能对你的面试起到正面的作用,因为面试官万一多问一句,你可能就露馅了,那还不如干脆点说不会更好. LZ参加的是阿里的社招面试,而社招不同

聊聊阿里社招面试,谈谈“野生”Java程序员学习的道路

阿里社招面试都问什么? 和之前一样,文章一上来,我们先来谈谈阿里的社招面试都问什么,其实这个话题并不是什么秘密,所有来阿里面试过的同学,都能回答一二. 两年前的时候,笔者在文章里是这么回答的. 这个是让LZ最头疼的一个问题,也是群里的猿友们问的最多的一个问题. 说实话,LZ只能隐约想起并发.JVM.分布式.TCP/IP协议这些个关键字,具体的问题真的是几乎都没记住.而且就算LZ记住了,也告诉你了,你也背会了,但LZ觉得,在面试中,你被问到一模一样问题的可能性依然很小. 甚至,就算你运气好被问到了