本記事は SAPアドベントカレンダー 2021 8日目の記事となります。また同時にBeeXアドベントカレンダー 2021の8日目でもあります。
本記事ではSAP Connector for Microsoft .NET(NCo)
をWindows PowerShell
から実行して、SAPシステムを操作してみます。
なお本記事で操作するのはSAP ABAP Platform 1909, Developer Edition(dockerhub)をopenSUSE Leap 15.3(EC2)で起動してみるで構築している、SAP ABAP Platform 1909, Developer Edition
となります。
SAP ABAP Platform 1909, Developer Edition
についてはPユーザのみで構築はできますが、本記事で利用するSAP Connector for Microsoft .NET
についてはライブラリがPユーザでは取得できないため、権限のあるSユーザが必須となります。
ドキュメント
SAP Connector for Microsoft .NETとは?
SAP Connector for Microsoft .NET
とは.NET Framework
を用いたSAPとの接続用コネクタになり、NCo
と表記されます。
この接続コネクタを利用することにより、.NetアプリケーションからBAPI(Business Application Programming Interface)・汎用モジュール(リモート対応)を実行することができます。
2021年12現在、NCo 3.0
が提供されています。
サポート期限について
.NET Framework
を背景にしているところで引っかる方がいるかと思いますが、サポート期限について。
Supportのページだったり、856863 - SAP NCo Release and Support Strategyのノートに記載があり。
2021年12月現在、NCo 3.0
のサポート期限は、For the .NET 4.0 variant support will be offered until December 31, 2022.
と記載されています。
NCO 3.0
については以前はMaintenance and support for the Microsoft .NET 4.0 runtime variant of NCo 3.0 will end on December 31, 2020
と記載されていたのが伸びていたりしていますが、.NET 4.0
である点は変わらず。
個人的には.NET(旧称.NET Core)
対応されれば……とは思いますが、.NET Framework 4
で延命され続けてるように見えるので、SAPとしては積極的には対応されてない? とは個人的に感じます。
.NET Framework
自体のサポート期限もありますし、ここらへん本格的にシステムで利用される場合は、他にもJava用のコネクタとしてSAP Java Connector(SAP JCo)
やSAP NetWeaver RFC SDK
なども用意されているため、それぞれのサポート期限等の状況を見つつ選択するのがよさそうです。
Windows PowerShell
Windows PowerShell
は.NET Framework
を基盤としており、.NET Framework
を利用できるため今回はWindows PowerShell
からSAP Connector for Microsoft .NET
を実行してみます。
今回利用する環境
- Windows 10 21H1
- Windows PowerShell 5.1.19041.1320
- SAP Connector for Microsoft .NET 3.0.24.0 for Windows 64bit (x64)(Compiled with .NET Framework 4.0)
- SAP ABAP Platform 1909, Developer Edition
2021年12月現在、NCo 3.0
が提供されていますが、ダウンロードをみると下記2つがそれぞれ提供されています。
- Compiled with .NET Framework 2.0, final patch level
- Compiled with .NET Framework 4.0
Nco 3.0
で.NET Framework 2.0
と.NET Framework 4.0
とバージョン番号が色々と出てくるので、所見だとちょっと紛らわしいかと思います。
本記事では.NET Framework 4.0を選択します。
SAP Connector for Microsoft .NET3.0のサポート期間
NCo
とはのところで少し触れましたが、サポート期限について下記にノートがあるためこちらを参照して下さい。
SAPnote:856863 SAP NCo Release and Support Strategy
過去、NCo 3.0
のサポート期限をみていると切れそうになると伸びてを繰り返していて、新しいバージョン…… とは少し思ってしまいますが。
ライブラリのダウンロード
今回はSAP Connector for Microsoft .NET 3.0.24.0 for Windows 64bit (x64)(Compiled with .NET Framework 4.0)
を利用します。
にリンクがあるのでこちらからダウンロードします。(S-Userが必要です)
なおサイトには下記のようにコーディングの参考になるプログラミングガイドやサンプルコードも置いてあります。
- dotnet_connector_30_programming_guide.pdf
- dotnet_connector_30_tutorial.zip <-サンプルコードの詰め合わせ(言語はVBとC#)
- dotnet_connector_30_overview.pdf
SAP .NET Connector 3.0のドキュメント(chmファイル)について。
今回ダンロードしたファイル、sapnco30dotnet40P_24-20007348.zip
の中にchmファイルが入っており、これがドキュメントになります。(NCo30APIDocumentation.chm
)
ダウンロードファイルのブロック設定
ダウンロードしてきたchmファイルを実行しても内容が表示されないケースがあります。
これは"ファイルのプロパティ"からセキュリティのチェックをつけない場合、内容が表示されないので注意して下さい。
ライブラリのインストール
▶今回は展開されたdllがほしいだけなので、Noneを選択してNextを選択
▶インストールが完了すると、インストール時に選択したフォルダに下記のdllがインストールされるのでこれらを使ってコーディングを行う。
- libicudecnumber.dll
- rscp4n.dll
- sapnco.dll
- sapnco_utils.dll
4つのdllがありますが、基本的に利用するのはsapnco.dll
とsapnco_utils.dll
の2つになります。
他2つのdll(libicudecnumber.dll,rscp4n.dll)については、下記の場合のみ必要となってくるようです。(SAP .NET Connector 3.0 Programming Guideより)
ABAP type DECFLOAT, your project will need the libicudecnumber.dll, and only if you
use the “UseSAPCodepages” parameter, your project will need the rscp4n.dll. In that
case make sure they can be found in the PATH environment variable.
基本的にな進め方について
基本的にな進め方については
- 1.chmファイルのドキュメントを読み、お目当ての操作を探す(ログイン/RFC実行/etcetc)
- 2.TRCD:BAPIやRFCで実行できる汎用モジュールをTRCD:SE37で探して、適宜コーディング
なおRFC出来る汎用モジュールは下記のように処理タイプの所がRemote-Enable Moduleになっています。
ちなみにRFC_CALL_TRANSACTION_USING
はBDCテーブルを渡すとバッチインプットを動かす汎用モジュール。
ライブラリを読み込んでSAPに接続してみる
ここではインストールディレクトリに配置されたsapnco.dll
とsapnco_utils.dll
をc:\temp\NCo
にコピーしたものをAdd-Typeコマンドレットで読み込み利用します。
今回、ログインに利用するユーザとしてRFCTEST
というダイアログユーザを作成し、権限SAP_ALL
をつけた物を利用しています。
RFCで実行できる汎用モジュールを制限したりと、権限構成とかの話もありますが、本記事では対象にしていません。
ここではSAP_ALL
をつけたユーザを利用しています。
# c:\temp\NCo\に配置したdllを読み込む
Add-Type -path "C:\temp\NCo\sapnco.dll"
Add-Type -path "C:\temp\NCo\sapnco_utils.dll"
# SAP.Middleware.Connector.RfcConfigParametersを生成してSAPのログオンパラメータを設定
# RfcConfigParametersを生成
[SAP.Middleware.Connector.RfcConfigParameters] $rfcParam = New-Object
# RfcConfigParametersに接続情報を設定
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::name, "TESTLOGON")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemID, "A4H")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::AppServerHost, "10.10.10.182")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemNumber, "00")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Client, "001")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::User, "RFCTEST")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Password, "パスワード")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SAPRouter, "")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Language, "EN")
# RfcDestinationに接続設定を渡す
[SAP.Middleware.Connector.RfcDestination] $rfcDest = [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($rfcParam)
# RfcDestinationのpingメソッドは汎用モジュールRFC_PINGを実行して接続確認を行うメソッド。
# Invokes a remote call to RFC_PING in order to test whether the physical connection to the backend system is still ok.
$rfcDest.ping()
スクリプト中で利用しているRfcConfigParameters
、RfcDestinationManager
、RfcDestination
について詳しいことはドキュメントに記載があります。
指定された情報でログオン出来るかチェックするスクリプト
プロンプトからコマンドを実行しましたが、引数としてログオン情報を渡すと接続テストを行うスクリプトのサンプルとしては下記のようになります。
(sapnco.dllとsapnco_utils.dllについてはps1ファイルと同じディレクトに格納して下さい)
<#
.SYNOPSIS
SAPログオンテスト
.DESCRIPTION
引数で指定したSAPシステムへログオンテストを行う
.PARAMETER systemID
SAP システムID
.PARAMETER appServerHost
SAP ホスト名
.PARAMETER systemNumber
SAP システムNO
.PARAMETER client
ログオンクライアント
.PARAMETER user
ログオンユーザ
.PARAMETER sapRouterString
SAPRouterストリング
.PARAMETER language
ログオン言語
#>
PARAM(
[Parameter(Mandatory = $true)][string]$SystemID,
[Parameter(Mandatory = $true)][string]$AppServerHost,
[Parameter(Mandatory = $true)][string]$SystemNumber,
[Parameter(Mandatory = $true)][string]$Client,
[Parameter(Mandatory = $true)][string]$User,
[Parameter(Mandatory = $true)][secureString]$Password,
[Parameter(Mandatory = $true)][AllowEmptyString()][string]$SAPRouterString,
[Parameter(Mandatory = $false)][string]$Language = "EN"
)
BEGIN {
# 初期処理
# secureStringからパスワードを取得
$plainPassword = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password) | ForEach-Object { [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($_) }
# dll読み込み
try {
$sapNcoPath = (Join-Path -Path $PSScriptRoot -ChildPath "sapnco.dll")
$sapnco_utils = (Join-Path -Path $PSScriptRoot -ChildPath "sapnco_utils.dll")
Add-Type -Path $sapNcoPath
Add-Type -Path $sapnco_utils
}
catch {
Write-Error -Message "dll読み込み失敗"
exit
}
}
PROCESS {
# RFCのログオンパラメータオブジェクトに値を設定
[SAP.Middleware.Connector.RfcConfigParameters] $rfcParam = New-Object SAP.Middleware.Connector.RfcConfigParameters
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::name, "testLogon")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemID, $SystemID)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::AppServerHost, $AppServerHost)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemNumber, $SystemNumber)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Client, $Client)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::User, $User)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Password, $plainPassword)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SAPRouter, $SAPRouterString)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Language, $Language)
# RfcDestinationに接続設定を渡す
[SAP.Middleware.Connector.RfcDestination] $rfcDest = [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($rfcParam)
# ログオン判定
try {
# RfcDestinationのpingメソッドは汎用モジュールRFC_PINGを実行して接続確認を行うメソッド。
# Invokes a remote call to RFC_PING in order to test whether the physical connection to the backend system is still ok.
$rfcDest.ping()
Write-Host "ログオン成功"
}
catch {
Write-Host "ログオン失敗"
}
Read-Host -Prompt "enterで終了"
}
BAPI(Business Application Program Interfaces)を実行してみる(BAPI_USER_GETLIST)
今回はBAPI_USER_GETLIST
を実行してみます。
▶今回BAPIからの戻り値として取得するテーブル:USERLIST
NCo
で汎用モジュールを実行する場合は、SAP.Middleware.Connector.IRfcFunction
を利用します。
<#
.SYNOPSIS
SAPユーザリスト取得
.DESCRIPTION
対象システムのユーザ一覧を取得する
.PARAMETER systemID
SAP システムID
.PARAMETER appServerHost
SAP ホスト名
.PARAMETER systemNumber
SAP システムNO
.PARAMETER client
ログオンクライアント
.PARAMETER user
ログオンユーザ
.PARAMETER sapRouterString
SAPRouterストリング
.PARAMETER language
ログオン言語
#>
PARAM(
[Parameter(Mandatory = $true)][string]$SystemID,
[Parameter(Mandatory = $true)][string]$AppServerHost,
[Parameter(Mandatory = $true)][string]$SystemNumber,
[Parameter(Mandatory = $true)][string]$Client,
[Parameter(Mandatory = $true)][string]$User,
[Parameter(Mandatory = $true)][secureString]$Password,
[Parameter(Mandatory = $false)][AllowEmptyString()][string]$SAPRouterString,
[Parameter(Mandatory = $false)][string]$Language = "EN"
)
BEGIN {
# 初期処理
# secureStringからパスワードを取得
$plainPassword = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password) | ForEach-Object { [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($_) }
# dll読み込み
try {
$sapNcoPath = (Join-Path -Path $PSScriptRoot -ChildPath "sapnco.dll")
$sapnco_utils = (Join-Path -Path $PSScriptRoot -ChildPath "sapnco_utils.dll")
Add-Type -Path $sapNcoPath
Add-Type -Path $sapnco_utils
}
catch {
Write-Error -Message "dll読み込み失敗"
exit
}
}
PROCESS {
# RFCのログオンパラメータオブジェクトに値を設定
[SAP.Middleware.Connector.RfcConfigParameters] $rfcParam = New-Object SAP.Middleware.Connector.RfcConfigParameters
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::name, "getUser")
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemID, $SystemID)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::AppServerHost, $AppServerHost)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SystemNumber, $SystemNumber)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Client, $Client)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::User, $User)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Password, $plainPassword)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::SAPRouter, $SAPRouterString)
$rfcParam.Add([SAP.Middleware.Connector.RfcConfigParameters]::Language, $Language)
# SAPログオン
[SAP.Middleware.Connector.RfcDestination] $rfcDest = [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($rfcParam)
# ログオン判定
try {
# RfcDestinationのpingメソッドは汎用モジュールRFC_PINGを実行して接続確認を行うメソッド。
# Invokes a remote call to RFC_PING in order to test whether the physical connection to the backend system is still ok.
$rfcDest.ping()
Write-Host "ログオン成功"
}
catch {
Write-Host "ログオン失敗"
exit
}
# BAPI_USER_GETLIST
[SAP.Middleware.Connector.IRfcFunction] $sapFunc = $rfcDest.Repository.CreateFunction("BAPI_USER_GETLIST")
# 実行
$sapFunc.Invoke($rfcDest)
# 返値取得
[SAP.Middleware.Connector.IRfcTable] $returnUserList = $sapFunc.GetTable("USERLIST")
# 情報格納用にArrayListを宣言
$userArray = New-Object System.Collections.ArrayList
# 返値から情報を取得しArrayListに格納
$returnUserList | ForEach-Object {
$userRow = New-Object PSCustomObject
# USERNAMEとFULLNAME項目を取得
$userRow | Add-Member -MemberType NoteProperty -Name "USERNAME" -Value $_.getValue("USERNAME")
$userRow | Add-Member -MemberType NoteProperty -Name "FULLNAME" -Value $_.getValue("FULLNAME")
$userArray.add($userRow) > $null
}
$userArray | Format-Table
Read-Host -Prompt "enterで終了"
}
SAP.Middleware.Connector.IRfcFunction
にRfcDestination
のRfcRepository.CreateFunctionメソッド
で実行したい汎用モジュールを設定し、Invoke
メソッドで実行。
実行結果テーブルからGetTable
メソッドでテーブルを取得し、あとはUSERNAME
とFULLNAME
を出力しています。
総評
NCo
について、.Net Framework
のためWindows PowerShell
からさっくりと利用することができて、ツールの作成がとても手軽に実現できます。
ただし、2021年現在は.NET Framework 4
で提供されており先行きがちょっと不透明な部分があるため、本格的なシステム連携に使うには状況をよく見て選択する必要があるかと思います