.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中单元格因为是文本格式而存储了数 ...
随机推荐
- androidannotations 简单配置
1.build.gradle 需要添加的内容 标注的颜色是新建项目之后,build.gradle文件需要添加的内容. buildscript { repositories { jcenter() } ...
- JAVA学习<六>
1.Java中的局部变量和成员变量: 2.变量同名,优先方法的局部变量. 3. 4.构造方法: 5.Java 中的 static 使用之静态变量: Java 中被 static 修饰的成员称为静态成员 ...
- ajax无刷新上传图片
页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...
- Python笔记——break的注意事项
在python中有个控制流的语句:break 它是用来终止循环语句的,不管此时循环体进行到哪,只要碰到break都停止执行循环语句. 1.举例脚本: #!/usr/bin/env python for ...
- AngularJS学习--- 过滤器(filter),格式化要显示的数据 step 9
1.切换目录,启动项目 git checkout step- npm start 2.需求: 格式化要显示的数据. 比如要将true-->yes,false-->no,这样相互替换. 3. ...
- 数据字典和动态性能视图<五>
数据字典和动态性能视图 介绍:数据字典是什么 数据字典是 oracle 数据库中最重要的组成部分,它提供了数据库的一些系统信息. 动态性能视图记载了例程启动后的相关信息. 数据字典 数据字典记录了 ...
- Word-wrap&Text-overflow
- Ubuntu 14.04中gedit打开文件出现中文乱码问题
http://blog.csdn.net/cywosp/article/details/32325449/ 在中文支持配置还不完整的Ubuntu 14.04中,使用gedit打开带有中文字符的文件有时 ...
- LeetCode OJ-- Valid Number **@
https://oj.leetcode.com/problems/valid-number/ 判断给的串,是不是合理的 数字形式 主要问题在需求定义上吧 class Solution { public ...
- 解决Failed to load class "org.slf4j.impl.StaticLoggerBinder"
Hibernate使用SLF4J API记录日志,所以在Hibernate的lib中,不再提供Log4J的包,而大部分框架依然使用Log4J记录日志,这样导致了兼容性问题. 解决办法,两步: 一.在编 ...