最近为SAP的接口开发调测伤透,项目进度再急,也有必要整理下笔记。
1.SAP接口文档
接口中有三种类型的参数:a. 字符串参数 ; b.表参数; c.扁平结构参数 (SAP术语,个人认为可以理解为在java数据交互中常用的view对象,按照一定表结构初始化的伪表对象,为方便数据组装和流转)
接口名: ZINDEX_LLD_CREATE
输入参数:
SI_HEAD ZLLD_HEAD 领料单抬头
输入表: TI_ITEM ZLLD_ITEM 领料单明细
输出参数:
O_LLDNO 领料单号码
SO_HEAD ZLLD_HEAD
O_OK 成功标识
输出表: TO_ITEM ZLLD_ITEM 领料单明细
TO_ERROR 错误消息
ZLLD_HEAD
LLDNO CHAR 10 0 领料单号
LLDTY CHAR 1 0 领料单类型
LLDTR CURR 13 2 领料单金额
LLDAR CURR 13 2 领料单过账金额
SO CHAR 1 0 销售订单
WO CHAR 1 0 生产订单
CO CHAR 1 0 成本中心
JOBNO CHAR 35 0 工作令号
WERKS CHAR 4 0 工厂
AUFNR CHAR 12 0 订单号
VBELN CHAR 10 0 销售和分销凭证号
2.字符串参数及表参数的传参接参方式
sapConn = createConn();
if(sapConn.isAlive())
log.info("SAP连接成功!");
JCO.Function fun = createFunction(sapConn, rfcFunName);
JCO.ParameterList inputList = fun.getImportParameterList();
inputList.setValue((String) params.get("jobNum"), "I_JOBNO"); //jobNum 工作令号
inputList.setValue((String) params.get("ipAddress"), "I_IPADDRESS"); //ipAddress IP地址
inputList.setValue((String) params.get("pcName"), "I_COMPUTER"); //pcName 计算机名
inputList.setValue((String) params.get("userName"), "I_USERNAME"); //userName 用户名
inputList.setValue((String) params.get("proNum"), "I_VERSION"); //proNum 程序版本号
List<ViewInfo> quotaList = (List<ViewInfo>) params.get("quotaList");
JCO.Table quotaData = fun.getTableParameterList().getTable(inputTableName);
for(int i = 0; i < quotaList.size(); i++){
WeldQuotaInfo weldQuotaInfo = quotaList.get(i);
quotaData.appendRow();
quotaData.setRow(i);
quotaData.setValue(weldQuotaInfo.getJobNum(), "KDMAT");
quotaData.setValue(weldQuotaInfo.getGapCode(), "WLDNO");
quotaData.setValue(weldQuotaInfo.getMatCode(), "MATNR");
quotaData.setValue(weldQuotaInfo.getWeldMatName(), "WLDNA");
quotaData.setValue(weldQuotaInfo.getWeldMaterial(), "WLDME");
quotaData.setValue(weldQuotaInfo.getMatSize(), "GUIGE");
quotaData.setValue(weldQuotaInfo.getQuotaCount(), "MENGE_DE");
quotaData.setValue(weldQuotaInfo.getWeldMatDesc(), "MAKTX");
}
try{
sapConn.execute(fun);
JCO.ParameterList outputList = fun.getExportParameterList();
if(null != outputList){
log.info("outputList=" + outputList.toString());
}
result = outputList.getString("E_FLAG");
}catch(Exception ex){
log.error("执行RFC函数异常!函数名:" + rfcFunName);
}finally{
closeConn();
}
return result;
3.难点---扁平结构参数处理
总结:主要难在第一次处理,不知道对于所谓扁平结构怎么入参,尝试过getImportParameterList(),getTableParameterList()皆不可。
我知道入参SI_HEAD对应的结构为ZLLD_HEAD,所以尝试构造一个JCO.MetaData结合JCO.createTable处理,如下
JCO.MetaData jcoMetaComp = new JCO.MetaData(parTableName);
jcoMetaComp.addInfo("ZLLD_HEAD",JCO.TYPE_CHAR,21,0,0);
JCO.Table jcoTable = JCO.createTable(jcoMetaComp);
parDate.setValue((String) billHeadMap.get("LLDTY"), "LLDTY");
parDate.setValue((String) billHeadMap.get("JOBNO"), "JOBNO");
JCO.ParameterList inputList = fun.getImportParameterList();
inputList .setTableParameterList(jcoTable );
多番尝试还是失败,于是寻来SAP接口代码研究。摘录如下:
function zindex_lld_create.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(SI_HEAD) LIKE ZLLD_HEAD STRUCTURE ZLLD_HEAD
*" EXPORTING
*" REFERENCE(O_OK) TYPE CHAR1
*" REFERENCE(O_LLDNO) TYPE ZLLDNO
*" VALUE(SO_HEAD) TYPE ZLLD_HEAD
*" TABLES
*" TI_ITEM STRUCTURE ZLLD_ITEM
*" TO_ITEM STRUCTURE ZLLD_ITEM OPTIONAL
*" TO_ERROR STRUCTURE BAPIRET2
*"----------------------------------------------------------------------
tables: marc.
data: l_lldno like zlld_head-lldno.
data: l_short(1).
data: gt_index like zhjindex occurs 0 with header line.
********* check data *********
refresh: to_error,to_item.
clear: to_error,to_item.
move si_head to zlld_head.
to_item = ti_item.
zlld_head-source = 'GY'.
zlld_head-lldty = 'HC'.
zlld_head-stats = '1'.
zlld_head-prntx = 'X'.
* zlld_head-gy = 'X'.
* zlld_head-gz = 'X'.
* CLEAR zlld_head-sg.
发现亮点两处
IMPORTING
*" REFERENCE(SI_HEAD) LIKE ZLLD_HEAD STRUCTURE ZLLD_HEAD
move si_head to zlld_head.
我看到了构造器 STRUCTURE ,以及SI_HEAD和ZLLD_HEAD之间的关系。
于是在JCO中寻找适合的对象,简略若干,最终可行代码如下:
public List<Map<String,Object>> sendBillToSAP(List<Map<String,Object>> zlldHeadList,List<List<Map<String,Object>>> zlldItemList,
String rfcFunName, String parTableName, String tableName,String exportParTableName,String exportTableName){
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
/**Test Start
* 测试传入的数据
**/
/**Test End
*/
sapConn = createConn();
JCO.Function fun;
if(sapConn.isAlive())
log.info("SAP连接成功!");
for(int i=0; i<zlldHeadList.size(); i++){
fun = createFunction(sapConn, rfcFunName);
Map<String,Object> billHeadMap = (Map<String,Object>)zlldHeadList.get(i);
List<Map<String,Object>> billItemList = (ArrayList<Map<String,Object>>)zlldItemList.get(i);
JCO.Structure parDate = fun.getImportParameterList().getStructure(parTableName);
parDate.setValue((String) billHeadMap.get("LLDTY"), "LLDTY");
parDate.setValue((String) billHeadMap.get("JOBNO"), "JOBNO");
parDate.setValue((String) billHeadMap.get("LLRQ"), "LLRQ");
parDate.setValue((String) billHeadMap.get("PERNR"), "PERNR");
parDate.setValue(Integer.parseInt(billHeadMap.get("GRPNR").toString()), "GRPNR");
parDate.setValue((String) billHeadMap.get("WLDER"), "WLDER");
parDate.setValue(billHeadMap.get("STATS").toString(), "STATS");
parDate.setValue((String) billHeadMap.get("PRNTX"), "PRNTX");
parDate.setValue((String) billHeadMap.get("P_NH"), "P_NH");
parDate.setValue((String) billHeadMap.get("P_NH"), "P_NH");
parDate.setValue((String) billHeadMap.get("P_NT"), "P_NT");
parDate.setValue((String) billHeadMap.get("GZ"), "GZ");
parDate.setValue((String) billHeadMap.get("SG"), "SG");
parDate.setValue((String) billHeadMap.get("GY"), "GY");
parDate.setValue((String) billHeadMap.get("KDMAT"), "KDMAT");
parDate.setValue((String) billHeadMap.get("LAYOUT"), "LAYOUT");
parDate.setValue((String) billHeadMap.get("WS"), "WS");
parDate.setValue((String) billHeadMap.get("SOURCE"), "SOURCE");
parDate.setValue((String) billHeadMap.get("LLTYP"), "LLTYP");
parDate.setValue((String) billHeadMap.get("PSDAT"), "PSDAT");
parDate.setValue(Integer.parseInt(billHeadMap.get("PSTIM").toString()), "PSTIM");
JCO.Table tableData = fun.getTableParameterList().getTable(tableName);
for(int j = 0; j < billItemList.size(); j++){
Map<String,Object> billItems = (Map<String,Object>)billItemList.get(j);
tableData.appendRow();
tableData.setRow(i);
tableData.setValue(Integer.parseInt(billItems.get("ITEMNO").toString()), "ITEMNO");
tableData.setValue((String) billItems.get("MATNR"), "MATNR");
tableData.setValue((String) billItems.get("MEINS"), "MEINS");
tableData.setValue( billItems.get("MENGE1"), "MENGE1");
tableData.setValue((String) billItems.get("WLDNO"), "WLDNO");
tableData.setValue((String) billItems.get("WPSNO"), "WPSNO");
tableData.setValue( billItems.get("WPSVR"), "WPSVR");
tableData.setValue((String) billItems.get("PQRNO"), "PQRNO");
tableData.setValue((String) billItems.get("WLDPR"), "WLDPR");
tableData.setValue((String) billItems.get("WLDIT"), "WLDIT");
tableData.setValue((String) billItems.get("WLDME"), "WLDME");
tableData.setValue((String) billItems.get("BASME"), "BASME");
}
try{
// sapConn.execute(fun);
JCO.Structure exportParDate = fun.getExportParameterList().getStructure(exportParTableName);
JCO.Table outputTable = fun.getTableParameterList().getTable(exportTableName);
JCO.Table eMessageTable = fun.getTableParameterList().getTable("TO_ERROR");
JCO.ParameterList outputList = fun.getExportParameterList();
if(null != outputList){
log.info("outputList=" + outputList.toString());
}
String oOk = outputList.getString("O_OK");//成功标示
String oLldno = outputList.getString("O_LLDNO");//领料单号码
if(oOk != null)
log.info("SAP-生成领料单接口调用标示:"+oOk);
}catch(Exception ex){
log.error("执行RFC函数异常!函数名:" + rfcFunName);
}
}
closeConn();
return list;
}