PythonからSAP処理を呼び出してみる

2020/02/23追記 以下がアップデート版です。

yomon.hatenablog.com



今回はPythonからSAPのABAP汎用モジュールをRFC経由で呼び出してみます。
検証環境構築とかしている時にいちいちSAPGUIからログオンしてマウス操作で作業するのが面倒な作業をどうにかしたいと思ってます。
JavaやC#を使えば簡単にGUI使わないSAP接続処理書けるですが、ちょっと書き換えるにしても結構面倒なので、それだったらSAPGUIで。。。となってしまいます。
ちょっとしたコマンドやスクリプト感覚でやりたいなと思ってPython選んでみました。


CのRFC接続用ライブラリを準備

まずはSAP接続用のCのライブラリを準備します。SAP Service Market Placehttp://service.sap.com/swdcからNetWeaver RFC Libraryをダウンロードしてきます。ダウンロードにはSユーザが必要になります。
似たようなものに「SAP RFC SDK」や「SAP RFC SDK UNICODE」もありますが、今回利用するのは「SAP NW RFC SDK」なのでお間違えなく。

ファイル名はこんな感じです。
NWRFC_XX-XXXXXXXX.SAR


ダウンロードしたSARファイルをSAPCARで解凍します。

sapcar -xvf NWRFC_XX-XXXXXXXX.SAR

解凍したフォルダの中にあるlibフォルダ「nwrfcsdk\lib」に環境変数のPathを通します。
これでSAP接続用ライブラリの準備は完了です。



SAP接続用Pythonモジュールを準備

まずは以下のSDNサイトよりPythonモジュールをダウンロードしてきます。
https://cw.sdn.sap.com/cw/groups/pyrfc

→こちらに移動していました
github.com


こちらもダウンロードにはSユーザが必要になります。
現時点の最新版の「pyrfc_starterkit_1.9.2.zip」をダウンロードしてきました。

ZIPファイルを解凍して、eggファイルをインストールします。

easy_install X:\pyrfc_starterkit_1.9.2\eggs\sapnwrfc2-1.9.2-py2.7-<Platform>.egg


インストールできてるかPythonインタプリタから確認してみます。

>>> from sapnwrfc2 import *
>>>
>>> dir()
['ABAPApplicationError', 'ABAPRuntimeError', 'CommunicationError', 'Connection', 'ExternalApplicationError','ExternalAuthorizationError', 'ExternalRuntimeError', 'FunctionDescription', 'LogonError', 'RFCError', 'RFCLibError', 'Server', 'Ty
peDescription', '__builtins__', '__doc__', '__name__', '__package__']

しっかりSAP関連のモジュールがインストールされているみたいです。
ここで以下のようなエラーが出た場合は、RFCライブラリのあるフォルダにPathが通っているか、RFCライブラリ自体が間違ってないか確認してみてください。

ImportError: DLL load failed: 指定されたモジュールが見つかりません。

これで下準備が完了しました。


PythonからSAPへの接続テスト

最後にSAPへの接続テストとしてSAP汎用モジュールを読んでみます。

#まずはSAP接続情報を設定
>>> conn = Connection(user='ddic', passwd='password', ashost='hostname', sysnr='00', client='000')
#SAP汎用モジュールの呼び出し
>>> result = conn.call('STFC_STRUCTURE')
#SAP汎用モジュールの実行結果確認
>>> print(result[u'RESPTEXT'])
SAP R/3 Rel. 702   Sysid: SID      Date: 20130607   Time: 013546


ちゃんとPythonからSAPへ繋がりました。SMGWで見てもPythonで接続があるのがわかります。
f:id:yomon8:20130607212323p:plain

#最後は接続Closeして終了
>>>conn.close()

対話型で繋がるのはやはり良いですね。色々できそうです。