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。

原文地址:https://www.cnblogs.com/tianfu/p/1801604.html