• VS2005调用RFC


    今日心血来潮,想自己做一些VS2005调用SAP的RFC的程序例子来学习学习。

    1、 SE37,进入FUNCTION BUILDER主界面;

    2、 转到主菜单上的Goto->Function Group->Create Group,然后输入名称等,由于只是测试,所以就选择本地对象进行保存,对应的开发类为$TMP;

    3、 SE80,进入对象浏览器,选择自己刚才创建的函数组,点击右键,在弹出菜单中选择激活选项进行激活,如图:

    clip_image001

    4、 重新回到SE37,创建函数YCTF_RFC2,选择刚才创建的函数组Y_CTF_FUN_GROUP,然后进入,选择clip_image002,这样整个函数就可以被外部系统进行RFC了。IMPORT这边我就输入参数INPUT,类型为I,EXPORT处我也只输入参数OUTPUT,类型为I,其它的就修改下源代码,输入output = input * 2.

    5、 激活此函数

    6、 现在开始进行VS2005的操作了,新建一个类库,然后在引用中导入Interop.SAPFunctionsOCX、Interop.SAPLogonCtrl和Interop.SAPTableFactoryCtrl。

    7、 添加Conn类的编写,代码如下:

    1、 namespace Sap

    2、 {

    3、 public class Conn

    4、 {

    5、 /// <summary>

    6、 /// sap连接

    7、 /// </summary>

    8、 private static SAPLogonCtrl.Connection conn = null;

    9、

    10、 /// <summary>

    11、 /// 登录

    12、 /// </summary>

    13、 /// <param name="ip"></param>

    14、 /// <param name="client"></param>

    15、 /// <param name="language"></param>

    16、 /// <param name="user"></param>

    17、 /// <param name="password"></param>

    18、 /// <param name="systemNumber"></param>

    19、 /// <returns></returns>

    20、 public static bool logon(

    21、 string ip,

    22、 string client,

    23、 string language,

    24、 string user,

    25、 string password,

    26、 int systemNumber)

    27、 {

    28、 SAPLogonCtrl.SAPLogonControlClass logon = new SAPLogonCtrl.SAPLogonControlClass();

    29、 logon.ApplicationServer = ip; //SAP system’s IP

    30、 logon.Client = client; //SAP system’client

    31、 logon.Language = language; //Lauguage

    32、 logon.User = user; //Username

    33、 logon.Password = password; //Password

    34、 logon.SystemNumber = systemNumber; //System number

    35、 conn = (SAPLogonCtrl.Connection)logon.NewConnection();

    36、 return conn.Logon(0, true);

    37、 }

    38、

    39、 /// <summary>

    40、 /// 获取某个值

    41、 /// </summary>

    42、 /// <param name="functionName"></param>

    43、 /// <param name="importNames"></param>

    44、 /// <param name="importValues"></param>

    45、 /// <param name="exportFieldName"></param>

    46、 /// <returns></returns>

    47、 public static string getValue(string functionName,

    48、 List<string> importNames,

    49、 List<string> importValues,

    50、 string exportFieldName)

    51、 {

    52、 SAPFunctionsOCX.SAPFunctionsClass func = new SAPFunctionsOCX.SAPFunctionsClass();

    53、 func.Connection = conn;

    54、 SAPFunctionsOCX.IFunction ifunc = (SAPFunctionsOCX.IFunction)func.Add(functionName);

    55、 for (int i = 0; i < importNames.Count; ++i)

    56、 {

    57、 SAPFunctionsOCX.IParameter parameter = (SAPFunctionsOCX.IParameter)ifunc.get_Exports(importNames[i]);

    58、 parameter.Value = importValues[i];

    59、 }

    60、 ifunc.Call();

    61、 SAPFunctionsOCX.IParameter output = (SAPFunctionsOCX.IParameter)ifunc.get_Imports(exportFieldName);

    62、 return output.Value.ToString();

    63、 }

    64、

    65、 /// <summary>

    66、 /// 获取表

    67、 /// </summary>

    68、 /// <param name="functionName"></param>

    69、 /// <param name="importNames"></param>

    70、 /// <param name="importValues"></param>

    71、 /// <returns></returns>

    72、 public static DataSet getDs(

    73、 string functionName,

    74、 List<string> importNames,

    75、 List<string> importValues)

    76、 {

    77、 DataSet ds = new DataSet();

    78、

    79、 SAPFunctionsOCX.SAPFunctionsClass func = new SAPFunctionsOCX.SAPFunctionsClass();

    80、 func.Connection = conn;

    81、 SAPFunctionsOCX.IFunction ifunc = (SAPFunctionsOCX.IFunction)func.Add(functionName);

    82、 for (int i = 0; i < importNames.Count; ++i)

    83、 {

    84、 SAPFunctionsOCX.IParameter parameter = (SAPFunctionsOCX.IParameter)ifunc.get_Exports(importNames[i]);

    85、 parameter.Value = importValues[i];

    86、 }

    87、 ifunc.Call();

    88、 //SAPFunctionsOCX.IParameter NUMBER = (SAPFunctionsOCX.IParameter)ifunc.get_Imports("P_SUBRC");

    89、 SAPTableFactoryCtrl.Tables tables = (SAPTableFactoryCtrl.Tables)ifunc.Tables;

    90、

    91、 for (int i = 1; i <= tables.Count; ++i)

    92、 {

    93、 SAPTableFactoryCtrl.Table t = (SAPTableFactoryCtrl.Table)tables.get_Item(i);

    94、 DataTable dt = new DataTable();

    95、 dt.TableName = t.Name;

    96、 for (int j = 1; j <= t.ColumnCount; ++j)

    97、 {

    98、 string title = t.get_ColumnName(j);

    99、 DataColumn column = new DataColumn(title, typeof(string));

    100、 dt.Columns.Add(column);

    101、 }

    102、 for (int j = 1; j <= t.RowCount; ++j)

    103、 {

    104、 DataRow dr = dt.NewRow();

    105、 for (int col = 0; col < dt.Columns.Count; ++col)

    106、 {

    107、 string title = dt.Columns[col].Caption;

    108、 dr[title] = t.get_Cell(j, title).ToString();

    109、 }

    110、 dt.Rows.Add(dr);

    111、 }

    112、 ds.Tables.Add(dt);

    113、 }

    114、

    115、 return ds;

    116、 }

    117、 }

    118、 }

    119、

    8、 编写部分代码进行RFC函数编写:

    1、 List<string> importNames = new List<string>();

    2、 List<string> importValues = new List<string>();

    3、 importNames.Add("INPUT");

    4、 importValues.Add("13");

    5、

    6、 string output = Sap.Conn.getValue("YCTF_RFC2", importNames, importValues, "OUTPUT");

    7、 MessageBox.Show(output);

    8、 OK,很正常。

    9、

    来个复杂的,整个太简单了点,可是由于自己水平有限,写不出什么来,原来有个顾问写的一个获取批次属性的函数,我们都用它,逻辑还是有点复杂,所以打算直接调用整个函数来试试看,此函数既有返回的单个值,也有表格返回。

    10、 编写测试代码:

    1、 List<string> importNames = new List<string>();

    2、 List<string> importValues = new List<string>();

    3、 importNames.Add("P_MATNR");

    4、 importNames.Add("P_CHARG");

    5、 importValues.Add("000000000064000024");

    6、 importValues.Add("N10052501 ");

    7、

    8、 DataSet ds = Sap.Conn.getDs("Y_FIG001_GET_CHAR_FROM_BATCH", importNames, importValues);

    9、 if (ds.Tables.Count > 0)

    10、 {

    11、 dataGridView1.DataSource = ds.Tables[1];

    12、 dataGridView1.Visible = true;

    13、 }

    测试,表格中没有返回任何值,但在SAP中进行测试是有的。跟踪IFunc变量,在调用call方法之前都是正常的,但是在调用之后,里面的RFC结果显示SYSTEM_FAILURE.,不知道什么原因,马上GOOGLE一下,有人建议说用ST22可以查看运行时错误信息。

    11、 ST22,选择今天错误信息进行查看,马上定位到了,打开日志信息,显示如下:

    clip_image004

    哦,原来在函数的属性中不是Remote Enable Module,不行,恩,应该就是这个原因。

    12、 拷贝Z_FIG001_GET_CHAR_FROM_BATCH,新生成函数Y_ FIG001_GET_CHAR_FROM_BATCH,函数组选择前面自己创建的那个函数组,OK,进去激活,没想到错误一大堆,不管了,定位错误地方,到原来的Z_FIG001_GET_CHAR_FROM_BATCH,把引用的代码都给拷贝过来,现在也差不多慢慢懂得了函数组的一些用户了,就是可以自己定义一些结构、变量等供该函数组下面的功能模块调用。

    13、 代码没错之后,激活、测试,OK,通过。

    另外要注意的是,因为物料代码是18位,所以前面一定要补0以合乎要求,否则是取不到结果的。

    涉及TCODE:SE37、SE80、ST22。

  • 相关阅读:
    两个Stirng[]拼接成一个数组
    Visual code 常用快捷键
    mysql 中的分页limit
    移动端web轮播图插件swiper,功能很强大
    array_splice()函数 ,删除数组中的某个值
    Github简单的上传和修改
    PHP数组在循环的时候修改本身的值
    IP定位,天气接口
    使用百度翻译的API接口
    laravel 队列
  • 原文地址:https://www.cnblogs.com/tianfu/p/1801604.html
Copyright © 2020-2023  润新知