本篇文章中我主要讲的是.NET如何通过RFC从SAP中读取数据。为了功能的可复用性,我将调用RFC的代码从业务层中分离出来单独建立在一个namespace中。

  当然除了需要我们自己编写代码以外,还需要引用SAP提供的程序集文件(sapnco.dll、sapnco_utils.dll),在代码文件需要引用相应的命名空间(using SAP.Middleware.Connector;)。

  我在这个namespace中建立了三个类来实现这个功能,一个配置类(RfcDestinationConfig)、一个参数类(RfcParam)、一个主体功能类(RfcManager)。

  • RfcDestinationConfig

  我们需要一个类来实现SAP的连接配置工作,就如同为数据连接层建立一个数据库配置类一样重要。

 1 public class RfcDestinationConfig : IDestinationConfiguration
 2     {
 3         #region 事件
 4         /// <summary>
 5         /// 配置变更事件
 6         /// </summary>
 7         public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
 8         /// <summary>
 9         /// 默认接收器名称
10         /// </summary>
11         public static readonly string DefaultDesName = "destination";
12         #endregion
13
14         #region 方法
15         /// <summary>
16         /// 配置变更事件触发时,暂时无用
17         /// </summary>
18         /// <param name="destinationName"></param>
19         /// <param name="args"></param>
20         public void OnConfigurationChanged(string destinationName, RfcConfigurationEventArgs args)
21         {
22             if (ConfigurationChanged != null)
23             {
24                 ConfigurationChanged(destinationName, args);
25             }
26         }
27
28         /// <summary>
29         /// 获取SAP配置参数
30         /// </summary>
31         /// <param name="destinationName"></param>
32         /// <returns></returns>
33         public RfcConfigParameters GetParameters(string destinationName)
34         {
35             if (destinationName == DefaultDesName)
36             {
37                 RfcConfigParameters parms = new RfcConfigParameters();
38                 parms.Add(RfcConfigParameters.AppServerHost,ConfigManager.GetAppSettings("SAPApplicationServer").Trim());   //SAP主机IP
39                 parms.Add(RfcConfigParameters.SystemNumber, ConfigManager.GetAppSettings("SAPSystemNumber").Trim());  //SAP实例
40                 parms.Add(RfcConfigParameters.User, ConfigManager.GetAppSettings("SAPUser").Trim());  //用户名
41                 parms.Add(RfcConfigParameters.Password,ConfigManager.GetAppSettings("SAPPwd").Trim());  //密码
42                 parms.Add(RfcConfigParameters.Client, ConfigManager.GetAppSettings("SAPClient").Trim());  // Client
43                 parms.Add(RfcConfigParameters.Language,ConfigManager.GetAppSettings("SAPLanguage").Trim());  //登陆语言
44                 return parms;
45             }
46             else
47             {
48                 return null;
49             }
50         }
51
52         /// <summary>
53         /// 变更事件方法,暂时无用
54         /// </summary>
55         /// <returns>true</returns>
56         public bool ChangeEventsSupported()
57         {
58             return true;
59         }
60         #endregion
61     }

  • RfcParam

  想要从SAP中读取数据,就必须将查询条件作为参数传递给RFC。另外为了返回的结果具有通用性,我使用DataTable作为返回结果的类型,然后考虑到不同条件下列是不同的,我又将列也参数化,最终我将输入参数和输出参数都封装在一个参数类之中。

 1 public class RfcParam
 2     {
 3         /// <summary>
 4         /// 初始化
 5         /// </summary>
 6         public RfcParam()
 7         {
 8             CoulmnNames = new List<string>();
 9             Param = new Dictionary<string, object>();
10         }
11         /// <summary>
12         /// RFC方法名称
13         /// </summary>
14         public string RfcName { get; set; }
15         /// <summary>
16         /// RFC表名
17         /// </summary>
18         public string TableName { get; set; }
19         /// <summary>
20         /// 数据表各列的列名
21         /// </summary>
22         public List<string> CoulmnNames { get; set; }
23         /// <summary>
24         /// RFC执行参数
25         /// </summary>
26         public Dictionary<string, object> Param { get; set; }
27     }

  • RfcManager

  该主角登场了,读取数据的功能正是业务层真正想要的东西。

  方法ExecRfc首先将输出参数转换成一个真正可用的新的DataTable,然后将输入参数传递给SAP执行相关的RFC功能并返回IRfcTable(SAP定义的一种接口),最后再将IRfcTable转换成我们自定义的DataTable。

 1 public class RfcManager
 2     {
 3         #region 属性字段
 4         /// <summary>
 5         /// 接收器
 6         /// </summary>
 7         public RfcDestination Prd { get; set; }
 8         /// <summary>
 9         /// 数据仓库
10         /// </summary>
11         public RfcRepository Repo { get; set; }
12         #endregion
13
14         #region 构造函数
15         /// <summary>
16         /// 初始化
17         /// </summary>
18         public RfcManager()
19         {
20             //初始化RFC接收器
21             //配置接收器
22             IDestinationConfiguration IDC = new RfcDestinationConfig();
23             //注册
24             RfcDestinationManager.RegisterDestinationConfiguration(IDC);
25             //获取RFC接收器
26             this.Prd = RfcDestinationManager.GetDestination(RfcDestinationConfig.DefaultDesName);
27             this.Repo = this.Prd.Repository;
28             //注销
29             RfcDestinationManager.UnregisterDestinationConfiguration(IDC);
30         }
31         #endregion
32
33         #region 方法
34         /// <summary>
35         /// 执行RFC获取数据表
36         /// </summary>
37         /// <param name="rfcname">rfc方法名称</param>
38         /// <param name="tablename">rfc表名</param>
39         /// <param name="columnnames">数据表列名列表</param>
40         /// <param name="param">rfc执行参数</param>
41         /// <returns>数据表</returns>
42         public DataTable ExecRfc(string rfcname, string tablename, List<string> columnnames, Dictionary<string, object> param)
43         {
44             DataTable dt = new DataTable();
45
46             if (columnnames != null && columnnames.Count > 0)
47             {
48                 //配置datatable
49                 dt.Columns.Clear();
50                 foreach (string cname in columnnames)
51                 {
52                     dt.Columns.Add(cname, typeof(string));
53                 }
54                 dt.AcceptChanges();
55
56                 //从SAP那获取数据表
57                 if (!string.IsNullOrEmpty(rfcname) && param != null && param.Count > 0)
58                 {
59                     IRfcFunction rfc = this.Repo.CreateFunction(rfcname);
60                     foreach (KeyValuePair<string, object> kv in param)
61                     {
62                         rfc.SetValue(kv.Key, kv.Value);
63                     }
64                     rfc.Invoke(this.Prd);
65                     IRfcTable iTable = rfc.GetTable(tablename);
66                     if (iTable.Count > 0)
67                     {
68                         for (int i = 0; i < iTable.RowCount; i++)
69                         {
70                             iTable.CurrentIndex = i;
71                             DataRow oNewRow = dt.NewRow();
72                             foreach (string cname in columnnames)
73                             {
74                                 oNewRow[cname] = iTable.GetString(cname).ToString();
75                             }
76                             dt.Rows.Add(oNewRow);
77                         }
78                     }
79                 }
80             }
81
82             return dt;
83         }
84         #endregion
85     }

转载于:https://www.cnblogs.com/liusuqi/p/3745099.html

.NET通过RFC读取SAP数据相关推荐

  1. PP实施经验分享(5)——SAP中MD04显示常用函数(读取SAP MRP运行数据)

    PP实施经验分享(5)--SAP中MD04显示常用函数(读取SAP MRP运行数据) SAP实施过程中,经常会遇到用户对于现有MD04标准功能展示有一定的抱怨,不符合我们查看的习惯,经常会提出相关报表 ...

  2. SAP ABAP 探索 CL_FDT_XL_SPREADSHEET 读取大数据量 Excel 的可能性

    SAP ABAP 探索 CL_FDT_XL_SPREADSHEET 读取大数据量 Excel 的可能性 引言: 今时不同往日了,特别是在电商和零售行业中,动不动一个导入的 Excel 就有几十万行几十 ...

  3. 33. 如何找出 SAP Fiori Launchpad 里点击 tile 之后,读取业务数据调用的是哪个 SAP 后台系统的 OData 服务

    文章目录 如何找到 SAP Fiori Launchpad tile 对应的 SAP UI5 应用名称 如何找到 SAP UI5 应用发出的 OData 请求明细 如何找到 SAP UI5 应用发送的 ...

  4. JAVA与SAP数据交互的方式总结

    JAVA与SAP数据交互的方式总结 RFC方式:Java程序直接通过RFC访问SAP的对象(或称函数,可能叫法不对)     SAP提供了BAPI(Business Application Progr ...

  5. TensorFlow csv读取文件数据(代码实现)

    TensorFlow csv读取文件数据(代码实现) 大多数人了解 Pandas 及其在处理大数据文件方面的实用性.TensorFlow 提供了读取这种文件的方法. 前面章节中,介绍了如何在 Tens ...

  6. SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...

    转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发--关于TreeView树形控 ...

  7. Kinect V1读取图像数据(For Windows)

    Kinect V1读取图像数据(For Windows) 这篇博客 Kinect V1介绍 数据读取的基本流程 运行代码和注释 结尾 这篇博客  刚好有一台现成的Kinect V1相机,所以就拿过来学 ...

  8. C++ 简单读写文本文件、统计文件的行数、读取文件数据到数组

    转自:http://hi.baidu.com/ctralt/blog/item/cde79fec87f841302697911c.html fstream提供了三个类,用来实现c++对文件的操作.(文 ...

  9. 图像数据读取及数据扩增方法

    Datawhale干货 作者:王程伟,Datawhale成员 本文为干货知识+竞赛实践系列分享,旨在理论与实践结合,从学习到项目实践.(零基础入门系列:数据挖掘/cv/nlp/金融风控/推荐系统等,持 ...

最新文章

  1. 开始测试React Native App(下篇)
  2. objc swift 混编
  3. 一起学nRF51xx 13 - twi iic
  4. neo4j删除所有节点
  5. html的段落标志中 标注行中断,?HTML的段落标志中,标注行中断的是?
  6. LeetCode单链表题目测试代码(只需添加对应题目,本地即可debug)
  7. 哇、、、、C++ 实现单向链表
  8. 在Windows平台下使用Gitblit搭建Git服务器图文解说
  9. 广数系统u盘支持什么格式_u盘装系统,u盘要格式化成什么格式
  10. Spring boot配置文件两种方式
  11. 05MySQL基本操作
  12. php支付自定义金额,自定义付款/支付/收费
  13. 免费又稳定的短链接生成工具
  14. JAVA计算机毕业设计在线购书商城系统Mybatis+源码+数据库+lw文档+系统+调试部署
  15. 扫描全能王添加头像的方法
  16. 织梦个人网站即时到账支付插件
  17. 什么是SAAS——软件即服务
  18. 记一次手机本地时间修改引起的https请求失效的bug分享 转 萧竹
  19. 这5个设计师都在用的配色网站,你一定要收藏起来
  20. BLUESIGN认证辅导,bluesign system管理输入,采取哪些负责任的行动

热门文章

  1. GitHub 五万星登顶,命令行的艺术!
  2. 对一些架构设计原则的反思
  3. GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean
  4. Java:写2个线程,其中一个线程打印1-52,另一个线程打印A-Z,打印顺序应该是12A34B56C...5152Z。
  5. 网络:.cookie和session原理及区别
  6. 【Python】青少年蓝桥杯_每日一题_5.27_画菱形
  7. 描述一下普适计算时代中的计算机,《课程总结报告-普适计算及其应用》.doc
  8. 人工智能时代的数据中心该怎么建?腾讯给出了自己的答案
  9. mysql 数据目录迁移_MySQL数据库数据文件路径迁移步骤
  10. CV:计算机视觉技术之图像基础知识—以python的cv2库来了解计算机视觉图像基础