C#连接SAP获取RFC函数数据 中文乱码变为#问题

本文主要记录C#这边的代码,至于SAP那边的操作不做讨论。

C#连接SAP获取RFC函数数据,一般有两种方法。

  1. 使用COM组件获取数据
  2. 使用SAP的NCO connector

一开始使用的COM组件来访问SAP,开发时安装好SAP,这样通过COM引用Interop.SAPFunctionsOCX.dll、Interop.SAPLogonCtrl.dll、Interop.SAPTableFactoryCtrl.dll这三个DLL

主要C#代码如下:

using SAPFunctionsOCX;
using SAPLogonCtrl;
using SAPTableFactoryCtrl;

private void btnGetResult_Click(object sender, EventArgs e)
        {
            try
            {
                //Console.WriteLine("try to logon...");
                string str = String.Empty;
                SAPLogonControlClass connctl = new SAPLogonControlClass();
                //下面的参数值根据实际情况赋值
                connctl.Client = "";
                connctl.Language = Common.GetConfigMessage(@"", @"/Language");//语言
                connctl.ApplicationServer = "";//Application server IP
                connctl.SystemNumber = ;//
                connctl.User = Common.GetConfigMessage(@"", @"/User");
                connctl.Password = Common.GetConfigMessage(@"", @"/Password");
                
                //自定义变量
                string po = Common.GetConfigMessage(@"", @"/PO");//订单号
                string materials = Common.GetConfigMessage(@"",@"/Materials");//

                //实例化连接对象
                Connection conn = (Connection)connctl.NewConnection();
                //conn.CodePage = "8400";//简体中文  -->Fail  会引发异常  未解决

                //登陆
                if (conn.Logon(null, true))
                {
                    //Console.WriteLine("SUCCESS!");
                    this.textResult.Text = "logon ok...";
                }

                SAPFunctionsClass functions = new SAPFunctionsClass();
                functions.Connection = conn;

                //这里就可以传入Function Name
                Function fucntion = (Function)functions.Add("*********");

                //这里是传入值参数
                Parameter parameter1 = (Parameter)fucntion.get_Exports("*******");
                parameter1.Value = po;

                //调用函数
                if (fucntion.Call())
                {
                    Tables Tables = (Tables)fucntion.Tables;
                    Table table = (Table)Tables.get_Item("****");//传出Table参数

                    DataTable dt = ToDataTable(table);//转为DataTable
                    string HtmlBody = ExportDatatableToHtml(dt);  //DataTable输出HTML
                    System.IO.File.WriteAllText(@"d:\abc.HTML", HtmlBody);

                    foreach (DataRow row in dt.Rows)
                    {
                        string itemNo = row["POSNR"].ToString();
                        string material = row["MATNR"].ToString();

                        #region Get Bom
                        if (materials.IndexOf(material) >=0)
                        {
                            //传入Function
                            Function fucntion2 = (Function)functions.Add("*****");
                            //传入参数
                            Parameter parameter21 = (Parameter)fucntion2.get_Exports("*****");
                            parameter21.Value = po;
                            Parameter parameter22 = (Parameter)fucntion2.get_Exports("****");
                            parameter22.Value = Convert.ToInt32(itemNo);
                            Parameter parameter23 = (Parameter)fucntion2.get_Exports("*****");
                            parameter23.Value = "S";
                            Parameter parameter24 = (Parameter)fucntion2.get_Exports("*****");
                            parameter24.Value = "X";
                            //传出参数
                            Parameter parameter25 = (Parameter)fucntion2.get_Imports("*****");
                            SAPFunctionsOCX.Structure parameter26 = (SAPFunctionsOCX.Structure)fucntion2.get_Imports("****");

                            //调用函数
                            if (fucntion2.Call())
                            {
                                Tables Tables2 = (Tables)fucntion2.Tables;
              
                                SaveToFile(Path.Combine(folderPath, material + "-PE_INSTANCE.txt"), parameter25.Value.ToString());

                                for (int i = 1;i<=parameter26.ColumnCount; i ++)
                                {
                                    SaveToFile(Path.Combine(folderPath, material + "-PE_SODATA.txt"), parameter26.ColumnName[(short)i] +":"+ parameter26.Value[i]);
                                }
                                
                            }
                        }
                        #endregion
                    }

                    table.FreeTable(); //释放Table
                }
                //退出登陆
                conn.Logoff();
                this.textResult.Text = "ok\r\n" + str;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                this.textResult.Text = ex.ToString();
            }
        }                     

 

    /// <summary>
        /// 从SAP Table转DataTable
        /// </summary>
        /// <param name="itab"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(SAPTableFactoryCtrl.Table itab)
        {
            DataTable dt = new DataTable();

            // Header
            for (int col = 1; col <= itab.ColumnCount; col++)
            {
                dt.Columns.Add(itab.get_ColumnName(col), typeof(string));
            }

            // Line items
            for (int row = 1; row <= itab.RowCount; row++)
            {
                DataRow dr = dt.NewRow();
                for (int col = 1; col <= itab.ColumnCount; col++)
                {
                    dr[col - 1] = itab.get_Cell(row, col);
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }      

其中描红的代码处出现异常,一旦不注释掉就会异常。

注释掉后数据可以正常获取,但是所有的中文都变为 "#"

实在找不到解决方法,最后就又换位NCO方式抓取。

通过VS的NuGet获取NCO

项目的目标框架变为.NET Framework4

主要代码如下:

using SAP.Middleware.Connector;

//登陆SAP前的准备工作
        public class MyConfig : IDestinationConfiguration
        {
            public RfcConfigParameters GetParameters(String destinationName)
            {
                if ("Test1".Equals(destinationName))
                {
                    RfcConfigParameters parms = new RfcConfigParameters();
                    parms.Add(RfcConfigParameters.AppServerHost, "");   //SAP主机IP
                    parms.Add(RfcConfigParameters.SystemNumber, "");  //SAP实例
                    parms.Add(RfcConfigParameters.User, "");  //用户名
                    parms.Add(RfcConfigParameters.Password, "");  //密码
                    parms.Add(RfcConfigParameters.Client, "");  // Client
                    parms.Add(RfcConfigParameters.Language, "ZH");  //登陆语言
                    parms.Add(RfcConfigParameters.PoolSize, "5");
                    parms.Add(RfcConfigParameters.MaxPoolSize, "10");
                    parms.Add(RfcConfigParameters.IdleTimeout, "60");
                    parms.Add(RfcConfigParameters.Codepage, "8400"); //解决中文问题
                    return parms;
                }
                else return null;
            }

            public bool ChangeEventsSupported()
            {
                return false;
            }

            public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
        }

private void btnGetResult_Click(object sender, EventArgs e)
        {
            try
            {
                nco();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                this.textResult.Text = ex.ToString();
            }
        }

        public void nco()

        {
            IDestinationConfiguration ID = new MyConfig();
            RfcDestinationManager.RegisterDestinationConfiguration(ID);
            RfcDestination test = RfcDestinationManager.GetDestination("Test1");
            RfcDestinationManager.UnregisterDestinationConfiguration(ID);
            ncoTest(test);
        }

        public void ncoTest(RfcDestination prd)

        {
            RfcRepository repo = prd.Repository;
            IRfcFunction companyBapi = repo.CreateFunction("***");   //调用函数名
            companyBapi.SetValue("****", po);   //设置Import的参数
            companyBapi.Invoke(prd);   //执行函数
            IRfcTable table = companyBapi.GetTable("*****");  //获取相应的表
            DataTable dt = ToDataTable(table);
            string HtmlBody = ExportDatatableToHtml(dt);
            System.IO.File.WriteAllText(@"d:\abc.HTML", HtmlBody);

            foreach (DataRow row in dt.Rows)
            {
                string itemNo = row["POSNR"].ToString();
                string material = row["MATNR"].ToString();

                #region Get Bom
                if (materials.IndexOf(material) >= 0)
                {
                    IRfcFunction bomFunction = repo.CreateFunction("*****");   //调用函数名
                    bomFunction.SetValue("****", po);   //设置Import的参数
                    bomFunction.SetValue("****", Convert.ToInt32(itemNo));   //设置Import的参数
                    bomFunction.SetValue("****", "S");   //设置Import的参数
                    bomFunction.SetValue("****", "X");   //设置Import的参数
                    bomFunction.Invoke(prd);   //执行函数
                    //传出参数
                    object INSTANCE = bomFunction.GetValue("****");
                    IRfcStructure bomStr =  bomFunction.GetStructure("****");

                    try
                    {

                        for (int i = 0; i <= bomStr.ElementCount - 1 ; i++)
                        {
                            RfcElementMetadata metadata = bomStr.GetElementMetadata(i);
                            SaveToFile(Path.Combine(folderPath, material + "-PE_SODATA.txt"), metadata.Name + ":" + bomStr.GetString(metadata.Name));
                        }
                    }
                    catch (Exception ex2)
                    {
                        throw new Exception(ex2.ToString());
                    }
                }
                #endregion
            }

            prd = null;
            repo = null;

            this.textResult.Text = "ok\r\n";
        }

/// <summary>
        /// 从SAP Table转DataTable
        /// </summary>
        /// <param name="myrfcTable">IRfcTable</param>
        /// <returns></returns>
        public DataTable ToDataTable(IRfcTable myrfcTable)
        {
            DataTable loTable = new DataTable();
            int liElement = 0;

            for (liElement = 0; liElement <= myrfcTable.ElementCount - 1; liElement++)
            {
                RfcElementMetadata metadata = myrfcTable.GetElementMetadata(liElement);
                loTable.Columns.Add(metadata.Name);
            }

            foreach (IRfcStructure Row in myrfcTable)
            {
                DataRow ldr = loTable.NewRow();

                for (liElement = 0; liElement <= myrfcTable.ElementCount - 1; liElement++)
                {
                    RfcElementMetadata metadata = myrfcTable.GetElementMetadata(liElement);
                    ldr[metadata.Name] = Row.GetString(metadata.Name);
                }

                loTable.Rows.Add(ldr);
            }

            return loTable;
        }

  描红处解决了中文变为#的问题。

转载于:https://www.cnblogs.com/allenfly/p/8888695.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android Studio中远程调用SAP RFC函数,可以通过以下步骤实现: 1. 首先,确保你的Android Studio项目中已经添加了相应的SAP Java Connector(SAP JCo)库。你可以在项目的build.gradle文件中添加依赖项,例如: ```java dependencies { implementation &#39;com.sap.conn.jco:jco3:3.1.2&#39; } ``` 2. 创建一个SAP连接: 在你的代码中,实例化一个`JCoDestination`对象,并设置连接所需的属性,如SAP服务器的地址、用户名、密码等。例如: ```java JCoDestination destination = JCoDestinationManager.getDestination("MY_DESTINATION"); destination.getRepository(); // 设置连接属性 destination.getProperties().setProperty(DestinationDataProvider.JCO_ASHOST, "SAP服务器地址"); destination.getProperties().setProperty(DestinationDataProvider.JCO_SYSNR, "系统编号"); destination.getProperties().setProperty(DestinationDataProvider.JCO_CLIENT, "客户端"); destination.getProperties().setProperty(DestinationDataProvider.JCO_USER, "用户名"); destination.getProperties().setProperty(DestinationDataProvider.JCO_PASSWD, "密码"); ``` 3. 调用RFC函数: 使用SAP连接后,可以从SAP系统的函数库中获取function module,然后通过函数的`execute()`方法调用RFC函数并传递参数。例如: ```java JCoFunction function = destination.getRepository().getFunction("RFC_FUNCTION_NAME"); if (function == null) { throw new RuntimeException("Function not found"); } // 设置RFC函数的输入参数 function.getImportParameterList().setValue("parameterName", parameterValue); function.execute(destination); // 获取RFC函数的输出参数 String result = function.getExportParameterList().getString("outputParamName"); ``` 4. 处理RFC函数的返回结果: 根据你的需求,可以根据RFC函数的返回结果进行一系列的操作,例如显示在界面上、保存到本地等。 以上就是在Android Studio中远程调用SAP RFC函数的基本步骤。请注意,在实际应用中,你可能还需要处理连接的异常、异常情况下的处理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值