方式1:使用客户端自带的组件
安装客户端以后,添加引用:SAPFunctionsOCX(.net 的Com列表里一般找不到,需要引用DLL【一般位于以下路径:Program Files\SAP\FrontEnd\SAPgui\wdtfuncs.ocx】),SAPLogonCtrl,SAPTableFactoryCtrl。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | public DataTable GetRFCData() { Connection conn = null ; SAPFunctionsClass func = null ; IFunction ifunc = null ; conn = this .getSAPConnection(); //返回SAP登录类 func = this .getSAPFunctionsClass(conn); //返回SAP操作类 ifunc = this .getIFunction( "ZHRIF01_FM01" , func); //返回SAP接口 //设定SAP RFC函数的参数 IParameter IP_DATA_BEGIN = (IParameter)ifunc.get_Exports( "I_DATUM" ); // IP_DATA_BEGIN.Value = "201602" ; // "20100101";//;strDatB; //"20090101"; //CALL RFC函数 ifunc.Call(); //输出参数 Tables Table_Outs = (Tables)ifunc.Tables; Table Table_mkpf = (Table)Table_Outs.get_Item( "T_RESULT" ); //获取返回结果集 DataTable dt = GetDataTable(Table_mkpf); //this.label1.Text = dt.Rows.Count.ToString(); return dt; } public Connection getSAPConnection() { //SAP登录类 SAPLogonControlClass logon = new SAPLogonControlClass(); Connection Conn; logon.ApplicationServer = "10.1.8.11" ; logon.Client = "300" ; logon.Language = "ZH" ; //EN OR ZH .... //logon.Language = "zh"; //EN OR ZH .... logon.User = "test" ; logon.Password = "test1234" ; logon.SystemNumber = Convert.ToInt16( "00" ); Conn = (SAPLogonCtrl.Connection)logon.NewConnection(); //Conn.CodePage = "8300"; //登录SAP if (!Conn.Logon(0, true )) //Login Successful { throw new Exception( "登录SAP系统失败,请重新登录!" ); } //返回SAP登录类 return Conn; } public SAPFunctionsClass getSAPFunctionsClass(Connection conn) { //SAPFunction Object SAPFunctionsClass func = new SAPFunctionsClass(); //Set Connection func.Connection = conn; return func; } /// <summary> /// 返回接口 /// </summary> /// <param name="IFunctionName"></param> /// <returns></returns> private IFunction getIFunction( string IFunctionName, SAPFunctionsClass func) { IFunction ifunc = (SAPFunctionsOCX.IFunction)func.Add(IFunctionName); return ifunc; } /// <summary> /// 将从sap获取的table转换为datatable /// </summary> /// <param name="saptb"></param> /// <returns></returns> /// private DataTable GetDataTable(Table saptb) { DataTable dt = new DataTable(); try { for ( int i = 1; i < saptb.ColumnCount; i++) { //dt.Columns.Add(saptb.get_ColumnName(i), typeof(string)); dt.Columns.Add(saptb.get_ColumnName(i)); } for ( int m = 1; m <= saptb.RowCount; m++) { DataRow dr = dt.NewRow(); for ( int n= 1; n < saptb.ColumnCount; n++) { string columnName=saptb.get_ColumnName(n); dr[saptb.get_ColumnName(n)] = saptb.get_Cell(m, columnName).ToString(); } dt.Rows.Add(dr); } } catch (Exception ex) { throw ex; } return dt; } |
注意:如果出现中文数据全部为#(井)的情况,这说明是CodePage的问题,暂时没找到解决办法。尝试设定SAPConnection的CodePage,结果提示内存不能写入。
方法2:在机器上没有安装客户端的情况下,使用官网提供的Nco3.0.16.0(SAP Connector for Microsoft .Net)。本DLL含有四个版本。
32位和64位,以及基于.Net2.0 或者 4.0编译的组件(本处代码基于:32位 4.0 的组件,开发环境VS2010),安装完毕后需要引用如下DLL文件:sapnco.dll,sapnco_utils.dll(位于安装目录下)
代码如下:
配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <configSections> <sectionGroup name= "SAP.Middleware.Connector" > <sectionGroup name= "ClientSettings" > <section name= "DestinationConfiguration" type= "SAP.Middleware.Connector.RfcDestinationConfiguration,sapnco" /> </sectionGroup> </sectionGroup> </configSections> <SAP.Middleware.Connector> <ClientSettings> <DestinationConfiguration> <destinations> <add NAME= "DEV" USER= "test" PASSWD= "1234" CLIENT= "300" LANG= "EN" ASHOST= "10.1.8.11" SYSNR= "00" MAX_POOL_SIZE= "10" IDLE_TIMEOUT= "10" /> </destinations> </DestinationConfiguration> </ClientSettings> </SAP.Middleware.Connector> <startup useLegacyV2RuntimeActivationPolicy= "true" > <supportedRuntime version= "v4.0" sku = ".NETFramework,Version=v4.0" /> <supportedRuntime version= "v2.0.50727" /> </startup> |
程序代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | public static DataTable GetSAPTestData() { RfcDestination destination = RfcDestinationManager.GetDestination( "DEV" ); RfcFunctionMetadata BAPI_COMPANYCODE_GETDETAIL_MD = destination.Repository.GetFunctionMetadata( "ZHRIF01_FM01" ); IRfcFunction function = null ; function = BAPI_COMPANYCODE_GETDETAIL_MD.CreateFunction(); function.SetValue( "I_DATUM" , "20160203" ); //设置参数 //function.SetParameterActive("COMPANYCODE_ADDRESS", false);设置参数 function.Invoke(destination); //提交调用 IRfcTable returnTable = function.GetTable( "T_RESULT" ); return GetDataTable(returnTable); } /// <summary> /// 将从sap获取的table转换为datatable /// </summary> /// <param name="saptb"></param> /// <returns></returns> /// public static DataTable GetDataTable(IRfcTable IrfTable) { DataTable dt = new DataTable(); //遍历元素个数,循环添加列 for ( int i=0;i<IrfTable.ElementCount;i++) { string columnName=IrfTable.GetElementMetadata(i).Name; dt.Columns.Add(columnName); } ////循环把IRfcTable里面的数据放入Table里面,因为类型不同,不可直接使用。 for ( int m= 0; m < IrfTable.RowCount; m++) { IrfTable.CurrentIndex = m; DataRow dr = dt.NewRow(); for ( int n =0;n<IrfTable.CurrentRow.Metadata.FieldCount;n++) { string colName = IrfTable.GetElementMetadata(n).Name; dr[colName]=IrfTable.CurrentRow.GetString(colName); } dt.Rows.Add(dr); } return dt; } |
不使用配置文件直接代码写入参数的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public static DataTable GetSapData() { RfcConfigParameters rfcPar = new RfcConfigParameters(); rfcPar.Add(RfcConfigParameters.Name, "CON" ); rfcPar.Add(RfcConfigParameters.AppServerHost, "10.1.8.11" ); rfcPar.Add(RfcConfigParameters.Client, "300" ); rfcPar.Add(RfcConfigParameters.User, "test" ); rfcPar.Add(RfcConfigParameters.Password, "1234" ); rfcPar.Add(RfcConfigParameters.SystemNumber, "00" ); rfcPar.Add(RfcConfigParameters.Language, "EN" ); rfcPar.Add(RfcConfigParameters.Codepage, "8400" ); RfcDestination dest = RfcDestinationManager.GetDestination(rfcPar); RfcRepository rfcrep = dest.Repository; IRfcFunction myfun = null ; myfun = rfcrep.CreateFunction( "ZHRIF01_FM01" ); myfun.SetValue( "I_DATUM" , "20160203" ); //SAP里面的传入参数 try { myfun.Invoke(dest); } catch (Exception ex) { MessageBox.Show(ex.Message); } IRfcTable IrfTable = myfun.GetTable( "T_RESULT" ); return GetDataTable(IrfTable); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端