ビジネスプロセスフロー（BPF）の各ステージにかかった時間をログ化

モデル駆動型アプリのビジネスプロセスフロー（以下BPF）は、フォームへのデータ入力をステップ化することができ、注文プロセスや申請プロセスなどプロセス化された文脈の中でデータを入れてほしいという場合に利用されます。

ステップ（以下ステージ）はフォーム上で矢羽根のように表現され、あるステージをクリックすると、そのステージを達成するのに必要なデータ入力項目が表示されます（↓イメージ）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/046fe0ae-0771-44f6-8e59-5981d6ba8ccd.png)

さらに注目すべきは、このBPFでは全体のプロセスにかかっている時間と、現在のステージにかかっている時間を自動的に記録してくれており、プロセスの効率性を見直すための分析材料として活用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/eb0eb386-45f2-4b3f-bbac-88215a3c795a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/efa3e3be-0e7c-413c-8496-64164a23baa3.png)

しかし、通常の状態だとすでに完了した各ステージにかかった時間の履歴までは記録されておらず、分析材料としてはあと一歩という感想は否めないと思っています。
そこで今回はその履歴を記録する方法をご紹介します。

# ①BPFを用意する
まずは BPF を用意しましょう。ここでは具体的な作成方法の説明は割愛しますが、今回の例では以下のような簡単な注文管理用の BPF を作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/9a4ba0af-66ea-456e-b452-0c9a4907c2bc.png)

BPFを作成すると、同じ名前でDataverseテーブルも自動的に作成されますが、このテーブルに各BPFトランザクションの情報が保管されていることがわかります。
・アクティブステージ＝各BPFトランザクションの現在のステージ
※次のステージに進むとアクティブステージも更新される。
・期間=各BPFトランザクションが完了したときに計算される全体のプロセスにかかった所要時間

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/36d74124-93c5-4752-9d21-7b4028591282.png)

# ②履歴を格納するテーブルを作成する
上記のDataverseテーブルのアクティブステージが変更されるタイミングで別テーブルにログを残すようにするような、履歴保管テーブルを作成します。
テーブルとしては以下のような列があれば良いかと思います。

・項番（オートナンバー）
・ステージ（一行テキスト）
・From（日付と時刻）
・To（日付と時刻）
・経過時間（計算式：DateDiff(From,To,TimeUnit.Minutes)）
・BPFの対象になっているテーブル（検索）※今回の例で言うと、「注文テーブル」
・BPFテーブル（検索）※今回の例で言うと、「注文BPF」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/b71d9dc3-864a-431e-959a-b2d714670751.png)

# ③ ②で作成したテーブルに履歴を残す Power Automate フローを作成する
全体の構成としてはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/e507973d-8b3b-4670-bd39-cfbba8cdca57.png)

上から順に説明していきます。
① 注文BPFテーブルが作成または更新された場合をトリガーにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/f943d265-92fd-46e1-895d-0c6020455521.png)
② トリガーの情報だけでは取れない情報があるので改めて行を取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/e99f1fe9-3f17-4442-ba30-440f6d2de4bb.png)
③ 条件分岐（completedonが空か否か。ステージの最後で「終了」したときはcompletedonに記録されます（この場合、falseになります））
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/e90fe119-487d-4f14-b470-0eb9e044b797.png)
```
coalesce(outputs('ID_で行を取得する')?['body/completedon'],1)
```
↓↓以下、真のとき↓↓
④ データ操作-作成 でステージ名を特定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/e612e223-eb1c-4ed5-9a38-bad9f304582b.png)
```
outputs('ID_で行を取得する')?['body/_activestageid_value@OData.Community.Display.V1.FormattedValue']
```
⑤ スイッチ で④で作成したデータ本文を入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/5761d118-c2fa-48d5-8cd0-6d6a7a253b20.png)
⑥ スイッチ1（最初のステージに関して）
履歴を格納するテーブルに対して、以下のように設定。
検索列は、論理名に複数形のsをつけるので注意。table → tables
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/339fe0b0-47cd-4c3d-8d5b-949be35ce3f9.png)
⑦ スイッチ2以降（2番目以降のステージに関して）
一つ前のステージのレコードを更新する必要があるので（具体的にはTo列）、まずは一覧でレコードを取得する。フィルターをこのような形で書くことで一意にすることが可能。
```
列の論理名 eq '前ステージ名' and BPFの対象になっているテーブル(_はじまり,_valueおわり) eq ②で取得した列データ
```
行数は1で良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/5f16cccb-cf79-4ec1-ade9-b4e9c7729a37.png)
そして取得したレコードを更新する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/57d70c18-c9da-4152-9c60-53989df2b5b9.png)
```
utcNow()
```
そして最後に、⑥と同じ要領で現ステージのレコードを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/74506c14-00b6-4102-80e7-da8c38585a3d.png)

↑↑以上、真のとき↑↑
↓↓以下、偽のとき↓↓
⑦と同じ要領で一つ前のステージのレコードを更新する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/bb451214-49c6-4d77-be86-bc54a0e79c7e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/f7f12600-b222-4aee-b819-c32d5a4f811c.png)
↑↑以上、偽のとき↑↑

# テストしてみる
実際にBPFを進めてみてログが残るかを確認してみましょう。
以下のようにグリッド内に関連テーブルとして表示させることもできますし、ダッシュボードにして各BPFの平均経過時間を取るなんてことも考えられるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/528ed8d9-15d9-48c7-8b01-3f61ad1f46e0.png)



以上ご参考になれば幸いです。