C# 用nco Call SapRfc函数
Java用Jco,而C#用Nco
都需要安装sap客户端
首先调用sap有两种方式,一种是用VB或者VB.net ,新建VB类库 并添加类
Functions类
Public Class Functions Implements IFunctions Private m_sapObject As Object 'sap远程函数调用对象 Protected m_sapFun As Object 'sap函数 Private m_sapConnection As Object '与SAP的连接 ''' <summary> ''' 构造函数,传入sap的基本信息 ''' </summary> ''' <param name="sapSystem">Sap系统,可以传入null</param> ''' <param name="applicationServer">SAP服务器ip</param> ''' <param name="Client">集团号,如800</param> ''' <param name="SystemNumber">系统编号,如00</param> ''' <remarks></remarks> Public Sub New(ByVal sapSystem As String, ByVal ApplicationServer As String, ByVal Client As String, ByVal SystemNumber As String) Me.m_sapObject = CreateObject("SAP.Functions") Me.m_sapConnection = Me.m_sapObject.Connection() If String.IsNullOrEmpty(sapSystem) = False Then Me.m_sapConnection.System = sapSystem End If Me.m_sapConnection.ApplicationServer = ApplicationServer Me.m_sapConnection.Client = Client Me.m_sapConnection.SystemNumber = SystemNumber End Sub ''' <summary> ''' 登录SAP,成功,返回True,失败,返回False ''' </summary> ''' <param name="User">用户</param> ''' <param name="PassWord">口令</param> ''' <param name="Language">语言,如ZH、EN等,可以传入null</param> ''' <returns>是否登录成功</returns> ''' <remarks></remarks> Public Function ConnectToSAP(User As String, Password As String, Language As String) As Boolean Implements IFunctions.ConnectToSAP Me.m_sapConnection.user = User Me.m_sapConnection.Password = Password If String.IsNullOrEmpty(Language) = False Then Me.m_sapConnection.Language = Language Else Me.m_sapConnection.Language = "EN" End If Me.m_sapObject.AutoLogon = True '自动登录 Return Me.m_sapObject.Connection.logon(0, True) '登录是否成功 End Function ''' <summary> ''' 设置调用的sap函数名称 ''' </summary> ''' <param name="sapFuncName">sap函数名称</param> ''' <remarks></remarks> Public Sub SetFuncName(sapFuncName As String) Implements IFunctions.SetFuncName Me.m_sapFun = Me.m_sapObject.Add(sapFuncName) If m_sapFun Is Nothing Then Throw New Exception("Sap远程函数名无效:" + sapFuncName) End If End Sub ''' <summary> ''' 设置Sap函数的传入调用参数 ''' </summary> ''' <param name="paramName">参数名称</param> ''' <param name="paramValue">参数值</param> ''' <remarks></remarks> Public Sub SetParamName(paramName As String, paramValue As Object) Implements IFunctions.SetParamName Dim param As Object param = Me.m_sapFun.Exports(paramName) If param Is Nothing Then Throw New Exception("Sap远程函数的参数名无效:" + paramName) End If param.Value = paramValue End Sub ''' <summary> ''' 设置sap的传入内表,用dt_value模拟这个内表 ''' </summary> ''' <param name="SapTableName">sap函数传入内表的名字</param> ''' <param name="dt_value">模拟的DataTable,要求与传入内表的字段名一致</param> ''' <remarks></remarks> Public Sub SetInPutTable(SapTableName As String, dt_value As DataTable) Implements IFunctions.SetInPutTable Dim sapdata As Object 'sap传入内表 Dim saprow As Object 'sap传入内表的一行 Dim dc As DataColumn Dim index As Integer sapdata = Me.m_sapFun.Tables(SapTableName) For index = 0 To dt_value.Rows.Count - 1 '循环表,并给sap传入内表赋值 saprow = sapdata.Rows.Add() '传入内表新增一行记录,下面为传入内表记录赋值 For Each dc In dt_value.Columns saprow(dc.ColumnName) = dt_value.Rows(index)(dc.ColumnName).ToString() Next Next End Sub ''' <summary> ''' 当参数设置完成后,执行函数调用 ''' </summary> ''' <remarks></remarks> Public Sub ExecFun() Implements IFunctions.ExecFun If Me.m_sapFun.Call() = False Then Throw New Exception("Sap远程函数调用失败。") '从SAP取数出错,退出函数 End If End Sub ''' <summary> ''' 根据字段列表(逗号分隔)建立指定字段的DataTable ''' </summary> ''' <param name="fields">字段列表(逗号分隔)</param> ''' <returns>空表</returns> ''' <remarks></remarks> Public Function CreateTable(fields As String) As DataTable Implements IFunctions.CreateTable Dim dt As New DataTable Dim strs As String() Dim s As String strs = fields.Split(",") For Each s In strs dt.Columns.Add(s.Trim()) Next Return dt End Function ''' <summary> ''' 取得sap的传出参数值 ''' </summary> ''' <param name="paramName">传出参数名</param> ''' <returns>传出参数值</returns> ''' <remarks></remarks> Public Function GetOutPutParam(paramName As String) As String Implements IFunctions.GetOutPutParam Dim param As Object param = Me.m_sapFun.Imports(paramName) If param Is Nothing Then Throw New Exception("Sap远程函数的参数名无效:" + paramName) End If If param.Value Is Nothing Then Return "" Else Return param.Value.ToString() End If End Function ''' <summary> ''' 把sap函数调用结构的传出内表转成dotNet的表 ''' </summary> ''' <param name="fields">sap传出内表的字段列表,字段间以逗号分隔</param> ''' <param name="SapTableName">sap传出内表的表名</param> ''' <param name="strTrim">是否清除前后空格</param> ''' <returns>把sap内表导出的dotnet表,字段都为string型</returns> ''' <remarks></remarks> Public Function GetOutPutTable(fields As String, SapTableName As String, strTrim As Boolean) As DataTable Implements IFunctions.GetOutPutTable '按字段列表建立表,fields中的字段列表用逗号分隔 Dim dt As DataTable dt = Me.CreateTable(fields) '从sap表中读数据,循环sap中取得的数据,写入dt Dim sapdata As Object Dim saprow As Object Dim dr As DataRow '数据增加的新行 Dim dc As DataColumn sapdata = Me.m_sapFun.Tables(SapTableName) For Each saprow In sapdata.Rows dr = dt.NewRow() For Each dc In dt.Columns If strTrim = True Then dr(dc.ColumnName) = saprow(dc.ColumnName).ToString().Trim() Else dr(dc.ColumnName) = saprow(dc.ColumnName).ToString() End If Next dt.Rows.Add(dr) Next Return dt End Function ''' <summary> ''' 关闭sap的连接 ''' </summary> ''' <remarks></remarks> Public Sub DisConnectSAP() Implements IFunctions.DisConnectSAP Me.m_sapConnection.logoff() End Sub End Class
C#引入类库,并调用:
SapHelper sap = new SapHelper("127.0.0.1", "SFC_USER", "yhpwd", "801", "04", "EN"); SoDetailConn.SetFuncName("ZRFC_GET_SALES_DETAIL");//执行的RFC名称 SoDetailConn.SetParamName("ORDERNUM", ""); SoDetailConn.SetParamName("PLANT", ""); SoDetailConn.ExecFun();//执行这个RFC DataTable outPutTable = SoDetailConn.GetOutPutTable("aa,bb", "table1", true);//返回的Table
第二种方式:
项目右键引入rscp4n 、sapnco 、sapnco.utils三个引用
saphelper如下
public class SapHelper { private RfcConfigParameters parms = null; private RfcDestination prd = null; /// <summary> /// Sap初始化 /// </summary> /// <param name="Server">ip地址</param> /// <param name="UseID">登录sap账号</param> /// <param name="Password">密码</param> /// <param name="Client">端口号</param> /// <param name="SysNumber">系统编号,如00</param> /// <param name="Language">语言,如ZH、EN等,可以传入null</param> public SapHelper(string Server, string UseID, string Password, string Client, string SysNumber, string Language) { parms = new RfcConfigParameters(); //parms.Add(RfcConfigParameters.Name, "mycon"); //parms.Add(RfcConfigParameters.AppServerHost, "10.134.28.112"); //parms.Add(RfcConfigParameters.SystemNumber, "00"); //parms.Add(RfcConfigParameters.User, "accadm"); //parms.Add(RfcConfigParameters.Password, "1707sap"); //parms.Add(RfcConfigParameters.Client, "801"); //parms.Add(RfcConfigParameters.Language, "EN"); parms.Add(RfcConfigParameters.Name, "mycon"); parms.Add(RfcConfigParameters.AppServerHost, Server); parms.Add(RfcConfigParameters.User, UseID); parms.Add(RfcConfigParameters.Password, Password); parms.Add(RfcConfigParameters.Client, Client); parms.Add(RfcConfigParameters.SystemNumber, SysNumber); parms.Add(RfcConfigParameters.Language, Language); parms.Add(RfcConfigParameters.PoolSize, "5"); parms.Add(RfcConfigParameters.PeakConnectionsLimit, "10"); parms.Add(RfcConfigParameters.IdleTimeout, "10"); prd = RfcDestinationManager.GetDestination(parms); } public List<Sapinfo> CallRfc(string functionname, String plant, String ref1, String ref2) { List<Sapinfo> list = new List<Sapinfo>(); //获取Repository对象 RfcRepository repo = prd.Repository; if (functionname.Equals("ZRFC_GET_SALES_DETAIL")) { //指定函数 IRfcFunction mySapFunction = repo.CreateFunction(functionname); //设置参数 mySapFunction.SetValue(3, ref2); mySapFunction.SetValue(4, plant); //IRfcTable tables = mySapFunction.GetTable("TIMETICKETS"); //IRfcStructure struSAP = tables.Metadata.LineType.CreateStructure(); //struSAP.SetValue("ORDERID", workorderId); //struSAP.SetValue("OPERATION", "0010"); //struSAP.SetValue("POSTG_DATE", ""); //struSAP.SetValue("Yield", Num); //tables.Append(struSAP); //函数执行 mySapFunction.Invoke(prd); //获取结果 IRfcTable outReturnTable = mySapFunction.GetTable("SOSKU"); //遍历放回结果 outReturnTable.AsEnumerable().ToList().ForEach(x => { list.Add(new Sapinfo() { orderno = x.GetString("VBELN"), skuno = x.GetString("MATNR"), price = x.GetDouble("NETPR") + "", packageno = x.GetInt("POSNR") + "", shiporderno1 = null, shiporderno2 = null, Pgidate = null }); }); //for (int i = 0; i < outReturnTable.RowCount; i++) //{ // outReturnTable.CurrentIndex = i; // String so = outReturnTable.CurrentRow.GetString("VBELN"); // so // String pn = outReturnTable.CurrentRow.GetString("MATNR"); // pn // double price = outReturnTable.CurrentRow.GetDouble("NETPR");// 單價 // int packageno = outReturnTable.CurrentRow.GetInt("POSNR"); // list.Add(new Sapinfo(so, pn, price + "", packageno + "", null, null, null)); //} } else if (functionname.Equals("ZRFC_CES_SHIP_DETAIL")) { IRfcFunction mySapFunction = repo.CreateFunction(functionname); //设置参数 mySapFunction.SetValue(0, ref2); mySapFunction.SetValue(1, plant); //IRfcTable tables = mySapFunction.GetTable("TIMETICKETS"); //IRfcStructure struSAP = tables.Metadata.LineType.CreateStructure(); //struSAP.SetValue("ORDERID", workorderId); //struSAP.SetValue("OPERATION", "0010"); //struSAP.SetValue("POSTG_DATE", ""); //struSAP.SetValue("Yield", Num); //tables.Append(struSAP); //函数执行 mySapFunction.Invoke(prd); //获取结果 IRfcTable outReturnTable = mySapFunction.GetTable("SHIP01"); //遍历放回结果 outReturnTable.AsEnumerable().ToList().ForEach(x => { Console.WriteLine(x.GetObject("PGIDATE")); if (x.GetObject("PGIDATE") == null) Console.WriteLine("no PGI"); else list.Add(new Sapinfo() { orderno = null, skuno = null, price = null, packageno = null, shiporderno1 = ref1, shiporderno2 = ref2, Pgidate = x.GetObject("PGIDATE").ToString() + x.GetObject("PGITIME") }); }); //outReturnTable.AsEnumerable().ToList().Where(y=>{!string.IsNullOrEmpty()}).ForEach(x => //{ // if (string.IsNullOrEmpty(x.GetObject("PGIDATE").ToString())) // Console.WriteLine("no PGI"); // else // list.Add(new Sapinfo() // { // orderno = null, // skuno = null, // price = null, // packageno = null, // shiporderno1 = ref1, // shiporderno2 = ref2, // Pgidate = x.GetObject("PGIDATE").ToString() + x.GetObject("PGITIME") // }); //}); } else if (functionname.Equals("ZRFC_SEND_ST_SHIPMENT")) { } return list; } public List<B2Bdata> callRfcshipment(string functionname, String plant, String ref1, String ref2) { List<B2Bdata> list = new List<B2Bdata>(); RfcRepository repo = prd.Repository; if (functionname.Equals("ZRFC_SEND_ST_SHIPMENT")) { IRfcFunction mySapFunction = repo.CreateFunction(functionname); //设置参数 mySapFunction.SetValue(0, ref2); mySapFunction.SetValue(1, plant); //IRfcTable tables = mySapFunction.GetTable("TIMETICKETS"); //IRfcStructure struSAP = tables.Metadata.LineType.CreateStructure(); //struSAP.SetValue("ORDERID", workorderId); //struSAP.SetValue("OPERATION", "0010"); //struSAP.SetValue("POSTG_DATE", ""); //struSAP.SetValue("Yield", Num); //tables.Append(struSAP); //函数执行 mySapFunction.Invoke(prd); //获取结果 IRfcTable table = mySapFunction.GetTable("HEADER_OUT"); IRfcTable table2 = mySapFunction.GetTable("DETAIL_OUT"); //遍历放回结果 table2.AsEnumerable().ToList().ForEach(x => { list.Add(new B2Bdata() { PARTNUMBER = x.GetString("KDMAT"), PARTDESCRIPTION = x.GetString("ARKTX"), DROPSHIPPO = x.GetString("PONO"), POLINE = x.GetString("PO_LINE").Replace("^(0+)", ""), SHIPTOCUSTOMERNAME = table.GetString("NAME1"), SHIPTOADDRESS1 = table.GetString("NAME2") + table.GetString("NAME3") + table.GetString("NAME4"), SHIPTOADDRESS2 = table.GetString("NAME_CO") + table.GetString("ADDR2"), SHIPTOADDRESS3 = table.GetString("ADDR3") + table.GetString("ADDR4"), SHIPTOADDRESS4 = table.GetString("ADDR5") + table.GetString("STREET"), SHIPTOCITY = table.GetString("CITY"), SHIPTOSTATE = table.GetString("REGION"), SHIPTOPOSTALCODE = table.GetString("POST_CODE"), SHIPTOCOUNTRY = table.GetString("COUNTRY"), UNITPRICE = string.Empty, SERVICELEVEL = string.Empty, MODEOFTRANSPORT = string.Empty, COSTCENTER = string.Empty, item_no = x.GetString("POSNR").Replace("^(0+)", ""), dn2=x.GetString("DN2") }); }); } return list; } }
main函数调用
static void Main(string[] args) { List<Sapinfo> sapsolist = new List<Sapinfo>(); List<Sapinfo> SapDnList = new List<Sapinfo>(); List<B2Bdata> shipmentlist = new List<B2Bdata>(); new List<string>() { "efoxsfcmu3seagate", "efoxsfclxdh" }.ForEach(x => { Dbhelper helper = new Dbhelper(x); List<Dninfo> lDninfo = new List<Dninfo>(); lDninfo = helper.query(); SapHelper sap = new SapHelper("127.0.0.1", "SFC_USER", "yhpwd", "801", "04", "EN"); lDninfo.ForEach(y => { Console.WriteLine(y.shiporderno2); SapDnList.AddRange(sap.CallRfc("ZRFC_CES_SHIP_DETAIL", y.plant, y.shiporderno1, y.shiporderno2)); sapsolist.AddRange(sap.CallRfc("ZRFC_GET_SALES_DETAIL", y.plant, "", y.orderno)); shipmentlist.AddRange(sap.callRfcshipment("ZRFC_SEND_ST_SHIPMENT", y.plant, y.shiporderno1, y.shiporderno2)); }); helper.InSert(SapDnList); helper.UpDate(sapsolist); }); }