SAP接口编程之 NCo3.0系列(04) : Table作为输出参数

前面反复提到,SAP函数的table参数可以作为输入参数(importing parameter), 也可以作为输出参数(exporting paramter)。我们结合具体的例子来看看NCo3.0处理的要点。

将IRfcTable转换成DataTable

很多时候,SAP通过table参数提供返回值,table具有行列这样的结构,为了方便使用,我们将table(类型为IRfcTable,对应的meta-data类型为RfcTableMetaData)转换成Ado.net的DataTable。

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从获取,每一个元素(element)通过GetElementMetaData方法获取。通过查看Object Browser,可以看到GetElementMetaData方法可以通过element name来获取,也可以通过element index来获取:
RfcElementMetadata GetElementMetadata(int index);
RfcElementMetadata GetElementMetadata(string name);

为了具有一般性,我们使用index。

  • IRfcTable包括多行,每一行都是一个IRfcStructure。刚才的代码通过双重循环,将每一行每一列的数据读取到DataTable中。因为IRfcTable继承自IEnumerable接口,具有iteration功能,所以ToDataTable方法也可以改写为:
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;
}
  • SAP获取table中某个获取element值,可以有以下写法:
itab[rowIdx].GetObject(idx);  // using IRfcContainer.GetObject()

// or 
itab[rowIdx][colIdx].GetObject(); // using IRfcElement.GetObject()

// or 
itab[rowIdx]["columnName"].GetObject();

另外,对于不同的类型,nco3.0接口提供了不同的Get方法。比如GetString(), GetInt()等等。

完整代码:

Utils.cs

using SAP.Middleware.Connector;
using System.Data;

namespace NCo03
{
    public class Utils
    {
        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;
        }

        public static void PrintDataTable(DataTable dataTable)
        {
            // purpose: print data table in console

            foreach (DataRow row in dataTable.Rows) {
                foreach (DataColumn col in dataTable.Columns) {
                    System.Console.Write(row[col].ToString() + "\t");
                }
                System.Console.WriteLine();
            }
        }
    }
}

TableManipulation.cs

/**
 * Author: Stone Wang([email protected])
 * Date: 2016/3/26
 */

using SAP.Middleware.Connector;
using NCo02;
using System.Data;

namespace NCo03
{
    public class TableManipulation
    {
        public DataTable GetCocdList()
        {  
            // method purpose: get company code list from SAP system

            DataTable cocdDataTable = null;

            RfcDestination dest = DestinationProvider.GetDestination();
            IRfcFunction fm = dest.Repository.CreateFunction("BAPI_COMPANYCODE_GETLIST");
            fm.Invoke(dest);

            IRfcTable cocdRfcTable = fm.GetTable("COMPANYCODE_LIST");
            cocdDataTable = Utils.ToDataTable(cocdRfcTable);

            return cocdDataTable;            
        }        
    }
}

单元测试
TestTableManipulation.cs

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using NCo03;

namespace UnitTestProject1
{
    [TestClass]
    public class TestTableManipulation
    {
        [TestMethod]
        public void Test_GetCocdList()
        {
            TableManipulation rfc = new TableManipulation();
            DataTable cocdList = rfc.GetCocdList();
            Utils.PrintDataTable(cocdList);
        }        
    }
}

你可能感兴趣的:(SAP接口编程之 NCo3.0系列(04) : Table作为输出参数)