はじめに
coocleさんの記事で「【UiPath】UiPathでAccess VBAを動かす」というのが紹介されています。
そこではマクロ経由(Access起動時引数)とExcel経由が取り上げられているので、他の方法としてCOM使用(経由)をまとめました。
(すごく見やすく書かれているので、似せて書かせて頂きました m(_ _)m 箇条書きで説明するから図に起こして・・・角丸なんかせずに真四角白地に黒文字でエエやん・・・で、JKに「ダサっ」て言われるのよね~~。何と戦っているんだお前は・・・)
呼び出しイメージと用途による使い分け
用途による使い分け
UiPath⇔Access 引数・戻り値の扱い |
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も同様)
1-1-2. Sub、Functionプロシージャの作成
標準モジュールにSub、Functionプロシージャを作成します。
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.***の方は数字として古すぎますが、意図して残していると思われます(真相不明)。
プロジェクトの「依存関係」ツリーに表示されているのを確認してください。
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
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推奨)も書けるようになります。
無料アプリは山ほどありますが、「こんな機能があればいいのに」とか「多機能すぎてシンプルで余計な表示外してほしい」とか思うことあるでしょう。
そんなとき「完全自分仕様」なアプリを作れるのです。(大風呂敷)
さあ、あなたもコードの迷宮へ。