善待自己,珍惜今天,恩泽他人,享受生活

不放弃任何解决困难的机会,人的一生就是解决困难的过程。 当我们走完一生才能说没有问题要解决了。 面对工作、生活上的压力,面对来自家庭、朋友、同事、上司等的困惑。 要排除万难,否则我们就会被万难排除!

博客园 首页 新随笔 联系 订阅 管理

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这个东西了。

我们假定要实现这样的一个功能:

  1. 运行在SAP系统外的一个程序窗体,上面有一个下拉框和文本框
  2. 程序运行之后自动载入SAP中某个Client的物料号至该下拉框
  3. 用户点击了这个下拉框,则旁边的文本框就现实该品号的物料的名称

1.在SAP端创建RFC函数

  • 登陆SAP
  • 运行SE37:

image

  • 创建函数组

imageimage

 

  • 点击保存;之后回到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(); //获取品名

  1. 对异常的处理
  2. 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里面去

posted on 2011-12-10 23:27  笨笨丁  阅读(2707)  评论(1编辑  收藏  举报