Automation Anywhere A2019で、より良いアクションリストを作るための7つの方法

通常のプログラミング言語では、よく[**「より良いコード (リーダブルコード)」**を書くための実践テクニック](https://qiita.com/AKB428/items/20e81ccc8d9998b5535d)が議論されることがあります。これはAutomation Anywhere においてより良いアクションリストを作成する場合にも同様のことを考える必要があります。「より良いアクションリスト」を作成するためには、いくつかの要素を実施する必要があります。この記事ではその要素をご紹介します。また、利用するバージョンはA2019を前提としていますが、ほとんどの事は他のバージョンでも成り立ちます。

# 1. アクションリストの行数を制限する
Botを作っていると、よく聞くのは「**いつの間にかアクションの数がすごく増えてしまった**」ということです。数百、数千、時にはなんと五千ものアクションがひとつのBotに詰め込まれていることもあるようです。

ただ、想像してみてください。通常の業務プロセスを回すのに五千のステップを経ないといけないとすると、そもそも業務整理が必要になりませんか? 業務のステップを減らしたり、いくつかに分割して分担したり、ということをしたうえで取り組まないと、ミスや非効率化の原因となってしまいます。

マイBotのTaskBot編集画面でも、フローだと普通に表示すると5~6アクションくらい、「ズームの自動調整」で大きさを調整したり、リストビューで表示させても20アクションくらいが1画面で表示できる限界となります。後述する「ステップ」などの折りたたみできる仕組みをうまく活用したとしても、この4~5倍の長さである**100アクション未満**に全体のアクションを抑えるのがお勧めです。(Automation Anywhere社ではv11で[500アクション未満を推奨](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/bot-design-guidelines.html?_LANG=jpjp)しています。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/f5d204cc-6ee4-bec4-f31e-811caa8a7fc6.png)

アクションの数が多くなりそうな場合は、その部分をTaskBotとして外出しにすることを考えるか、繰り返し使う共通部品であるならば、アクションパッケージとして作りこむ検討をすることをお勧めします。

**TaskBotとして切り出す例**

元のアクションリスト:
(本筋と関係がないログ出力のアクションがある <font color="Orange">(オレンジの部分)</font>)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/86049758-b46a-5ff1-832a-e616b9d2c053.png)


切り出し後:
(ログ出力は別のTaskBotに切り出し、外部呼出しをするようにした。<font color="Orange">(オレンジの部分)</font>呼び出しをすると呼び出し先のTaskBotが完了するまで待機します)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/072c21c5-37b0-afc1-2ca1-048abe72642c.png)


# 2.『[Don't repeat yourself](https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself)』原則に従う
「繰り返さない (Don't repeat yourself, DRY)」原則はITシステム構築やプログラミングの世界でよく言われる原則です。コーディングにおいては、コードの中に、同じパターンのコードを繰り返し登場させないようにしようということです。

いままでとちょっとだけ違う、かなり似たことをやりたいということはよくあります。その場合にソースコードやアクションリストをコピー&ペーストで複製すると、すぐに完成できるのですが、後から他の人が見たときにわかりづらくなり、変更や管理をやっていくうえで足かせになりがちになります。

DRY原則を実現するのに気を付けるポイントは、細かいことを言うと様々なレベルのものがありかならずしも簡単ではないのですが、Automation Anywhere A2019におけるアクションリストの構築で、とても簡単にすぐできることを3つ取り出すと以下になります。

* ハードコードの定数を使って繰り返し処理をしているところは、**変数**を導入することで単純化できる場合があります。
* **ループ**処理を使うとアクションリストの長さを短くできる場合があります。変数を2つ使うと複雑な処理もループで処理できる場合があります。ただし、無理にループ処理をしてアクションリストがかえって複雑になる場合もあるので注意です。
* 誰もが良く使う処理は切り出してパブリックワークスペースで共有し、**中央で集中管理**するのがお勧めです。たとえばシステムへのサインイン、ログの出力、メールの送信処理、外部サービスとの通信、などです。

単純な例:5期後の複利計算
最初のアクションリスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/ab0a358e-befb-0d37-5818-d4b23f147944.png)

ループの導入でだいぶスッキリしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/cd17a399-cce0-5237-c943-2df5c2a09ca9.png)

さらに、利率と期を変数にしてサブTaskBotに外出しでさらにスッキリします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/ba6f4661-2672-4d8f-d0df-e100a53610f5.png)

>注: 親TaskBotからサブTaskBotに変数を引き継ぐ方法の詳細は『[Automation Anywhere A2019で親BotからサブBotに変数の値を受け渡す (v11との比較)](https://qiita.com/RPAbot/items/d4c04cca3cefebbe93f3)』を参照してください。

# 3.『[循環的複雑度 (Cyclomatic complexity)](https://ja.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E7%9A%84%E8%A4%87%E9%9B%91%E5%BA%A6)』を最小化する
「循環的複雑度」とは、ざっくり言うとBotの中のループや条件分岐 (if/else) の数の合計です。テストケースを作る際に独立した経路として実施が必要となるため、これが大きくなるとテストが複雑になり間違いが起こりやすくなるのは想像できますね。

ひとつのBotの中でループや条件分岐がいくつくらいまでなら許されるかというのは一概にはなかなか言えませんが、プログラマーでない人が複雑なループや分岐を作ると容易にミスにつながります。だいたい**5つ以下**くらいに抑えておくのが良いと思われます。

それ以上になりそうな場合は、条件分岐やループがより単純化して減らせないかを検討したり、Botを細かく分けたり、ループや条件分岐のネストが深いところは別のTaskBotで切り出すなどの工夫が必要となります。

例:
切り出し前:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/f68a6411-2f4f-57b6-c0af-da758c7e25f1.png)

切り出し後:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/d97fa0db-b337-1254-8541-ed9f78895ec8.png)

ひとつのBotには**「単一責務の原則」**つまり一つの事だけをやらせるようにすることがお勧めです。複数のことが実施されている場合は、Botを分けられないかどうか検討してみてください。また、Bot同士の**依存関係をなくす**、つまりあるBotを修正すると、連鎖的に他のBotも修正が必要にならないようにしましょう。また、サブBot数は多すぎても管理が難しくなってしまうので、目安として**30未満**に抑えられるようにしましょう。


# 4. ステップ/コメントをうまく使う
「ステップ」を使うとアクションリストの折りたたみを行うことができ、同時にコメントも入れることができますので、ちょっと長めの操作をまとめるときに使うと便利です。

たとえば以下のリストが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/cf9caaf2-eb6e-2a93-c875-af5058aab3fe.png)
こんな風に折りたためます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/500c1f10-72c5-8fef-e6a6-9fb3a194539d.png)

リストビューだけでなく、フロービューでも折りたたまれます。また、ネストも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/8e5ef4ed-55ff-078e-57f4-c586fc952063.png)

「コメント」と合わせて、アクションを取りまとめたり注釈をつけるのにうまく利用してください。

詳しくは記事『[Automation Anywhere A2019の「コメント」と「ステップ」で見やすいフローを作ろう](https://qiita.com/RPAbot/items/519a694ea9de622f679c)』を参照してください。

# 5. 無効化したアクションリストを整理する
アクションの無効化は、Botの作成で試行錯誤しているときは便利ですが、ずっと残しているわけにはいきません。見た目が煩雑になってしまう原因となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/e66ef698-75e6-c3bb-3412-b6b10a316512.png)
無効化したアクションがある場合は、Botを作る過程のどこかで思い切って削除しましょう。少なくとも別の場所に移したりそこだけ切り出して別途個人的に保存しておくなどの整理が必要です。

# 6. 変数やタスクの命名規則を統一する
プロジェクトを通して首尾一貫した規則で記載するように心がけましょう。特に複数人数でBotを作成していく場合は、記法をあらかじめ統一してガイドラインを作成しておくことがお勧めです。

[命名規則](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/naming-development-.html?_LANG=jpjp)としては、以下のようなことを守りましょう。

* **変数名:** [キャメル記法](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9)が推奨されます。("fileName" など)
* **タスク名:** [パスカル記法](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9)が推奨されます。そして「動詞/目的語」形式の記述方式にしておくとわかりやすいです。("ExportSettingFiles" など)
* 1文字の変数名は避けましょう。なんの変数だかわかりにくくなってしまうので。
* アンダースコアは使用しない。
* 変数名に数字は入れないようにしましょう。
* プレフィックスを付ける記法 ([システムハンガリアン記法](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E8%A8%98%E6%B3%95))は避けましょう。("szFileName" など) ハンガリアン記法はC/C++全盛の時代の古い記法で、現在においてはあまり推奨されていません。

推奨される (🟢)、されない (❌)記述法を表にまとめてみました。

|項目|🟢|❌|
|:--|:--|:--|
|変数名|fileName |vFileName, szFileName, s, i, s_file, ERROR_FILE_NOT_FOUND, file|
|タスク名|ExportToText|txtExport, taskbot_export|

# 7. 設定/初期値は外に出す
Botの中で使う変数の初期値や定数については、「変数に代入」アクションで値を変数に代入したり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/d1992599-f344-d557-49e7-89c09dce3e41.png)
「変数マネージャー」の中で初期値を入れてしまうのが楽です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/d9afc1fb-3842-ffd5-093d-7dc04997ba77.png)
ただし、これらだといずれもどこでどういった値が代入されるのかがわかりにくくなってしまったり、値を変更したいときに汎用性がない作りになってしまいます。

そのため、このような**「設定」「初期値」については、極力外部ファイルに書き出して保存し、Botの最初で読み込む**というつくりにすることをお勧めします。

外部に書き出す方法はいくつかあります。「Excelファイル」や「CSV/Text」ファイルは、初心者でもなじみのあるアクションを使って実装できるので、最初のうちはこれらを使うとよいでしょう。

上級者になってくると、「XML」や「JSON」の形式を好むかもしれません。これらは構造化されたテキストファイルであり、俯瞰してみたときにわかりやすい形式となっています。

ただ、どの種類のファイルに書き出すかは好みですので、ルールさえ全体で決まっていれば問題ないかと思います。


# 参考情報 (v11)

Automation Anywhere Enterprise v11向けには、Automation Anywhere社から以下にアクションリストを構築する上でのガイドラインが記載されているので、参考になります。

* [Bot設計のガイドラインおよび標準](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/bot-design-guidelines.html?_LANG=jpjp)
    * [テスト](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/testing-development.html?_LANG=jpjp)
    * [コメント作成](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/commenting-deploy.html?_LANG=jpjp)
    * [命名規則](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/naming-development-.html?_LANG=jpjp)
    * [ログ記録](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/logging-development.html?_LANG=jpjp)
    * [VBスクリプト](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/vb-script-development.html?_LANG=jpjp)
    * [構成ファイル](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-architecture-implementation/config-files-development.html?_LANG=jpjp)