8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

BeeXAdvent Calendar 2021

Day 8

SAP Connector for Microsoft .NET(NCo)をWindows PowerShellから実行してSAPを操作してみる

Last updated at Posted at 2021-12-07

本記事は 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が必要です)

image.png

なおサイトには下記のようにコーディングの参考になるプログラミングガイドやサンプルコードも置いてあります。

image.png

  • 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

image.png

ダウンロードファイルのブロック設定

ダウンロードしてきたchmファイルを実行しても内容が表示されないケースがあります。
これは"ファイルのプロパティ"からセキュリティのチェックをつけない場合、内容が表示されないので注意して下さい。

image.png

ライブラリのインストール

▶インストーラ(MSIファイル)を実行する。
image.png

▶Nextを選択
image.png

▶インストール先を選択してNextを選択
image.png

▶今回は展開されたdllがほしいだけなので、Noneを選択してNextを選択
image.png

▶Nextを選択
image.png

▶Closeを選択
image.png

▶インストールが完了すると、インストール時に選択したフォルダに下記のdllがインストールされるのでこれらを使ってコーディングを行う。

image.png

  • libicudecnumber.dll
  • rscp4n.dll
  • sapnco.dll
  • sapnco_utils.dll

4つのdllがありますが、基本的に利用するのはsapnco.dllsapnco_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になっています。

image.png

ちなみにRFC_CALL_TRANSACTION_USINGはBDCテーブルを渡すとバッチインプットを動かす汎用モジュール。

ライブラリを読み込んでSAPに接続してみる

ここではインストールディレクトリに配置されたsapnco.dllsapnco_utils.dllc:\temp\NCoにコピーしたものをAdd-Typeコマンドレットで読み込み利用します。

今回、ログインに利用するユーザとしてRFCTESTというダイアログユーザを作成し、権限SAP_ALLをつけた物を利用しています。

RFCで実行できる汎用モジュールを制限したりと、権限構成とかの話もありますが、本記事では対象にしていません。
ここではSAP_ALLをつけたユーザを利用しています。

NCoでダイアログユーザRFCTESTでログイン確認
# 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()

スクリプト中で利用しているRfcConfigParametersRfcDestinationManagerRfcDestinationについて詳しいことはドキュメントに記載があります。

image.png

指定された情報でログオン出来るかチェックするスクリプト

プロンプトからコマンドを実行しましたが、引数としてログオン情報を渡すと接続テストを行うスクリプトのサンプルとしては下記のようになります。
(sapnco.dllとsapnco_utils.dllについてはps1ファイルと同じディレクトに格納して下さい)

Test-SAPLogon.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で終了"
}

▶実行結果
image.png

BAPI(Business Application Program Interfaces)を実行してみる(BAPI_USER_GETLIST)

今回はBAPI_USER_GETLISTを実行してみます。

▶BAPI_USER_GETLIST
image.png

image.png

▶今回BAPIからの戻り値として取得するテーブル:USERLIST
image.png

▶USERLISTテーブルの構造、BAPIUSNAME
image.png

NCoで汎用モジュールを実行する場合は、SAP.Middleware.Connector.IRfcFunctionを利用します。

Get-UserList.ps1
<#
.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で終了"
}

▶実行結果
image.png

SAP.Middleware.Connector.IRfcFunctionRfcDestinationRfcRepository.CreateFunctionメソッドで実行したい汎用モジュールを設定し、Invokeメソッドで実行。

実行結果テーブルからGetTableメソッドでテーブルを取得し、あとはUSERNAMEFULLNAMEを出力しています。

総評

NCoについて、.Net FrameworkのためWindows PowerShellからさっくりと利用することができて、ツールの作成がとても手軽に実現できます。

ただし、2021年現在は.NET Framework 4で提供されており先行きがちょっと不透明な部分があるため、本格的なシステム連携に使うには状況をよく見て選択する必要があるかと思います

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?