【🔥UiPath vs Automation Anywhere🔥】Excel を複数起動して転記してみる

Excel操作で、複数のExcelの間での情報の転記をよくやる、という人もいますよね？
ひとつのExcelファイルであればRPAでなくてもマクロを使えばいいじゃん！っていう意見もありますが、Excelファイルが複数になってくるとRPAの方が複雑性や管理性の意味で簡単になってきます。

この記事では、UiPathとAutomation Anywhereで複数のExcelを開いて処理を行う場合のロボット作成方法、実行の様子について比べてみることにしましょう～ ('ω')ノ✨

利用した環境

* UiPath 2020.2.0-beta.108
* Automation Anywhere A2019 ビルド2545

# Excelファイルを開いて保持する仕組みの違い

ところで、Excelを開く処理といってもRPAソフトウェアによって考え方が違う場合があります。UiPathとAutomation Anywhereでは、Excelファイルを開いて保持しておくためのしくみが違います。これについてまず見てみましょう～

### UiPathの場合 - "アプリケーションスコープ" というコンテナーを介してアクセス

UiPathではExcelアプリケーションでExcelファイルを扱う場合は**「Excelアプリケーションスコープ」**というコンテナーをシーケンスにドロップして使うことになります。(以下の<font color="DarkOrange"><b>オレンジ色</b></font>の部分)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f0998614-03b6-2f3f-423c-3028f571c7e4.png)

この中に、Excelファイル上でさまざまな操作を行う以下のアクティビティ (<font color="DarkGreen"><b>緑色</b></font>)を配置することになります。これらのアクティビティ自体には、<font color="Red">**どのExcelファイルを操作するかという情報をセットするプロパティは持っておらず**</font>、アクティビティが載っているExcelアプリケーションスコープに記載されたExcelファイルを操作することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/c6b765a7-eb82-8185-de3a-ea526b9d87af.png)


**スコープを抜けるときの処理**
スコープ内では、スコープに指定されているファイルがExcelによって開かれた状態となりますが、スコープを出ると、書き込みがあった場合は**ファイルが保存[^1]された上でExcelを閉じる[^2]**処理が行われます。

[^1]: Excelアプリケーションスコープのオプションで「自動保存」が既定でONとなっている効果です。
[^2]: Excelアプリケーションスコープの前に「プロセスを開始」でExcelファイルをExcelで開いておくと、スコープ終了後も閉じません。詳しくは[UiPathフォーラム](https://forum.uipath.com/t/excel-application-scope/25868)を参照してください。

**アプリケーションスコープがネスト (入れ子) している場合は?**

アプリケーションスコープはその仕組み上ネストさせることができます。その場合は、その中に入っているアクティビティは、自分から見てすぐ外側にあるアプリケーションスコープを参照します。以下の例では、<font color="DarkGreen"><b>緑色</b></font>で囲われた「セルを読み込む」アクティビティは、`D:\File2.xlsx`ではなく`D:\File1.xlsx`に対して実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f51b7fbc-452a-0f2f-9e57-6464e9d2ab2c.png)

>**注: 「セルを読み込む」アクティビティを使う際のハマりポイント**
>「セルを読み込む」アクティビティは、そのままの状態だと読み込むセルの書式によって異なるデータ型と値が返される仕様になっています。また、値はセルに表示されている形式ではなく内部で保持されている値が返されます。
>(例: セル上で"5"と表示されていても5.5が格納されている可能性があり、その場合、変数を作成したときの既定の変数型であるString型で結果の出力を受けてしまうとたとえば以下のようなエラーとなります。<font color="Red">"セルを読み込み: StringConverter を System.Double から変換できません。"</font>)
>**解決策:** オプションの「表示形式を保持」をONにして、常にフォーマットした文字列型で値を返すようにするか、結果を受ける変数の変数型をGenericValue型にします。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f95fd851-9f45-52b9-9e43-fcbbfb51e7fd.png)


### Automation Anywhereの場合 - "セッション" を介してアクセス
一方、Automation AnywhereはUiPathとは異なるアプローチをとっています。Automation Anywhere A2019でExcelを使ってExcelファイルを操作するには、**「Excelの高度な操作」**パッケージでExcelファイルを**「開く」**アクションを行い、アクションの詳細で得られる**「セッション」**を指定することで、どのファイルに対して操作を行うかを決定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/84e5b970-ba45-abf5-6944-5f1da8371f1a.png)
Excelファイルを開いた後は、用意されているアクションを使ってさまざまな操作が可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/42581fcf-9d15-2e04-1853-13bcd37485af.png)
**「1つのセルを取得」**アクションでは、アクティブなセル、もしくはアドレスで指定されたセルから値を取得します。Automation Anywhereでは、<font color="Red">**各アクションごとにどのセッションの操作をするかをアクションの詳細で指定できます**</font>。格納先は**文字列型の変数**になるので、その場で文字列型変数を作成して格納します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f2a067e2-42f9-47c9-860e-6b09c4900310.png)

**セッションを終了させる場合の処理**
**「閉じる」**アクションを実行すると、指定したセッションを閉じることができます。これを実行すると、関連付けられているExcelファイルが閉じます。ちなみに、最後まで「閉じる」を実行しない場合は、Excelファイルは開いたままロボットが終了します。

# 複数のExcelを開く場合の処理
それでは実際に行われる作業をUiPathとAutomation Anywhereの両方でロボットで作ってみたいと思います。いま、**File1.xlsx**には勤怠管理の情報が入っており、このファイルから**File2.xlsx**に一部の概要情報を転記する作業を行います。

それぞれのファイルの内容は以下の通りです。

**File1.xlsx**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/109ada10-78a3-05b2-aab4-9e7f23d37f92.png)

**File2.xlsx**(最初は空白。以下は転記後)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f4380155-64bf-6710-0bc5-900a2eaeea7a.png)


### UiPathの場合

UiPathで一番最初の説明のところで作ったExcelアプリケーションスコープと2つのセルからの読み取りのシーケンスを簡略的に以下のように書いてみます(^^♪

つまり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f0998614-03b6-2f3f-423c-3028f571c7e4.png)
を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/d2bba159-7008-f936-6939-c16a0930e503.png)
とします。読み取った名前はString型変数`Name1`に、日数はString型変数`Value1`に格納します。次に書き込みですが、以下のようにシーケンスを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/e90ed9df-8772-3098-902f-603136254925.png)
読み取りと書き込みをつなげて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/62b3800b-fae0-3aa0-b0d2-3a80c30d4139.png)
というシーケンスができました。これを1行目と2行目に適用して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/25b42050-91e8-a2ab-35c7-b48b83b7336c.png)
とします。アプリケーションスコープはネストさせても意味がないので、別々のブロックにしてつなげるほうがわかりやすいです。もう一つの書き方としては以下のようなことも想定はできますが。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/2f61683a-7e3a-32fa-f5c3-340a32d6b380.png)
これで実行してみると、File1.xlsxとFile2.xlsxがExcelで交互で開く形になります。転記するという目的は達成できるのですが、Excelの起動/終了がちらついてうっとうしいので、それぞれのファイルを開いたままにしたいと思います。

これを実施するには、あらかじめ「プロセスを開始」アクティビティを使って、File1.xlsx、File2.xlsxを起動します。**ファイル名**にはExcel.exeのパス、**引数**にはExcelファイルのパスを渡します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/07c274e8-367a-2eca-7a1e-d25031ce3beb.png)


最終的なシーケンスは以下の通りです。(展開して表示すると1画面に収まらないので、たたみました)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/7009df68-8884-d3a0-677b-29cd0a8c4aae.png)
概要だとこんな感じに見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/54da29c0-f53b-c7f2-f74f-941b4df407c3.png)
フルで広げるとこんな感じです！( 一一)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/92bceb9b-4cfc-cd92-4432-ff7b83ad5b73.png)
これを実行すると、File1.xlsx、File2.xlsxが開かれ、少し待機してから名前と時間が2回転記されることが確認できます。File1.xlsx、File2.xlsxは転記中も転記後も開かれたままとなります。

### Automation Anywhere の場合
Automation Anywhereの場合はFile1.xlsxとFile2.xlsxでセッションを別々に作成して開いたままにしておき、各アクションでどちらのセッションを使うのか指定できるため、より単純なつくりになります。単純に必要なアクションを繰り返せば完了です。「1つのセルを取得」アクションで読み取った名前は文字型変数`$Name1$`に、日数は文字型変数`$Value1$`に格納します。そして次に来る「セルを設定」アクションでそれぞれの変数の値でセルに書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/a4786c2d-c77f-d000-8d22-d1ddbb3622b0.png)
これを実行すると、File1.xlsx、File2.xlsxが開かれ、名前と時間が2回転記されることが確認できます。File1.xlsx、File2.xlsxは転記中も転記後も開かれたままとなります。
>注: Automation Anywhereの場合、変更されたExcelファイルは自動保存されません。明示的に「ブックを保存」アクションを実行する必要があります。

# まとめ
UiPathの場合もAutomation Anywhereの場合も、Excelファイルから別のExcelファイルへの転記を行うことができます。Excelファイルへのアクセスの使い分けは「アプリケーションスコープ」と「セッション」というように考え方が異なっており、Excelを複数開いたまま作業させる場合は「アプリケーションスコープ」の場合は少し工夫が必要です～(^_-)-☆

あと、UiPathの場合はセルから読み込む場合のお作法に気を付けましょう。これを知らないとハマる場合があります。