SAP接口编程之 JCo3.0 系列(03) : 表参数

表参数 (table parameter) 作为 export parameter

BAPI_COMPANYCODE_GETDETAIL 是一个适合演示的函数,没有 importing paramter 参数,调用后 COMPANYCODE_GETDETAIL 表参数 返回 SAP 系统中所有公司代码的清单。只有公司代码ID公司代码名称两个字段。

JCo 中,与表参数相关的两个接口( interface ) 类型是 JCoTableJCoRecordMetaDta, JCoTable 就是 Remote Function Module (RFM) 的表参数,而JCoRecordMetaDtaJCoTableJCoStructure 的元数据 (meta-data)。

在 .net 环境中,我喜欢将 IRfcTable 转换成 DataTable,但 Java 没有类似的数据结构,所以决定直接在方法中传递 JCoTable 算了。但为了方便输出,可以考虑使用一段通用代码:

package jco3.utils;

import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoRecordMetaData;
import com.sap.conn.jco.JCoTable;

public class JCoUtils
{
    public static void printJCoTable(JCoTable jcoTable)
    {
        // header
        
        // JCoRecordMeataData is the meta data of either a structure or a table.
        // Each element describes a field of the structure or table.        
        JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();     
        for(int i = 0; i < tableMeta.getFieldCount(); i++){
            System.out.print(String.format("%s\t", tableMeta.getName(i)));                  
        }
        System.out.println(); // new line
        
        // line items
        
        for(int i = 0; i < jcoTable.getNumRows(); i++){
            // Sets the row pointer to the specified position(beginning from zero)
            jcoTable.setRow(i);
            
            // Each line is of type JCoStructure
            for(JCoField fld : jcoTable){
                System.out.print(String.format("%s\t", fld.getValue()));
            }
            System.out.println();
        }
    }
}

要点说明

对于 JCoTable,输出表头和行项目。表头通过获取 JCoTable 的 meta-data,然后使用 meta-data 的 getName() 方法。

JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();     
for(int i = 0; i < tableMeta.getFieldCount(); i++){
      System.out.print(String.format("%s\t", tableMeta.getName(i)));                    
}

JCoTable 每一行都是一个 JCoStructure,可以通过 setRow() 设置指针的位置,然后再遍历各个 field:

for(int i = 0; i < jcoTable.getNumRows(); i++){
    // Sets the row pointer to the specified position(beginning from zero)
    jcoTable.setRow(i);
    
    // Each line is of type JCoStructure
    for(JCoField fld : jcoTable){
        System.out.print(String.format("%s\t", fld.getValue()));
    }
    System.out.println();
}

完成输出之后,接下来就是 RFM 调用:

package jco3.demo5;

import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils;

public class JCoTableDemo
{
    public JCoTable getCocdList() throws JCoException
    {
        /**
         * Get company code list in SAP system  using BAPI BAPI_COMPANYCODE_GETLIST. 
         * Since JCoTable is rather flexible, we simply use this interface as return value
         */
        
        JCoDestination dest = JCoDestinationManager.getDestination("ECC");
        JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST");      
        fm.execute(dest);
        
        JCoTable companies = fm.getTableParameterList().getTable("COMPANYCODE_LIST");
        
        return companies;       
    }
    
    @Test
    public void printCompanies() throws JCoException
    {
        JCoTable companies = this.getCocdList();
        JCoUtils.printJCoTable(companies);
    }
}

表参数作为 import parameter

table 作为输入参数,主要解决 table 数据填充问题,基本模式如下:

someTable.appendRow();
someTable.setValue("FIELD_NAME", someValue);

RFC_READ_TABLE 函数为例,读取 SAP 标准表 USR04 数据。

package jco3.demo5;

import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils;

public class JCoTableAsImport
{   
    public JCoTable readTable() throws JCoException
    {
        /**
         * Shows how to process JCoTable as importing parameter
         */
        
        JCoDestination dest = JCoDestinationManager.getDestination("ECC");
        JCoFunction fm = dest.getRepository().getFunction("RFC_READ_TABLE");
        
        // table we want to query is USR04
        // which is the user authorization table in SAP system
        fm.getImportParameterList().setValue("QUERY_TABLE", "USR04");
        
        // output data will be delimited by comma
        fm.getImportParameterList().setValue("DELIMITER", ",");
        
        // processing table parameters
        JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
        // modification date >= 2012.01.01 and <= 2015.12.31
        options.appendRow();
        options.setValue("TEXT", "MODDA GE '20120101' ");
        options.appendRow();
        options.setValue("TEXT", "AND MODDA LE '20151231' ");
        
        // We only care about fields of [user id] and [modification date]       
        String[] outputFields = new String[] {"BNAME", "MODDA"};
        JCoTable fields = fm.getTableParameterList().getTable("FIELDS");
        int count = outputFields.length;
        fields.appendRows(count);
        for (int i = 0; i < count; i++){
            fields.setRow(i);
            fields.setValue("FIELDNAME", outputFields[i]);          
        }
        
        fm.execute(dest);
        
        JCoTable data = fm.getTableParameterList().getTable("DATA");
        
        return data;
    }
    
    @Test
    public void printUsers() throws JCoException
    {
        JCoTable users = this.readTable();
        JCoUtils.printJCoTable(users);
    }
}

在代码中我们使用了两种方法来插入 table 的行项目.

第一种方法

JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
// modification date >= 2012.01.01 and <= 2015.12.31
options.appendRow();
options.setValue("TEXT", "MODDA GE '20120101' ");
options.appendRow();
options.setValue("TEXT", "AND MODDA LE '20151231' ");

第二种方法:

String[] outputFields = new String[] {"BNAME", "MODDA"};
JCoTable fields = fm.getTableParameterList().getTable("FIELDS");
int count = outputFields.length;
fields.appendRows(count);
for (int i = 0; i < count; i++){
    fields.setRow(i);
    fields.setValue("FIELDNAME", outputFields[i]);          
}

JCoTable 重要方法总结

SAP接口编程之 JCo3.0 系列(03) : 表参数_第1张图片

你可能感兴趣的:(SAP接口编程之 JCo3.0 系列(03) : 表参数)