從外部環(huán)境調(diào)用自定義函數(shù) (FM, Function Module)與調(diào)用 SAP 內(nèi)置的函數(shù)并沒(méi)有不同,需要注意的是在 SAP 系統(tǒng)自定義 FM 的要點(diǎn):
1)FM 必須是 Remote-enabled Module (屬性(attribute)中設(shè)置)
2)參數(shù)必須是 pass by value豆同,不允許 pass by reference
下面是具體的例子剩瓶,當(dāng)然不會(huì)采用加減乘除四則運(yùn)算這樣無(wú)聊的例子驹溃。我們自定義一個(gè)函數(shù)城丧,根據(jù)透明表的表名獲取所有字段,信息比RFC_READ_TABLE
函數(shù)要多豌鹤,后面綜合實(shí)例還會(huì)就這個(gè)函數(shù)實(shí)現(xiàn) C# 的應(yīng)用場(chǎng)景亡哄。
首先在 SAP 中使用 SE11 創(chuàng)建一個(gè)結(jié)構(gòu),作為函數(shù)輸出的 table 參數(shù)傍药。
然后使用 SE37 創(chuàng)建函數(shù):Z_FM_TABLE_FIELDS
FUNCTION z_fm_table_fields.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(TAB_NAME) TYPE TABNAME
*" TABLES
*" TAB_FIELDS STRUCTURE ZTABFIELDS
*"----------------------------------------------------------------------
DATA: BEGIN OF gt_tabflds OCCURS 0 ,
tabname LIKE dd03l-tabname,
fieldname LIKE dd03l-fieldname,
keyflag LIKE dd03l-keyflag,
position LIKE dd03l-position,
rollname LIKE dd03l-rollname,
datatype LIKE dd03l-datatype,
leng LIKE dd03l-leng,
ddtext LIKE dd04t-ddtext,
scrtext_s LIKE dd04t-scrtext_s,
scrtext_m LIKE dd04t-scrtext_m,
scrtext_l LIKE dd04t-scrtext_l,
END OF gt_tabflds.
SELECT tabname
fieldname
keyflag
position
rollname
datatype
leng
INTO CORRESPONDING FIELDS OF TABLE gt_tabflds
FROM dd03l
WHERE tabname = tab_name.
SORT gt_tabflds BY position.
DELETE gt_tabflds WHERE fieldname+0(1) = '.'.
LOOP AT gt_tabflds.
SELECT SINGLE ddtext
scrtext_s
scrtext_m
scrtext_l
INTO CORRESPONDING FIELDS OF gt_tabflds
FROM dd04t
WHERE rollname = gt_tabflds-rollname
AND ddlanguage = sy-langu.
MODIFY gt_tabflds.
ENDLOOP.
LOOP AT gt_tabflds.
CLEAR tab_fields.
MOVE-CORRESPONDING gt_tabflds TO tab_fields.
APPEND tab_fields.
ENDLOOP.
ENDFUNCTION.
C# 通過(guò) RFC 調(diào)用
1)定義 TableFields (TableFields.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SAPZFunction
{
public class TableFields
{
public string TabName { get; set; } // table name
public string FieldName { get; set; } // field name
public string KeyFlag { get; set; } // flag to indicate whether the field is primary key
public string Positiion { get; set; } // position
public string RollName { get; set; } // data element name
public string DataType { get; set; } // data type
public int Leng { get; set; } // length
public string DDText { get; set; } // explaintory short text
public string ScrText_S { get; set; } // short field label
public string ScrText_M { get; set; } // medium field label
public string ScrText_L { get; set; } // long field label
}
}
- 調(diào)用 RFC (ZFunction.cs)
using System;
using System.Collections.Generic;
using SAPLogonCtrl;
using SAPFunctionsOCX;
using SAPTableFactoryCtrl;
using ConnectionProvider;
namespace SAPZFunction
{
public class ZFunction
{
private Connection conn; // sap connection
// demo how to use GetFields
public List<TableFields> GetTableFieldsDemo()
{
var fields = new List<TableFields>();
bool isSuccessful = SAPConnection.SilentLogon(
"192.168.65.100", "D01", 00, "001", "STONE", "PWD", "ZH");
if (isSuccessful) {
conn = SAPConnection.Connection;
fields = this.GetFields("SKB1");
SAPConnection.Logoff();
}
return fields;
}
// get fields from SAP table
public List<TableFields> GetFields(String tableName)
{
var fieldsList = new List<TableFields>();
if (conn == null
|| conn.IsConnected != CRfcConnectionStatus.tloRfcConnected) {
return null;
}
SAPFunctions functions = new SAPFunctions();
functions.Connection = conn;
Function fm = functions.Add("Z_FM_TABLE_FIELDS");
fm.get_Exports("TAB_NAME").Value = tableName;
fm.Call();
Table fields = fm.Tables["TAB_FIELDS"];
fieldsList = this.Convert(fields); // convert table to List<TableFields>
return fieldsList;
}
private List<TableFields> Convert(Table itab)
{
var fields = new List<TableFields>();
if (itab.RowCount == 0) return null;
for (int row = 1; row <= itab.RowCount; row++) {
var entity = new TableFields();
entity.TabName = itab.get_Cell(row, 1); // first column
entity.FieldName = itab.get_Cell(row, 2);
entity.KeyFlag = itab.get_Cell(row, 3);
entity.Positiion = itab.get_Cell(row, 4);
entity.RollName = itab.get_Cell(row, 5);
entity.DataType = itab.get_Cell(row, 6);
entity.Leng = itab.get_Cell(row, 7);
entity.DDText = itab.get_Cell(row, 8);
entity.ScrText_S = itab.get_Cell(row, 9);
entity.ScrText_M = itab.get_Cell(row, 10);
entity.ScrText_L = itab.get_Cell(row, 11);
fields.Add(entity);
}
return fields;
}
}
}
- 單元測(cè)試 (TestZFM.cs)
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SAPZFunction;
using System.Collections.Generic;
namespace UnitTestProject
{
[TestClass]
public class TestZFM
{
[TestMethod]
public void Test_ZFunction()
{
ZFunction zfm = new ZFunction(); // Customized fm in SAP
List<TableFields> fields = zfm.GetTableFieldsDemo();
foreach (TableFields item in fields) {
Console.WriteLine(item.TabName);
Console.WriteLine(item.FieldName);
Console.WriteLine(item.Positiion);
Console.WriteLine(item.KeyFlag);
Console.WriteLine(item.RollName);
Console.WriteLine(item.DataType);
Console.WriteLine(item.Leng);
Console.WriteLine(item.DDText);
Console.WriteLine(item.ScrText_S);
Console.WriteLine(item.ScrText_M);
Console.WriteLine(item.ScrText_L);
Console.WriteLine("---------------------------");
}
}
}
}