【🔥UiPath vs Automation Anywhere🔥】RPAはどこまでUI変更に耐えられるか試してみた (C++ダイアログ編)

よくできたRPAソフトウェアではユーザーインターフェイスの構造解析ライブラリーを活用して、多少環境が変わってもUI要素を追従して正しい操作をしてくれます。今回はどれくらい環境を変えるところまでRPAソフトウェアが耐えられるのか、**ストレスチェック**をしてみたいと思います。

ユーザーインターフェイスの種類もいろいろあるので、今回は標準的なもの、かつ昔からあるアプリケーションで実装されている「**Windows デスクトップアプリケーション (C++)**」タイプで試します。

使用するRPAソフトウェアは、**UiPath**と**Automation Anywhere**の2つです。これらはいずれも[UI Automationと呼ばれるUI構造解析ライブラリーに対応しており、レコーディングにも対応している](https://qiita.com/Okura_/items/95a78c46454ae0dac036)ため、RPAソフトウェアの中では優秀な部類に入ります。この2つにどこまでできるかやらせてみましょう！

(これらはいずれもCommunity Editionが無料で取得できます。)

**利用した環境**

* [UiPath Community Edition (2019.8.0)](https://www.uipath.com/ja/developers/community-edition-download)
* [Automation Anywhere Community Edition 11.0.0.0 (Build19922720)](https://www.automationanywhere.com/jp/lp/rpa-editions-comparison)
* Microsoft Visual Studio Community 2017 (15.9.16)
* Microsoft Windows 10 Version 1809

# Visual Studio のWindows デスクトップアプリケーションテンプレートを改造

まずは、操作をさせる元となるデスクトップアプリケーションを作ります。Microsoft Visual Studio Community 2017を開いて、新しいプロジェクトから「Windowsデスクトップアプリケーション (Visual C++)」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/3dd262ac-8881-8494-b2e1-176e2ea1e0fa.png)

このアプリケーションテンプレートでは、「ファイル」「ヘルプ」というメインメニューがあるメインウィンドウと、バージョン情報ダイアログボックスの2画面から成っています。今回はこのうちのバージョン情報ダイアログボックスを少しいじって、いろいろな標準コントロールを足してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/3b48c53d-128b-49b3-74c5-ea36a3b1108c.png)

その結果がこちら。Check Box、Edit Control、Combo Box (Dropdown)、Radio Button、Slider Control、Date Time Picker、Month Calendar Control、IP Address Controlを追加で配置しました。これをビルドして**WindowsProject1.exe**(通常版)を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/a7750054-a665-86a3-13c4-eaef586d08ec.png)

実行して「ヘルプ」-「バージョン情報」を開くと、以下のような画面になります。(バージョン情報ダイアログボックスは、親ウィンドウの左上近くから描画されています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/a1d7bd68-c6cb-1179-e79b-afe4b9c7bbc9.png)

### ストレスチェックバージョンの作成
RPAソフトウェアにストレスを与えるための変型版を作成してみます。ひとつは、ダイアログボックスのリソースファイルで「位置」の "Center" をTrueにして、ダイアログボックスの表示位置を画面中央になるようにしたバージョンです。これをビルドして**WindowsProject1.exe**(ウィンドウ位置変更版)を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f1dc3799-4e12-1caf-08a0-3e5bf3d5dddc.png)

もうひとつ、ダイアログボックスの中のコントロールの場所を大きく変えてしまうものも作ってみましょう。こんな風にレイアウトを変えてみました。タブオーダーは変更していません。これをビルドして**WindowsProject1.exe**(レイアウト変更版)を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/11334d13-c69a-1848-2aa6-727d16d78b05.png)

### 操作の手本
メインウィンドウが立ち上がった状態で、マウスで「ヘルプ」-「バージョン情報」を開いて、Check1をマウスでON、その下のEdit Boxをクリックして "ABCDEFG" と入力、その下のCombox Boxをクリックして "ABC" と入力、その下のRadio2をクリックしてON、さらにその下のスライダーを一番左から2回に分けて図の位置までドラッグしてくる、右側に移って、Month Calendar Controlで "27" をクリックして選択、その下のIP Address Controlの4つの数字入力部分をそれぞれクリックして "33" と入力して終了、という動きです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/f19d7916-9c11-9571-7c3e-c4be76f2fab5.png)


# 1. Automation Anywhere スマートレコーダーで記録して再生してみる
まずAutomation Anywhere Community Editionで操作を記録して再生してみましょう。Automation Anywhereの3つのレコーダーのうち、デスクトップアプリケーションを記録するための最も技術の高いしくみは「スマートレコーダー[^1]」なので、この方法で記録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/9d9618d1-a1a0-9c7a-6da0-16fd06e22730.png)

この方法では、画面右下に以下のツールバーが出ている間、最初に指定したウィンドウ上で操作を行うと、それが記録されていきます。動作としては記録中はマウス操作が多少慣性がついて重く感じるのと、時々マウスの場所が飛ぶのが気になりますが、慣れれば対応できるでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/1c34b3c3-d064-ceb5-4d5c-38b0758a1af7.png)

記録を終了すると、以下のようなアクションリストが自動的に生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/cc19f63f-13e9-00d9-b6ed-49949a713d89.png)

「Visualize」タブでは、要所要所で記録されたユーザーインターフェイスのスクリーンキャプチャが記録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/d0e77ab2-27b6-77cb-13e1-b66e5e66e3fd.png)



### 1-1. 通常の再生
生成されたアクションリストを再生してみると、以下の結果を得ました。Slider Controlのつまみの位置がずれている以外はOKです。Sliderはマウス操作のみなので誤差が出やすいですが、これは該当するコマンドを編集することで修正できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/493a8c01-e2a9-6b5b-c1ae-9186b5083257.png)


### 1-2. 画面の拡大率を変えるとどうなるか?
Windows 10の設定で、「テキスト、アプリ、その他の項目のサイズを変更する」で100%から125%に変更してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/a02fa5a9-ea60-290c-708f-f0be33604c63.png)

この状態での実行結果はこちら。100%の時と同様、きちんと実行されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/fb4ad9d9-fbae-b2a3-40e9-8867ae50f0c4.png)

100%と125%の画面を重ね合わせてみると、各コントロールの位置はだいぶ違うことがわかります。このような違いがあっても、UI構造解析を行っていれば止まることなく操作を再現させることが可能なことがわかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/ded1457c-7c0f-56f4-079d-b63f70c87235.png)



### 1-3. ダイアログボックスの場所を変えるとどうなるか?
バージョン情報ダイアログボックスが画面中央に表示されるように変更したアプリケーション**WindowsProject1.exe**(ウィンドウ位置変更版)を実行します。結果はこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/a1d7bd68-c6cb-1179-e79b-afe4b9c7bbc9.png)

実行時に、一瞬バージョン情報ダイアログボックスが画面中央に表示されるのですが、その後Automation Anywhereが強制的にダイアログボックスの表示位置を元に戻しているようです。これも、正しい結果が得られました。

### 1-4. ダイアログボックスのレイアウトを変えるとどうなるか?
**WindowsProject1.exe**(レイアウト変更版)を実行して操作してみると、以下のようにCheckbox1がONになった次のテキストボックスが見つけられずにエラーが表示されます。各コマンドをコメントアウトしてひとつずつ調べていくと、CheckboxやRadio Buttonなど、テキストが入っているコントロールや、Slider Control、Monthly Calendar Controlは場所が変わっても正しく認識するものの、Edit Box、Combo Box、IP Address Controlは難しいようです。これは、後の[考察](#考察)セクションで詳しく見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/c454bb4e-00ea-10f9-1357-fbebf2591874.png)

ちなみに、以下のような、もっとレイアウトを大きく変更したバージョンでも結果は同様でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/def58e4b-b7ca-535d-fed9-4620ed7650eb.png)



[^1]: Automation Anywhereで持っているAIによる高度なフィールド認識機能 (AISense)はこの方法には含まれません。

# 2. UiPath デスクトップレコーディングで記録して再生してみる
次にUiPath Community Editionで操作を記録して再生してみましょう。UiPathの5つのレコーダーのうち、デスクトップアプリケーションを記録するための最も技術の高いしくみは「デスクトップレコーディング」なので、この方法で記録します。
![recording1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/e67b4dae-9ad3-eca8-7217-f96a02756f68.png)

以下のツールバーで「レコーディング」モードにして進めます。
![recording2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/d2cc44ce-bc3c-cd07-5fae-68e315ef1502.png)

「レコーディング」モードの間は、拡大鏡があらわれてマウスカーソル周辺を拡大してくれるのと、マウスカーソルが選択しているコントロールに枠線が付けられるので分かりやすい。
![recording3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/72f910b9-ed80-e36f-533c-9c3cc6183263.png)


記録を終了すると、以下のような巨大なシーケンスが出来上がります。
![flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/56cc2b3b-a6eb-853a-2d80-5857d71957f9.png)


### 2-1. 通常の再生
生成されたシーケンスを再生してみると、以下の結果を得ました。Edit BoxとCombo Boxのテキスト入力領域がうまく識別できず、いずれもEdit Boxにテキストが入力されてしまうのと、IP Address Controlも後ろの3つの数字が入らずに、すべて最初の場所に入力されてしまっています。前者は該当するアクションを編集することで修正できましたが、後者は簡単には修正できなかったので主題とは関係ないためそのままにしました。(マウスでの操作をやめてタブキーで移動するように改変すれば入力はできるはず) 前者の改変の仕方は後の[考察](#考察)セッションで見てみることにします。
![result01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/c40a3169-e97b-1000-f229-ccc6671868e2.png)


### 2-2. 画面の拡大率を変えるとどうなるか?
Windows 10の設定で、「テキスト、アプリ、その他の項目のサイズを変更する」で100%から125%に変更した状態での実行結果は、100%の時と同様、きちんと実行されています。
![result02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/92fea345-38bf-3db4-fc59-a3cb09222190.png)


### 2-3. ダイアログボックスの場所を変えるとどうなるか?
バージョン情報ダイアログボックスが画面中央に表示されるように変更したアプリケーション**WindowsProject1.exe**(ウィンドウ位置変更版)を実行します。これはうまく再生されます。Automation Anywhereの場合は、むりやりウィンドウの位置を記録時の場所に移動していましたが、UiPathでは移動することなく正常に終了します。

### 2-4. ダイアログボックスのレイアウトを変えるとどうなるか?
**WindowsProject1.exe**(レイアウト変更版)を実行して操作してみると、UiPathの場合は、今までと同様に正しく認識して正常終了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/eb100be8-6266-d009-b4f5-300b5059f666.png)

もっと大きくレイアウトを変更したバージョンでも、同様に正しく認識して正常終了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/7ced6da5-85ed-d738-e29a-4bfc29066b45.png)


# 考察

### Automation Anywhere
レイアウトを変更したときにうまく動かなかったのは、以下の緑色にしたObject Cloningコマンドです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/95c73d1b-87db-bf6e-00cd-123b9bf3d8b1.png)

これらを編集すると、Object Cloningコマンドが何を識別としてコントロールを認識しているかがわかります。たとえば、Check Boxでは、NameがCheck1と等しいか、TypeがCheckboxか、とPathの値で見分けています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/c21ccd52-c334-4f6a-2c4c-9d62267f6914.png)

右上の「Select Search Criteria」ボタンをクリックしてみると、他のさまざまな候補も表示されます。双眼鏡マークが表示されているものが、識別子としてONになっているものです。これをON/OFFしてみることで、より良い条件を探し出すことが可能です。使えるものとしては、コントロールに入力されている値 (Value)、クラス名 (Class)、タブオーダー (Index)、座標とサイズ (left, Top, Height, Width)などです。識別子としてONするものを追加しておくと、認識がうまくいかなかったときは追加で条件に加えてくれるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/dea4110b-5d05-37f6-d588-481b4b6e7e20.png)

IP Address ControlはDescriptionに固有の値が入っていたので、これを条件に加えることで、場所が変わっても正しく認識するようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/aba9debf-4b4a-ef3f-72a6-2e5cf2149300.png)

Edit BoxはClassの追加でうまく認識するようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/b9c3ea0d-12ad-74a2-f1ae-81953d6d8be8.png)

Combo Boxはというと、Classの追加で、Edit Boxと同じフィールドに値が上書きするようになりました。Index (タブオーダー)は今回はすべてのコントロールで同じにしてしまったのですが、これが違う値であればこれが固有の識別子として使えたかもしれません。

Automation Anywhereでは、Object Cloningコマンドの各プロパティを見て、**固有のテキストが含まれているプロパティを識別子として追加したり、Class名を追加しておく**と、今後バージョンアップでUI変更があった時の追従の確率があがるかもしれません。


### UiPath
うまく認識ができなかったコントロールのアクティビティを選択してプロパティを見ると、「入力」-「ターゲット」-「セレクター」で、どの属性でコントロールを識別しているかがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/6e973b03-300b-5419-6e69-cb5ee6551399.png)

今回の場合は、Edit BoxとCombo Boxで、ctrlidが同じ1001と認識されてしまっていたので、Combo Boxのほうを1002 (このIDはあてずっぽうできっと隣であろうということでずらして試してみるとうまくいった！)に書き換えれば正しく認識するようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/3ef6d683-9bd4-af65-3c5c-9fe8d7c6909c.png)


 
# まとめ
UiPathもAutomation Anywhereも、UI構造解析ライブラリー (UIAutomation)を利用しているため、ウィンドウやコントロールの場所や大きさがかわっても、基本的にはきちんと認識します。ただしそれぞれまだ不完全な場所があるので、癖を把握しながら手探りでよい設定方法を見出す必要があります。そのような作業の一助になれば幸いです！

次回は.NET WPF、UWP、Webアプリなどでも同様のことを試してみたいと思います。