来源
C# SAP .Net Connector 3.0連接RFC示例
必备环境:
1,类库sapnco.dll、sapnco_utils.dll。可以通过官方下载安装取得,也可以直接从网上只下载这两个类库,还能直接从NuGet获取:Install-Package SAPDotNetConnector3 -Version 0.3.0。
2,Microsoft Visual C++ 2010 Redistributable Package,简称Microsoft Visual C++ 2010 。下载链接,可从控制面板查看已安装程序确认有没安装。Windows更新中可能已包含了Microsoft Visual C++ 2010,但不在已安装程序中显示。
步骤1:SAP定义RFC
步骤2:C#实现
a):调用SAP RFC封装类:
namespace RFCLib
{
//C#代码创建Sap连接对象的类SapConnection
public class SapConnection : IDestinationConfiguration
{
RfcConfigParameters IDestinationConfiguration.GetParameters(string destinationName) //或 public RfcConfigParameters GetParameters(string destinationName)
{
SAPClient sapClient;
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SAPClient));
string sapClientSettingPath = System.AppDomain.CurrentDomain.BaseDirectory+ "SAPClientSetting.config";
using (System.IO.FileStream fileStream = new System.IO.FileStream(sapClientSettingPath, System.IO.FileMode.Open))
{
sapClient = (SAPClient)serializer.Deserialize(fileStream);
}
return GetParameters(destinationName, sapClient);
}
public RfcConfigParameters GetParameters(string destinationName, SAPClient sapInfo)
{
RfcConfigParameters conf = new RfcConfigParameters();
if (destinationName == "NSP")//给连接SAP的对象命个名
{
//先添加必填参数
conf.Add(RfcConfigParameters.SystemNumber, sapInfo.SystemNumber);
//conf.Add(RfcConfigParameters.SystemID, "");
conf.Add(RfcConfigParameters.User, sapInfo.User);
conf.Add(RfcConfigParameters.Password, sapInfo.Password);
conf.Add(RfcConfigParameters.Client, sapInfo.Client);
conf.Add(RfcConfigParameters.Language, sapInfo.Language);
//添加可选参数(普通登陆参数)
if (!string.IsNullOrEmpty(sapInfo.ApplicationServer))
conf.Add(RfcConfigParameters.AppServerHost, sapInfo.ApplicationServer);
if (!string.IsNullOrEmpty(sapInfo.AppServerService))
conf.Add(RfcConfigParameters.AppServerService, sapInfo.AppServerService);
//添加可选参数(服务器组参数)
if (!string.IsNullOrEmpty(sapInfo.MessageServerHost))
conf.Add(RfcConfigParameters.MessageServerHost, sapInfo.MessageServerHost);
if (!string.IsNullOrEmpty(sapInfo.MessageServerService))
conf.Add(RfcConfigParameters.MessageServerService, sapInfo.MessageServerService);
if (!string.IsNullOrEmpty(sapInfo.LogonGroup))
conf.Add(RfcConfigParameters.LogonGroup, sapInfo.LogonGroup);
if (!string.IsNullOrEmpty(sapInfo.SystemID))
conf.Add(RfcConfigParameters.SystemID, sapInfo.SystemID);
}
return conf;
}
public bool ChangeEventsSupported()
{
return true;
}
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
}
//SAP连接参数类
public class SAPClient
{
public string ApplicationServer { get; set; } //应用服务器IP地址,如 10.88.88.88
public string AppServerService { get; set; }
public string Client { get; set; } //sap客户端 如 100
public string Language { get; set; } //语言,如 ZH 或 EN
public string LogonGroup { get; set; } //登录组名
public string MessageServerHost { get; set; } //消息服务器IP地址
public string MessageServerService { get; set; }
public string Password { get; set; } //登录密码
public string SystemID { get; set; } //系统标识
public string SystemNumber { get; set; } //实例号,如 00
public string User { get; set; } //登录账号
}
//自定义的调用RFC的类
public class NcoQueryRFC
{
//创建Sap连接对象的类SapConnection的实例global_dest,单例模式
private static RfcDestination global_dest;
public static RfcDestination SapConnInfo()
{
if (global_dest == null)
{
//SapConnection类定义见代码末
SapConnection con= new SapConnection();
RfcDestinationManager.RegisterDestinationConfiguration(con);
}
//这里定义
global_dest = RfcDestinationManager.GetDestination("NSP");
return global_dest;
}
//查询RFC的方法
//public static IRfcFunction ExcuteAndGetSAPFuntion(string funtionName,List<Dictionary<string,object>> functionparamsList)
/// <summary>
/// 调用RFC并获取SAP函数调用结果
/// </summary>
/// <param name="funtionName">函数名称</param>
/// <param name="functionparamsList">函数所需参数</param>
/// <returns>RFC调用结果</returns>
static IRfcFunction ExcuteAndGetSAPFuntion(string funtionName, List<Dictionary<string, object>> functionparamsList)
{
RfcDestination dest = NcoQueryRFC.SapConnInfo();
RfcRepository rfcrep = dest.Repository;
IRfcFunction myfun = rfcrep.CreateFunction(funtionName); //RFC的名称
foreach (Dictionary<string,Object> functionparams in functionparamsList)
{
foreach (var item in functionparams)
{
myfun.SetValue(item.Key, item.Value);
}
}
myfun.Invoke(dest);//调用
return myfun;//直接返回function,取到的结果由调用者提取。
}
//查询RFC导出
public static Dictionary<string, object> GetRFCExport(string funtionName, List<Dictionary<string, object>> functionparamsList, List<string> exportParams)
{
Dictionary<string, object> exports = new Dictionary<string, object>();
IRfcFunction myfun = ExcuteAndGetSAPFuntion(funtionName,functionparamsList); //RFC的名称
foreach (string exportParam in exportParams)
{
exports.Add(exportParam,myfun.GetValue(exportParam));
}
return exports;
}
/// <summary>
/// 调用RFC,获取返回的table
/// </summary>
/// <param name="funtionName">函数名</param>
/// <param name="functionparamsList">函数参数列表</param>
/// <param name="tableName">RFC中定义的返回table的名称</param>
/// <returns></returns>
public static IRfcTable GetRFCTable(string funtionName, List<Dictionary<string, object>> functionparamsList, string tableName)
{
Dictionary<string, object> exports = new Dictionary<string, object>();
IRfcFunction myfun = ExcuteAndGetSAPFuntion(funtionName, functionparamsList); //RFC的名称
IRfcTable rfcTable = myfun.GetTable(tableName);
return rfcTable;
}
}
}
b):RFC返回Table转.Net平台DataTable对象。
/// <summary>
/// 将RFC返回的Table转换为.Net平台的DataTable对象
/// </summary>
/// <param name="rfcTable">RFC返回Table</param>
/// <returns>转换后的.Net平台DataTable对象</returns>
DataTable GetRFCData(IRfcTable rfcTable)
{
DataTable sourceTable = new DataTable();
string columnName;
//新增列
for (int i = 0; i < rfcTable.Metadata.LineType.FieldCount; i++)
{
columnName = rfcTable.Metadata[i].Name;
sourceTable.Columns.Add(columnName);
}
DataRow row;
//新增行
foreach (SAP.Middleware.Connector.IRfcStructure item in rfcTable)
{
row = sourceTable.NewRow();
string cellValue;
for (int i = 0; i < rfcTable.Metadata.LineType.FieldCount; i++)
{
columnName = rfcTable.Metadata[i].Name;
cellValue = item.GetString(columnName);
//NUM类型,去除前导0
if (rfcTable.Metadata[i].DataType == RfcDataType.NUM )
{
cellValue = Convert.ToInt32(item.GetString(columnName)).ToString();
}
row[columnName] = cellValue;
}
sourceTable.Rows.Add(row);
}
return sourceTable;
}
c):C#通过封装类库调用RFC
/// <summary>
/// 从SAP根据料号及类别获取SAP图文档类别、编号、版本、名称
/// </summary>
/// <param name="part">料号</param>
/// <param name="sapDoctype">SAP类别代号</param>
///// <param name="code">返回结果状态码:0成功 1失败</param>
///// <param name="msg">返回结果描述</param>
/// <param name="result">返回结果</param>
[WebMethod(Description = "从SAP根据料号及类别获取图文档类别、编号、版本、名称")]
//public void GetPLMCADD_SAP(string part, string sapDoctype, ref string code,ref string msg, ref object result)
public string GetPLMCADD_SAP(string part, string sapDoctype)
{
#region 初始返回对象与参数检验
SAPServiceResult sAPServiceResult = new SAPServiceResult()
{
Code = "1",
Message = "未处理!",
Data = null
};
if (string.IsNullOrEmpty(part) || string.IsNullOrEmpty(sapDoctype))
{
sAPServiceResult.Message = "缺少参数";
return Newtonsoft.Json.JsonConvert.SerializeObject(sAPServiceResult, Newtonsoft.Json.Formatting.Indented);
}
else if (!RFCLib.RFC.SAPDocTypes.Split(',').Contains(sapDoctype))
{
sAPServiceResult.Message = $"类别{sapDoctype}不存在";
return Newtonsoft.Json.JsonConvert.SerializeObject(sAPServiceResult, Newtonsoft.Json.Formatting.Indented);
}
#endregion
List<Dictionary<string, object>> paramsList = new List<Dictionary<string, object>>();
Dictionary<string, object> keyValuePairs2 = new Dictionary<string, object>() { { "IM_MATNR", part } };
paramsList.Add(keyValuePairs2);
//1,通过料号获取SAP图文档类别、编号、版本、名称
string rfcTableName = RFCLib.RFC.sapRfcs.Where(x => x.Name == "ZPLM_MAT_LINK_DIRS_GET_MES").Take(1).Select(x => x.Table.Name).FirstOrDefault();
IRfcTable rfcTable = RFCLib.NcoQueryRFC.GetRFCTable("ZPLM_MAT_LINK_DIRS_GET_MES", paramsList, rfcTableName);
DataTable ZPLM_MAT_LINK_DIRS_GET_TableData = GetRFCData(rfcTable);
DataRow row1 = ZPLM_MAT_LINK_DIRS_GET_TableData.AsEnumerable().Where(x => x["DOKAR"].ToString() == sapDoctype.Trim()).OrderByDescending(x => x["DOKVR"]).FirstOrDefault();
object[] rowData = row1.ItemArray;//先将结果保存起来,否则Rows.Clear()后,row1会被清空。
ZPLM_MAT_LINK_DIRS_GET_TableData.Rows.Clear();
ZPLM_MAT_LINK_DIRS_GET_TableData.Rows.Add(rowData);
sAPServiceResult.Code = "0";
sAPServiceResult.Message = "ok";
sAPServiceResult.Data = ZPLM_MAT_LINK_DIRS_GET_TableData;
string jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(sAPServiceResult, Newtonsoft.Json.Formatting.Indented);
return jsonStr;
}
/// <summary>
/// SAPService接口返回封装对象
/// </summary>
class SAPServiceResult
{
/// <summary>
/// 状态码:0执行成功,其他执行失败
/// </summary>
public string Code { get; set; }
/// <summary>
/// 说明
/// </summary>
public string Message { get; set; }
/// <summary>
/// 执行结果
/// </summary>
public object Data { get; set; }
}

本文介绍如何使用C#通过SAP NetConnector 3.0库调用SAP系统的RFC功能,包括环境搭建、类库使用、连接配置、RFC函数调用及结果处理。
3682

被折叠的 条评论
为什么被折叠?



