PADを使ってみよう ー （上級編）複数のデスクトップフローを共通モジュール化して構成しよう

皆さんこんにちは、マイクロソフトの川端です。
Power Automate for desktop (通称PAD) を使い始める方向けのトレーニングコンテンツを提供しています。
こちらの内容は[中級編]の応用としての上級編です。まだ[中級編]を読まれていない方はそちらをまずご参照されることをお勧めいたします。

[中級編]:https://qiita.com/YutoKa/items/da6913a10c17a470c390

#1.はじめに
###1-1.今回作成するフローの全体像について
PCの現在日時を取得し、特定のファイルに日時付きのファイル名を書き込みに行くというシンプルなフローを題材に、Power Automate for desktopで *共通モジュール 化を行っていく方法と考え方についてご紹介していきます。

*共通モジュール：ユーザーの判断で最小構成とし、入出力データの受け渡しをインターフェースしたうえで、共通的に部品利用可能なデスクトップフローのこと

共通モジュール化をせずに重厚長大な１つのデスクトップフローを構成してしまうことももちろん可能で、エラーなく動作しているケースでは問題が無いでしょう。しかし、複数の共通モジュールとしてのデスクトップフローを定義しておけば（理論的には）複数人で多くのRPAを保守する場合で、保守性が向上し、組織内でのフローの利活用が進みます。複数のデスクトップフロー間でのデータの受け渡しはクラウドフローを経由して構成すると便利です。

詳細な説明とハンズオンに入る前に、動画で今回構成するフローの全体の動きをまず把握していただくと分かりやすいと思います。
以下の動画でまず動作イメージをご覧ください（音声なし）
<iframe width="560" height="315" src="https://www.youtube.com/embed/ZyAa-ItHcRQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

###1-2.デスクトップフローを共通モジュール化する際の考え方
上記動画のフローは下図のようなモジュール１～３で構成されています（モジュール毎、モジュール間のインターフェースの内容については後ほど詳細に記載します）。
これらのモジュール１～３の構成は、１つのデスクトップフローの構成で記述することもできるでしょう。
![module2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/79bf5e33-24ce-d71d-6605-92d87c53be9e.png)

しかし、これらのデスクトップフローを他のクラウドフローと共通して利用する場合、もしくは中長期的にデスクトップフローをメンテナンスし複数人で管理保守することを考えると、可能な限り、デスクトップフローを疎結合、かつ共通部品化して内部的に保持したほうが、一般的に保守性は向上します。

その理由について説明していきます。
以下のようにモジュール１，２，３のどこかで問題（/障害）が実際に起きてしまったと想定しましょう（下図の例ではモジュール３への障害）。
１つのデスクトップフローとして構成していたとしてどういった違いがあるでしょうか？細かく機能単位を分けていれば、複数個あるデスクトップフローの中のうち、どこで障害が起きたのか、モジュールレベルで把握することができ、原因の切り分けと問題個所の修正を素早く行うことができます。
また、下図に示す通り、他のクラウドフロー内で共通モジュールとしての呼び出しがあったとしても、１か所の共通モジュールの修正ですみます。その共通モジュールを参照しているフローでは、一括で修正反映されますので、素早く全体のフローを復旧させることができるでしょう。
![一括共通モジュール修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/edc57a45-03c3-7db3-4686-f1800a6ca2f1.png)

以上、やや理論的な話が続きましたが、以降のハンズオンで、この共通モジュール化の流れを実際に体験してみましょう。

#2. 事前準備（環境設定）
- 最新版のPower Automate for Desktopのダウンロード：https://flow.microsoft.com/ja-jp/desktop/
- インストール、初期セットアップ手順: ロボ研@K2_kzyさんがまとめて頂いている内容が分かりやすいです。
    - https://qiita.com/K2_kzy/items/b8b22edbf56b65248949#2-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%A9%E3%83%BC%E8%B5%B7%E5%8B%95

#3. クラウドフローから呼び出す複数のデスクトップフローを構成しよう
##3-1.デスクトップフロー側の構成の準備をまずは進めよう。
今回構成するデスクトップフロー（モジュール１～３）は３種類あります。
・モジュール１：現在日時の取得
・モジュール２：サブテキスト（モジュール１から加工）の取得で短い日時の文字列へ変更
・モジュール３：ファイル名の変更
これらの３つのモジュールをまずデスクトップ側(Power Automate for desktop)で構成し、その後クラウドフローで
構成を束ねて実行していきます。以下に細かな手順を示しますが、随時お好みでカスタマイズしてみてください。

##3-2.モジュール１の構成(現在日時の取得)
以下の通り、アクションを構成しましょう。
「モジュール１」などとデスクトップフローの名前を付け、適時内容の保存を行いましょう。

1.[メッセージを表示]のアクション

- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：モジュール１を開始します
- メッセージボックスを常に手前に表示する：トグルオン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/c6e6b01d-1931-776c-ca3a-6d310620dee7.png)

2.[現在の日時を取得します]のアクション

- 取得：現在の日時
- タイムゾーン：システムタイムゾーン
- 生成された変数：module1outputと名前を付けておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/0c7c4543-76e9-58c7-7111-183ab9edde45.png)

3.[メッセージを表示]のアクション
- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：%module1output%
- メッセージボックスを常に手前に表示する：トグルオン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/83b4171c-75b1-a8a7-9c6a-4bbd03f182fb.png)

以上で、アクションの構成は完了です。

得られた日時データを入出力変数として定義しましょう。

- 変数の種類：出力
- 変数名：module1output
- 外部名：module1output
- 説明：お好みで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/92a2402f-39fd-6a0e-5bae-68bed290b9f2.png)

##3-3.モジュール２の構成
モジュール２ではモジュール１で得られた値「2021/10/21 10:43:59」といった文字列のスラッシュ（/）と時間に関係するところを省き、
「20211021」といった形で文字列を整形する処理を構成していきます。

「モジュール２」などとデスクトップフローの名前を付け、適時内容の保存を行いましょう。

1.[メッセージを表示]のアクション

- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：%modfule2input%
- メッセージボックスを常に手前に表示する：トグルオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/76c2ce15-816c-bbe3-59ec-8af111f5bb53.png)

2.[サブテキストの取得]のアクション

- 元のテキスト：%module2input%
- 開始インデックス：文字の位置
- 文字の位置： 0
- 長さ：文字数
- 文字数：4
- 生成された変数：subtext1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/d7586fd0-cbb0-7c78-038a-737875e6a368.png)

3.[サブテキストの取得]のアクション

- 元のテキスト：%module2input%
- 開始インデックス：文字の位置
- 文字の位置： 5
- 長さ：文字数
- 文字数：2
- 生成された変数：subtext2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/446a6d9a-109d-c0da-2247-06b18584e75b.png)

4.[サブテキストの取得]のアクション

- 元のテキスト：%module2input%
- 開始インデックス：文字の位置
- 文字の位置： 8
- 長さ：文字数
- 文字数：2
- 生成された変数：subtext3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/1b4006ab-5006-fe4c-9c6f-4796863ee7de.png)

5.[テキストの結合]のアクション

- 結合するリストを指定：%subtext1%%subtext2%%subtext3%
- リスト項目を区切る区切り記号：なし
- 生成された変数：module2output

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/0a9598cc-5907-5605-36bd-fc3b4347e201.png)


6.[メッセージを表示]のアクション

- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：%modfule2output%
- メッセージボックスを常に手前に表示する：トグルオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/02412f8e-d5bd-642a-50fa-392d7d363bd5.png)

以上でモジュール２のアクション構成は完了です。

モジュール１から得られる入力変数を定義していきましょう。
- 変数の種類：入力
- 変数名：module2input
- データの種類：テキスト
- 外部名：module2input
- 説明：お好みで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/b92430d2-0e1e-83ce-8c6c-3dc46d5cdf64.png)

モジュール２で得られたサブテキストを出力する出力変数を定義していきましょう。
- 変数の種類：出力
- 変数名：module2output
- 外部名：module2output
- 説明：お好みで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/7c195cd7-390e-03d4-8a3b-e83a07cdd6f6.png)

以上で、モジュール２の入出力変数の設定は完了です。

##3-4.モジュール３の構成

モジュール３ではモジュール２で得られた値「20211021」といった年日付を用いて、ターゲットのファイル名を変更する処理を構成していきます。
「モジュール３」などとデスクトップフローの名前を付け、適時内容の保存を行いましょう。

1.[メッセージを表示]のアクション

- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：モジュール３を開始します
- メッセージボックスを常に手前に表示する：トグルオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/5c0d382e-5cf3-a32a-84ea-4f0b7b09ca27.png)

2.[メッセージを表示]のアクション

- メッセージボックスのタイトル：PADからのメッセージ
- 表示するメッセージ：%module3input%
- メッセージボックスを常に手前に表示する：トグルオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/064ab7a3-badc-1f59-4610-e0e1d7ff8842.png)

3.[ファイルの名前を変更する]のアクション

- 名前を変更するファイル：お好みで
- 名前の変更の方法：テキストを追加する
- 追加するテキスト：%module3input%
- ファイルが存在する場合：上書き　（お好みで）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/80260cbf-04ff-708a-6369-f1bebc392840.png)

以上でモジュール３のアクション構成は完了です。


モジュール２から得られる入力変数を定義しましょう。
- 変数の種類：入力
- 変数名：module3input
- データの種類：テキスト
- 外部名：module3input
- 説明：お好みで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/5adc6fed-d94a-4e3b-00be-dba7e1ed8840.png)

以上でモジュール３の入出力変数の設定は完了です。


#4. クラウドフローから作成したデスクトップフローを呼び出そう。
下図のようにクラウドフローを構成していきます。クラウドフローの作成時の詳細な操作については、[Power Automateを使ってみよう ー （中級編）クラウドフローの承認フローの内容を受けてPADで請求処理自動実行]も合わせて参照してみてください。

[Power Automateを使ってみよう ー （中級編）クラウドフローの承認フローの内容を受けてPADで請求処理自動実行]:https://qiita.com/YutoKa/items/f160f74f90686ff6ad3d

「共通モジュールのデスクトップフローを呼び出すクラウドフロー」などとクラウドフローに名前を付けるとよいでしょう。

トリガーとしては下図のように「手動でフローをトリガーします」を設定しておきます。今回は動画にある通り手動実行で共通モジュール化の流れを検証していきます。

下の構成のように、モジュール間の関係性を間違えないように作成しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/a9f90784-ba20-8738-7c84-d91c0d33b06c.png)


構成は以上です。実際に動作させてみてください。正しく動作しましたでしょうか？
もし動かない場合には、[1-1.今回作成するフローの全体像について]の動画や設定内容を再度確認してみましょう。

[1-1.今回作成するフローの全体像について]:https://qiita.com/YutoKa/private/28c48a9c6d8b4afebceb#1-1%E4%BB%8A%E5%9B%9E%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E5%85%A8%E4%BD%93%E5%83%8F%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6


#5.まとめ
上級編として、デスクトップフローを最小構成単位でモジュール化し、クラウドフローからのデータの受け渡しのインターフェースを疎結合に構成することで、保守性の高い共通モジュールとしてのデスクトップフローが作成可能になる点について、具体的なクラウドフロー/デスクトップフローのハンズオンを通じて学んでいただきました。共通部品化を効率的に進め、ターゲットアプリケーション、プロセスの変化に頑強なシステムを構成していきましょう。

[公式ドキュメント]:https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/introduction
[Power Automate Community]:https://powerusers.microsoft.com/t5/Microsoft-Power-Automate/ct-p/MPACommunity
[初級編はこちら]:https://qiita.com/YutoKa/items/43dc0ac25e28192a4d78
[中級編]:https://qiita.com/YutoKa/private/da6913a10c17a470c390