unijun 发表于 2015-9-17 12:14:14

C# Call SAP RFC传入表

  这段时间公司做了一个SAP的外围系统,之前也做了一些外围系统,不够都挺简单的,就是通过物料号拿价格和描述之类的,像这类的RFC只需要传个参数过去就OK,而现在这个系统需要传大量的表到SAP,之前也问过同事,他们都说C#不能传表到SAP,后来自己在网上找了些资料,自己也尝试了下,果然是不行,虽然API中有Table 对象,好像那Table对象传了值就会报错,后来我在网上看到,C#是不能传表,但是VB可以,用VB写的代码编译成DLL,C#的项目来引用这个DLL,就OK了,我就抱着死马当活马医心态,用VS创建一个VB的项目,然后再网上找了点资料,拿到c#里面测试,居然成功了!!看来SAP对C#的支持不是很友好,很多东西都被阉割了!
  下面我就将这个DLL和代码共享出来,供大家参考,免得在这上面走弯路(我弄了一天多才弄出来.........):
  接口类:


View Code


1 Public Interface IFunctions
2
3   ''' <summary>
4   '''登录SAP,成功,返回True,失败,返回False
5   ''' </summary>
6   ''' <param name="User">用户</param>
7   ''' <param name="PassWord">口令</param>
8   ''' <param name="Language">语言,如ZH、EN等,可以传入null</param>
9   ''' <returns>是否登录成功</returns>
10   ''' <remarks></remarks>
11   Function ConnectToSAP(ByVal User As String, ByVal Password As String, ByVal Language As String) As Boolean
12
13   ''' <summary>
14   ''' 设置调用的sap函数名称
15   ''' </summary>
16   ''' <param name="sapFuncName">sap函数名称</param>
17   ''' <remarks></remarks>
18   Sub SetFuncName(ByVal sapFuncName As String)
19
20   ''' <summary>
21   ''' 设置Sap函数的传入调用参数
22   ''' </summary>
23   ''' <param name="paramName">参数名称</param>
24   ''' <param name="paramValue">参数值</param>
25   ''' <remarks></remarks>
26   Sub SetParamName(ByVal paramName As String, ByVal paramValue As Object)
27
28   ''' <summary>
29   ''' 设置sap的传入内表,用dt_value模拟这个内表
30   ''' </summary>
31   ''' <param name="SapTableName">sap函数传入内表的名字</param>
32   ''' <param name="dt_value">模拟的DataTable,要求与传入内表的字段名一致</param>
33   ''' <remarks></remarks>
34   Sub SetInPutTable(ByVal SapTableName As String, ByVal dt_value As DataTable)
35
36   ''' <summary>
37   ''' 当参数设置完成后,执行函数调用
38   ''' </summary>
39   ''' <remarks></remarks>
40   Sub ExecFun()
41
42   ''' <summary>
43   ''' 根据字段列表(逗号分隔)建立指定字段的DataTable
44   ''' </summary>
45   ''' <param name="fields">字段列表(逗号分隔)</param>
46   ''' <returns>空表</returns>
47   ''' <remarks></remarks>
48   Function CreateTable(ByVal fields As String) As DataTable
49
50   ''' <summary>
51   ''' 取得sap的传出参数值
52   ''' </summary>
53   ''' <param name="paramName">传出参数名</param>
54   ''' <returns>传出参数值</returns>
55   ''' <remarks></remarks>
56   Function GetOutPutParam(ByVal paramName As String) As String
57
58   ''' <summary>
59   ''' 把sap函数调用结构的传出内表转成dotNet的表
60   ''' </summary>
61   ''' <param name="fields">sap传出内表的字段列表,字段间以逗号分隔</param>
62   ''' <param name="SapTableName">sap传出内表的表名</param>
63   ''' <param name="strTrim">是否清除前后空格</param>
64   ''' <returns>把sap内表导出的dotnet表,字段都为string型</returns>
65   ''' <remarks></remarks>
66   Function GetOutPutTable(ByVal fields As String, ByVal SapTableName As String, ByVal strTrim As Boolean) As DataTable
67
68   ''' <summary>
69   ''' 关闭sap的连接
70   ''' </summary>
71   ''' <remarks></remarks>
72   Sub DisConnectSAP()
73
74 End Interface
  
  
  实现类:


View Code


1 Public Class Functions
2   Implements IFunctions
3
4
5   Private m_sapObject As Object       'sap远程函数调用对象
6   Protected m_sapFun As Object      'sap函数
7   Private m_sapConnection As Object   '与SAP的连接
8
9   ''' <summary>
10   ''' 构造函数,传入sap的基本信息
11   ''' </summary>
12   ''' <param name="sapSystem">Sap系统,可以传入null</param>
13   ''' <param name="applicationServer">SAP服务器ip</param>
14   ''' <param name="Client">集团号,如800</param>
15   ''' <param name="SystemNumber">系统编号,如00</param>
16   ''' <remarks></remarks>
17   Public Sub New(ByVal sapSystem As String, ByVal ApplicationServer As String, ByVal Client As String, ByVal SystemNumber As String)
18         Me.m_sapObject = CreateObject("SAP.Functions")
19         Me.m_sapConnection = Me.m_sapObject.Connection()
20
21         If String.IsNullOrEmpty(sapSystem) = False Then
22             Me.m_sapConnection.System = sapSystem
23         End If
24
25         Me.m_sapConnection.ApplicationServer = ApplicationServer
26         Me.m_sapConnection.Client = Client
27         Me.m_sapConnection.SystemNumber = SystemNumber
28   End Sub
29
30
31   ''' <summary>
32   '''登录SAP,成功,返回True,失败,返回False
33   ''' </summary>
34   ''' <param name="User">用户</param>
35   ''' <param name="PassWord">口令</param>
36   ''' <param name="Language">语言,如ZH、EN等,可以传入null</param>
37   ''' <returns>是否登录成功</returns>
38   ''' <remarks></remarks>
39   Public Function ConnectToSAP(ByVal User As String, ByVal Password As String, ByVal Language As String) As Boolean Implements IFunctions.ConnectToSAP
40         Me.m_sapConnection.user = User
41         Me.m_sapConnection.Password = Password
42
43         If String.IsNullOrEmpty(Language) = False Then
44             Me.m_sapConnection.Language = Language
45         Else
46             Me.m_sapConnection.Language = "EN"
47         End If
48
49
50         Me.m_sapObject.AutoLogon = True                              '自动登录
51         Return Me.m_sapObject.Connection.logon(0, True)                '登录是否成功
52   End Function
53
54
55   ''' <summary>
56   ''' 设置调用的sap函数名称
57   ''' </summary>
58   ''' <param name="sapFuncName">sap函数名称</param>
59   ''' <remarks></remarks>
60   Public Sub SetFuncName(ByVal sapFuncName As String) Implements IFunctions.SetFuncName
61         Me.m_sapFun = Me.m_sapObject.Add(sapFuncName)
62         If m_sapFun Is Nothing Then
63             Throw New Exception("Sap远程函数名无效:" + sapFuncName)
64         End If
65   End Sub
66
67   ''' <summary>
68   ''' 设置Sap函数的传入调用参数
69   ''' </summary>
70   ''' <param name="paramName">参数名称</param>
71   ''' <param name="paramValue">参数值</param>
72   ''' <remarks></remarks>
73   Public Sub SetParamName(ByVal paramName As String, ByVal paramValue As Object) Implements IFunctions.SetParamName
74         Dim param As Object
75         param = Me.m_sapFun.Exports(paramName)
76         If param Is Nothing Then
77             Throw New Exception("Sap远程函数的参数名无效:" + paramName)
78         End If
79         param.Value = paramValue
80
81   End Sub
82
83   ''' <summary>
84   ''' 设置sap的传入内表,用dt_value模拟这个内表
85   ''' </summary>
86   ''' <param name="SapTableName">sap函数传入内表的名字</param>
87   ''' <param name="dt_value">模拟的DataTable,要求与传入内表的字段名一致</param>
88   ''' <remarks></remarks>
89   Public Sub SetInPutTable(ByVal SapTableName As String, ByVal dt_value As DataTable) Implements IFunctions.SetInPutTable
90         Dim sapdata As Object                     'sap传入内表
91         Dim saprow As Object                        'sap传入内表的一行
92         Dim dc As DataColumn
93         Dim index As Integer
94         sapdata = Me.m_sapFun.Tables(SapTableName)
95         For index = 0 To dt_value.Rows.Count - 1    '循环表,并给sap传入内表赋值
96             saprow = sapdata.Rows.Add()             '传入内表新增一行记录,下面为传入内表记录赋值
97             For Each dc In dt_value.Columns
98               saprow(dc.ColumnName) = dt_value.Rows(index)(dc.ColumnName).ToString()
99             Next
100         Next
101   End Sub
102
103   ''' <summary>
104   ''' 当参数设置完成后,执行函数调用
105   ''' </summary>
106   ''' <remarks></remarks>
107   Public Sub ExecFun() Implements IFunctions.ExecFun
108         If Me.m_sapFun.Call() = False Then
109             Throw New Exception("Sap远程函数调用失败。")       '从SAP取数出错,退出函数
110         End If
111   End Sub
112
113   ''' <summary>
114   ''' 根据字段列表(逗号分隔)建立指定字段的DataTable
115   ''' </summary>
116   ''' <param name="fields">字段列表(逗号分隔)</param>
117   ''' <returns>空表</returns>
118   ''' <remarks></remarks>
119   Public Function CreateTable(ByVal fields As String) As DataTable Implements IFunctions.CreateTable
120         Dim dt As New DataTable
121         Dim strs As String()
122         Dim s As String
123         strs = fields.Split(",")
124         For Each s In strs
125             dt.Columns.Add(s.Trim())
126         Next
127         Return dt
128   End Function
129
130   ''' <summary>
131   ''' 取得sap的传出参数值
132   ''' </summary>
133   ''' <param name="paramName">传出参数名</param>
134   ''' <returns>传出参数值</returns>
135   ''' <remarks></remarks>
136   Public Function GetOutPutParam(ByVal paramName As String) As String Implements IFunctions.GetOutPutParam
137         Dim param As Object
138         param = Me.m_sapFun.Imports(paramName)
139         If param Is Nothing Then
140             Throw New Exception("Sap远程函数的参数名无效:" + paramName)
141         End If
142
143         If param.Value Is Nothing Then
144             Return ""
145         Else
146             Return param.Value.ToString()
147         End If
148   End Function
149
150   ''' <summary>
151   ''' 把sap函数调用结构的传出内表转成dotNet的表
152   ''' </summary>
153   ''' <param name="fields">sap传出内表的字段列表,字段间以逗号分隔</param>
154   ''' <param name="SapTableName">sap传出内表的表名</param>
155   ''' <param name="strTrim">是否清除前后空格</param>
156   ''' <returns>把sap内表导出的dotnet表,字段都为string型</returns>
157   ''' <remarks></remarks>
158   Public Function GetOutPutTable(ByVal fields As String, ByVal SapTableName As String, ByVal strTrim As Boolean) As DataTable Implements IFunctions.GetOutPutTable
159         '按字段列表建立表,fields中的字段列表用逗号分隔
160         Dim dt As DataTable
161         dt = Me.CreateTable(fields)
162
163         '从sap表中读数据,循环sap中取得的数据,写入dt
164         Dim sapdata As Object
165         Dim saprow As Object
166         Dim dr As DataRow                     '数据增加的新行
167         Dim dc As DataColumn
168         sapdata = Me.m_sapFun.Tables(SapTableName)
169         For Each saprow In sapdata.Rows
170             dr = dt.NewRow()
171             For Each dc In dt.Columns
172               If strTrim = True Then
173                     dr(dc.ColumnName) = saprow(dc.ColumnName).ToString().Trim()
174               Else
175                     dr(dc.ColumnName) = saprow(dc.ColumnName).ToString()
176               End If
177             Next
178             dt.Rows.Add(dr)
179         Next
180
181         Return dt
182   End Function
183
184   ''' <summary>
185   ''' 关闭sap的连接
186   ''' </summary>
187   ''' <remarks></remarks>
188   Public Sub DisConnectSAP() Implements IFunctions.DisConnectSAP
189         Me.m_sapConnection.logoff()
190   End Sub
191
192 End Class
  使用方法:
  新建VB的项目,复制这两个类的代码,然后生成的DLL C#调用 C#调用代码如下:
  


View Code


1 SapServers.IFunctions sap;
2         protected void Page_Load(object sender, EventArgs e)
3         {
4             CallRfc();
5         }
6
7         private void CallRfc()
8         {
9             sap = new SapServers.Functions(null, "172.16.8.225", "370", "00");//传入SAP配置参数
10
11             sap.ConnectToSAP("dotnetuser", "net2009", "zf");//登录SAP
12
13             string str = "KNUMH,DATAB,DATBI,ESOKZ,EKORG,MATNR,LIFNR,KSCHL,KAPPL";
14
15             DataTable newTable = sap.CreateTable(str);
16
17             for (int i = 0; i < 5; i++)
18             {
19               DataRow newRow = newTable.NewRow();
20               newRow["KAPPL"] = "M";
21               newRow["KSCHL"] = "PB00";
22               newRow["LIFNR"] = "D0004";
23               newRow["MATNR"] = "800500002Q";
24               newRow["EKORG"] = "HK01";
25               newRow["ESOKZ"] = "0";
26               newRow["DATBI"] = "2011-06-15";
27               newRow["DATAB"] = "2011-06-15";
28               newRow["KNUMH"] = "0000007232";
29
30               newTable.Rows.Add(newRow);
31             }
32
33             sap.SetFuncName("Z_TEST");//执行的RFC名称
34             sap.SetInPutTable("A018", newTable);//传入表
35
36             sap.ExecFun();//执行这个RFC
37
38             DataTable outPutTable = sap.GetOutPutTable(str, "T_A018", true);//返回的Table
39
40             GridView1.DataSource = outPutTable;
41             GridView1.DataBind();
42         }


  
  
页: [1]
查看完整版本: C# Call SAP RFC传入表