『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 Scripting | RPA | |
---|---|---|
実行の速さ |
◎ |
○ |
お値段 | ◎ | △ |
作りやすさ | ○ | ◎ |
他のアプリとの連携しやすさ | × | ◎ |
実はマクロをすごく書ける人は、マクロでなんでもできちゃいます(Outlookでメールを送るとかIE操作とか)。しかし全員がそのような人ばかりではないのが現実で、難しくしすぎると後々の保守が大変になります。
その場合は既存のRPAの入力作業をSAP GUI Scriptingに変えるだけでも、かなりスピードアップが図れます。
最後に
最後までお付き合いいただきありがとうございました。
今回は入力のみを行いましたが、ウィンドウ上に表示されるメッセージを拾ってエラー判断をしたり、SAP起動から実行させたり、実はもっといろいろなことができます。ぜひ気になった方は試してみてください。
(2022/9/27追記)「メッセージを拾ってエラー判断」について詳しいコラムが出ました!
RPAに限らず、このようなツールによる自動化についても多数実績がありますので、お悩み事等ございましたら、弊社へお気軽にお問い合わせ下さい。
関連記事
最新情報をお届けします!
RPAに関する最新コラムやイベント情報をメールで配信中です。
RPA領域でお仕事されている方に役立つナレッジになりますので、ぜび登録してください!
- October 2024 (3)
- September 2024 (2)
- August 2024 (4)
- July 2024 (1)
- June 2024 (2)
- May 2024 (3)
- April 2024 (1)
- March 2024 (1)
- February 2024 (1)
- January 2024 (1)
- December 2023 (1)
- November 2023 (2)