方式1:使用客戶端自帶的組件
安裝客戶端以后,添加引用:SAPFunctionsOCX(.net 的Com列表里一般找不到,需要引用DLL【一般位於以下路徑:Program Files\SAP\FrontEnd\SAPgui\wdtfuncs.ocx】),SAPLogonCtrl,SAPTableFactoryCtrl。
public DataTable GetRFCData()
{
Connection conn = null;
SAPFunctionsClass func = null;
IFunction ifunc = null;
conn = this.getSAPConnection(); //返回SAP登錄類
func = this.getSAPFunctionsClass(conn); //返回SAP操作類
ifunc = this.getIFunction("ZHRIF01_FM01", func); //返回SAP接口
//設定SAP RFC函數的參數
IParameter IP_DATA_BEGIN = (IParameter)ifunc.get_Exports("I_DATUM"); //
IP_DATA_BEGIN.Value = "201602"; // "20100101";//;strDatB; //"20090101";
//CALL RFC函數
ifunc.Call();
//輸出參數
Tables Table_Outs = (Tables)ifunc.Tables;
Table Table_mkpf = (Table)Table_Outs.get_Item("T_RESULT"); //獲取返回結果集
DataTable dt = GetDataTable(Table_mkpf);
//this.label1.Text = dt.Rows.Count.ToString();
return dt;
}
public Connection getSAPConnection()
{
//SAP登錄類
SAPLogonControlClass logon = new SAPLogonControlClass();
Connection Conn;
logon.ApplicationServer = "10.1.8.11";
logon.Client = "300";
logon.Language = "ZH"; //EN OR ZH ....
//logon.Language = "zh"; //EN OR ZH ....
logon.User = "test";
logon.Password = "test1234";
logon.SystemNumber = Convert.ToInt16("00");
Conn = (SAPLogonCtrl.Connection)logon.NewConnection();
//Conn.CodePage = "8300";
//登錄SAP
if (!Conn.Logon(0, true)) //Login Successful
{
throw new Exception("登錄SAP系統失敗,請重新登錄!");
}
//返回SAP登錄類
return Conn;
}
public SAPFunctionsClass getSAPFunctionsClass(Connection conn)
{
//SAPFunction Object
SAPFunctionsClass func = new SAPFunctionsClass();
//Set Connection
func.Connection = conn;
return func;
}
/// <summary>
/// 返回接口
/// </summary>
/// <param name="IFunctionName"></param>
/// <returns></returns>
private IFunction getIFunction(string IFunctionName, SAPFunctionsClass func)
{
IFunction ifunc = (SAPFunctionsOCX.IFunction)func.Add(IFunctionName);
return ifunc;
}
/// <summary>
/// 將從sap獲取的table轉換為datatable
/// </summary>
/// <param name="saptb"></param>
/// <returns></returns>
///
private DataTable GetDataTable(Table saptb)
{
DataTable dt = new DataTable();
try
{
for (int i = 1; i < saptb.ColumnCount; i++)
{
//dt.Columns.Add(saptb.get_ColumnName(i), typeof(string));
dt.Columns.Add(saptb.get_ColumnName(i));
}
for (int m = 1; m <= saptb.RowCount; m++)
{
DataRow dr = dt.NewRow();
for (int n= 1; n < saptb.ColumnCount; n++)
{
string columnName=saptb.get_ColumnName(n);
dr[saptb.get_ColumnName(n)] = saptb.get_Cell(m, columnName).ToString();
}
dt.Rows.Add(dr);
}
}
catch (Exception ex)
{
throw ex;
}
return dt;
}
注意:如果出現中文數據全部為#(井)的情況,這說明是CodePage的問題,暫時沒找到解決辦法。嘗試設定SAPConnection的CodePage,結果提示內存不能寫入。
方法2:在機器上沒有安裝客戶端的情況下,使用官網提供的Nco3.0.16.0(SAP Connector for Microsoft .Net)。本DLL含有四個版本。
32位和64位,以及基於.Net2.0 或者 4.0編譯的組件(本處代碼基於:32位 4.0 的組件,開發環境VS2010),安裝完畢后需要引用如下DLL文件:sapnco.dll,sapnco_utils.dll(位於安裝目錄下)
代碼如下:
配置文件:
<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="DEV" USER="test" PASSWD="1234" CLIENT="300" LANG="EN" ASHOST="10.1.8.11" SYSNR="00" MAX_POOL_SIZE="10" IDLE_TIMEOUT="10"/>
</destinations>
</DestinationConfiguration>
</ClientSettings>
</SAP.Middleware.Connector>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku = ".NETFramework,Version=v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
程序代碼:
public static DataTable GetSAPTestData()
{
RfcDestination destination = RfcDestinationManager.GetDestination("DEV");
RfcFunctionMetadata BAPI_COMPANYCODE_GETDETAIL_MD = destination.Repository.GetFunctionMetadata("ZHRIF01_FM01");
IRfcFunction function = null;
function = BAPI_COMPANYCODE_GETDETAIL_MD.CreateFunction();
function.SetValue("I_DATUM", "20160203"); //設置參數
//function.SetParameterActive("COMPANYCODE_ADDRESS", false);設置參數
function.Invoke(destination);//提交調用
IRfcTable returnTable = function.GetTable("T_RESULT");
return GetDataTable(returnTable);
}
/// <summary>
/// 將從sap獲取的table轉換為datatable
/// </summary>
/// <param name="saptb"></param>
/// <returns></returns>
///
public static DataTable GetDataTable(IRfcTable IrfTable)
{
DataTable dt = new DataTable();
//遍歷元素個數,循環添加列
for(int i=0;i<IrfTable.ElementCount;i++)
{
string columnName=IrfTable.GetElementMetadata(i).Name;
dt.Columns.Add(columnName);
}
////循環把IRfcTable里面的數據放入Table里面,因為類型不同,不可直接使用。
for (int m= 0; m < IrfTable.RowCount; m++)
{
IrfTable.CurrentIndex = m;
DataRow dr = dt.NewRow();
for(int n =0;n<IrfTable.CurrentRow.Metadata.FieldCount;n++)
{
string colName = IrfTable.GetElementMetadata(n).Name;
dr[colName]=IrfTable.CurrentRow.GetString(colName);
}
dt.Rows.Add(dr);
}
return dt;
}
不使用配置文件直接代碼寫入參數的方式:
public static DataTable GetSapData()
{
RfcConfigParameters rfcPar = new RfcConfigParameters();
rfcPar.Add(RfcConfigParameters.Name, "CON");
rfcPar.Add(RfcConfigParameters.AppServerHost, "10.1.8.11");
rfcPar.Add(RfcConfigParameters.Client, "300");
rfcPar.Add(RfcConfigParameters.User, "test");
rfcPar.Add(RfcConfigParameters.Password, "1234");
rfcPar.Add(RfcConfigParameters.SystemNumber, "00");
rfcPar.Add(RfcConfigParameters.Language, "EN");
rfcPar.Add(RfcConfigParameters.Codepage, "8400");
RfcDestination dest = RfcDestinationManager.GetDestination(rfcPar);
RfcRepository rfcrep = dest.Repository;
IRfcFunction myfun = null;
myfun = rfcrep.CreateFunction("ZHRIF01_FM01");
myfun.SetValue("I_DATUM", "20160203");//SAP里面的傳入參數
try
{
myfun.Invoke(dest);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
IRfcTable IrfTable = myfun.GetTable("T_RESULT");
return GetDataTable(IrfTable);
}
