前面多次提到,SAP 函数的 table 型参数既可以作为入参(importing parameter), 又可以作为出参(exporting parameter)。本篇讲解 table 型参数 (IRfcTable) 作为出参的要点,下一篇讲述 IRfcTable 作为出参的要点。
将 IRfcTable 转换成 DataTable
SAP 的 table参数数据类型是 IRfcTable,具有行列这样的结构,为了方便使用,我们通过一个通用的方法将 IRfcTable 转换为 ADO.Net 中的数据结构 DataTable,代码放在 SAPUtils 类中。
public static DataTable ToDataTable(IRfcTable itab)
{
// purpose: convert IRfcTable to DataTable
DataTable dataTable = new DataTable();
// dataTable column definition
for (int i = 0; i < itab.ElementCount; i++) {
RfcElementMetadata metadata = itab.GetElementMetadata(i);
dataTable.Columns.Add(metadata.Name);
}
// line items
for (int rowIdx = 0; rowIdx < itab.RowCount; rowIdx++) {
DataRow dRow = dataTable.NewRow();
// each line is a structure
for (int idx = 0; idx < itab.ElementCount; idx++) {
dRow[idx] = itab[rowIdx].GetObject(idx);
}
dataTable.Rows.Add(dRow);
}
return dataTable;
}
要点讲解
- DataTable 的表头从 meta-data 获取,通过
GetElementMetaData()
方法得到每一个元素 (element)。方法有两个签名:1) 通过element name 来获取;2) 通过element index 来获取,为了具有一般性,我们使用index。
RfcElementMetadata GetElementMetadata(int index);
RfcElementMetadata GetElementMetadata(string name);
- IRfcTable 包括多行,每一行都是 IRfcStructure 类型 。通过双重循环,将每行和列的数据读取到 DataTable 中。因为 IRfcTable 继承自IEnumerable 接口,具有 iteration 功能,所以 ToDataTable 方法也可以这样写(使用 foreach 循环):
public static DataTable ToDataTable(IRfcTable itab)
{
// purpose: convert IRfcTable to DataTable
DataTable dataTable = new DataTable();
// dataTable column definition
for (int i = 0; i < itab.ElementCount; i++) {
RfcElementMetadata metadata = itab.GetElementMetadata(i);
dataTable.Columns.Add(metadata.Name);
}
// line items
foreach (IRfcStructure currenRow in itab) {
DataRow dRow = dataTable.NewRow();
for (int idx = 0; idx < currenRow.ElementCount; idx++) {
dRow[idx] = currenRow.GetObject(idx);
}
dataTable.Rows.Add(dRow);
}
return dataTable;
}
获取 IRfcTable 某个单元格的值
- 获取 IRfcTable 中某个单元格的值,可以有以下方法:
itab[rowIdx].GetObject(idx); // using IRfcContainer.GetObject()
itab[rowIdx][colIdx].GetObject(); // using IRfcElement.GetObject()
itab[rowIdx]["columnName"].GetObject();
GetObject() 方法返回的数据类型为 Object,如果需要得到具体的数据类型,可以使用 NCo3.0 提供的 GetXXX() 方法。比如GetString(), GetInt()等等。ToDataTable() 方法仅做功能性的演示,还比较粗糙。
Table 作为输出参数示例
选择 SAP 的 BAPI_COMPANYCODE_GETLIST 函数来演示。
using SAP.Middleware.Connector;
using System.Data;
namespace NCo3Demo {
public class SAPService {
public DataTable GetCocdList() {
DataTable cocdDataTable = null;
RfcDestination dest = DestinationProvider.GetSAPDestination();
IRfcFunction fm = dest.Repository.CreateFunction("BAPI_COMPANYCODE_GETLIST");
fm.Invoke(dest);
IRfcTable cocdRfcTable = fm.GetTable("COMPANYCODE_LIST");
cocdDataTable = SAPUtils.ToDataTable(cocdRfcTable);
return cocdDataTable;
}
}
}
单元测试:
namespace UnitTestProject1 {
[TestClass]
public class UnitTest1 {
[TestMethod]
public void Test_GetCocdList() {
SAPService sap = new SAPService();
DataTable cocdList = sap.GetCocdList();
DataTableHelper.Print(cocdList);
}
}
}
DataTableHelper.Print() 是一个自定义方法,代码如下:
using System;
using System.Data;
namespace NCo3Demo {
public class DataTableHelper {
public static void Print(DataTable dataTable) {
foreach (DataRow row in dataTable.Rows) {
foreach (DataColumn col in dataTable.Columns) {
System.Console.Write(row[col].ToString() + "\t");
}
Console.WriteLine();
}
}
}
}