首页 > 编程语言 >C#使用sapnoc类库SAPRFC接口调用

C#使用sapnoc类库SAPRFC接口调用

时间:2024-02-27 10:11:57浏览次数:23  
标签:类库 get C# System sapnoc new var using public

 

  1. 使用NuGet引用sapnoc程序包来进行RFC接口的连接,类库框架为framework,暂不支持.net Core框架,会提示冲突。

     

 

 

   

  1. 编写SapRfcHelper帮助类供接口的连接调用

using SAP.Middleware.Connector;

using System;

using System.Collections.Generic;

using System.Data;

using System.Linq;

using System.Runtime.CompilerServices;

using System.Text;

using System.Threading.Tasks;

 

namespace SAPRFC

{

    /// <summary>

    /// Rfc连接Sap的帮助类

    /// </summary>

    public class SapRfcHelper

    {

        #region 单例模式

        private SapRfcHelper()

        {

 

        }

 

        /// <summary>

        /// 创建锁对象

        /// </summary>

        private static readonly object LockObj = new object();

 

        /// <summary>

        /// 创建帮助类实例

        /// </summary>

        private static SapRfcHelper _instance;

 

        private static SapRfcHelper Instance

        {

            get

            {

                lock (LockObj)

                {

                    if (_instance == null)

                    {

                        _instance = new SapRfcHelper();

                    }

                    return _instance;

                }

            }

        }

        #endregion

 

        #region RFC操作客户端

        private RfcDestination _sapRfcDestination;

 

        public RfcDestination SapRfcDestination

        {

            get

            {

                if( _sapRfcDestination == null)

                {

                    _sapRfcDestination = RfcDestinationManager.GetDestination("saprfc");

                    

                }

                return _sapRfcDestination;

            }

 

            private set

            {

                _sapRfcDestination = value;

            }

        }

        #endregion

 

        #region 方法

        /// <summary>

        /// 获取RFC操作对象

        /// </summary>

        /// <returns></returns>

        public RfcRepository GetRfcRepository()

        {

            return SapRfcDestination.Repository;

        }

 

        /// <summary>

        /// RFCTable转化为DataTable

        /// </summary>

        /// <param name="table"></param>

        /// <returns></returns>

        public DataTable ToDataTable(IRfcTable table)

        {

            DataTable rtnDt = new DataTable();

 

            for( var i = 0;i <= table.ElementCount - 1; i++)

            {

                RfcElementMetadata metadata = table.GetElementMetadata(i);

                rtnDt.Columns.Add(metadata.Name);

            }

 

            foreach(IRfcStructure row in table)

            {

                DataRow dr = rtnDt.NewRow();

                for( var i = 0; i <= table.ElementCount - 1; i++)

                {

                    RfcElementMetadata metadata = table.GetElementMetadata(i);

                    dr[metadata.Name] = row.GetString(metadata.Name);

                }

                rtnDt.Rows.Add(dr);

            }

 

            return rtnDt;

        }

 

        /// <summary>

        /// 调用RFC接口方法

        /// </summary>

        /// <param name="FuncName">方法名称</param>

        /// <param name="InPut">输入参数</param>

        /// <param name="OutPut">输出参数</param>

        /// <param name="tablename">输出表</param>

        /// <returns></returns>

        public RetObj CallRFCFunc(string FuncName,List<InputParams>InPut,List<cloumn>OutPut,string tablename = "")

        {

            RetObj retObj = new RetObj();

            DataTable rtnDt = new DataTable();

 

            try

            {

                var rfcRepository = GetRfcRepository();

                var rfcFunction = rfcRepository.CreateFunction(FuncName);

 

                #region 输入参数管理

                InPut.ForEach(item =>

                {

                    switch(item.inputType)

                    {

                        case 1:

                            item.cloumns.ForEach(sub =>

                            {

                                rfcFunction.SetValue(sub.name, sub.value);

                            });

                            break;

                        case 2:

                            var table = rfcFunction.GetTable(item.tableName);

                            if(item.rows.Count == 0)

                            {

                                table.Insert();

                                item.cloumns.ForEach(sub =>

                                {

                                    table.CurrentRow.SetValue(sub.name, sub.value);

                                });

                            }

                            else

                            {

                                item.rows.ForEach(row =>

                                {

                                    table.Insert();

                                    row.ForEach(sub =>

                                    {

                                        table.CurrentRow.SetValue(sub.name, sub.value);

                                    });

                                });

                            }

                            break;

                    }

                });

                #endregion

 

                rfcFunction.SetParameterActive(0, true);

                rfcFunction.Invoke(_sapRfcDestination);

 

                OutPut.ForEach(item =>

                {

                    item.value = rfcFunction.GetValue(item.name).ToString();

                });

                retObj.retval = OutPut;

 

                if(!string.IsNullOrWhiteSpace(tablename))

                {

                    var rfcTable = rfcFunction.GetTable(tablename);

                    retObj.rettab = ToDataTable(rfcTable);

                }

 

            }

            catch (Exception ex)

            {

                //日志记录或抛出异常信息

            }

 

            return retObj;

        }

 

 

        #endregion

    }

}

 

封装的SapRfcParams参数类

using System;

using System.Collections.Generic;

using System.Data;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace SAPRFC

{

    public class cloumn

    {

        /// <summary>

        /// 参数名称

        /// </summary>

        public string name {  get; set; }

        /// <summary>

        /// 参数值

        /// </summary>

        public string value { get; set; }

    }

 

    public class InputParams

    {

        /// <summary>

        /// 参数类型:0,无入参;1,键值对;2,参数表

        /// </summary>

        public int inputType { get; set; }

        /// <summary>

        /// 参数表名

        /// </summary>

        public string tableName {  get; set; }

        /// <summary>

        /// 入参字段

        /// </summary>

        public List<cloumn> cloumns { get; set; }

        /// <summary>

        /// 入参表行

        /// </summary>

        public List<List<cloumn>> rows { get; set; }

    }

 

    public class RetObj

    {

        public List<cloumn> retval { get; set; }

        public DataTable rettab { get; set; }

    }

}

 

  1. 编写测试调用程序,实际使用调用方法一致

编写Win Form程序调用接口,主要目标平台选为64位,默认为32位

 

修改连接配置文件,配置SAP接口的连接

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />

    </startup>

<configSections>

<sectionGroup name="SAP.Middleware.Connector">

<sectionGroup name ="ClientSettings">

<section name="DestinationConfiguration" type="SAP.Middleware.Connector.RfcDestinationConfiguration,sapnco"/>

</sectionGroup>

</sectionGroup>

</configSections>

<SAP.Middleware.Connector>

<ClientSettings>

<DestinationConfiguration>

<destinations>

<add NAME="saprfc" USER="test" PASSWORD="123456" CLIENT="900" SYSNR="00" ASHOST="127.0.0.1" LANG="zh" SAPROUTER="" MAX_POOL_SIZE="10" IDLE_TIMEOUT="600"/>

</destinations>

</DestinationConfiguration>

</ClientSettings>

</SAP.Middleware.Connector>

<!--配置此條的目的是為了解決不同編譯版本引起的衝突。-->

<!--例如當前我們的項目使用的編譯環境是.net4.0,然後我們引用其他自行編寫的DLL使用的是.NET3.5版本,就會發生衝突。-->

<startup useLegacyV2RuntimeActivationPolicy="true">

<supportedRuntime version="4.0"/>

</startup>

</configuration>

 

调用接口的参数组装代码示例:

using SAPRFC;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

 

namespace TestRFCWinForm

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            //获取RFC接口实例

            var rfc = SapRfcHelper.Instance;

 

            #region 输入参数组装

            var input = new List<InputParams>();

            var cloumns = new List<cloumn>();

 

            cloumns.Add(new cloumn

            {

                name = "name1",

                value = "value1"

            });

 

            input.Add(new InputParams

            {

                inputType = 2,

                tableName = "table",

                cloumns = cloumns,

                rows = new List<List<cloumn>>()

            });

 

            #endregion

 

            #region 输出参数组装

            var output = new List<cloumn>()

            {

                new cloumn

                {

                    name = "out",

                    value = "value"

                }

            };

            #endregion

 

            #region 调用接口,获取返回值

            var rtnObj = rfc.CallRFCFunc("funcname",input,output,"tablename");

 

            //返回键值对

            var message = rtnObj.retval.Find(x => x.name == "out").ToString();

            //返回表

            var dt = rtnObj.rettab;

            #endregion

        }

    }

}

 

标签:类库,get,C#,System,sapnoc,new,var,using,public
From: https://www.cnblogs.com/jiangyuhu/p/18036284

相关文章

  • abc305_f (构造实现)
    首先考虑正常的怎么做,就是一遍dfs,是\(O(n)\)的,然而这题在到达每一个点时都要输出它的下一个点才能到达下一个点,同时看到这个\(2n\)觉得不对劲,自然想到走过去走回来,耗2n代码实现还是有点东西的,走过去好搞,但走回来时怎么办呢。我们想到dfs是一个栈,所以在要退出时输出就可以了#inc......
  • ABC283E (dp思想)
    难度1这题看到一点思路也没有,但是看到最小操作数想到二分,dp和贪心,二分答案的check显然不会,贪心不会。发现对于一行,前面的\(i-2\)是不会影响的,这一行也不会影响后面的\(i+2\)行,所以是dp。考虑如何设计状态因为\(i-1\)和\(i+1\)行都会影响,所以设计出来一个dp[i][0/1][0/1][0/1]的东......
  • 多线程系列(十) -ReadWriteLock用法详解
    一、摘要在上篇文章中,我们讲到ReentrantLock可以保证了只有一个线程能执行加锁的代码。但是有些时候,这种保护显的有点过头,比如下面这个方法,它仅仅就是只读取数据,不修改数据,它实际上允许多个线程同时调用的。publicclassCounter{privatefinalLocklock=newReentra......
  • 机器学习策略篇:详解单一数字评估指标(Single number evaluation metric)
    单一数字评估指标无论是调整超参数,或者是尝试不同的学习算法,或者在搭建机器学习系统时尝试不同手段,会发现,如果有一个单实数评估指标,进展会快得多,它可以快速告诉,新尝试的手段比之前的手段好还是差。所以当团队开始进行机器学习项目时,经常推荐他们为问题设置一个单实数评估指标。......
  • 【13.0】JavaScript之流程控制
    【一】if判断【1】语法//if-elseif(条件){条件成立执行的代码块}else{条件不成立时执行的代码块}//if-elseif-elseif(条件){条件成立执行的代码块}elseif(条件){条件成立执行的代码块}else{条件不成立时执行的代码块}//()条件{}执行的代码块【2】if~e......
  • CF1928C (数学思想)
    难度3其实是有点虚高的,可能是我这种数学题做的少了。在考试时式子都写出来了,但不知道怎么处理。然后注意一下细节就可以了。懒懒懒。对于xy=k(k为常数)可以直接枚举k的因子,然后看一下限制条件即可。#include<bits/stdc++.h>usingnamespacestd;longlongT,n,x,tot=0;unorde......
  • 【16.0】JavaScript之对象
    【一】对象js中的对象是无序的属性集合我们可以把js中的对象想象成键值对,其中值可以是数据或者函数特征-在对象中属性表示行为-在对象中用方法表示可以看成Python中的字典,但是在JS中的自定义对象要比Python里面的字典操作起来更方便【二】对象创建【1】对象字面量(Objec......
  • C# WPF 根据RGB三色得出透明度Opacity
    当我们把ARGB压缩为RGB数据时,会丢失A透明通道那么就有可能会遇到反推A透明通道的问题原理很简单,取RGB三色最大通道除255得到A通道Randomrandom=newRandom();bytered=Convert.ToByte(random.Next(0,0xff));bytegreen=Conver......
  • 【15.0】JavaScript之函数
    【一】函数函数function,也叫做功能,方法,函数可以将一段代码封装起来,函数就具备了特定的功能函数的作用就是封装一段代码,将来可以重复使用在Python中定义函数需要用def在JavaScript中定义函数需要用function【二】函数声明【1】先声明再调用函数必须先声明,才能......
  • 【14.0】JavaScript之数组
    【一】什么是数组数组是一组有序的数据集合,数组内部可以存放多个数据,不限制数据类型,数组的长度可以动态调整数组类似于Python当中的列表【二】创建数组创建数据的最简单方式是通过字面量vararr=[]也可以通过数组对象去创建vararr=newArray()存放多个......