UiPathから Microsoft Access マクロ、VBAを呼び出す

# はじめに
coocleさんの記事で「【UiPath】UiPathでAccess VBAを動かす」というのが紹介されています。

https://qiita.com/coocle/items/c5a4e29625a972d2e6f9

そこではマクロ経由（Access起動時引数）とExcel経由が取り上げられているので、他の方法としてCOM使用(経由)をまとめました。
（すごく見やすく書かれているので、似せて書かせて頂きました m(_ _)m 箇条書きで説明するから図に起こして・・・角丸なんかせずに真四角白地に黒文字でエエやん・・・で、JKに「ダサっ」て言われるのよね～～。何と戦っているんだお前は・・・）

## 呼び出しイメージと用途による使い分け
![呼び出しイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456318/ac32b53d-0088-590c-7bd0-1eca8153240b.png)

#### 用途による使い分け
|UiPath⇔Access<br>引数・戻り値の扱い|COM使用|
|---|:-:|
|引数を使用しない|〇|
|1つの引数を渡す|〇 ※1|
|複数の引数を渡す|〇 ※1|
|任意の型の引数を渡す|〇 ※1|
|戻り値を取得する|〇 ※2|
|シンプルな構成にしたい|〇|

※1 マクロでの引数渡しはできません。Sub、Functionで可。
※2 Functionのみ可。

※ 難点としては、場合によってはC#やVB.Netコードの知識が少し必要なところでしょうか。
Functionの戻り値を複数（Tupleや構造体使用）返せないか少し実験してみましたが、ダメでした。頭が固いだけかもしれません…。

#### 動作環境
UiPath Studio 2022.4.1
Access 2019

# 1. COMを使用してAccess マクロ、VBA（Sub、Function）を実行
## 1-1. テスト用Access dbの作成
新しく任意のフォルダーにテスト用のdbを作成します。（以下では「Test用.accdb」）
### 1-1-1. マクロの作成
処理内容は何でもいいですが、動作確認ができるのでメッセージボックスを表示しています。
（UiPathでボタン押させるためではなく、人間が押す必要がありますので念のため。Sub、Functionも同様）
![Ac_マクロ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456318/bcea9b00-640f-62dd-4f88-470af27c678c.png)

### 1-1-2. Sub、Functionプロシージャの作成
標準モジュールにSub、Functionプロシージャを作成します。
```vb:Test用.accdb
Option Compare Database
Option Explicit          ' ←これは絶対に記述すべきです。『絶対』です。理由は・・・問答無用です。

Public Sub TestSub(arg1 As String, arg2 As Integer)
MsgBox "TestSub() " & arg1 & (arg2 + 1)
End Sub

Public Function TestFunction1(arg1 As String, arg2 As Integer) As String
MsgBox "TestFunction1() " & arg1 & (arg2 + 1)
TestFunction1 = "TestFunction1 return " & arg1
End Function

Public Function TestFunction2() As Integer()    ' Variantでも可(非推奨。場合により)
Dim ary(1) As Integer
MsgBox "TestFunction2()"
ary(0) = 1
ary(1) = 2
TestFunction2 = ary
End Function
```

## 1-2. UiPathのワークフロー
### 1-2-1. 依存関係にMicrosoft.Office.Interop.Accessを追加
テストプロジェクトを新規に作成し、「パッケージを管理」から「Microsoft.Office」を検索します。なぜAccessまで含めないかは理由があります。
それは、お宝もいっぱい表示されるからw。お～～って思う人いるはず。（下記スクショも参照）
Microsoft.Office.Interop.Accessを選択してインストールしてください。
バージョンは15.***でいいでしょう。12.***の方は数字として古すぎますが、意図して残していると思われます（真相不明）。
プロジェクトの「依存関係」ツリーに表示されているのを確認してください。
![US_パッケージinst.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456318/4151c3d0-aed5-4e01-0ed8-ee07bce6e303.png)

### 1-2-2. UiPathのワークフロー追加
Accessのマクロ、Sub、Function実行を、「コードを呼び出し(Invoke code)」に記述します。
当方C#erなのでVBソースは提示できませんが、簡単な内容なので変換は難しくないと思います。
2022/6/8追記：coocleさんがVBソースを作成してくださいました。コメント欄にあります。 https://qiita.com/coocle/items/c5a4e29625a972d2e6f9#comment-0901ef188e18b77791c0
![US_Access実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456318/03abad67-7cff-c43c-791b-3223d9c72cea.png)
```C#:コードを呼び出し
Microsoft.Office.Interop.Access.Application appAc = new Microsoft.Office.Interop.Access.Application();
// Application appAc = new Application();                    // 今回説明割愛
appAc.Visible = true;
appAc.OpenCurrentDatabase(@"フルパス\Test用.accdb");
appAc.DoCmd.RunMacro("マクロ1");                             // マクロ実行

appAc.Run("TestSub", "hoge", 1);                             // Sub実行

var ret1 = appAc.Run("TestFunction1", "fuge", 2);            // Function実行、戻り値取得
Console.WriteLine($"ret:{ret1} " + ret1.GetType());          // 「出力」に表示されます（$使える～のテスト兼）
         // 配列を返す例
         // また、VBAのIntegerはUiPathではintではなくshort
         // VBAのlongがUiPathでint
         // 型が一致しないとエラーになりますので、変な値のまま動くということにはなりません。（←何気に重要）
         // しかし、shortをintで受けるのは問題ないはず…。明示型変換必要だっけ???と素人のような疑問… arrayだから？放置
short[] ret2 = (short[])appAc.Run("TestFunction2");          // short:Int16、int:Int32
Console.WriteLine($"ret:{ret2[0]} {ret2[1]} " + ret2.GetType());

if (appAc != null)
    appAc.Quit();
appAc = null;
```

Activityとしてはチマっと1個だけですが、これだけです。
各行をそれぞれActivity（代入や条件分岐等）で記述すると画面からはみ出すほどに広がって、昔々からのプログラマーからするとウガ～って思うんですよ…。
もうね、コードに落とせるものは全部コードにしてやるって神に誓うと（老害とも言う）。
高密度表示オプションを要望しようかと思ってます。（依頼文章書く気になれば）

## おわりに
うまく動作しましたでしょうか・・・。
「コードで書けるのいいな・・・」って思ったUiPathからプログラミングに入ってきたあなた。
コードで書けるようになると、Windowsアプリやスマホアプリ（敷居的にAndroid推奨）も書けるようになります。
無料アプリは山ほどありますが、「こんな機能があればいいのに」とか「多機能すぎてシンプルで余計な表示外してほしい」とか思うことあるでしょう。
そんなとき「完全自分仕様」なアプリを作れるのです。（大風呂敷）
さあ、あなたもコードの迷宮へ。