【UiPath】UiPathでAccess VBAを動かす 

# はじめに
UiPathの標準機能にはAccessとの連携機能が十分にないため、UiPathでAccess VBAを実行するには少し工夫が必要になります。

この記事ではUiPathからAccess VBAを実行する方法を2つ紹介します。

1. Accessツールのマクロを経由して、UiPathからAccess VBAを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/303762b4-5c05-8260-8c83-670cd227ff97.png)
　
2. Excelツールを経由して、UiPathからAccess VBAを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/03defda2-c3ac-3c99-902e-1eda058a807b.png)

#### 用途による使い分け
|用途|マクロ経由|Excel経由|COM使用<br><font color="DarkBlue">※4</font>
|---|:-:|:-:|:-:|
|引数を使用しない|〇|〇|〇|
|1つの引数を渡す|〇|〇|〇|
|複数の引数を渡す|△ <font color="DarkBlue">※1</font>|〇|〇|
|任意の型の引数を渡す|× <font color="DarkBlue">※2</font>|〇|〇|
|戻り値を取得する|×|〇|〇|
|シンプルな構成にしたい|△|×|〇|
|標準アクティビティーで構成|〇|〇|×|
|異なる引数で複数回実行 <font color="DarkBlue">※3</font>|×|〇|△|

※1 本来は単一の引数しか渡せませんが、配列操作により複数の引数を渡すこともできます。

※2 文字列型の引数のみ渡すことができます。

※3 異なる引数を使用して、同一のプロシージャを複数回実行する場合

※4 UiPath MarketplaceでMicrosoftが公開しているAccess用のアクティビティパッケージを使用して、UiPathからAccess VBAを実行する方法です。

UiPath Marketplaceを利用できる環境であれば、このアクティビティを使用してよりシンプルな構成にできます。

この記事では説明を割愛しますが、TechPark55さんの記事でわかりやすく解説されていますので、参考にしてみてください。

https://qiita.com/TechPark55/items/ca432b5953a02fb7c228

:::note warn
Accessのデータベースを直接操作する場合はUiPath.Database.Activitiesを使用します。使用方法はKajiitaさんの記事で紹介されています。
:::

https://qiita.com/Kajiita/items/93abc25d33fc216fd369

# 1. Accessのマクロ経由でAccess VBAを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/303762b4-5c05-8260-8c83-670cd227ff97.png)
UiPathでは【[プロセスを開始](https://docs.uipath.com/ja/activities/other/latest/ui-automation/start-process)】アクティビティでAccessの起動とマクロの実行ができます。この機能を利用し、Accessのマクロを経由することで、UiPathからAccess VBAを実行できます。

引数　：Accessツールに複数の文字列型の引数を渡すことができます。
戻り値：Accessツールから戻り値を取得することはできません。

## 1-1. Accessツールの作成
**全体の構成**
Accessツール内でマクロからFunctionプロシージャを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/9a65c360-0063-31fd-b10d-f3b4d6592480.png)

### 1-1-1. Functionプロシージャの作成
Accessツールの標準モジュールにFunctionプロシージャを作成します。

引数を渡す場合、【[Command](https://docs.microsoft.com/ja-jp/office/vba/Language/Reference/User-Interface-Help/command-function)】関数でUiPathから渡された引数を取得します。

:::note info
マクロが実行できるのはFunctionプロシージャのみです。
Subプロシージャは実行できません。
:::

```vb:AccessTool.accdb
Option Compare Database
Option Explicit

'待機時間を設定する場合はモジュール先頭にSleep関数を宣言します。
'Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal MilliSecond As Long)

Function SampleCode()
    '起動時にウィンドウを最大化する場合、最大化の処理の前後にDoEvents関数を記載します。
    DoEvents
    DoCmd.RunCommand acCmdAppMaximize
    DoEvents

    '1つの引数を渡す場合
    'Command関数でUiPathから渡された引数を取得します。
    'Command関数で取得した値は後ろに半角スペースがつくためTrim関数で半角スペースを除去します。
    Debug.Print Trim(Command)
    
    '複数の引数を渡す場合
    '複数の引数を区切り文字で区切られた単一の引数として渡し、
    'Split関数で配列として取得します。
    Dim tmpArray As Variant
    Dim i As Long    
    tmpArray = Split(Trim(Command))    
    For i = 0 To UBound(tmpArray)
        Debug.Print tmpArray(i)
    Next

    'インポート処理
    'クエリ実行処理
    'エクスポート処理
    
    'エクスポート処理が完了していない状態で、Accessツールの終了処理(DoCmd.Quit)が
    '開始されてエラーになる場合、待機時間を設定します。
    'Call Sleep(5000)

    '最後にAccessの終了処理を記載します。(後述のマクロの最後に終了処理を入れてもOKです。)
    DoCmd.Quit
End Function
```

### 1-1-2. マクロの作成
【[プロシージャの実行](https://support.microsoft.com/ja-jp/office/runcode-%E3%83%9E%E3%82%AF%E3%83%AD-%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3-e6a62d3f-02c6-4daf-a5f7-402fd600bed4)】マクロアクションを使用して、Functionプロシージャを実行するマクロを作成します。

UiPathで渡した引数は、FunctionプロシージャのCommand関数で直接受け取るため、マクロでの引数の指定は不要です。

■AccessツールのFunctionプロシージャにAccess終了処理(DoCmd.Quit)を入れる場合
【[プロシージャの実行](https://support.microsoft.com/ja-jp/office/runcode-%E3%83%9E%E3%82%AF%E3%83%AD-%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3-e6a62d3f-02c6-4daf-a5f7-402fd600bed4)】マクロアクションのみ設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/34a0e704-fab0-fc4a-5105-a0596a965be3.png)

■AccessツールのFunctionプロシージャにAccess終了処理(DoCmd.Quit)を入れない場合
【[プロシージャの実行](https://support.microsoft.com/ja-jp/office/runcode-%E3%83%9E%E3%82%AF%E3%83%AD-%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3-e6a62d3f-02c6-4daf-a5f7-402fd600bed4)】マクロアクションと【[Accessの終了](https://support.microsoft.com/ja-jp/topic/quitaccess-%E3%83%9E%E3%82%AF%E3%83%AD-%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3-3c67235d-a429-4d04-a455-113b611f18e2)】マクロアクションを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/74f7ab8b-7fd2-3990-e3a6-825bb69db26c.png)

## 1-2. UiPathのワークフロー
Accessツールのマクロ実行と処理終了確認のプロセスを作成します。

① マクロ実行
【[プロセスを開始](https://docs.uipath.com/ja/activities/other/latest/ui-automation/start-process)】アクティビティでAccessツールを起動しマクロを実行します。
マクロと引数の指定には【[コマンドラインスイッチ](https://support.microsoft.com/ja-jp/office/microsoft-office-%E8%A3%BD%E5%93%81%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-%E3%83%A9%E3%82%A4%E3%83%B3-%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81-079164cd-4ef5-4178-b235-441737deb3a6#Category=Access)】を使用します。

■引数を使用しない場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/406a7fc7-2eec-39c2-e091-fd0793305a5a.png)

■引数を使用する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/f361a077-e8bb-ec6b-dd09-6379af9903a1.png)
※文字列型の引数を渡すことができます。

② 処理終了確認
【[トリガー スコープ](https://docs.uipath.com/ja/activities/other/latest/ui-automation/start-process)】アクティビティと【[プロセス終了トリガー](https://docs.uipath.com/ja/activities/other/latest/workflow/process-end-trigger)】アクティビティを使用して、Accessツールの処理終了まで待機します。

トリガースコープのスケジュールモードは「1回」に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/25d5a7de-870f-e64e-6a7b-045d88fa8098.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/3b13ddf9-562b-4d83-5e4f-024b97db08b4.png)

# 2. Excelツール経由でAccess VBAを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/03defda2-c3ac-3c99-902e-1eda058a807b.png)
UiPathとExcelの連携機能は充実しており、同じMicrosoft OfficeシリーズのExcelとAccessの連携も容易にできます。そのため、Excelツールを経由することで、UiPathからAccess VBAを実行できます。

引数　：Accessツールに複数の任意の型の引数を渡すことができます。
　　　　そのため、配列型の引数を渡すなど様々な用途に使用することができます。
戻り値：Accessツールから任意の型の戻り値を取得することができます。

## 2-1. Accessツールの作成

標準モジュールに処理内容を記載します。

戻り値を返す場合はFunctionプロシージャを使用し、
戻り値を返さない場合はSubプロシージャを使用します。

UiPath・Excel・Accessを連携させた場合、UiPathはAccessの処理完了まで待機するため、処理完了検知用の処理は不要です。

```vb:AccessTool.accdb
Option Compare Database
Option Explicit

Sub SampleCode(ByVal parameter1 As String, ByVal parameter2 As String)
    Debug.Print parameter1
    Debug.Print parameter2
    'インポート処理
    'クエリ実行処理
    'エクスポート処理
End Sub
```

## 2-2. Excelツールの作成
標準モジュールにAccessツールの起動処理・実行処理・終了処理を作成します。

戻り値を返す場合はFunctionプロシージャを使用し、
戻り値を返さない場合はSubプロシージャを使用します。

```vb:ExcelTool.xlsm
Option Explicit

'Accessのインスタンス変数をモジュールレベル変数として宣言
Private acApp As Object

'Accessツールの起動処理
Sub OpenTool()    
    'Accessツールのファイルパスの変数を宣言
    Dim toolPath As String
    
    'Accessツールのファイルパスを作成
    toolPath = ThisWorkbook.Path & "\AccessTool.accdb"

    'Accessのインスタンス作成時にエラーが発生する場合は待機時間を設定する
    'Application.Wait Now() + TimeValue("00:00:03")

    'Accessのインスタンスを作成
    Set acApp = CreateObject("Access.Application")
    
    'Accessツールを起動
    acApp.OpenCurrentDatabase toolPath
    
    'Accessツールを最大化
    acApp.RunCommand 10 'Application.RunCommand acCmdAppMaximize
    
    'Accessオブジェクトを表示
    acApp.Visible = True
End Sub

'Accessツールの実行処理
Sub ExecuteCode(ByVal parameter1 As String, ByVal parameter2 As String)
    'acApp.Run プロシージャ名, 引数1,引数2
    acApp.Run "SampleCode", parameter1, parameter2
End Sub

'Accessツールの終了処理
Sub CloseTool()
    'Accessを終了
    acApp.Quit
  
    'Accessのインスタンスを破棄
    Set acApp = Nothing
End Sub
```

## 2-3. UiPathのワークフロー
【[スプレッドシートのマクロを実行](https://docs.uipath.com/ja/activities/other/latest/productivity/execute-macro-x)】アクティビティを配置し、Excelツールの起動処理・実行処理・終了処理のプロシージャを指定します。

引数を渡す場合は「マクロ引数」に必要数の引数を記載します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/b84bd03f-0e49-0a97-496a-97f093274416.png)

戻り値を返す場合は「出力先」に受け取り用の変数を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/015c0daa-3085-9a40-8413-3fb4577bf429.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/129afdad-8605-614b-9bd1-0c6d0e41da69.png)

# おわりに
業務の中でUiPathからAccessツールを操作することが多いのですが、UiPathの標準機能ではAccess VBAを直接実行できず、UiPathのシナリオの作成にかなり苦労しました。

皆さんもUiPathとAccessツールの連携において様々な工夫をされていると思いますが、この記事がお役に立てると幸いです。