.NET通过RFC读取SAP数据
本篇文章中我主要讲的是.NET如何通过RFC从SAP中读取数据。为了功能的可复用性,我将调用RFC的代码从业务层中分离出来单独建立在一个namespace中。
当然除了需要我们自己编写代码以外,还需要引用SAP提供的程序集文件(sapnco.dll、sapnco_utils.dll),在代码文件需要引用相应的命名空间(using SAP.Middleware.Connector;)。
我在这个namespace中建立了三个类来实现这个功能,一个配置类(RfcDestinationConfig)、一个参数类(RfcParam)、一个主体功能类(RfcManager)。
- RfcDestinationConfig
我们需要一个类来实现SAP的连接配置工作,就如同为数据连接层建立一个数据库配置类一样重要。
public class RfcDestinationConfig : IDestinationConfiguration
{
#region 事件
/// <summary>
/// 配置变更事件
/// </summary>
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
/// <summary>
/// 默认接收器名称
/// </summary>
public static readonly string DefaultDesName = "destination";
#endregion #region 方法
/// <summary>
/// 配置变更事件触发时,暂时无用
/// </summary>
/// <param name="destinationName"></param>
/// <param name="args"></param>
public void OnConfigurationChanged(string destinationName, RfcConfigurationEventArgs args)
{
if (ConfigurationChanged != null)
{
ConfigurationChanged(destinationName, args);
}
} /// <summary>
/// 获取SAP配置参数
/// </summary>
/// <param name="destinationName"></param>
/// <returns></returns>
public RfcConfigParameters GetParameters(string destinationName)
{
if (destinationName == DefaultDesName)
{
RfcConfigParameters parms = new RfcConfigParameters();
parms.Add(RfcConfigParameters.AppServerHost,ConfigManager.GetAppSettings("SAPApplicationServer").Trim()); //SAP主机IP
parms.Add(RfcConfigParameters.SystemNumber, ConfigManager.GetAppSettings("SAPSystemNumber").Trim()); //SAP实例
parms.Add(RfcConfigParameters.User, ConfigManager.GetAppSettings("SAPUser").Trim()); //用户名
parms.Add(RfcConfigParameters.Password,ConfigManager.GetAppSettings("SAPPwd").Trim()); //密码
parms.Add(RfcConfigParameters.Client, ConfigManager.GetAppSettings("SAPClient").Trim()); // Client
parms.Add(RfcConfigParameters.Language,ConfigManager.GetAppSettings("SAPLanguage").Trim()); //登陆语言
return parms;
}
else
{
return null;
}
} /// <summary>
/// 变更事件方法,暂时无用
/// </summary>
/// <returns>true</returns>
public bool ChangeEventsSupported()
{
return true;
}
#endregion
}
- RfcParam
想要从SAP中读取数据,就必须将查询条件作为参数传递给RFC。另外为了返回的结果具有通用性,我使用DataTable作为返回结果的类型,然后考虑到不同条件下列是不同的,我又将列也参数化,最终我将输入参数和输出参数都封装在一个参数类之中。
public class RfcParam
{
/// <summary>
/// 初始化
/// </summary>
public RfcParam()
{
CoulmnNames = new List<string>();
Param = new Dictionary<string, object>();
}
/// <summary>
/// RFC方法名称
/// </summary>
public string RfcName { get; set; }
/// <summary>
/// RFC表名
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 数据表各列的列名
/// </summary>
public List<string> CoulmnNames { get; set; }
/// <summary>
/// RFC执行参数
/// </summary>
public Dictionary<string, object> Param { get; set; }
}
- RfcManager
该主角登场了,读取数据的功能正是业务层真正想要的东西。
方法ExecRfc首先将输出参数转换成一个真正可用的新的DataTable,然后将输入参数传递给SAP执行相关的RFC功能并返回IRfcTable(SAP定义的一种接口),最后再将IRfcTable转换成我们自定义的DataTable。
public class RfcManager
{
#region 属性字段
/// <summary>
/// 接收器
/// </summary>
public RfcDestination Prd { get; set; }
/// <summary>
/// 数据仓库
/// </summary>
public RfcRepository Repo { get; set; }
#endregion #region 构造函数
/// <summary>
/// 初始化
/// </summary>
public RfcManager()
{
//初始化RFC接收器
//配置接收器
IDestinationConfiguration IDC = new RfcDestinationConfig();
//注册
RfcDestinationManager.RegisterDestinationConfiguration(IDC);
//获取RFC接收器
this.Prd = RfcDestinationManager.GetDestination(RfcDestinationConfig.DefaultDesName);
this.Repo = this.Prd.Repository;
//注销
RfcDestinationManager.UnregisterDestinationConfiguration(IDC);
}
#endregion #region 方法
/// <summary>
/// 执行RFC获取数据表
/// </summary>
/// <param name="rfcname">rfc方法名称</param>
/// <param name="tablename">rfc表名</param>
/// <param name="columnnames">数据表列名列表</param>
/// <param name="param">rfc执行参数</param>
/// <returns>数据表</returns>
public DataTable ExecRfc(string rfcname, string tablename, List<string> columnnames, Dictionary<string, object> param)
{
DataTable dt = new DataTable(); if (columnnames != null && columnnames.Count > )
{
//配置datatable
dt.Columns.Clear();
foreach (string cname in columnnames)
{
dt.Columns.Add(cname, typeof(string));
}
dt.AcceptChanges(); //从SAP那获取数据表
if (!string.IsNullOrEmpty(rfcname) && param != null && param.Count > )
{
IRfcFunction rfc = this.Repo.CreateFunction(rfcname);
foreach (KeyValuePair<string, object> kv in param)
{
rfc.SetValue(kv.Key, kv.Value);
}
rfc.Invoke(this.Prd);
IRfcTable iTable = rfc.GetTable(tablename);
if (iTable.Count > )
{
for (int i = ; i < iTable.RowCount; i++)
{
iTable.CurrentIndex = i;
DataRow oNewRow = dt.NewRow();
foreach (string cname in columnnames)
{
oNewRow[cname] = iTable.GetString(cname).ToString();
}
dt.Rows.Add(oNewRow);
}
}
}
} return dt;
}
#endregion
}
.NET通过RFC读取SAP数据的更多相关文章
- .NET利用RFC连接SAP,查询、读取SAP数据
为黄朴整理!!!!!!!!!!!!!!!!! 在NuGet 添加 sapnco 一个简单的SAPCommand,方法 GetDataTableFromRFCTable 复制于 https://www. ...
- ABAP案例:灵活读取SAP各表的数据
案例说明 RFC读取表中数据. Import 参数名称 Type spec. 参考打印 FIELDS_NAME1 TYPE CHAR25 TABLE_NAME1 TYPE CHAR25 WHE ...
- 一百一十五、脱离SAP本体,通过ActiveX读取SAP表中数据
一.Sap自带有客户端,但是非常之臃肿卡顿,可以利用ActiveX的方式,脱离Sap本体,来读取Sap表中的内容进行插入等操作,非常之方便.代码如下: 二.界面如下,输入好相关内容,点击登录,提示登录 ...
- C#通过RFC调用SAP
using System;using System.Collections.Generic;using SAP.Middleware.Connector;using System.Data;using ...
- java的poi技术读取Excel数据到MySQL
这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...
- Hive读取外表数据时跳过文件行首和行尾
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 有时候用hive读取外表数据时,比如csv这种类型的,需要跳过行首或者行尾一些和数据无关的或者自 ...
- 读取数据库数据,并将数据整合成3D饼图在jsp中显示
首先我将生成饼图的方法独立写成一个PieChar.java类,详细代码如下:(数据库需要自己建,如有需要的话) import java.io.IOException; import java.sql. ...
- .NET读取Excel数据,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
解决.NET读取Excel数据时,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序的操作: 1. 检查本机是否安装Office Access,如果未安装去去h ...
- oledbdataadapter 读取excel数据时,有的单元格内容不能读出
表现:excel中某列中,有的单元格左上角有绿色箭头标志,有的没有,c#编写读取程序,但是只能读取出带绿色箭头的单元格中的内容,其余不带的读取不到内容 原因:excel中单元格因为是文本格式而存储了数 ...
随机推荐
- 【python】密码生成器
#!/usr/bin/env python#-*- coding:UTF-8 -*- import random #导入random模块import string #导入string模块 sal ...
- singleton(单件)-对象创建型模式
1.意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 2.动机 对一些类来说,只有一个实例是很重要的.让类自身负责保存它唯一的实例,这个类可以保证没有其他实例可以被创建(通过截取创建新对象 ...
- ProtoType(原型)-对象创建型模式
1.意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.动机 通过拷贝或者“克隆”一个类的实例来创建新的实例. 3.适用性 当一个系统应该独立于它的产品创建.构成和表示时,要使 ...
- web工程中URL地址的推荐写法
三.web工程中URL地址的推荐写法 使用c标签<c:url value="" /> 会自动添加项目名 -> value中的值 前面要加 “/” 在JavaWeb ...
- POSIX信号处理
信号用于通知进程发生了某件事情,可以由一个进程发给另一个进程,也可以由内核发个一个进程. 每个信号都有一个关联的行为,可以通过sigaction函数来设置一个信号的行为,有3种选择: 1.定义一个信号 ...
- java基础(1)-比较jdk5,jdk6,jdk7的新特性
jdk8已经出来好长时间了,这里自己学习时简单总结的jdk5,jdk6和jdk7的新特性:本文提纲: 一.jdk5的新特性 二.jdk6的新特性 三.jdk7的新特性 一.jdk5的新特性 首先简单介 ...
- 乐视云计算基于OpenStack的IaaS实践
本文作者岳龙广,现在就职于乐视云计算有限公司,负责IaaS部门的工作. 从开始工作就混在开源世界里,在虚拟化方面做过CloudStack/Ovirt开发,现在是做以OpenStack为基础的乐视云平台 ...
- MySQL日期时间函数大全(转)
MySQL日期时间函数大全 DAYOFWEEK(date) 返回日期date是星期几(1=星期天,2=星期一,……7=星期六,ODBC标准)mysql> select DAYOFWEEK('1 ...
- php实现验证码
验证码在表单实现越来越多了,但是用js的写的验证码,总觉得不方便,所以学习了下php实现的验证码.好吧,其实是没有事情干,但是又不想浪费时间,所以学习了下php实现验证码.正所谓,技多不压身.而且 ...
- windows小技巧 从文件夹直接打开命令行位置
windows下从命令行打开某个目录下的东东时,会一直cd ~~~~,更简单的是: 直接用鼠标找到该文件夹或者文件,按住Shift键然后点击鼠标右键,选择"在此处打开命令行"即可 ...