【WinActor】交通費精算ロボットを作ってみる

UiPathに慣れれば慣れるほど扱いづらいWinActorですが、サンプルロボットを実装してみることにします。
今回はUiPathの記事でおなじみの「交通費精算」ロボットを作ります。
今回はルートのキャプチャも保存するようにします。

##処理概要
① 以下フォーマットの交通費精算書に記載された「日付」「利用区間」を抽出します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/dfe6af21-8f04-0873-502f-5c3109eefbfe.png)

② IEでYahoo!路線検索を開きます。以下入力後、検索ボタンをクリック。
・①で抽出した「利用区間」を入力
・日時は①で抽出した「日付」の9:00を入力（日中の移動を想定しているため）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/1b26326a-c35a-9419-edeb-c0ac4c12b91e.png)

③ 検索結果画面で、ルート1の料金を取得し、交通費精算書に転記します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/3fe1d6a5-4db2-7970-4f78-84099d32aeba.png)

④ ルート1のルート詳細までスクロールし、キャプチャを取ります。
以降、交通費精算書に記載されている行数分ループします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/b24b944a-e3d4-a7d2-ad1c-43e807428ec8.png)

⑤ ④で取得したキャプチャは、デスクトップの「交通費精算キャプチャ」フォルダにまとめて配置します。
ファイル名は「区間（From）‐区間（To）_（①で取得した日付）.png」とします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/dce023ee-8238-a41f-9f6c-1b9996219a75.png)

##フローチャート構成
メインとサブルーチンに分けています。

- メインのフローを見れば大体このロボットが何をしたいのかが分かるようにしたい
- 各サブルーチンで予期しないエラーが発生したとしても、メイン側で例外をキャッチしてエラーハンドリングできるようにしたい

のが理由です。
UiPathのReFrameworkの考え方をベースにしてみました。WinActorの公式フレームワークがあれば教えてくださいw

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/befd08c6-cb98-8082-2838-aa121136e0fe.png)

以降、メインのフローに沿って解説します。

###初期処理　その１
まず最初に実行されるのが**「初期処理」**です。
IEが起動されている場合は、一度終了してから再起動させます。
稀にIE終了処理で例外が発生するため、その時は少し待機してから改めてIE終了⇒起動しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/c802e85d-b0fe-7426-2658-2568eee1565e.png)

ライブラリの中に**「IE操作（全て閉じる）」**というノードがあるのですが、たまにIEが終了しません。
やっていることはほぼ変わらないのですが、**「コマンド実行」**ノードを使って以下コマンドを叩くことでプロセスを強制終了しています。

```
/c taskkill /im iexplore.exe /F
```

ブラウザ調整グループの中の「IE操作（読込完了待ち）」は、IEに表示されたWebページが完全にロードされるまで待つアクションです。
Webページ中の項目を操作するとき、ロードが完了していない項目を操作しようとしてエラーになってしまうことを避けたいので、このノードを入れています。（ここでは特に画面操作はしていないので無くてもOKです）


###初期処理　その２
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/d7e855bc-d085-6ad1-db91-c4ef5596ddec.png)

スクリーンショットを保存するフォルダの初期化を行います。
路線詳細キャプチャを保存する流れは以下のとおりです。

1. 路線詳細をスクリーンショットで保存。デフォルトの保存先（C:\Users\XXXXXXXX\Pictures\Screenshots）に「スクリーンショット（項番）.png」というファイル名で保存される。
2. 1.で保存されたファイルを**「出発駅-到着駅_乗車日.png」**にリネームする。
3. 交通費精算書に記載された全行分のルートに対して料金記載が終わったら、デフォルトの保存先に置かれたキャプチャファイルを、デスクトップの**「交通費精算キャプチャ」**フォルダに移動します。

上記処理を行う前に、以下初期処理をしておきます。

- デフォルトの保存先に保存されているキャプチャファイルを全削除
- デスクトップに「交通費精算キャプチャ」フォルダが存在する場合は削除

全削除するのに使用したノードは**「ファイル削除」**ですが、ソースを一部修正しています。
指定したフォルダ配下の全ファイルを削除するようにしていますが、削除ファイルのパターンを**"*.png"**として、画像ファイルに限定しても良いと思います。

````
delete_folder = !削除フォルダ名!

Set objFS = CreateObject("Scripting.FileSystemObject")

'ファイルを削除する
objFS.DeleteFile delete_folder & "\*.*"

```

「交通費精算キャプチャ」フォルダの削除は、「コマンド実行」ノードで以下コマンドを実行することによって実現しています。

```
/c rd /s /q directory （交通費精算キャプチャフォルダパス）
```

上記コマンドを変数：フォルダ削除用コマンドに設定し、「コマンド実行」ノードの項目：オプションに設定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/686e7462-db6e-7627-a6be-e70df53e8d2b.png)


最後に、Excelプロセスを終了しておきます。
これも「コマンド実行」ノードで実現しています。

```
/c taskkill /im excel.exe /F
```

###交通費ファイル読込
「ファイル選択ボックス（Java）」ノードを使います。
このノードの返却値は選択したファイルのフルパスなので、後の処理で行うExcel操作系のノードで使えます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/ce62dcf0-dc93-426d-d378-d7411596d755.png)

###交通費検索　その１
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/f7eea59b-50cd-e1dd-2d01-e11947a1b3b3.png)

ループを継続する条件は以下のとおりです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/5aa45e44-1d80-5ec4-7e2a-af197523652c.png)
ループ内で、交通費精算書の各ルートを順次読み取りループしていくわけですが、読み取った行にルート情報が記載されているかどうかは「日付」列の記載有無をもって判断します。
ただし、初回のループでは、まだ交通費精算書からルート情報を読み取っておらず、変数：日付には値が設定されていないため、このままではループせずに終わってしまいます。
そのため、変数：行カウントが2（初期値）の場合は変数：日付が空でもループ内の処理を実行するように、OR条件を追加します。
初回ループで行カウントが+1された後は、変数：日付は何らかの日付が設定されている状態が続き、日付が空白の行を読み込んだ段階で、ループを抜けます。

出発駅/到着駅は、読み込んだルート情報から取得して路線検索画面に入力します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/4991a72d-9600-1d98-1ba2-fc6537ab9b04.png)

####日時入力
路線検索画面の「日時」の項目の入力ですが、「年」「月」「日」をルート情報の「日付」を用いて設定します。
ただ、変数：日付には「2018/10/31」といった形で設定されているため、

- 年・月・日に分解
- それぞれ「年」「月」「日」をくっつける

という処理を施し、

・変数：日付（年）⇒2018年
・変数：日付（月）⇒10月
・変数：日付（日）⇒31日

と設定します。

出発時刻は9:00で固定なので、

- 出発時刻（時）⇒9時
- 出発時刻（分）⇒00分

と設定します。

###交通費検索　その２
検索ボタンクリック後、検索結果画面に遷移します。
「ウインドウ識別クリア」ノードを使って、キャッシュから前画面のウインドウ情報を削除し、「IE操作（読込完了待ち）」ノードで画面が完全にロードされるのを待ちます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/cbbd57ca-16a3-4905-00c9-3835527c71fe.png)

####画面キャプチャ取得
次に、ルート1のルート詳細の画面キャプチャを取ります。
まず、ルート1のルート詳細が表示されている位置までスクロールバーを移動します。
その後、スクリーンショットを取り、キャプチャファイル名を「区間（From）‐区間（To）_（日付）.png」に変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/24de4da6-50b2-752b-cb6b-80b22ed74bec.png)

スクロールの実行は、エミュレーションで下図のように記録します。
↓キー押下を連続実行してしまうとうまくスクロールされない場合があるので、300ミリ秒ずつ間をおいて連打するようにしています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/69f68cab-24e0-ed6b-9f02-512c205dbdbe.png)

スクリーンショットの取得は、エミュレーションで下図のように記録します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/acce9cce-ecbb-4fd2-77c3-bb3f34790231.png)

その後、1000ミリ秒待機しています。
これはキャプチャファイルが保存されていないうちに、ロボットがファイルを探しにいってしまい空振りするのを防ぐためです。

####キャプチャファイル名変更
まず、「キャプチャファイル検索」ノードで、スクリーンショットのデフォルト保存先で「スクリーンショット\**.png」のパターンに合致するファイルを検索します。
初期処理でデフォルト保存先のファイルは全削除しており、ループ内でキャプチャファイル名を都度リネームするため、デフォルト保存先における「スクリーンショット**.png」ファイルは１つしかないはず。そのため、意図していないファイルをリネームすることはない想定です。

ちなみに、このノードの設定タブにインデックス番号を設定する箇所がありますが、これはおそらく複数ファイルが該当した場合に何番目のファイルのパスを取得するかを指定するためのパラメータかと思われます。
どのような順番でファイルにインデックス番号が割り振られるのかは分かりません。誰か知ってる人いたら教えてくださいｗ

そして、ルート情報から取得した日付のフォーマットをyyyy/mm/dd⇒yyyymmdd形式に修正し、キャプチャファイル名に使用できる形にします。（「/」はファイル名に使用できない）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/ffc60303-f3fb-ce18-0f1f-852330ff632f.png)

最後に、ファイル名変更コマンドとして以下のコマンドを作成し、「コマンド実行」ノードで実行することで、キャプチャファイル名を変更します。

```
/c ren C:\Users\XXXXXXXX\Pictures\Screenshots\スクリーンショット（項番）.png (出発駅-到着駅_日付（yyyymmdd）.png）
```

####交通費精算書にルート1の料金を記載
ループ内の処理に話を戻します。
続いて、検索結果画面のルート1の料金を取得し、文字列「円」を削除してから転記します。
行インデックス設定グループ内で、変数：行インデックスに変数：行カウント-1の値を設定します。
これを「料金をExcelに記載」ノードのセル（行）項目の設定値として使います。行カウントがそのまま使えないところに注意。
そして、路線検索画面に戻ります。
以降、交通費精算書のルート件数分ループします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/abf0cb78-1cb5-d4bf-1969-316d77a01bb6.png)

ループを抜けた後、交通費精算書を上書き保存して閉じます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/d5847415-3eb5-ff70-20b9-67acbbb92133.png)

####キャプチャファイル移動
ルート件数分のキャプチャファイルを、デスクトップの「交通費精算キャプチャ」フォルダに移動します。
ファイル移動には、ライブラリの「ファイル移動」ノードを使います。移動対象ファイルの名前指定にワイルドカードが使えるため、パターンマッチした複数ファイルをまとめて移動させることが可能です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/1eb04012-6ba6-b1ca-00dc-82d943c1ba1d.png)

###アプリケーション終了
交通費精算書の料金記入、ルート詳細のキャプチャファイル保存も完了しました。
あとはIE、Excelを終了させてロボット処理終了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186221/f7080d78-3afb-1d14-80d5-aaace4ef8586.png)