.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中单元格因为是文本格式而存储了数 ...
随机推荐
- (十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- Linux网络编程-readn函数、writen函数、readline函数实现
readn函数功能:在网络编程的读取数据中,通常会需要用到一个读指定字节才返回的函数,linux系统调用中没有给出,需要自己封装. readn实现代码: int readn(int fd, void ...
- 项目Windows服务安装命令:
sc create YY.SmsPlatform.RemoteDataCenter binPath= "E:\YY.SmsPlatform\YY.SmsPlatform.RemoteData ...
- android笔记:DatePickerDialog日期设置对话框
在开发中,可以通过DatePickerDialog来设置日期,TimePickerDialog来设置时间. 实例化DatePickerDialog对象之后,再调用show方法就可以显示对话框了. 具体 ...
- 揭开HTTP网络协议神秘面纱系列(二)
HTTP报文内的HTTP信息 HTTP协议交互的信息被称为HTTP报文,请求端的HTTP报文叫做请求报文,响应端的叫做响应报文. HTTP为了提升传输速率,其在传输数据时,按照数据原样进行压缩传输,相 ...
- Android编译环境搭建(0818-0819)
1 在虚拟机VMware上安装64位Ubuntu14.04LTS 首先需要安装虚拟机并激活.然后新建虚拟机,选择使用下载好的Ubuntu镜像.注意需要将光驱改为自己下载的,而不是autoinst.is ...
- three.js 源码注释(四十四)Light/DirectionalLight.js
/** * * DirectionalLight方法 根据设置灯光的颜属性color, 强度属性intensity创建平行光光源. * DirectionalLight 对象的功能函数采用定义构造的函 ...
- Java实现多线程的两种方式
实现多线程的两种方式: 方式1: 继承Thread类 A: 自定义MyThread类继承Thread类 B: 在MyThread类中重写run() C: 创建MyThread类的对象 D: 启动线程对 ...
- Android(Xamarin)之旅(一)
Xamarin废话我就不多说了. 就是一款编写Android和IOS应用的IDE,从Visual Studio2010就开始有个这个插件.只要发展什么的,我觉得在这里说还不如自己去百度呢. 入正题: ...
- cocos2d-x 之 CCArray 的遍历(3)
cocos2d-x中CCArray的遍历,需要几个宏.现代C++程序设计建议尽量不要使用宏,所以数组的遍历也可以自己写. 但cocos2d-x官方已经提供了几个方便数组遍历的几个宏,用好了,能方便许多 ...