原本以為這輩子應該是沒什麼機會碰到這種非個人領域內的技術(SAP),孰不知資訊IT的世界果然是很小,想起以往年少輕狂,第一個工作是當個程式設計師,寫的是JSP網頁程式的部分,也有部分的JAVA開發,後來因為否些因素轉而投向比爾蓋茲的懷抱,開始寫起VB和ASP等微軟技術來,到了中菲以後,莫名奇妙又多少接觸到AS400和Oracle相關的技術,雖然沒有真正下去開發這AS400的系統,不過大致上皮毛也算是有摸到,正所謂沒吃過豬肉,也看過豬走路,到了恆逸算是個人領域技術的萬流歸宗,幾乎所有的時間就只專精在MS的技術上面。
直到前一陣子,因為答應幫忙朋友的忙,結果居然扯到的SAP,朋友要的只是很簡單的一句話,用.NET Call SAP/RFC 將資料取回在微軟相關的產品上。媽呀,這又是一個完全陌生的領域,我甚至連RFC是啥東西都不清楚(雖然後來問一下google大神就知道了),就好像一個武林高手,一腳踏入一個飄邈虛無的危險聳聳森林中,也只能憑著自身的保命技能努力的生活下來,身邊一切的環境尚待自我摸索。當然這樣說是有點誇張了點,有那種嚇死人不償命的feel,不過老實說,亞當斯以往從來沒有接觸過SAP,因此也就把這個幫忙,當作是一個自我的挑戰,嘗試看看是否可以搞點什麼東西出來。
話說,為了幫這個忙,花了我幾乎快兩個禮拜的時間,心疼阿~我的光陰~
開始進入正題吧,欲使用.NET技術與SAP溝通,有很多種方式,但是對於亞當斯來說,最簡單也是做快速的方式就是直接使用SAP的Client元件,來個直搗黃龍。因此要使用這種最簡單,也是最直接的方式來連結SAP的話,就必須有一些事先的開發環境必須要準備一下,以下亞當斯分為兩個部分來做說明,第一部分是開發環境的需求,第二部分是程式語言的撰寫。
首先先來談談開發環境的部分,我用的是Vs2010+VB
- 安裝SAP Client應用程式
- 就如同用Oracle Client 連到Oracle Server、As400 client連到As400 Server一樣,在欲開發的機器上,安裝SAP Client,並且設定一個可以連接到SAP Server的 Client Setting
- 確定這個client可以順利連結到SAP,設定好相關的IP、ID、系統號碼和登入的帳號密碼等等。
接著打開Visual Studio開發工具,新增一個專案挑選適當的語言,開始撰寫程式:
- 先在專案中加入以下四個參考組件,分別為參考COM頁簽中的SAP BAPI Control、SAP Logon Control、SAP Table Factory、SAP Remote Function Call Control。
- 加入完成參考,VS專案中會將這些COM元件轉換為相對應的 .NET Interop Assembly放在Bin資料夾中
- 在此以ASP.NET為例,新增一個網頁,開發寫程式,首先當然就是把這幾個.NET Interop Assembly相關的命名空間加入到應用程式中:
Imports SAPBAPIControlLib
Imports SAPLogonCtrl
Imports SAPTableFactoryCtrl
Imports SAPFunctionsOCX - 接著撰寫相關登入SAP的功能,建立SAPLogonCtrl.SAPLogonControlClass物件,用來設定帳號密碼等相關的登入訊息,以便連結
Dim login As New SAPLogonCtrl.SAPLogonControlClass()
login.ApplicationServer = "192.168.10.10"
login.Client = "888"
login.Language = ""
login.User = "Adams"
login.Password = "P@ssw0rd"
login.SystemNumber = Integer.Parse("00")
Dim conn As SAPLogonCtrl.Connection = CType(login.NewConnection(), SAPLogonCtrl.Connection)
If conn.Logon(0, True) Then
' 這邊撰寫連結SAP成功之後,.NET所要運作的事項
Else
lblMsg.Text = "Login Fail"
End If - 在來說說SAP/RFC的情境,在這個示範中:
假設SAP/RFC 的模組名稱叫做:BAPISDORDER_GETDETAILEDLIST
需要一個Structure,命名為:I_BAPI_VIEW
以及一個Table當作參數,這個Table命名為:SALES_DOCUMENTS
如此一來程式碼如下:
- 當叫用SAP/RFC成功之後,接著就把所得的資料結果接收回來,假設這邊叫用了SAP/RFC之後,會有3個Table會傳回給.NET,那個就可以使用.NET的相關物件(如:DataTable…)去接收以及使用了
如此一來,.NET Call SAP/RFC 的設計應該就完成了,到時候再依據不同的SAP/RFC所需要的參數,給予不同的數值即可達到動態叫用的功能,以上這幾個步驟和程式碼看起來雖然不多,但是老實說,可是把亞當斯搞得精疲力盡,原因一開始就說了,SAP是一個我從來沒有碰過的東西,又是必須在極短的時間內,也沒有其他人可以提供多餘的資源下,一步一腳印去測試出來,當然有問了一下google大神,但是得到的東西畢竟不多,例如:COM這些元件中的interface叫用的方式等等,都幾乎是一個method、一個method抓出來測試,說來真的是吐血。
不過,等到都測試完成,也搞懂一些有關整合SAP技術的時候,算是學習到一些新技術、新東西吧!當然也希望以上的經驗可以讓有需要的看倌有機會可以運用的上,這樣也算是亞當斯努力的心血中,有得到回報 ^_^y
34 則留言:
您好~
看到你的文章之後
宛如看到救星一樣
因為我目前正在做.NET呼叫SAP/RFC的功能
可是一直卡住很久
卻一直解不出來
我也試過您的Source Code修改一下測試
但一直到ifunc.Call()這一段就失敗了
雖然他沒有出現錯誤訊息
但我用if ifunc.Call() Then的語法去測試
發現他回傳都是False
表示呼叫RFC的時候是失敗的
但前面的Connection是正常的
就是這一段我一直卡住
不知道這位大哥是否有建議指導一下小弟
感激不盡~
我補充一下我使用ifunc.Call()的回傳訊息
No connection to SAP system available.
如果是回傳false這樣的話,看起來是沒有連線成功唷,最基本的至少你叫用ifun.call的時候,要可以有回傳true才行,阿對了 建議你在叫用的時候 使用多執行緒 來設計
謝謝Adams的提醒
我後來step dubug之後才發現
在func.Connection = conn
就有發生Error了
訊息是Bad variant type
可是我前面的Logon是成功的
只有這一段是失敗的
不知道前輩之前是否又遇到同樣的問題
在麻煩給予小弟指教~謝謝!
你試著把4-6這幾個步驟寫到工作執行緒就可以了
感謝Adams
終於可以測試成功了
小弟受教良多~謝謝!
不客氣,如果您也有相關.NET / SAP整合的資訊,也可以一起討論分享一下!^^
您好~
在func.Connection = conn時發生error
訊息是Bad variant type
試過把程式放在執行緒裡
但是功力太弱試不成功
後來把該行mark起來
程式就可以運行了
不過這樣在運行此程式時每次都要做登入的動作
是否有其他方法可以讓程式執行時免去登入動作
請前輩指導~~
感激不盡!!謝謝
甯,你好:
解決的方式就是把 4-6這幾個步驟的程式碼寫到另一個執行緒緒中,去執行工作執行緒就可以了
謝謝Adams!!
測試後成功了^^
Logon回傳是true,可是在func.Connection = conn
就會有Bad variant type的錯誤訊息,我是把整段放在asp.net中的page_load裏,請問我該如何修正呢? 謝謝!
請參考上列的提問,答案就在其中,把程式碼放到多執行緒即可!!
我在業界幾家公司call RFC都是採用另一種做法,SAP有出一套工具免費的,叫SAP CONNECTOR,只支援到VS2003,我都直接在VS2003上使用這套工具,它會像程式拶生器把RFC變成.NET的CLASS,將類別檔整個GEN 出來 ,再COPY到VS20XX其他版本上,直接把類別NEW起來用就可以,非常方便喔,您可以查看看sap connector
馬大大,多謝提供另一種解決的方案,我有查了一下,也找到一篇不錯的教學。
http://www.codeproject.com/KB/dotnet/Connect_SAP_from_VS2008.aspx
不過,我想唯一的缺點就是要借用VS2003來設計產生class or component,可能是因為SAP不支援後續的vs版本了。
.net connector已經不再改版了,每次都要在VS2003處理後再拿到VS2008上處理,debug上有點麻煩;SAP有出一套新的工具叫SAP Enterprise Services Explorer for Microsoft .NET可以取帶.net connector,只是必需要先在SAP上先安裝NetWeaver;但是因為公司的SAP沒有安裝NetWeaver所以才想找看看還有沒有別的方法
所以說,最直覺也是最快的方式就是使用SAP原本的API,不過這些API也都是COM的感覺,比較麻煩的是沒有函式說明,一切都自己猜。這比較令人灰心~
您好,func.connection=conn
我用vs2005也是error,如果4-6這幾個步驟寫到工作執行緒就可以了,是要如何修改程式碼 ?
您好,我依您的範例練習,卻出現以下錯誤,不知是不是版本問題?
在func.connection=conn 出現
Bad variant type,請各位協助..
您好,
請問如果輸出的中文都變成#,
要如何解決?
您好,
我現在遇到一個問題,在SAP T-code ST22 會出現,User "xxx" has no RFC authorization for function group "RFC1".
可是在.Net 2003 的SAP Connecter不會有這種權限的問題.所以Basic同事覺得我們programer應該有別的寫法.可是功力太淺試不出來,請問大人有沒有什麼建議.謝謝!
您好!
我想請問一下 sap.net的連接tool在哪下載& 參考要去哪下載><~一直找不到...
SAP Connector for Microsoft .NET已可 Compiled with .NET Framework 4.0
您好 不好意思 看到你的文章 讓我獲益良多
目前小弟有個問題 想請問一下 倘若 擷取的
SAP Table 需要給予參數值當作條件式篩選
要如何撰寫呢? 還請大大回覆了 感謝!!
有兩個方式可以針對SAP Table下條件,一個是在Call RFC時,就丟入篩選條件,本範例就是這種方式,這種方式要在RFC就設計好,另一種方式比較簡單,也就是抓取SAP Table資料出來之後我是把結果資料放到一個DataTable的,你可以想像,只要資料放在.NET的DataTable中,你是否就可以隨意去篩選資料呢? 建議用LINQ比較快唷!!
感謝~
我順便想再問一下 第一個方式是需要SAP開發人員先撰寫篩選條件的RFC涵式嗎??
第二種方式應該不會要用了 因為想減低資料傳輸的負擔..才會設立條件~
是的! 請你看一下我上面所寫的範例程式,參數就是訂單號碼(一個Table當作參數,再把訂單單號加入),也就是說,要請SAP開發人員先撰寫好可以允許篩選條件的RFC! 就可以啦
感謝 解決了 最後用這個寫法
Dim OPStart As SAPFunctionsOCX.Parameter = CType(iSAPCONN.Exports("START_DATE"), SAPFunctionsOCX.Parameter)
Dim OPEnd As SAPFunctionsOCX.Parameter = CType(iSAPCONN.Exports("END_DATE"), SAPFunctionsOCX.Parameter)
OPStart.Value = "20120101"
OPEnd.Value = "20120501"
搞定 @@
今天測試發現重大問題~發現傳接的資料 中文字串皆無法顯示~會出現####取代字元 英文字串及數字類別卻正常 請問有何方式可以解決這個問題呢?? 感謝!!
今天有找到解決中文#字不能正常顯示方式
但必須要換個寫法 不能使用OCX方式
參考資料:http://www.cnblogs.com/yqy542006/archive/2009/03/30.html
大陸簡體文
希望能給有需要的人參考看看
中文####用Unicode的dll,問題就可以解決
你提供的程式,我都沒問題但是RFC傳回筆數卻是0,可是用SE37檢查又有資料,請問要如何解決. 感謝
您好~
因為是新手,有看沒有很懂,想透過完整的內容做學習,方便向您索取sample code 嗎?
麻煩了!感謝!
已經將範例程式碼,提供在以下的說明中,請參考!
http://ms-net.blogspot.tw/2015/01/net-call-saprfc-by-visual-basic.html
請問在VB叫用COM元件時是否有遇到32位元與64位元的問題呢?
因SAP GUI目前只有32位元的
我是用Lotusscript(語法類似VB)欲叫用COM元件會無法取到
Google後是由於32位元與64位元的問題
若您有遇到請教一下如何解決呢?謝謝
張貼留言