﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-玄铁剑-文章分类-SAP</title><link>http://www.cnitblog.com/MartinYao/category/7700.html</link><description>成功的途径：抄，创造，研究，发明...</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 13:52:45 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 13:52:45 GMT</pubDate><ttl>60</ttl><item><title>FRC  DataProviderSAP</title><link>http://www.cnitblog.com/MartinYao/articles/62849.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Thu, 26 Nov 2009 11:45:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/62849.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/62849.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/62849.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/62849.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/62849.html</trackback:ping><description><![CDATA[<div><font face="Times New Roman"><strong><font size=3>1．</font> </strong><strong><font size=3>DataProviderSAP. </font></strong></font><strong><font size=3>安装：</font></strong></div>
<div><font size=3><font face="Times New Roman"></font></font><font size=2 face=宋体>执行安装文件进行安装DataProviderSAP.msi，默认安装路径：</font></div>
<div><font size=2 face=宋体>C:\Program Files\Common Files\Microsoft Shared\Adapters\ SAP\。</font></div>
<div></div>
<div><font size=3><strong><font face="Times New Roman">2</font></strong><strong>．<font face="Times New Roman">Microsoft Visual Studio&#174; 2005</font></strong><strong>新建项目</strong>：</font></div>
<div><font size=2 face=宋体>添加引用Microsoft.Adapter.SAP.SAPProvider.dll。</font></div>
<div><font size=2 face=宋体>Microsoft.Adapter.SAP.SAPProvider.dll从以下安装路径查找：</font></div>
<div><font size=2 face=宋体>C:\Program Files\Common Files\Microsoft Shared\Adapters\ SAP\。</font></div>
<div></div>
<div><font size=3><strong><font face="Times New Roman">3</font></strong><strong>．<font face="Times New Roman">C# </font></strong><strong>调用<font face="Times New Roman">FRC</font></strong><strong>语句：</strong></font></div>
<div align=left></div>
<div>using Microsoft.Adapter.SAP;//添加引用</div>
<div></div>
<div align=left>SAPConnection con = new SAPConnection("ASHOST=10.1.10.102; CLIENT=200;SYSNR=00;USER=***;PASSWD=***;LANG=zh");//SAP服务器连接参数设置，</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; con.Open();</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPCommand cmd = new SAPCommand(con);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = "EXEC BAPI_CUSTOMER_GETLIST @IDRANGE=@param OUTPUT";//执行远程RFC BAPI_CUSTOMER_GETLIST，执行RFC的参数传递过程参考下边的EXEC 语句的语法</div>
<div align=left></div>
<div align=left>//以下为RFC调用参数赋值并指定Input、Output类型</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPParameter param = new SAPParameter("@param", ParameterDirection.InputOutput);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTable dt = new DataTable();</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Columns.Add("SIGN");</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Columns.Add("OPTION");</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Columns.Add("LOW");</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Columns.Add("HIGH");</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataRow row = dt.NewRow();</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row["LOW"] = 1;</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row["HIGH"] = 1000;</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Rows.Add(row);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.Value = dt;</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.Parameters.Add(param);</div>
<div align=left>//执行结果放在SAPDataReade中</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPDataReader dr = cmd.ExecuteReader();</div>
<div align=left></div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //retrieving returned datareaders</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("value of returned datareader: " + dr.GetSchemaTable().TableName);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dr.Read())</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string line = "";</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; dr.FieldCount; i++)</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = line + "| " + dr.GetValue(i).ToString();</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(line);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (dr.NextResult());</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Checking returned value of parameter @IDRANGE...");</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTable dt1 = (DataTable)param.Value;</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (DataRow row1 in dt1.Rows)</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string line = "";</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; dt1.Columns.Count; i++)</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = line + "| " + row1[i].ToString();</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(line);</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div align=left></div>
<div><font size=3><strong><font face="Times New Roman">4</font></strong><strong>．</strong></font><strong>EXEC </strong><strong>语句的语法</strong></div>
<div align=left>以下几节介绍了针对该提供程序实现 EXEC 语句的语法规范。请注意，在某些情况下，该语法与 Transact-SQL 语法稍有不同。</div>
<div align=left><a name=91></a><strong>4.1 EXEC </strong><strong>语法</strong></div>
<div align=left>&nbsp;&nbsp;&nbsp; EXEC rfc_name</div>
<div align=left>&nbsp;&nbsp;&nbsp; [{value | @variable [OUTPUT]}][,...n]</div>
<div align=left>&nbsp;&nbsp;&nbsp; [@parameter = {value | @variable [OUTPUT]}][,...n] [;]</div>
<div align=left>&nbsp;&nbsp;&nbsp;</div>
<div align=left>其中：</div>
<div align=left><strong><em>rfc_name</em></strong> 指定要执行的函数调用的名称。</div>
<div align=left><strong><em>parameter</em></strong> 指定函数接口中定义的参数名。</div>
<div align=left><strong><em>value</em></strong> 指定参数值。</div>
<div align=left><strong><em>@variable</em></strong> 指定替换参数。使用 <strong>DbParameter</strong> 接口可以绑定参数值。</div>
<div align=left><strong><em>output</em></strong> 指定 SAP RFC 参数为 <strong>Output</strong> 或 <strong>InputOutput</strong>。</div>
<div align=left><a name=92></a><strong>4.2 </strong><strong>处理命名参数和未命名参数</strong></div>
<div align=left>以下内容是在 EXEC 查询中指定命名参数和未命名参数的准则：</div>
<div align=left>1. 在指定参数时，可以通过命名这些参数（例如，@parameter_name=value）来指定参数，也可以只提供值。</div>
<div align=left>2. 当使用默认值定义参数时，可以在不指定参数的情况下执行该操作。</div>
<div align=left>3. 当使用 @parameter_name=value 格式时，则无需按照函数调用中所定义的顺序来提供参数名和常数。</div>
<div align=left>4. 未命名参数的所需顺序如下所示：</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IMPORT (Input)</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXPORT (Output)</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE (InputOutput)</div>
<div align=left><br>但是，排序是在参数类型内按照上面所列顺序进行的。例如，您有 6 个未命名参数，这 3 种参数类型各两个，如下表所示，参数排序应为 <strong>param1</strong>、<strong>param2</strong>、<strong>param3</strong>、<strong>param4</strong>、<strong>param5</strong>、<strong>param6</strong>。</div>
<table border=1 cellPadding=0 width=450>
    <tbody>
        <tr>
            <td vAlign=bottom width=150>
            <div align=left><strong>IMPORT </strong><strong>参数</strong></div>
            </td>
            <td vAlign=bottom width=150>
            <div align=left><strong>EXPORT </strong><strong>参数</strong></div>
            </td>
            <td vAlign=bottom width=150>
            <div align=left><strong>TABLE </strong><strong>参数</strong></div>
            </td>
        </tr>
        <tr>
            <td vAlign=top>
            <div align=left>param1</div>
            </td>
            <td vAlign=top>
            <div align=left>param3</div>
            </td>
            <td vAlign=top>
            <div align=left>param5</div>
            </td>
        </tr>
        <tr>
            <td vAlign=top>
            <div align=left>param2</div>
            </td>
            <td vAlign=top>
            <div align=left>param4</div>
            </td>
            <td vAlign=top>
            <div align=left>param6</div>
            </td>
        </tr>
    </tbody>
</table>
<div align=left></div>
<div align=left>5. 使用未命名参数时，您需要指定所有参数（包括可选参数和必选参数）的值。只有当可选参数出现在参数列表的末尾时，才可以省略它们。不支持使用&#8220;Default&#8221;或空格跳过可选参数，如下面示例所示：<br><br>EXEC Proc_Test_Defaults , 'A';<br><br>请改用下列语法以获取所需的结果：<br><br>EXEC Proc_Test_Defaults @p2='A';</div>
<div align=left>6. EXEC 查询不支持使用具有下列属性的参数：</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 嵌套结构（包含其他结构作为其字段的结构）。</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 嵌套表。</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含结构的表。</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含表的结构。</div>
<div align=left>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 字段中包含复合字符串类型（例如 <strong>SSTRING</strong> 或 <strong>RAWSTRING</strong>）的结构或表。</div>
<div align=left>7. 下表列出了执行 RFC 时 RFC 参数类型与参数方向之间的逻辑映射：</div>
<table border=1 cellPadding=0 width=600>
    <tbody>
        <tr>
            <td vAlign=bottom width=200>
            <div align=left><strong>PFC </strong><strong>参数类型</strong></div>
            </td>
            <td vAlign=bottom width=200>
            <div align=left><strong>查询关键字</strong></div>
            </td>
            <td vAlign=bottom width=200>
            <div align=left><strong>参数方向</strong></div>
            </td>
        </tr>
        <tr>
            <td vAlign=top>
            <div align=left>Import 参数</div>
            </td>
            <td vAlign=top>
            <div align=left>无</div>
            </td>
            <td vAlign=top>
            <div align=left>Paramdirection.Input</div>
            </td>
        </tr>
        <tr>
            <td vAlign=top>
            <div align=left>Export 参数</div>
            </td>
            <td vAlign=top>
            <div align=left>Output</div>
            </td>
            <td vAlign=top>
            <div align=left>Paramdirection.Output</div>
            </td>
        </tr>
        <tr>
            <td vAlign=top>
            <div align=left>Table 参数</div>
            </td>
            <td vAlign=top>
            <div align=left>Output /无</div>
            </td>
            <td vAlign=top>
            <div align=left>InputOutput</div>
            </td>
        </tr>
    </tbody>
</table>
<div align=left>8. </div>
<div align=left>9. 以下内容是处理参数的一般准则：</div>
<div align=left>a.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 您可以将参数值指定为常数，也可以通过在查询中使用占位符来指定参数值。</div>
<div align=left>b.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在查询中使用占位符时，必须创建 <strong>SAPParameter</strong> 对象并将其添加到相应的命令对象中。然后，将占位符的名称传递到构造函数中；方向和值取决于上下文。</div>
<div align=left>&#167;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于 <strong>Input</strong> 参数，请不要在查询中指定参数方向的关键字。但必须设置该参数对象的 <strong>value</strong> 字段，否则该提供程序将引发异常。请一定不能显式设置该参数对象的 <strong>direction</strong> 字段，因为该提供程序的默认设置为 <strong>Input</strong>。</div>
<div align=left>&#167;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于其他参数，请使用格式 @paramname=@placeholder 并在查询中显式指定 <strong>Output</strong> 关键字。然后，您必须添加与占位符相对应的 <strong>SAPParameter</strong> 并根据参数类型将参数方向显式设置为 <strong>ParamDirection.Output</strong> 或 <strong>ParamDirection.InputOutput</strong>。</div>
<div align=left>c.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数名称和占位符名称不区分大小写。</div>
<div align=left>d.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 除非参数具有不同的方向，否则它们的名称不能在查询中重复。</div>
<div align=left>e.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 占位符名称不能在查询中重复。</div>
<div align=left><a name=93></a><strong>4.3 EXEC </strong><strong>语句示例</strong></div>
<div align=left>&#183; 若要执行不带输入参数的 BAPI，请使用以下语法；数据通过 DataReader 对象返回：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXEC BAPI_COMPANYCODE_GETLIST</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>&#183; 若要执行带有输入参数的 RFC，请使用以下语法：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exec RFC_CUSTOMER_GET @NAME1='Contoso'</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>&#183; 若要执行带有指定的输入参数但没有参数名称的 RFC，请使用以下语法：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exec RFC_CUSTOMER_GET '*', 'Contoso'</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>&#183; 若要执行带有指定为变量的输入参数的 RFC，请使用以下语法：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exec RFC_CUSTOMER_GET @var</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>在此示例中，必须创建名为 <strong>@var</strong> 的参数，并显式设置该参数的值（例如，设置为&#8220;1001&#8221;)，原因是 RFC_CUSTOMER_GET 的第一个参数对应于 KUNNR（客户号）。</div>
<div align=left>&#183; 若要执行使用变量作为输入参数名称的 RFC，请使用以下语法：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exec RFC_CUSTOMER_GET @KUNNR=@var1, @NAME1='Contoso'</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>您必须创建名为 <strong>@var1</strong> 的 SAPParameter，指定它的值，然后将它绑定到对应的命令对象。新创建的参数对象的默认方向为 <strong>input</strong>。</div>
<div align=left>&#183; 若要执行 BAPI，并将表作为参数返回，请使用以下语法：</div>
<div align=left>&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXEC BAPI_COMPANYCODE_GETLIST @ COMPANYCODE_LIST=@tableVar OUTPUT</div>
<div align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div align=left>您必须创建名为 <strong>@var1</strong> 的 SAPParameter，指定它的值，然后将它绑定到对应的命令对象。新创建的参数对象的方向应为 <strong>InputOutput</strong>。<br></div>
<a href="http://www.microsoft.com/downloads/details.aspx?familyid=D09C1D60-A13C-4479-9B91-9E8B9D835CDC&amp;displaylang=en"><font color=#1d58d1>http://www.microsoft.com/downloads/details.aspx?familyid=D09C1D60-A13C-4479-9B91-9E8B9D835CDC&amp;displaylang=en</font></a>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/62849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2009-11-26 19:45 <a href="http://www.cnitblog.com/MartinYao/articles/62849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>.NET调用SAP RFC</title><link>http://www.cnitblog.com/MartinYao/articles/62821.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Wed, 25 Nov 2009 11:12:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/62821.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/62821.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/62821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/62821.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/62821.html</trackback:ping><description><![CDATA[<p>using System;<br>using System.Collections.Generic;<br>using System.Linq;<br>using System.Text;<br>using System.Data;<br>using Microsoft.Adapter.SAP;</p>
<p>namespace ConsoleForSap<br>{<br>&nbsp;&nbsp;&nbsp; public class SapConfig<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string ASHOST { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string CLIENT { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string LANG { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string USER { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string PASSWD { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int SYSNR { get; set; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public class SapParameter<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string ParamName { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public object ParamValue { get; set; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private ArrayList ObjSapParam = new ArrayList();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void AddParam(string ParamName, object ParamValue)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SapParameter param = new SapParameter();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.ParamName = ParamName;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.ParamValue = ParamValue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjSapParam.Add(param);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ClearParam()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjSapParam.Clear();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object[] GetParam()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ObjSapParam.ToArray();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public class CallSAP<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private DataSet MapSapData(SAPDataReader Sapdr)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet ds = new DataSet();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTable dtResult;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTable dtSchema;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dtResult = new DataTable();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dtSchema = Sapdr.GetSchemaTable();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (DataRow dr in dtSchema.Rows)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataColumn col = new DataColumn();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; col.ColumnName = dr["ColumnName"].ToString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; col.Caption = dr["Caption"].ToString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; col.DataType = System.Type.GetType(dr["DataType"].ToString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dr["DataType"].ToString().ToLower().EndsWith(".system") == true)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int iSize = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int.TryParse(dr["ColumnSize"].ToString(), out iSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; col.MaxLength = iSize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dtResult.Columns.Add(col);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (Sapdr.Read())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataRow dr = dtResult.NewRow();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; Sapdr.FieldCount; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[i] = Sapdr.GetValue(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch { }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dtResult.Rows.Add(dr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ds.Tables.Add(dtResult);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (Sapdr.NextResult());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ds;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public DataSet ExecuteSapCmd(SapConfig conf, string SapRfcName, SapParameter ObjParam, ref string strMsg)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string strConn = "ASHOST=" + conf.ASHOST + "; CLIENT=" + conf.CLIENT + ";SYSNR=" + conf.SYSNR.ToString() + ";USER=" + conf.USER + ";PASSWD=" + conf.PASSWD + ";LANG=" + conf.LANG;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ExecuteSapCmd(strConn, SapRfcName, ObjParam, ref strMsg);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public DataSet ExecuteSapCmd(string strConn, string SapRfcName, SapParameter ObjParam, ref string strMsg)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet dsOut = new DataSet();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strMsg = "ok";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPConnection con = new SAPConnection(strConn);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; con.Open();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPCommand cmd = new SAPCommand(con);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string strCmd = "EXEC " + SapRfcName + " ";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (SapParameter obj in ObjParam.GetParam())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (string.IsNullOrEmpty(obj.ParamName) == true)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strCmd += "'" + obj.ParamValue + "',";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strCmd += "@" + obj.ParamName + "='" + obj.ParamValue + "',";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (strCmd.EndsWith(",") == true)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strCmd = strCmd.Substring(0, strCmd.Length - 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = strCmd;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPDataReader drOut = cmd.ExecuteReader();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dsOut = MapSapData(drOut);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drOut.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strMsg = e.Message;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return dsOut;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; class Program<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string strMsg = "";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SapConfig cof = new SapConfig();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.ASHOST = "192.168.0.1";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.CLIENT = "20";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.LANG = "ZF";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.USER = "sap";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.PASSWD = "sap";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cof.SYSNR = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SapParameter param = new SapParameter();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.AddParam("PartNo", "PN6022"); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.AddParam("Factory", "WBA");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CallSAP call = new CallSAP();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet dsBom = call.ExecuteSapCmd(cof, "rfc_Bom", param, ref strMsg);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteData(dsBom, strMsg);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.ClearParam();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param.AddParam("", "01436886");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet dsSd = call.ExecuteSapCmd(cof, "rfc_Delivery", param, ref strMsg);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteData(dsSd, strMsg);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Running finished.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadKey(true);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void WriteData(DataSet ds, string strMsg)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,64:C}|", "-".PadLeft(64, '-'));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,64:C}|",(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ")+strMsg).PadRight(64,' '));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,64:C}|", "-".PadLeft(64, '-'));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (DataTable dt in ds.Tables)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,12:C}|{1,12:C}|{2,12:C}|{3,12:C}|{4,12:C}|", dt.Columns[0].Caption, dt.Columns[1].Caption,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dt.Columns[2].Caption, dt.Columns[3].Caption,dt.Columns[4].Caption);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,64:C}|", "-".PadLeft(64, '-'));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (DataRow dr in dt.Rows)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(String.Format("|{0,12:C}|{1,12:C}|{2,12:C}|{3,12:C}|{4,12:C}|", dr[0], dr[1], dr[2], dr[3], dr[4]));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("|{0,64:C}|","-".PadLeft(64,'-'));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}<br><br><br><a href="http://download.microsoft.com/download/4/4/D/44DBDE61-B385-4FC2-A67D-48053B8F9FAD/DataProviderSAP.exe">DataProviderForSAP<br></a></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/62821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2009-11-25 19:12 <a href="http://www.cnitblog.com/MartinYao/articles/62821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Read Tables from SAP R/3 using SAP.NET Connector</title><link>http://www.cnitblog.com/MartinYao/articles/62803.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Tue, 24 Nov 2009 14:25:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/62803.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/62803.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/62803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/62803.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/62803.html</trackback:ping><description><![CDATA[<ul class=download>
    <li><a href="http://69.10.233.10/KB/database/SapDBReader/DBReader_src.zip"><u><font color=#000080>Download source - 85.5 Kb</font></u></a>
    <li><a href="http://69.10.233.10/KB/database/SapDBReader/DBReader_demo.zip"><u><font color=#000080>Download demo project - 102 Kb </font></u></a></li>
</ul>
<h2>Introduction</h2>
<p>Using SAP's .NET Connector is very easy, all it takes to manage it is a little work and effort. This article provides you an introductory example on how to use the Connector within C#.
<p>
<p>The example will teach you:
<ol>
    <li>How to use <code>SAP.Connector.SAPLogonDestination</code> to let you select any destination provided by your <em>saplogon.ini </em>file.
    <li>How to make an RFC call to the SAP R/3 System. Especially the example shows how to call the <code>RFC_READ_TABLE</code> function module to read from any table within your SAP system.
    <li>How to extract the field values of the data rows returned by the RFC call. </li>
</ol>
<p>
<p>Any GUI stuff is omitted to keep the example as simple as possible and to focus on the Connector's use. </p>
<h2>Background</h2>
<p>You should have some experiences with ABAP/4 and function modules and the SAP.NET Connector installed. Any project that uses the Connector must have a reference to <code>SAP.Connector.dll</code>. The Connector is available at <a href="http://service.sap.com/connectors"><u><font color=#800080>http://service.sap.com/connectors</font></u></a> and an overview is given at <a href="http://www.microsoft-sap.com/net_connector.aspx"><u><font color=#000080>http://www.microsoft-sap.com/net_connector.aspx</font></u></a>.</p>
<h2>Using the code</h2>
<p>If you want to use <code>DBReader</code> in your application, download and unzip the source file. Add a reference to the library assembly <em>DBReader.dll</em> that comes with the sources. <em>DBReader.dll</em> provides the following classes:
<ol>
    <li><code>DBReader.TableReader</code>, wrapper for the <code>RFC_READ_TABLE</code> call to SAP.
    <li><code>DBReader.ResultSet</code>, to manage the returned dataset.
    <li><code>DBReader.ResultColumn</code>, to hold a column of the returned dataset.
    <li><code>DBReader.Proxy</code>, wrapper for the proxy generated by the Connector wizard.
    <li><code>DBReader.Logon</code>, wrapper for <code>SAP.Connector.SAPLogonDestination</code>.
    <li><code>DBReader.ConnectionInfo</code>, to hold logon information. </li>
</ol>
<p>
<p>If you want to see how it works, download and unzip the demo file to disk. Either run <em>DBReaderDemo.exe</em> in the bin subfolder of the demo project from console directly, or open <em>DBReaderDemo.sln</em> into Visual Studio and run the demo. </p>
<p>The <code>TableReaderDemo</code> class shows how to use the <code>DBReader</code> for a query to SAP. Consider the following SQL statement in ABAP: </p>
<div style="WIDTH: 100%" id=premain0 class=SmallText><img style="CURSOR: pointer" id=preimg0 src="http://69.10.233.10/images/minus.gif" width=9 height=9 preid="0"><span style="MARGIN-BOTTOM: 0px; CURSOR: pointer" id=precollapse0 preid="0"> Collapse</span><img style="MARGIN-LEFT: 35px" src="http://69.10.233.10/images/copy_16.png" width=16 height=16><a href="http://69.10.233.10/KB/database/SapDBReader.aspx#" preid="0"><u><font color=#000080> Copy Code</font></u></a></div>
<pre style="MARGIN-TOP: 0px" id=pre0 lang=sql>    <span class=code-keyword>SELECT</span> TABNAME, TABCLASS
<span class=code-keyword>FROM</span> DD02L
<span class=code-keyword>WHERE</span> TABNAME <span class=code-keyword>LIKE</span> <span class=code-string>'</span><span class=code-string>NP%'</span>
<span class=code-keyword>AND</span> ( TABCLASS EQ <span class=code-string>'</span><span class=code-string>TRANSP'</span> <span class=code-keyword>OR</span>
TABCLASS EQ <span class=code-string>'</span><span class=code-string>CLUSTER'</span> <span class=code-keyword>OR</span>
TABCLASS EQ <span class=code-string>'</span><span class=code-string>POOL'</span> <span class=code-keyword>OR</span>
TABCLASS EQ <span class=code-string>'</span><span class=code-string>VIEW'</span> )</pre>
<p>The equivalent code to achieve this with <code>DBReader</code> from outside SAP shows a demo function of class <code>TableReaderDemo</code>: </p>
<div style="WIDTH: 100%" id=premain1 class=SmallText><img style="CURSOR: pointer" id=preimg1 src="http://69.10.233.10/images/minus.gif" width=9 height=9 preid="1"><span style="MARGIN-BOTTOM: 0px; CURSOR: pointer" id=precollapse1 preid="1"> Collapse</span><img style="MARGIN-LEFT: 35px" src="http://69.10.233.10/images/copy_16.png" width=16 height=16><a href="http://69.10.233.10/KB/database/SapDBReader.aspx#" preid="1"><u><font color=#000080> Copy Code</font></u></a></div>
<pre style="MARGIN-TOP: 0px" id=pre1 lang=cs>    <span class=code-keyword>public</span> <span class=code-keyword>void</span> demoTableReader(){
<span class=code-comment>//</span><span class=code-comment> Show the available destinations and let the user select one.
</span>      <span class=code-keyword>string</span> destName = <span class=code-keyword>this</span>.askForDestination();
<span class=code-keyword>if</span>(destName == <span class=code-keyword>null</span>)
<span class=code-keyword>return</span>;
<span class=code-comment>//</span><span class=code-comment> Get the selected destination object.
</span>      SAP.Connector.Destination dest = <span class=code-keyword>this</span>.saplogon.getDestinationByName(
destName);
Console.WriteLine(<span class=code-string>"</span><span class=code-string>Connecting to '"</span> + destName + <span class=code-string>"</span><span class=code-string>'"</span>);
<span class=code-comment>//</span><span class=code-comment> Information like system number, SAPServer etc. are already
</span>      <span class=code-comment>//</span><span class=code-comment> obtained by the .Net Connector from the c:\windows\saplogon.ini file.
</span>      <span class=code-comment>//</span><span class=code-comment> It remains to add these information:
</span>      dest.Client   = <span class=code-digit>1</span>;
Console.Write(<span class=code-string>"</span><span class=code-string>User:     "</span>);
dest.Username = Console.ReadLine();
Console.Write(<span class=code-string>"</span><span class=code-string>Password: "</span>);
dest.Password = Console.ReadLine();
dest.Language = <span class=code-string>"</span><span class=code-string>EN"</span>;
<span class=code-comment>//</span><span class=code-comment> Setup the TableReader
</span>      SAPReader.TableReader tabReader = <span class=code-keyword>new</span> TableReader(dest);
<span class=code-comment>//</span><span class=code-comment> Specify the table to read.
</span>      <span class=code-comment>//</span><span class=code-comment> The table DD02L contains metadata of all the available
</span>      <span class=code-comment>//</span><span class=code-comment> tables on a SAP system.
</span>      tabReader.QueryTable = <span class=code-string>"</span><span class=code-string>DD02L"</span>;
<span class=code-comment>//</span><span class=code-comment> How many rows of the table should be skipped.
</span>      tabReader.RowSkip = <span class=code-digit>10</span>;
<span class=code-comment>//</span><span class=code-comment> How many rows should be selected (at most, if available).
</span>      tabReader.RowCount = <span class=code-digit>6</span>;
<span class=code-comment>//</span><span class=code-comment> Yes, we want to see data.
</span>      <span class=code-comment>//</span><span class=code-comment> Default is NoData=true, i.e., only table information is retrieved.
</span>      tabReader.NoData = <span class=code-keyword>false</span>;
<span class=code-comment>//</span><span class=code-comment> Select FOI (fields of interest)
</span>      SAPReader.SAPKernel.RFC_DB_FLD tabNameField  =
tabReader.addQueryField(<span class=code-string>"</span><span class=code-string>TABNAME"</span>);
SAPReader.SAPKernel.RFC_DB_FLD tabClassField =
tabReader.addQueryField(<span class=code-string>"</span><span class=code-string>TABCLASS"</span>);
<span class=code-comment>//</span><span class=code-comment>
</span>      <span class=code-comment>//</span><span class=code-comment> Add the WHERE clause
</span>      <span class=code-keyword>string</span> pattern = <span class=code-string>"</span><span class=code-string>NP%"</span>;
<span class=code-comment>//</span><span class=code-comment> Select the names of all the transparent, cluster, pool
</span>      <span class=code-comment>//</span><span class=code-comment> and view tables containing the pattern:
</span>      tabReader.addWhereClause(<span class=code-string>"</span><span class=code-string>TABNAME LIKE '"</span> + pattern + <span class=code-string>"</span><span class=code-string>'"</span>);
tabReader.addWhereClause(<span class=code-string>"</span><span class=code-string>AND ( TABCLASS EQ 'TRANSP' OR"</span>);
tabReader.addWhereClause(<span class=code-string>"</span><span class=code-string>      TABCLASS EQ 'CLUSTER' OR"</span>);
tabReader.addWhereClause(<span class=code-string>"</span><span class=code-string>      TABCLASS EQ 'POOL' OR"</span>);
tabReader.addWhereClause(<span class=code-string>"</span><span class=code-string>      TABCLASS EQ 'VIEW' )"</span>);
<span class=code-comment>//</span><span class=code-comment> Force to read the table from SAP
</span>      <span class=code-keyword>string</span> abapException = tabReader.read();
<span class=code-keyword>if</span>(abapException == <span class=code-keyword>null</span>){
<span class=code-comment>//</span><span class=code-comment> Output the result:
</span>        SAPReader.ResultSet RS = tabReader.getResultSet();
Console.WriteLine(<span class=code-string>"</span><span class=code-string>\n\nTableData read:"</span>);
Console.WriteLine(tabNameField.Fieldname + <span class=code-string>"</span><span class=code-string>\t\t"</span> +
tabClassField.Fieldname);
Console.WriteLine(
<span class=code-string>"</span><span class=code-string>-----------------------------------------------------"</span>);
<span class=code-keyword>for</span>(<span class=code-keyword>int</span> i = <span class=code-digit>0</span>; i &lt; RS.LineCount; i++){
Console.Write(RS.getEntryAt(tabNameField.Fieldname, i).Trim());
Console.Write(<span class=code-string>"</span><span class=code-string>\t\t"</span> +
RS.getEntryAt(tabClassField.Fieldname, i).Trim());
Console.WriteLine();
}
}
<span class=code-keyword>else</span>{
Console.WriteLine(<span class=code-string>"</span><span class=code-string>ABAP-Exception: "</span> + abapException );
}
<span class=code-comment>//</span><span class=code-comment> That's it!
</span>    }
</pre>
<p>After the table was read successfully, the <code>ResultSet</code> is traversed row-wise (although the data is stored column-wise there) and printed to the screen. </p>
<h2>Points of Interest</h2>
<p>The fragmented screenshot below shows the console output for this example. </p>
<p><img border=0 src="http://69.10.233.10/KB/database/SapDBReader/DBReader.gif" width=433 height=318> </p>
<p>The <code>SAPReader.Logon saplogon</code> is an attribute of class <code>TableReaderDemo</code> and is derived from <code>SAP.Connector.SAPLogonDestination</code>. If the user selects a destination name, the saplogon selects the corresponding destination parameters: </p>
<div style="WIDTH: 100%" id=premain2 class=SmallText><img style="CURSOR: pointer" id=preimg2 src="http://69.10.233.10/images/minus.gif" width=9 height=9 preid="2"><span style="MARGIN-BOTTOM: 0px; CURSOR: pointer" id=precollapse2 preid="2"> Collapse</span><img style="MARGIN-LEFT: 35px" src="http://69.10.233.10/images/copy_16.png" width=16 height=16><a href="http://69.10.233.10/KB/database/SapDBReader.aspx#" preid="2"><u><font color=#000080> Copy Code</font></u></a></div>
<pre style="MARGIN-TOP: 0px" id=pre2 lang=cs>    <span class=code-keyword>public</span> SAP.Connector.Destination getDestinationByName(<span class=code-keyword>string</span> name){
<span class=code-comment>//</span><span class=code-comment> Map the name used for displaying the available destination,
</span>      <span class=code-comment>//</span><span class=code-comment> e.g. at SAPLogon, to the internal name used to address this item.
</span>      <span class=code-comment>//</span><span class=code-comment> BTW, the internal name (key) is derived from saplogon.ini.
</span>      <span class=code-keyword>string</span> destName = <span class=code-keyword>this</span>.GetDestinationNameFromPrintName(name);
<span class=code-comment>//</span><span class=code-comment> null returned if the destination does not exist.
</span>      <span class=code-keyword>if</span>(destName == <span class=code-keyword>null</span> || destName == <span class=code-string>"</span><span class=code-string>"</span> ){
Console.WriteLine(<span class=code-keyword>this</span>.GetType().ToString()
+ <span class=code-string>"</span><span class=code-string>.getDestinationByName: Destination "</span> + name +
<span class=code-string>"</span><span class=code-string> does not exist."</span>
);
Console.WriteLine(<span class=code-string>"</span><span class=code-string>Available Destinations are: "</span>);
<span class=code-keyword>this</span>.printAvailableDestinations(Console.Out);
Environment.Exit(<span class=code-digit>0</span>);
}
<span class=code-comment>//</span><span class=code-comment> This is the key statement for selecting the
</span>      <span class=code-comment>//</span><span class=code-comment> desired destination item:
</span>      <span class=code-keyword>this</span>.DestinationName = destName;
<span class=code-comment>//</span><span class=code-comment> Now all information is retrieved from the SAPLogon's ini file
</span>      <span class=code-comment>//</span><span class=code-comment> to the respective variables of 'this' destination object.
</span>      <span class=code-comment>//</span><span class=code-comment> (The ini file is stored in the private variable:
</span>      <span class=code-comment>//</span><span class=code-comment> SAP.Connector.SAPLogonDestination.saplogon.fileName)
</span>
<span class=code-keyword>return</span> (SAP.Connector.Destination)<span class=code-keyword>this</span>;
}
</pre>
<p>The RFC call is performed by <code>TableReader</code> this way: </p>
<div style="WIDTH: 100%" id=premain3 class=SmallText><img style="CURSOR: pointer" id=preimg3 src="http://69.10.233.10/images/minus.gif" width=9 height=9 preid="3"><span style="MARGIN-BOTTOM: 0px; CURSOR: pointer" id=precollapse3 preid="3"> Collapse</span><img style="MARGIN-LEFT: 35px" src="http://69.10.233.10/images/copy_16.png" width=16 height=16><a href="http://69.10.233.10/KB/database/SapDBReader.aspx#" preid="3"><u><font color=#000080> Copy Code</font></u></a></div>
<pre style="MARGIN-TOP: 0px" id=pre3 lang=cs>    <span class=code-keyword>public</span> <span class=code-keyword>string</span> read(){
<span class=code-keyword>if</span>(<span class=code-keyword>this</span>.proxy.connected() == <span class=code-keyword>false</span>){
<span class=code-keyword>this</span>.proxy.connectSAP();
}
<span class=code-keyword>try</span> {
<span class=code-comment>//</span><span class=code-comment> Force the proxy to make the rfc call synchronously
</span>        <span class=code-comment>//</span><span class=code-comment> See documentation for RFC_READ_TABLE Function Module at
</span>        <span class=code-comment>//</span><span class=code-comment> your SAP system for further details (Transaction SE37).
</span>        <span class=code-keyword>this</span>.proxy.SAPProxy.Rfc_Read_Table(<span class=code-keyword>this</span>.delim, <span class=code-keyword>this</span>.noData,
<span class=code-keyword>this</span>.qTable, <span class=code-keyword>this</span>.rowCount, <span class=code-keyword>this</span>.rowSkip,
<span class=code-keyword>ref</span> <span class=code-keyword>this</span>.data, <span class=code-keyword>ref</span> <span class=code-keyword>this</span>.fields, <span class=code-keyword>ref</span> <span class=code-keyword>this</span>.options);
<span class=code-comment>//</span><span class=code-comment> Check if data found
</span>        <span class=code-keyword>if</span>( <span class=code-keyword>this</span>.NoData == <span class=code-keyword>false</span> &amp;&amp; <span class=code-keyword>this</span>.data.Count == <span class=code-digit>0</span> ){
<span class=code-keyword>return</span> <span class=code-string>"</span><span class=code-string>No data found"</span>;
}
<span class=code-comment>//</span><span class=code-comment> NoData set
</span>        <span class=code-keyword>if</span>(<span class=code-keyword>this</span>.NoData == <span class=code-keyword>true</span>){
<span class=code-keyword>for</span>( <span class=code-keyword>int</span> i = <span class=code-digit>0</span>; i &lt; <span class=code-keyword>this</span>.fields.Count; i++){
<span class=code-keyword>this</span>.results.addEntry(<span class=code-keyword>this</span>.fields[i], <span class=code-string>"</span><span class=code-string>NoData"</span>);
}
}
<span class=code-comment>//</span><span class=code-comment> NoData not set
</span>        <span class=code-comment>//</span><span class=code-comment> Save data to the column-wise ResultSet.
</span>        <span class=code-keyword>else</span> <span class=code-keyword>if</span>(<span class=code-keyword>this</span>.data.Count &gt; <span class=code-digit>0</span> ){
<span class=code-comment>//</span><span class=code-comment>Loop over data rows
</span>          <span class=code-keyword>for</span>( <span class=code-keyword>int</span> i = <span class=code-digit>0</span>; i &lt; <span class=code-keyword>this</span>.data.Count; i++){
<span class=code-comment>//</span><span class=code-comment>Loop over fields
</span>            <span class=code-keyword>for</span>(<span class=code-keyword>int</span> j = <span class=code-digit>0</span>; j &lt; <span class=code-keyword>this</span>.fields.Count; j++){
<span class=code-keyword>string</span> val = <span class=code-keyword>this</span>.parseTableRow(<span class=code-keyword>this</span>.fields[j], <span class=code-keyword>this</span>.data[i]);
<span class=code-keyword>this</span>.results.addEntry(<span class=code-keyword>this</span>.fields[j], val);
}
}
}<span class=code-comment>//</span><span class=code-comment>else
</span>      }
<span class=code-keyword>catch</span> (SAP.Connector.RfcSystemException ex) {
System.Text.StringBuilder msg = <span class=code-keyword>new</span> System.Text.StringBuilder();
msg.Append(<span class=code-string>"</span><span class=code-string>Table: "</span> + <span class=code-keyword>this</span>.qTable);
<span class=code-keyword>foreach</span>(SAPKernel.RFC_DB_FLD field <span class=code-keyword>in</span> <span class=code-keyword>this</span>.fields){
msg.Append(<span class=code-string>"</span><span class=code-string>\nFields: "</span> + field.Fieldname);
}
<span class=code-keyword>foreach</span>(SAPKernel.RFC_DB_OPT opt <span class=code-keyword>in</span> <span class=code-keyword>this</span>.options){
msg.Append(<span class=code-string>"</span><span class=code-string>\nOptions: "</span> + opt.Text);
}
Console.WriteLine(msg + <span class=code-string>"</span><span class=code-string>\n"</span>
+ <span class=code-string>"</span><span class=code-string>Error calling SAP RFC \n"</span> + ex.ToString() + <span class=code-string>"</span><span class=code-string>\n"</span> + ex.ErrorCode,
<span class=code-string>"</span><span class=code-string>Problem with SAP"</span>
);
<span class=code-keyword>return</span> ex.ErrorCode;
}
<span class=code-keyword>catch</span>(SAP.Connector.RfcAbapException ex){
<span class=code-keyword>return</span> ex.ErrorCode;
}
<span class=code-keyword>return</span> <span class=code-keyword>null</span>;
}
</pre>
<p>Data returned by the RFC call is stored row-wise. A value of a field in a certain row can be extracted by using the offset and length stored in each field structure returned: </p>
<div style="WIDTH: 100%" id=premain4 class=SmallText><img style="CURSOR: pointer" id=preimg4 src="http://69.10.233.10/images/minus.gif" width=9 height=9 preid="4"><span style="MARGIN-BOTTOM: 0px; CURSOR: pointer" id=precollapse4 preid="4"> Collapse</span><img style="MARGIN-LEFT: 35px" src="http://69.10.233.10/images/copy_16.png" width=16 height=16><a href="http://69.10.233.10/KB/database/SapDBReader.aspx#" preid="4"><u><font color=#000080> Copy Code</font></u></a></div>
<pre style="MARGIN-TOP: 0px" id=pre4 lang=cs>    <span class=code-keyword>public</span> <span class=code-keyword>string</span> parseTableRow(SAPReader.SAPKernel.RFC_DB_FLD field,
SAPReader.SAPKernel.TAB512 dataRow ){
<span class=code-comment>//</span><span class=code-comment> Length of the field
</span>      <span class=code-keyword>int</span> len = <span class=code-keyword>int</span>.Parse(field.Length);
<span class=code-comment>//</span><span class=code-comment> Position where the field's value starts in the data row
</span>      <span class=code-keyword>int</span> offset = <span class=code-keyword>int</span>.Parse(field.Offset);
<span class=code-comment>//</span><span class=code-comment> The data row, containing all the field values concatenated
</span>      <span class=code-comment>//</span><span class=code-comment> by SAP's rfc_read_table
</span>      <span class=code-keyword>string</span> row = dataRow.Wa;
<span class=code-keyword>string</span> retValue = <span class=code-string>"</span><span class=code-string>"</span>;
<span class=code-keyword>try</span>{
<span class=code-keyword>if</span>(offset &lt; row.Length){
<span class=code-comment>//</span><span class=code-comment> Read the field's value starting at the position specified
</span>          <span class=code-comment>//</span><span class=code-comment> by offset.
</span>          <span class=code-keyword>if</span>(offset + len &gt; row.Length)
<span class=code-comment>//</span><span class=code-comment> Read until the end of the row string
</span>            retValue = dataRow.Wa.Substring(offset);
<span class=code-keyword>else</span>
<span class=code-comment>//</span><span class=code-comment> Read only len characters, otherwise.
</span>            retValue = dataRow.Wa.Substring(offset,len);
}
}<span class=code-keyword>catch</span>(System.ArgumentOutOfRangeException e){
Console.WriteLine(e.ToString());
Environment.Exit(<span class=code-digit>0</span>);
}
<span class=code-keyword>return</span> retValue;
}
</pre>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/62803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2009-11-24 22:25 <a href="http://www.cnitblog.com/MartinYao/articles/62803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#调用SAP RFC</title><link>http://www.cnitblog.com/MartinYao/articles/62693.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Thu, 19 Nov 2009 14:08:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/62693.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/62693.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/62693.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/62693.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/62693.html</trackback:ping><description><![CDATA[<p>添加SAP安装程序的四个dll文件引用：</p>
<p>Interop.SAPBAPIControlLib.dll<br>Interop.SAPFunctionsOCX.dll<br>Interop.SAPLogonCtrl.dll<br>Interop.SAPTableFactoryCtrl.dll</p>
<p>调用方法体：</p>
<p>private void GetMateriel()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string number = this.txtNumber.Text.Trim();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string desc = this.txtDesc.Text.Trim();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Config config = new Config();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPLogonCtrl.SAPLogonControlClass login = new SAPLogonCtrl.SAPLogonControlClass();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.ApplicationServer = config.Server;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.Client = config.Client;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.Language = config.Language;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.User = config.User;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.Password = config.Password;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; login.SystemNumber = config.Number;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPLogonCtrl.Connection conn = (SAPLogonCtrl.Connection)login.NewConnection();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet ds = new DataSet();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTable table = new DataTable();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Columns.Add("Number", typeof(string));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Columns.Add("Desc1", typeof(string));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Columns.Add("Desc2", typeof(string));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Columns.Add("Desc3", typeof(string));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Columns.Add("Uint", typeof(string));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (conn.Logon(0, true))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPFunctionsOCX.SAPFunctionsClass func = new SAPFunctionsOCX.SAPFunctionsClass();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; func.Connection = conn;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPFunctionsOCX.IFunction ifunc = (SAPFunctionsOCX.IFunction)func.Add("Z_MATERIAL_APPLICATION"); //（Z_MATERIAL_APPLICATION） SAP RFC 名称</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPFunctionsOCX.IParameter gclient = (SAPFunctionsOCX.IParameter)ifunc.get_Exports("I_WERKS"); //（I_WERKS）输入参数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gclient.Value = Factory; //（Factory）对参数赋值</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPFunctionsOCX.IParameter matnr = (SAPFunctionsOCX.IParameter)ifunc.get_Exports("I_MATNR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; matnr.Value = number;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPFunctionsOCX.IParameter maktx = (SAPFunctionsOCX.IParameter)ifunc.get_Exports("I_MAKTX");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maktx.Value = desc;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ifunc.Call();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPTableFactoryCtrl.Tables tables = (SAPTableFactoryCtrl.Tables)ifunc.Tables;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAPTableFactoryCtrl.Table ENQ = (SAPTableFactoryCtrl.Table)tables.get_Item("PO_TAB"); （PO_TAB）输出表名</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 1; i &lt;= ENQ.RowCount; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataRow dr = table.NewRow();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[0] = ENQ.get_Cell(i, "MATNR");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[1] = ENQ.get_Cell(i, "MAKTX");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[2] = ENQ.get_Cell(i, "MAKTX2");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[3] = ENQ.get_Cell(i, "MAKTX3");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dr[4] = ENQ.get_Cell(i, "MEINS");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table.Rows.Add(dr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ds.Tables.Add(table);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.Logoff();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Repeater1.DataSource = ds.Tables[0];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.DataBind();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.lblCount.Text = "共找到" + ds.Tables[0].Rows.Count.ToString() + "條記錄";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScriptManager.RegisterStartupScript(btnSAP, this.GetType(), "", "$(document).ready( function (){ jQuery.page('page',10);} )", true);<br>&nbsp;&nbsp;&nbsp; }</p>
<p><br>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/robaot/archive/2009/10/20/4704127.aspx">http://blog.csdn.net/robaot/archive/2009/10/20/4704127.aspx</a></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/62693.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2009-11-19 22:08 <a href="http://www.cnitblog.com/MartinYao/articles/62693.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SAP RFC Builder</title><link>http://www.cnitblog.com/MartinYao/articles/50170.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Tue, 14 Oct 2008 03:06:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/50170.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/50170.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/50170.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/50170.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/50170.html</trackback:ping><description><![CDATA[<p>終於發現一個可以直接生成RFC的程序了，不用再裝VS2003就可以使用。<br>下載地址：<br><a href="http://www.cnitblog.com/Files/MartinYao/RFCProxyBuilder.zip">RFC Builder</a></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/50170.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2008-10-14 11:06 <a href="http://www.cnitblog.com/MartinYao/articles/50170.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>