『SAP GUI Scripting』のご紹介 SAPをExcelマクロで動かしてみた! 

SAP GUI Scriptingとは?

皆さん、SAP GUI Scriptingってご存じでしょうか。様々な企業で広く使われているERPパッケージ「SAP」の機能の一つです。簡単に言うと、VBSというスクリプト言語を利用し、SAPの操作を自動化できる機能です。

 

SAP GUI Scriptingのポイントは、「スクリプトを使うのでロボがいらない」という点!(RPAのコラムなのにこんなことを書くと怒られそうですが…。)

今回はこれを使ってSAPのユーザー登録作業を自動化してみます。

百聞は一見に如かず、ということで先に完成形をお見せするとこんな感じに動きます。30秒ほどの短い動画です!

 

50行分のデータを約50秒で入力できました!

SAPが公式で提供しているだけあって、RPAで入力するよりずっと速く入力することができます。

 

安い(SAPの追加ライセンス不要)早い(実行スピードが速い)うまい(ユーザーに旨味がある)」

そんなSAP GUI Scriptingのご紹介です!

 

※前半は実践編なので、「要は何が良いの?」だけ知りたい方は動画をご覧になってから後半の「SAP GUI Scriptingのうれしいところ」からお読み下さい。

 

まずはやってみよう

やりたいこと

 

SAPにログオンするユーザー情報の登録を自動化します。登録作業は以下の手順で行います。

 

 

入力する情報はExcelにこんな感じで書いておきます。

 

登録の際に入力する項目は1件につき15項目です。筆者が手動で入力する時間を測ると1件の登録に1分15秒くらいかかりました…。この登録を50件実行させてみます。

 

下準備

 

実行するためにはSAPでスクリプトを有効にする設定が必要です。以下の手順で有効化ができます。

 

レコーディング

スクリプトの作成には、基本的にSAPのレコーディング機能を使います。レコーディングが終わると、②で設定した保存先パスにVBSファイルが出力されます。

レコーディングは以下の手順で行います。

 

 

※レコーディングの設定が有効になっていない場合は、システム管理者に問い合わせる等してください。

 

レコーディングを使うことで、入力したい場所のSAP ID(:SAP上のUI要素を特定するためのアドレス)を取ってくることができます。これにより「SAP上のどの欄に入力するか」を指定することが可能になります。

※レコーディングを使わずにSAPIDを取得する裏ワザとしては、UiPath Studioに標準実装されている UI Explorerを使う方法もあります。

 

ユーザー情報の入力を1件行うと、こんな感じにVBSが出力されました。この後スクリプトを書き換えるので、何の項目を入力しているのかわかるように記録していくと良いです。

If Not IsObject(application) Then
   Set SapGuiAuto  = GetObject("SAPGUI")
   Set application = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(connection) Then
   Set connection = application.Children(0)
End If
If Not IsObject(session) Then
   Set session    = connection.Children(0)
End If
If IsObject(WScript) Then
   WScript.ConnectObject session,     "on"
   WScript.ConnectObject application, "on"
End If
session.findById("wnd[0]").resizeWorkingPane 140,22,false
session.findById("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME").text = "TESTUSER"
session.findById("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/cmbSUID_ST_NODE_PERSON_NAME_EXT-TITLE_MEDI").key = "0002"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_LAST").text = "苗字"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_FIRST").text = "名前"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/ctxtSUID_ST_NODE_PERSON_NAME_EXT-TITLE_ACA1T").setFocus
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/ctxtSUID_ST_NODE_PERSON_NAME_EXT-TITLE_ACA1T").caretPosition = 0
session.findById("wnd[0]").sendVKey 4
session.findById("wnd[1]/usr/lbl[12,4]").setFocus
session.findById("wnd[1]/usr/lbl[12,4]").caretPosition = 3
session.findById("wnd[1]").sendVKey 2
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/cmbSUID_ST_NODE_PERSON_NAME-LANGU").key = "JA"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_WORKPLACE-FUNCTION").text = "Func"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_WORKPLACE-DEPARTMENT").setFocus
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_WORKPLACE-DEPARTMENT").caretPosition = 0
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_WORKPLACE-DEPARTMENT").text = "Dep"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_WORKPLACE-ROOMNUMBER").text = "1"

'割愛'

session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/cmbSUID_ST_NODE_WORKPLACE-DEFLT_COMM").setFocus
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO").select
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/pwdSUID_ST_NODE_PASSWORD_EXT-PASSWORD").text = "********"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/pwdSUID_ST_NODE_PASSWORD_EXT-PASSWORD2").text = "********"
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/pwdSUID_ST_NODE_PASSWORD_EXT-PASSWORD2").setFocus
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpLOGO/ssubMAINAREA:SAPLSUID_MAINTENANCE:1101/pwdSUID_ST_NODE_PASSWORD_EXT-PASSWORD2").caretPosition = 10
session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR").select
session.findById("wnd[0]/tbar[0]/btn[11]").press

 

「wnd[0]/usr/」で始まるところがSAPIDですね!

 

コードの修正

レコーディングしてそのままのコードではレコーディングした内容しか登録できないので、Excelから複数の情報を取ってきて入力するためにマクロ用に書き換えます。

繰り返し回数ごとに参照する行が変わるようにループ処理をつけてみます。

Do While Cells(row, 1) = "未登録"
        Cells(row, 2) = Format(Now, "yyyy/MM/dd HH:mm:ss")  'RPA処理日時'
        Session.findById("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME").Text = Cells(row, 3)
        Session.findById("wnd[0]/usr/ctxtSUID_ST_BNAME-BNAME").caretPosition = 4
        Session.findById("wnd[0]/tbar[1]/btn[8]").press
        
        If Session.findById("wnd[0]/sbar").Text <> "" Then
            strTemp = Session.findById("wnd[0]/sbar").Text
            Cells(row, 1) = "登録失敗:" & strTemp
            
            GoTo Continue
        End If
        
        If Not Session.findById("wnd[1]/usr/btnBUTTON_2", False) Is Nothing Then
            Session.findById("wnd[1]/usr/btnBUTTON_2").press
        End If
        
        If Cells(row, 4) <> "" Then
            If Cells(row, 4) = "Mr." Then
                Session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/cmbSUID_ST_NODE_PERSON_NAME_EXT-TITLE_MEDI").Key = "0001"
            Else
                Session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/cmbSUID_ST_NODE_PERSON_NAME_EXT-TITLE_MEDI").Key = "0002"
            End If
        End If
        Session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_LAST").Text = Cells(row, 5)
        Session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/txtSUID_ST_NODE_PERSON_NAME-NAME_FIRST").Text = Cells(row, 6)
        Session.findById("wnd[0]/usr/tabsTABSTRIP1/tabpADDR/ssubMAINAREA:SAPLSUID_MAINTENANCE:1900/ctxtSUID_ST_NODE_PERSON_NAME_EXT-TITLE_ACA1T").Text = Cells(row, 7)
        
        '割愛'
        
        Session.findById("wnd[0]/tbar[0]/btn[11]").press

        Cells(row, 1) = "登録済"
        
Continue:
        row = row + 1

Loop

こんな感じで書くと、冒頭の動画のように動かすことができます!

 

SAP GUI Scriptingのうれしいところ

①SAPの追加ライセンス不要!

最初にも書きましたが、SAP GUI Scripting APIを使う一番のメリットは

追加ライセンス不要でSAPの自動化ができることでしょう。

つまりランニングコストはSAP利用料および保守料でOK!元々SAPを使っているお客様であれば追加費用は不要ということです。低コストで、しかも高速な自動化を実現することが可能なんです。

 

②アドオン開発の代用として使える!

実はアドオン開発にはいろいろ問題があります。

SAP S/4HANA移行を取りまく、アドオン開発の取り扱いについてはこちら↓


ざっくり言うと、極力アドオンは必要最小限に留め、なるべくツールに合わせてやり方を変える方が良いという話です。しかし、今までの帳票のフォーマットを大きく変えたりするのは大変ですよね。

SAP GUI Scriptingを使うと、入力ファイルを合わせなくても転記方法をSAP標準フォーマットに合わせればいいので、自社フォーマットを好きなように作成することができます。

 

RPAとのちがい

冒頭でロボいらない、ライセンスいらない、と言ってきました。

しかし、Excelマクロで動かすという性質上はマクロでできること以上のことはできません(当然ですが)

 

そこで、それぞれの強み・弱みを表にまとめてみました。

 SAP GUI ScriptingRPA
実行の速さ

お値段
作りやすさ
他のアプリとの連携しやすさ×

実はマクロをすごく書ける人は、マクロでなんでもできちゃいます(Outlookでメールを送るとかIE操作とか)。しかし全員がそのような人ばかりではないのが現実で、難しくしすぎると後々の保守が大変になります。

その場合は既存のRPAの入力作業をSAP GUI Scriptingに変えるだけでも、かなりスピードアップが図れます。

 

最後に

最後までお付き合いいただきありがとうございました。

今回は入力のみを行いましたが、ウィンドウ上に表示されるメッセージを拾ってエラー判断をしたり、SAP起動から実行させたり、実はもっといろいろなことができます。ぜひ気になった方は試してみてください。

 

RPAに限らず、このようなツールによる自動化についても多数実績がありますので、お悩み事等ございましたら、弊社へお気軽にお問い合わせ下さい

 

関連記事

もっと知りたい方はこちら

ページトップ