Integration with SAP Software By Calling RFC Functions

To communicate with various SAP systems from Foresight Analytics Platform, remote function call (FRC) is used - it is a standard interface of communication and data exchange between various SAP systems. See below an example of connecting to data provider and communication with it using RFC.

Connection

To connect to SAP RFC, use SAP.Net Connector 3.0. It is important to have sapnco.dll and sapnco_utils.dll libraries. To get library data, go to SAP Market Place, to do it, it is required to have user identifier and password for downloading. If there is no identifier and password, contact SAP Basis support to get specified libraries. Bitness of installed Foresight Analytics Platform and obtained libraries must match.

If everything for the SAP.Net Connector 3.0is ready, execute one of the following actions:

  1. Create a new .Net assembly in Foresight Analytics Platform repository.

  2. Add link to SAP sapnco.dll and sapnco_utils.dll libraries:

  3. In the code of created .NET unit, add strings to import library contents:

Imports SAP.Middleware.Connector;

  1. Add code for SAP connection and calling various RFC functions, specified below.

Code to Work with RFC Functions

On starting the Main procedure, two actions are executed:

  1. The Connection procedure which connects to SAP server is called.

  2. The executeSAPFunction function which executes RFC function and returns the result is called. The list of parameters generated by SAPParams variable and the RFC function name and returned table name specified in the executeSAPFunction procedure must correspond to the signature of called RFC function.

The result of function execution will be available in the DataTable variable and can be further used to get and process data using various Foresight Analytics Platform tools.

Imports System;
Imports Prognoz.Platform.Interop.Metabase;
Imports SAP.Middleware.Connector;

Public Class StartParams
    
Private m_Metabase: Prognoz.Platform.Interop.Metabase.IMetabase;
    
Public Property Metabase: Prognoz.Platform.Interop.Metabase.IMetabase
        
Get
        
Begin
            
Return m_Metabase
        
End Get
        
Set
        
Begin
            m_Metabase := Value;
        
End Set
    
End Property Metabase;
End Class;

Public Class Program
    
Public Shared ConfigInitialized: boolean;
    
Public Shared rfcDestination: RfcDestination;

    [STAThread]
    
Public Shared Sub Main(Params: StartParams);
    
Var
        SAPParams: array[
2Of SAPParam;
        DataTable: IRfcTable;
        config: IDestinationConfiguration;
    
Begin
        Connection();
        SAPParams[
0] := New SAPParam("Country""Russia");
        SAPParams[
0] := New SAPParam("Retail""Food");
        DataTable := executeSAPFunction(
"GetData""Table", SAPParams);
        
//...
        //Further use of DataTable to communicate with Foresight analytics Platform objects
        //...
    End Sub;

    
Private Shared Sub Connection();
    
Var
        config: IDestinationConfiguration;
    
Begin
        
If Not ConfigInitialized Then
            config := 
New SAPDestinationConfig();
            config.GetParameters(
"TEST");
            RfcDestinationManager.RegisterDestinationConfiguration(config);
            ConfigInitialized := 
True;
        
End If;
        rfcDestination := RfcDestinationManager.GetDestination(
"TEST");
        rfcDestination.Ping();
    
End Sub Connection;

    
Private Shared Function executeSAPFunction(functionName: string; resultTableName: string; Paramarray params: array Of SAPParam): IRfcTable;
    
Var
        func: IRfcFunction;
    
Begin
        func := getSapFunction(functionName, params);
        
Try
            func.Invoke(rfcDestination);
            
Return func.GetTable(resultTableName);
        
Except On e: RfcBaseException Do
            System.Diagnostics.Debug.WriteLine(e.Message);
        
Finally
        
End Try;
    
End Function;

    
Private Shared Function getSapFunction(functionName: string; Paramarray params: array Of SAPParam): IRfcFunction;
    
Var
        func: IRfcFunction;
        param: SAPParam;
    
Begin
        func := rfcDestination.Repository.CreateFunction(functionName);
        
For Each param In params Do
            func.SetValue(param.name, param.value);
        
End For;
        
Return func;
    
End Function;
End Class;

Public Class SAPParam
    
Public name: string;
    
Public value: object;

    
Public Constructor SAPParam(_name: string; _value: object);
    
Begin
        name := _name;
        value := _value;
    
End Constructor SAPParam;
End Class;

Class SAPDestinationConfig: IDestinationConfiguration
    
Public Function ChangeEventsSupported(): boolean;
    
Begin
        
Return False;
    
End Function ChangeEventsSupported;
    
    
Public Event ConfigurationChanged: RFCDestinationManager.ConfigurationChangeHandler;
    
    
Public Function GetParameters(destinationName: string): RfcConfigParameters;
    
Var
        params: RfcConfigParameters;
    
Begin
        params := 
New RfcConfigParameters();
        params.Add(RfcConfigParameters.Name, 
"TEST");
        params.Add(RfcConfigParameters.AppServerHost, 
"ServerName");
        params.Add(RfcConfigParameters.SystemNumber, 
"0");
        params.Add(RfcConfigParameters.SystemID, 
"100");
        params.Add(RfcConfigParameters.User, 
"username");
        params.Add(RfcConfigParameters.Password, 
"password");
        params.Add(RfcConfigParameters.Client, 
"100");
        params.Add(RfcConfigParameters.Language, 
"EN");
        params.Add(RfcConfigParameters.PoolSize, 
"10")
        
Return params;
    
End Function GetParameters;
End Class;

See also:

Developers Knowledge Base