はじめに
UiPath から Execute Macro アクティビティを使用しての VBA コール時、 VBA からの返却値を取得できずに少しハマッたことがあったので、そのときにわかったことを記事としてまとめておきます。
Execute Macro アクティビティ使用時、これを知っておいて損は無いと思います。
前提
UiPath と VBA の連携を想定した際の「VBA 実装の基本方針」は、UiPath 社様が公式のナレッジベースにまとめて下さっているので、まずは以下の記事を読んでいることを前提として本記事を記載します。
結論から
VBA は必ず標準モジュール内に実装しましょう。
それ以外の箇所に実装した場合、マクロは動作しても返却値だけが返ってこない、という奇妙な現象に遭遇します。
次章以降で詳しく解説します。
検証環境
-
UiPath
- Studio Pro 2021.8.0-beta.5246 Community License
-
使用パッケージ
- UiPath.Excel.Activities v2.10.4
- UiPath.System.Activities v21.4.1
検証内容
Excel VBA を、UiPath からコールします。
Excel VBA 側には 100% エラーになる処理を入れておき、UiPath 側 で VBA でのエラー発生有無を拾えるかどうか、を検証ポイントとします。
Excel VBA
検証に使用する Excel VBA は以下です。
UiPath 社様の ナレッジベース を元にしています。
簡単に解説すると、
- 正常時:空白を返す
- 異常時:エラー内容を String 型で返す
上記の返却値を持つ関数で、今回は処理内容に Err.Raise
を入れているため必ずエラーになります。
Option Explicit
'/**
' * 100%エラーが発生するサンプル。
' *
' * @return {String} - 正常時は空白, 異常時はエラー内容を返す
' */
Public Function VbaSample() As String
' エラートラップ
On Error GoTo ERR_HANDLER_
' 意図的にエラーを発生させる
Err.Raise 9999, Description:="エラー内容"
' 正常終了(空の値を返す)
VbaSample = ""
Exit Function
' エラーハンドラー
ERR_HANDLER_:
' エラー詳細情報を返す
VbaSample = "Excelマクロ内でエラーが発生しました。" & vbCrLf & _
"エラー番号:" & Err.Number & vbCrLf & _
"エラー内容:" & Err.Description
End Function
検証動作
- UiPath から Execute Macro アクティビティを使用し、上記 Excel マクロをコール
- Excel マクロ内でエラー発生、エラー内容を返却
- UiPath 側で返ってきたエラー内容をログに出力
上記の動作を、Excel VBA の保存場所を変えるだけの以下3パターンで、実動作を見ていきたいと思います。
パターン①:VBA の保存場所:標準モジュール
パターン②:VBA の保存場所:Sheet
パターン③:VBA の保存場所:ThisWorkbook
パターン①:VBA の保存場所:標準モジュール
まずは Excel VBA の保存場所を、標準モジュール にして検証します。
VBA 実装
- Excel ファイル名:VBA_Module.xlsm
- VBA 保存場所:標準モジュール(Module1)
UiPath 実装
マクロを実行 アクティビティの出力変数に、Object 型変数 MacroResult
を設定。
その内容を メッセージをログ アクティビティで出力するだけ、というシンプルな実装になっています。
UiPath 動作結果
Excel マクロ内でエラーが発生し、そのエラー内容を返却。
UiPath 側では、返却されたエラー内容を正常に出力できていることを確認できました!
結論
VBA の保存場所が 標準モジュール の場合、VBA からの返却値を UiPath 側で取得可能
パターン②:VBA の保存場所:Sheet
次は Excel VBA の保存場所を、Sheet にして検証します。
パターン①との変更点は、VBA の保存場所を変えたのみ です。
VBA 実装
- Excel ファイル名:VBA_Sheet.xlsm
- VBA 保存場所:Sheet1
UiPath 実装
前項との実装変更箇所は以下一点のみです。
-
マクロを実行 アクティビティの、プロパティ
マクロ名
- 変更前:
Module1.VbaSample
- 変更後:
Sheet1.VbaSample
- 変更前:
UiPath 動作結果
なんとエラーで止まってしまいました
エラー原因
エラー発生時の MacroResult
変数をローカルパネルで見てみると、null
になっていました。
よって MacroResult.ToString
が実行できずにエラーになっていたようです。
検証したところ、この MacroResult
変数については初期化してようがしてなかろうが、関係なく null
になりエラーで落ちます。
マクロを実行 アクティビティから Sheet 内のマクロを呼ぶと、出力変数に設定した値は null
になるのが仕様のようです。
(マクロの結果が正常でも異常でも関係なく、出力変数が null
になってしまう)
結論
VBA の保存場所が Sheet の場合、VBA からの返却値は常に null になってしまう
パターン③:VBA の保存場所:ThisWorkbook
結論、Excel VBA の保存場所を ThisWorkbook にしてもパターン②とまったく同じ動作をします。
前項と同動作ですので、
本項の検証結果は折り畳んでおきます。(確認したい方は開いて下さい)
VBA 実装
- Excel ファイル名:VBA_ThisWorkbook.xlsm
- VBA 保存場所:ThisWorkbook
UiPath 実装
前項との実装変更箇所は以下一点のみです。
-
マクロを実行 アクティビティの、プロパティ
マクロ名
- 変更前:
Sheet1.VbaSample
- 変更後:
ThisWorkbook.VbaSample
- 変更前:
UiPath 動作結果
同じくエラーで止まってしまいました…。
エラー原因
やはりエラー発生時の MacroResult
変数が null
になっておりエラーになっていました。
マクロを実行 アクティビティから ThisWorkbook 内のマクロを呼んでも、出力変数に設定した値は null
になるのが仕様のようです。
(前項と同じく、マクロの結果が正常でも異常でも関係なく、出力変数が null
になってしまう)
結論
VBA の保存場所が ThisWorkbook の場合、VBA からの返却値は常に null になってしまう
結論まとめ
Excel VBA の保存先と動作結果をまとめました。
VBA保存先 | マクロ動作 | 返却値 |
---|---|---|
標準モジュール | 〇 | 〇 |
Sheet | 〇 | × |
ThisWorkbook | 〇 | × |
マクロ自体は動作するのに、返却値が取得できたり できなかったりする、という点が注意です。
上記のことから、UiPath から呼ばれることを前提とした VBA は標準モジュール内に配置したほうが無難と言えそうです。
最後に
私が知る限り、少なくとも2年以上前からこの動作は変わっていないので、これが UiPath の仕様なのでしょうね。
(Execute Macro アクティビティの公式ページに説明が欲しい気もします)
関連リンク
-
UiPath ドキュメントポータル:マクロを実行(Execute Macro)アクティビティ
https://docs.uipath.com/activities/lang-ja/docs/execute-macro -
ナレッジベース:VBA Macroの自動化対応時のエラーハンドリング(OnErrorGoto)
https://www.uipath.com/ja/resources/knowledge-base/vba-macro-onerrorgoto -
UiPath Forum:Execute MacroのMacro outputパラメータの使いかた
https://forum.uipath.com/t/execute-macro-macro-output/30869