SAP connector3.0支持的VS版本和使用前必须安装的东西:
完全兼容VS2005、VS2008、VS2010以及.NET2.0、3.0、3.5、4.0还有分32位和64位的两大版本。由于它所需要的两个文件sapnco.dll和sapnco_utils.dll这两个文件是通过VC++2005编译的,所以在目标电脑里必须要安装这个运行库方可正常运行(系统若有自带则可不用再安装),运行库大小2.6M,安装不到一分钟。
何谓RFC:
何谓RFC,就是一个Function,可以被非SAP系统调用,比如VB,C#,Java等。如果我们在RFC中INCLUDE了相关的业务逻辑,那么我们就可以完全操控SAP中的业务数据了。就像在TTE里,有一只程序,前端是在OA开发,设计了相关的客户提领库存,然后还要到SAP系统中去执行程序扣减相应的库存,这样是挺费劲的,如果能够在OA中放一个按钮,点击这个按钮就自动执行了这个程序,方便省事。而这一切,可以利用C#调用RFC来实现。
要实现整个过程,则必须要现在SAP中建立好相应的RFC函数,然后用VS建立好相应的程序,写代码调用就可以了。两者关联就是使用NCO3.0这个东西了。
我们假定要实现这样的一个功能:
- 运行在SAP系统外的一个程序窗体,上面有一个下拉框和文本框
- 程序运行之后自动载入SAP中某个Client的物料号至该下拉框
- 用户点击了这个下拉框,则旁边的文本框就现实该品号的物料的名称
1.在SAP端创建RFC函数
- 登陆SAP
- 运行SE37:
- 创建函数组
- 点击保存;之后回到SE37,输入我们要调用的RFC函数名,比如:ZRFC_GetClient 然后点击新建(右一按钮):
2.在VS端调用SAP创建的RFC函数
- 首先需要引用两个NCO3.0的DLL:sapnco.dll 和sapnco_utils.dll
- 然后在程序代码页面引用: using SAP.Middleware.Connector;
- 定义一个设置SAP connect 连接串的类
public class SAPConn : IDestinationConfiguration
{
#region IDestinationConfiguration Members
public RfcConfigParameters GetParameters(String sapConnStr)
{
//String destinationName
/*
<connectionStrings>
<!--<add name="SapConnectionString" connectionString="CLIENT=800 USER=Y_RFC_CON_01 PASSWD=Aa123456. ASHOST=10.138.250.237 SYSNR=0"/>-->
<add name="SapConnectionString" connectionString="Client=280;UserName=Y_RFC_CON_01;Password=Aa123456.;AppServerHost=10.138.250.142;Language=EN;SystemNumber=00"/>
</connectionStrings>
*/
//ConfigurationManager.ConnectionStrings[destinationName].ConnectionString.ToString()
if (!object.Equals(sapConnStr, null))
{
//retrieve parameters in connection string
string[] paramsstr = sapConnStr.Split(';');
RfcConfigParameters parms = new RfcConfigParameters();
parms.Add(RfcConfigParameters.Name, "SapConnectionString");
foreach (string str in paramsstr)
{
string[] strpar = str.Split('=');
switch (strpar[0])
{
case "AppServerHost": parms.Add(RfcConfigParameters.AppServerHost, strpar[1]); break;
case "Client": parms.Add(RfcConfigParameters.Client, strpar[1]); break;
case "SystemNumber": parms.Add(RfcConfigParameters.SystemNumber, strpar[1]); break;
case "Language": parms.Add(RfcConfigParameters.Language, strpar[1]); break;
case "UserName": parms.Add(RfcConfigParameters.User, strpar[1]); break;
case "Password": parms.Add(RfcConfigParameters.Password, strpar[1]); break;
}
}
return parms;
}
else return null;
}
public bool ChangeEventsSupported() { return false; }
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
#endregion
}
- /获取SAP 连接信息
destination1 = RfcDestinationManager.GetDestination(new SAPConn().GetParameters(SapConnectionString));
RfcRepository repo = destination1.Repository; - //声明调用的RFC 方法
rfcFunc = repo.CreateFunction("RFC_READ_TABLE"); - //RFC 输入参数
- //得到输出信息
companyBapi.Invoke(prd); //执行函数
IRfcTable table = companyBapi.GetTable("IT_MARA"); //获取相应的品号内表
string MAKTX = companyBapi.GetValue("MAKTX").ToString(); //获取品名
- 对异常的处理
public void nco(RfcDestination prd)
{
string type = string.Empty;
RfcRepository repo = prd.Repository;
IRfcFunction companyBapi = repo.CreateFunction("ZRFC_MARA_INFO"); //指定RFC名称
try
{
companyBapi.SetValue("NUM1", textBox1.Text.Trim()); //输入参数复制
companyBapi.SetValue("NUM2", textBox2.Text.Trim()); //输入参数复制
companyBapi.Invoke(prd); //开始调用执行
textBox3.Text = companyBapi.GetValue("NUM3").ToString(); //获取返回结果
}
catch (RfcAbapException ex) //此Exception专门用于获取用户自定义的异常信息!!!!
{
// companyBapi.Metadata.GetAbapException(ex.Key).Documentation 获取对应的异常的说明文字
MessageBox.Show(companyBapi.Metadata.GetAbapException(ex.Key).Documentation, "SAP RFC返回信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (RfcTypeConversionException ex) //此Exception专门用于获取变量类型转换的异常!!!!
{
MessageBox.Show("您输入的不是数值", "SAP RFC返回信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (RfcAbapRuntimeException ex) //此Exception专门用于获取RFC执行过程中的运行时异常!!!!
{
MessageBox.Show(companyBapi.Metadata.GetAbapException(ex.Key).Documentation, "SAP RFC返回信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (RfcBaseException ex) //此Exception是总Exception类,可以获取所有的异常,如果有多个Catch,则不可以放第一位!!!!
{
MessageBox.Show("其他所有错误", "SAP RFC返回信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
prd = null;
repo = null;
}
3.既然BAPI是一些特殊的RFC,封装了业务逻辑,使得将业务都变成一个一个对象,使用者只需要传入传出参数就可以了。
4.sapnco.dll在ASP.NET中载入失败的解决方法
- 当所有一切代码准备就绪之后,如果是ASP.NET那就是要发布网站到服务器了。如果服务器上的系统是WIN2003,那很不幸,系统会提示这样的“红脸”过来:
意思是说sapnco_utils.dll和sapnco.dll这两个文件不能载入。
Could not load file or assembly "sapnco_utils,Version=3.0.0.42,...
网上查找了方法也不尽然,各说纷纭。但是在WIN2008下的IIS7跟WinXP下的IIS5.1都可以完全正常,但是这个WIN2003就不行。
后来在对这两个DLL进行分析的时候发现它们是用VC++2005开发的,想到WIN2003系统可能没有必要的运行库。于是在工作站测试的时候安装了VC++2005 32bit版,然后刷新一切就正常了!
解决方法:安装相应vc++2005运行库即可!(实践证明:VC++2008不行!)
如果还不行,需要将这个连个DLL放到GAC里面去