PADで初めてのRPA、Excel表のデータをレガシーデスクトップアプリに登録する

#概要
- Excelにリスト化されたデータを1行ずつ手作業で社内クソシステムに入力していく作業の自動化を目指して学習します。
- 製造業や中小企業にありがちで、社内システムがcsvなどの一括インポートに対応していない場合に有効です。
- 無料化されたPAD(Power Automate Desktop)と練習用のレガシーデスクトップアプリを使って取り組んでみます。

#処理するデータの例とフロー
①Excelでは以下のような表が用意されています。
・PADでは以下のExcelを起動しデータを読み込む操作を行います。
・勉強用として、フローの最後にアプリの画面をキャプチャして別シートに貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/5277406c-faf6-2d44-610a-42eaedd148fe.png)

②練習として下記のようなデスクトップアプリに1行ずつデータを転記して登録していきます。
・学習用に一般公開されているアプリを使用します。(後述)
・新規ボタン→データ入力→保存ボタン→新規ボタン・・という流れで入力していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/8f234b46-41e9-5b4e-7223-c0f5783d613b.png)

#準備
##PADのインストール等
こちらの先人達の記事を参考にPADをインストールします。

https://qiita.com/maekawawawa/items/9edbd4c33b780fb2b8ec

https://qiita.com/maekawawawa/items/b9c7b866f5ee31d2acd3

##レガシーデスクトップアプリ
MicrosoftによりPADの学習用に公開されたアプリ「Contoso Invoicing」をMicrosoftの吉田さんが日本語化して頂いたものをインストールして使用します。
今回は、アプリ内の「請求管理」画面への入力を行います。

[Power Automate Desktop でRPAを試すための日本語版サンプルレガシーアプリを公開](https://memo.tyoshida.me/power-platform/power-automate/power-automate-desktop-sample-legacy-app-japanese-available/)

##Excelファイル
元データとなるExcelファイルを準備します。

まずは以下のシートを作成します。
・請求リスト
・スクリーンショット

請求リストには以下のようなデータを入力します。
見やすいようテーブル形式にしておきます。
テーブルの位置は必ずセルA1からデータが入るようにします。(後で正しくセル範囲が取得できるように)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/5277406c-faf6-2d44-610a-42eaedd148fe.png)

#フローの作成
先人たちの記事を参考にフローを作成します。
https://qiita.com/maekawawawa/items/ba6a4e8e8c72bd549e0a

Mainフローの全体は以下のような流れです。
フローの流れを理解しやすくするためと、ループで処理を再利用するため、サブフローも使います。
要点を絞って説明してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/6853396c-2c39-7b49-0a7a-bf1907e89003.png)


##①Excel表を読み込んでExcelData変数にデータテーブルを格納する
この処理はサブフローにまとめます。変数自体はグローバルなのでサブフローに移動しても問題ありません。

- まずは、サブフロー→＋ボタンから、「Read_ExcelData」の名前でサブフローを作成します。
すると、サブフローの作成画面に移動します。
- 左のアクションペインから「Excelの起動アクション」を探して追加し、準備したExcelファイルを指定して開きます。 既定でExcelInstanceという名前の変数にインスタンスが格納されます。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/a69401fb-cf37-bd95-57ec-b9a72b5bdb09.png)
- 次に「アクティブなExcelシートの設定」アクションを追加し、インスタンス：%ExcelInstance%、次とともにシートをアクティブ化：名前、ワークシート名：「請求リスト」と設定します
- 「Excelワークシートから最初の空の列や行の取得」アクションを追加し、インスタンス：%ExcelInstance%、生成された変数：2つ共Onにし、既定の変数名　%FirstFreeColumn%、%FirstFreeRow%に値が入るように設定します。<br>
　これはセルA1を基準として最初に現れる空白の行・列のインデックスを取得します。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/0e296d60-2717-d246-630b-0a78a02acb90.png)
- 次に、変数に値を設定する練習として、「変数の設定」アクションを追加し、設定(変数名)：LatestRow、宛先(設定する値)：%FirstFreeRow -1%とします。<br>
　　これは後でExcel表のサイズを指定するため、空白行番号の1つ前の行番号を最新行として変数に格納します。
　　変数-1等の演算は%%の中に書き込む必要があるようです。
- 同様に、「変数の設定」アクションを追加し、設定(変数名)：LatestColumn、宛先(設定する値)：%FirstFreeColumn -1%とします。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/fbec9734-fd89-310a-7b69-48db6f09c08b.png)
- 最後にExcel表から範囲指定でデータを読み込みます。「Excelワークシートから読み取り」アクションを追加します。
    - 先頭列は2(行番列は不要なため)、先頭行は1、他も画像の通り設定します。
    - ExcelData変数にデータテーブル型のデータテーブルが格納されます。
    - 範囲の最初の行に列名が含まれていますは、Onにします。すると列名でアクセスできるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/8accec08-13fa-8127-98f6-dcd228fb00f5.png)
- 完成したサブフロー全体
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/eec61b82-4eee-ea5f-7768-3cc5df0b6a39.png)

- ここで、Mainフローに戻り、「サブフローの実行」アクションを追加し作成したサブフローを実行してみます。　実行後画面右側のフロー変数からExcelDataをダブルクリックすると、DataTable型の変数にテーブルデータが格納されていることが確認できます。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ed3045ff-f732-b0e3-f460-226dbcf70f09.png)



##②デスクトップアプリに1行ずつデータを登録する
ここではデスクトップレコーダーを使って簡単にフローを作成します。
自分が操作した内容を記録しRPAのアクションに変換してくれますので、そのアクションを少し編集する形でフローを作成します。

- まずは、サブフロー→＋ボタンから、「Insert_DataRow」の名前でサブフローを作成します。
- 次に、「請求デモアプリ」を起動し、PADに戻って「デスクトップレコーダー」を起動します。
- 「記録の開始」をクリックし、請求デモアプリを操作していきます。
- まず請求管理画面を開く必要があるため「請求管理」をクリック。するとデスクトップレコーダー画面にフローが記録されます。
- 次に、左上の「新規作成ボタン」をクリック
- 請求日、請求先等のフィールドをマウスでクリックし、順番に適当なデータを入力していきます。後で入力内容をExcelデータに置き換えます。
- 最後に左上の「保存」ボタンをクリックします。 記録は以上です。
- デスクトップレコーダー画面で「終了」をクリックすると、PADの画面に戻り記録されたアクションが追加されています。
- 余計なキー入力やクリック等を行ってしまった場合も記録されてしまいますので削除しておきます。
- 一行目の「請求管理」をクリックするアクションは最初だけで良いため、Mainフローにドラッグアンドドロップして移動します。<br>
- 適当にデータを入力しましたが、後ほどExcelDataを入力できるように値を書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/dcb55ede-3095-06b4-bf73-beabe56b53f3.png)

##③一旦Mainフローに戻って全体フローを設定

- 1行目は「サブフローの実行」アクションを追加し①で作成した「Read_ExcelData」を実行します。
- 2行目には②から移動した「請求管理」をクリックするアクションを設定します。
- 次に「ForEach」アクションを追加し、以下のように設定します。 
- これはDataTable型のExcelData変数の各行に対してループ処理を行います。　現在の行はDataRow型のCurrentItem変数に格納されます。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ca6323b5-6516-5682-5692-66990f182851.png)
- ForEachの中には「サブフローの実行」アクションを追加し②の「Insert_DataRow」を実行するように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/f4d32f9e-c2e4-7813-86f4-9a36e9d98bdc.png)


##④再びInsert_DataRowサブフローに戻ってExcelの行データを割り付ける
- 各フィールドにはExcelの行データが設定されるように編集します。
- 先程のForEachにより、CurrentItem変数に行データが格納されています。
- この行データはDataRow型で、DataRow['列名']で特定の列の値にアクセス可能です。 なので各列の「ウィンドウ内のテキストフィールドに入力する」アクションを以下のような要領で書き換えていきます。<br>
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/c11af656-921a-2ec3-45bd-6a960104ea39.png)
- 修正するとサブフロー全体は以下のようになります。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/1b013fea-e725-7841-e4a1-dddf24b0ac4a.png)


##⑤Mainフローの続きを作成
ここまででExcelデータをデスクトップアプリに転記することはできました。
後は練習として処理後のスクリーンショットを撮影してExcelに貼り付けるといったフローを作成してみます。

- 「スクリーンショットを取得」アクションを追加し、「フォアグラウンドウィンドウ」、「クリップボード」に設定します。 これでデスクトップアプリの画面をキャプチャします。<br>
~~- Excelの画面をアクティブにしたいので、再びデスクトップレコーダーを起動してExcel画面の外枠が赤くなる状態でクリックし、「ウィンドウのUI要素をクリックする」アクションを記録させます。~~<br>
- Excelの画面をアクティブにしたいので、「ウィンドウにフォーカスする」アクションを追加し、ウィンドウの検索モード：UI要素ごと、ウィンドウ：▽で「新しいUI要素の追加」をクリック。UI要素の追加ウィンドウが表示されるため、Ctrlキーを押しながらExcelウィンドウの外枠が赤くなる状態でクリックします。
    - Ctrl+左矢印は誤訳のようです。
    - UI要素のクリックよりウィンドウにフォーカスが安定しました。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/d7a317b8-542b-c307-d743-5e8a2ec99aa8.png)

- 次に「Excelのワークシートをアクティブ化」のアクションを追加し、シート名「スクリーンショット」を設定しシートを切り替えます。
- 「Excelワークシート内のセルをアクティブ化」アクションを追加し、「絶対位置で指定したセル」、「行1」、「列1」を設定し、セルA1が選択されるようにします。
- 次にExcelで「貼り付けボタン」をクリックしたいのですが、ここでUI要素ではなく、画像でUIをクリックする方法を試してみたいと思います。
    - アプリがWindowsFormやWPF等で作成されている場合はデスクトップレコーダーにてUI要素を上手く取得できますが、駄目な場合に備えて画像によって要素の位置を取得できる機能があります。これを試してみます。
- 「マウスを画像に移動します」アクションを追加し、画面のキャプチャからExcelの「貼り付け」アイコンをキャプチャしてみます。マウスの移動後にクリックを送信：On、左クリック、失敗タイムアウト：5に設定します。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/e7f787b1-5401-5954-6c7f-3732dfba4b62.png)<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/c4ee79b7-7190-fa8c-7cf5-a93ca813200f.png)
- これでExcelのスクリーンショットシートにアプリの画面が貼り付けられれば成功です。
- 最後に「メッセージ表示」アクションでデータ入力が完了したことをポップアップ表示しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/c293827f-3075-4d13-194c-1d8c93a108c4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/e95bc643-c4d8-df68-af08-d809419e327e.png)

#その他
今回デスクトップアプリは事前に起動している前提です。
起動したい場合は「アプリケーションの実行」アクションでexeファイルを指定します。※ショートカットではなくインストールフォルダのexe
ウィンドウサイズを大きくする場合は「ウィンドウサイズの変更」アクションを。

日本語がまだ怪しく分かりにくいところもありますが改善に期待しましょう。
クライアント型なのでRPA実行中は他の操作ができませんが、ちょっとした作業なんかは自分のデスクトップ上で実行できた方が便利です。
間違ってサブフローの✕ボタンを押してしまっても、データタブが非表示になるだけでサブフローには残ってます。