步骤:
1. Create a SAP Connector Class - Application ( Under Visual C# Projects ) and give the RFC name and build the application. 创建才C#项目SAP Connector Class-application,指定rfc函数名称,然后编译项目。项目名称CSServerSimple。
2. Inside this application, write your .net code as per your requirement.在c#项目中,编写代码:
分别如下(除了(4)SAPProxy1Impl其它都可以自动生成):
(1) 结构类,对应sap中的结构:
[RfcStructure(AbapName ="BRFCKNA1" , Length = 197, Length2 = 394)]
[Serializable]
public class BRFCKNA1 : SAPStructure
{
/// <summary>
/// Customer Number 1
/// </summary>
[RfcField(AbapName = "KUNNR", RfcType = RFCTYPE.RFCTYPE_CHAR, Length = 10, Length2 = 20, Offset = 0, Offset2 = 0)]
[XmlElement("KUNNR")]
public string Kunnr
{
get
{
return _Kunnr;
}
set
{
_Kunnr = value;
}
}
private string _Kunnr;
………………其它属性,对应字段名
}
(2)表类型类,对于Sap中的表
[Serializable]
public class BRFCKNA1Table : SAPTable
{
/// <summary>
/// Returns the element type BRFCKNA1.
/// </summary>
/// <returns>The type BRFCKNA1.</returns>
public static Type GetElementType()
{
return (typeof(BRFCKNA1));
}
………………其它方法
}
(3)SAPProxy1
public abstract class SAPProxy1 : SAPServer
{
// Constructors
public SAPProxy1(){}
public SAPProxy1(string ConnectionString) :base(ConnectionString){}
public SAPProxy1(string connectionString, SAPServerHost host) : base(connectionString, host) {}
public SAPProxy1(string[] args) : base(args) {}
public SAPProxy1(string[] args, SAPServerHost host) : base(args, host) {}
public SAPProxy1(string programId, string gwhost, string sapgwxx, string codepage)
: base(programId, gwhost, sapgwxx, codepage) {}
public SAPProxy1(string programId, string gwhost, string sapgwxx, string codepage, SAPServerHost host)
: base(programId, gwhost, sapgwxx, codepage, host) {}
/// <summary>
/// Remote Function Module RFC_CUSTOMER_GET.
///
/// </summary>
/// <param name="Kunnr"></param>
/// <param name="Name1"></param>
/// <param name="Customer_T"></param>
/// <exception cref="Nothing_Specified"/>
/// <exception cref="No_Record_Found"/>
[RfcMethod(AbapName = "RFC_CUSTOMER_GET")]
protected abstract void Rfc_Customer_Get (
[RfcParameter(AbapName = "KUNNR",RfcType=RFCTYPE.RFCTYPE_CHAR, Optional = true, Direction = RFCINOUT.IN, Length = 10, Length2 = 20)]
[XmlElement("KUNNR", IsNullable=false)]
string Kunnr,
[RfcParameter(AbapName = "NAME1",RfcType=RFCTYPE.RFCTYPE_CHAR, Optional = true, Direction = RFCINOUT.IN, Length = 35, Length2 = 70)]
[XmlElement("NAME1", IsNullable=false)]
string Name1,
[RfcParameter(AbapName = "CUSTOMER_T",RfcType=RFCTYPE.RFCTYPE_ITAB, Optional = false, Direction =RFCINOUT.INOUT)]
[XmlArray("CUSTOMER_T", IsNullable=false)]
[XmlArrayItem("item", IsNullable=false)]
ref BRFCKNA1Table Customer_T);
}
(4)SAPProxy1Impl
[Serializable]
public class SAPProxy1Impl : SAPProxy1
{
public SAPProxy1Impl(string[] args, SAPServerHost host) : base(args, host) {}
// Implementation of Server Methods
// Implementation of remote function module RFC_CUSTOMER_GET
protected override void Rfc_Customer_Get (
string Kunnr,string Name1,ref BRFCKNA1Table Customer_T)
{
Console.WriteLine("Called by SAP : " + Name1.ToString());
// exceptions are returned to SAP ABAP/4 program as appropriate SY-SUBRC & SY-MSGV1
if ("" == Kunnr & "" == Name1)
{
RfcAbapException ns = new RfcAbapException("NOTHING_SPECIFIED", " Both kunnr and name1 were empty");
throw ns;
}
if ("SMITH" == Name1)
{
RfcAbapException nrf= new RfcAbapException("NO_RECORD_FOUND", " No customer by name: " + Name1);
throw nrf;
}
//return some data
BRFCKNA1 row = new BRFCKNA1();
row.Anred = "Mr";
row.Kunnr = "2";
row.Name1 = "Li";
row.Ort01 = "wiesloch";
row.Pfach = "";
row.Pstlz = "69999";
row.Stras = "Irgenwo";
Customer_T.Add(row);
}
(5)C#和sap类型影射
ABAP Type | .NET CLS |
C (String) | String |
I (integer) | Int32 |
F (Float) | Double |
D (Date) | String |
T (Time) | String |
P (BCD Packed, Currency, Decimal, Qty) | Decimal |
N (Numc) | String |
X (Binary and Raw) | Byte [ ] |
RFC String | String |
XString | String |
Complex Data Types
SAP Data Type | .NET Data Type |
Structure | C# class derived from SAPStructure |
Table (ITAB) | C# class derived from SAPTable |
(New) Hierarchical Table (type II ITAB) | Not supported in this version |
3. 应用程序完成并编译以后,生成exe的可执行文件(在项目的bin目录下)。After completed, this application will create an exe file ( Under the folder binrelease ). The exe file should run in the same domain/LAN of your SAP server. You can test the connection in SM59
4. 用如下的命令进行加连接参数进行注册。注册完成后在sap SMGW->GoTo->Logged on Clients中可以看见。You need to pass the command line parameters to execute this exe file. Command line parameters are
-aWbhTest_vendor -g10.1.10.102 -xSAPGW00
C:/Documents and Settings/Administrator>C:/CSServerSimple/bin/Debug/CSServerSimp
le.exe -aCSServerSimple -g10.1.10.102 -xSAPGW00
Create RFC Server SAPProxy1Impl instance 0
Create RFC Server SAPProxy1Impl instance 1
Create RFC Server SAPProxy1Impl instance 2
Start RFC Server SAPProxy1Impl instances
To stop SAPProxy1Impl, please enter Stop!
Syslog: k F6P : rscpmc 80
Called by SAP :
Called by SAP : aaa
Called by SAP : aaa
5. 查看建立的c#注册连接。 use SMGW->GoTo->Logged on Clients to check all registered RFC servers and their programIDs (TP name).
6. 用sm59创建rfc远程连接目标,选择TCP/IP连接。Create a RFC destination in SM59
Under TCP/IP,.Technical Settings --> Activation Type --> Registered Server Program ( Need to be selected ).
Program ID must be your registeration name : CSServerSimple.
Gateway Options are:
Gateway Host: erpdev (10.1.10.101)-SAP服务器的IP地址
Gateway Service:SAPGW00-SAP网关
For the parameter Gateway Host, you should enter the hostname of your SAP application server. The value for the parameter Gateway Service is usually SAPGW<XX>, where the XX is the system number of your SAP system.
然后点击连接进行测试,测试结果如下:
7. 编写abap程序,调用在上面建立的c#函数。调用如下:
CALL FUNCTION 'RFC_CUSTOMER_GET'(函数名称) DESTINATION P_DEST (RFC目标名称sm59创建)
Abap和C#函数输入输出参数对应表
A simple mapping of RFC parameter types to C# parameter types follows:
RFC Parameter Type | C# Parameter Type |
IMPORT | IN |
EXPORT | OUT |
CHANGING | REF (In/Out) |
TABLES | REF (In/Out) |
(http://help.sap.com/saphelp_nw2004s/helpdata/en/bd/ab5315ed92c4479d62036be9cdf678/frameset.htm)
To execute our .NET server stub application from the SAP system we need to execute the ABAP command Call function X Destination Y. This report calls our proxy and writes the results to screen. Alternatively, you can use the SAP function module’s single test capability with the TRFC destination for your .NET server stub.
To create a TRFC destination for the SAP .NET server stub create a destination of type T (TRFC) in transaction code SM59. The program ID in your server stub is case sensitive.
Example
REPORT Z_WBH_NET_LINK.
DATA: TBLCUST like BRFCKNA1 occurs 0 with header line.
PARAMETERS: P_CUSTNO like KNA1-KUNNR, P_CUSTNA like KNA1-NAME1,
P_DEST(15) TYPE C DEFAULT 'WBHTEST1'.
CALL FUNCTION 'CSServerSimple' DESTINATION P_DEST
EXPORTING
KUNNR = P_CUSTNO
NAME1 = P_CUSTNA
TABLES
CUSTOMER_T = TBLCUST
EXCEPTIONS
NOTHING_SPECIFIED = 1
NO_RECORD_FOUND = 2
OTHERS = 3.
CASE SY-SUBRC.
WHEN 0.
WRITE :'OK'.
LOOP AT TBLCUST.
WRITE: / SY-TABIX, TBLCUST-KUNNR, TBLCUST-NAME1, TBLCUST-ORT01.
ENDLOOP.
WHEN 1.
WRITE: / 'You need to specify a value ', SY-MSGV1.
WHEN 2.
WRITE: / '.NET component didnt find anything ', SY-MSGV1.
WHEN 3.
WRITE: / 'Some other error occurred ', SY-MSGV1.
WHEN OTHERS.
WRITE: / 'Something is wrong if we get here'.
ENDCASE.
The entry point in the C# method is the method with the function module name being called from the SAP system (for example, RFC_CUSTOMER_GET). In Microsoft Visual Studio, you can set a breakpoint here and examine the input values from the SAP system. This provides a similar idea to the ABAP_DEBUG functionality that is provided in the client proxy.
RFCServerConsole - is an SAP RFC Server implemented in C#.
The SAP system calls out to this .net component.
This component implements, RFC_CUSTOMER_GET and will return 2 customers to SAP. Before calling this
component from inside of SAP, you'll need a TCP/IP destination (SM59) - (type registration). Set the
SAP connection in the Visual Studio project properties for RFCServerConsole (e.g. right click on it)
Properties > Configuration Properties > Debugging > Command line arguments.
(example -aSomeProgID -gLOCALHOST -xSAPGW00)
The program id (-a) parameter must match exactly in your component and in the TCP/IP destination (SM59)
All you have to do in sm59 is write RFC destination , Program ID , Description .
The Program ID is important ,because it is just the SomeProgID (example -aSomeProgID -gLOCALHOST -xSAPGW00)run RFCServerConsole.exe -aSomeProgID -gLOCALHOST -xSAPGW00 in commond.exe
在此过程中,可能会出现无法找到sapmsg.ini的文件。在C:/WINDOWS找到saplogon.ini,打开后把SysName和SrvPort下面的内容清空,不清空的话他会引导你去找SAP 服务器上的Messaging server,总是告诉你无法打开或者无法找到sapmsg.ini的文件,非常麻烦。
[MSSysName]
Item1=
[MSSrvPort]
Item1=
如果机器上没有Java runtime environment 就会一直停留在Loading的画面
——————————————————————————————————————————————