SharePoint と Power Automate で稟議書を実装してみたメモ 5
経緯
前回の SharePoint と Power Automate で稟議書を実装してみたメモ 4 では、承認ルートの階層分繰り返す処理に入り、承認ルートがなくなった時に抜ける処理まで説明しました
今回は少し長いですが、承認ルートがあった時に下記の処理を行うところを説明します
- 確認者にメールを送り
- 承認者に承認依頼を送り、承認されたときと否認された情報を登録し
- 承認数が設定を越えていたら、次の承認ルートに進み、越えていなかったら否認として処理する
グループマスタリストから、アイテムを取得
申請経路に設定されたグループの参照先を取得し、登録されている承認者と確認者を取得します
この処理を SharePoint コネクタの「項目の取得」 で行います
ID は下記のようになっています
@{body('作成されたアイテムに設定された承認ルートの取得')?[variables('動的列名用オブジェクト')['PathTitle']]?['Id']}
1 週目だと variables('動的列名用オブジェクト')['PathTitle']
で「Path1」という文字列になり、body('作成されたアイテムに設定された承認ルートの取得')?['Path1']
で参照列の値 「グループ1」 となり、グループ1?['Id']
で参照列の ID を取得しています
つまり、グループマスタのグループ名「グループ1」のアイテムを取得するという処理です
確認者分メールを送る
確認者として登録されたユーザーに確認メールを送ります
繰り返し処理を、コントロールコネクタの「Apply to each」で行います
Apply to each を使うことにより、設定された値(コレクション)の分処理を行いますが、便利なことに、値が空だと処理は行われません
以前の手順から出力を選択は、動的コンテンツから「グループマスタリストから、アイテムを取得」の「確認者」を選びます
続いて、右にある ・・・ をクリックして、設定をクリックします
コンカレンシー制御をオンにして、並列処理の次数を 20 としています
これにより、メール送信を待たずに確認者に登録されたユーザーへどんどんメールを送ることが可能となります
確認メールの送信
次に、Office 365 Outlook コネクタの「メールの送信(V2)」を使って、メールを送信します
- 宛先は「確認者 Email」としています
- 件名、本文、は適当に作成しています
本文例<p>@{triggerBody()?['Author']?['DisplayName']} さんからワークフローが届いています<br> <br> @{triggerBody()?['Title']}<br> <br> <a href="@{triggerBody()?['{Link}']}">申請文はこちら</a> </p>
- 差出人は「登録者 Email」としています
承認者分メールとチャットを送る
続いて、承認者として登録されたユーザーに承認依頼(メール)と通知するためにチャットを送りますが、こちらは、コントロールコネクタの「Apply to each」 を並列分岐として追加します
以前の手順から出力を選択は、動的コンテンツから「グループマスタリストから、アイテムを取得」の「承認者」を選びます
こちらも先程と同様に、右にある ・・・ をクリックして、設定をクリックして、コンカレンシー制御をオンにして、並列処理の次数を 20 としています
この設定を行わないと、順次処理になってしまい、A さんが承認、または、否認をしたら B さんの承認依頼が作成されて、というように一人づつの処理になってしまいます
承認を作成
次に 承認コネクタの「承認を作成」 を使って、承認を作成します
- Assigned to は「承認者 Email」としています
- Title, Details は適当に作成しています
Details 例
## @{triggerBody()?['Author']?['DisplayName']} さんからワークフローが届いています
* @{triggerBody()?['Title']}
依頼のメールは次のように届き、メールで承認や拒否を行うことができます
メッセージをフローボットとしてユーザーに投稿する
承認依頼が届いていることを、チャットでも通知すると親切と思います
Microsoft Teams コネクタの「メッセージをフローボットとしてユーザーに投稿する」 を使います
- Recipient は「承認者 Email」としています
- Message は適当に作成しています
Message 例
* タイトル
@{body('承認を作成')?['title']}
* [承認依頼はこちら](@{body('承認を作成')?['respondLink']})
* [申請文はこちら](@{body('承認を作成')?['itemLink']})
- 詳細オプションを表示して、IsAlert を「はい」にしています
承認を待機する
承認を作成したら、ユーザーのアクションを待つ必要があるので、承認コネクタの「承認を待機」を使います
承認 ID は、「承認を作成」の Approval ID を使います
承認アクション時、登録されたアイテムの最新状態を取得
ユーザーからのアクションがあったとき、登録されたアイテムの最新状態から更新したいので、アイテムを取得します
承認結果を判定
ユーザーのアクションが承認だったかどうかの判定を行います
「承認を待機」の結果が「承認」、または、「Approve」かどうかを判定しています
「または」を使っているのは、言語設定の問題などを考慮したつもりです
また、今回試したフローでは、はいの場合といいえの場合の違いは、承認数に値を加えるかどうかだけですので、次の項目からは並行して説明します
現在の承認数に +1 、現在の否認数に +1
先程「承認アクション時、登録されたアイテムの最新状態を取得」で取得した承認数、または否認数をカウントアップする処理です
変数コネクタの「変数の設定」を使います
「現在の承認数に +1」の時
@{add(int(body('承認アクション時、登録されたアイテムの最新状態を取得')?[variables('動的列名用オブジェクト')['PathAcceptTitle']]),1)}
「現在の否認数に +1」の時
@{add(int(body('承認アクション時、登録されたアイテムの最新状態を取得')?[variables('動的列名用オブジェクト')['PathRejectTitle']]),1)}
動的列名用オブジェクトから、列名を取得している部分ですが、1 周目だと下記の文字列になります
variables('動的列名用オブジェクト')['PathAcceptTitle']
には「Path1Accept」variables('動的列名用オブジェクト')['PathRejectTitle']
には「Path1Reject」
最新状態のアイテム情報から、その列名の値を取得して整数(int)に変換後、式 add を使って 1 足しています
承認ログと承認コメントの生成、否認ログと否認コメントの生成
応答はコレクションになっているため、コントロールコネクタの「Apply to each」 を使って値を取得します
以前の手順から出力を選択に、「承認を待機」の応答を設定します
承認ログの生成、否認ログの生成
だれが承認(or 否認)したというログを残したいので、ログの生成を行います
変数コネクタの「変数の設定」を使います
違いは、利用する動的コンテンツと文言が微妙に違うだけです
「承認ログの生成」の時
[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] @{items('承認ログと承認コメントの生成')?['responder']?['displayName']}さんが承認しました
@{body('承認アクション時、登録されたアイテムの最新状態を取得')?['Log']}
「否認ログの生成」の時
[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] @{items('否認ログと否認コメントの生成')?['responder']?['displayName']}さんが否認しました
@{body('承認アクション時、登録されたアイテムの最新状態を取得')?['Log']}
承認コメントの生成、否認コメントの生成
承認(or 否認)時のコメントを残したいので、コメントの生成を行います
こちらも、変数コネクタの「変数の設定」を使います
「承認コメントの生成」の時
[@{convertFromUtc(body('承認を待機')?['completionDate'], 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] @{items('承認ログと承認コメントの生成')?['responder']?['displayName']}さんが承認しました
@{items('承認ログと承認コメントの生成')?['comments']}
@{body('承認アクション時、登録されたアイテムの最新状態を取得')?[variables('動的列名用オブジェクト')['PathCommentTitle']]}
「否認コメントの生成」の時
[@{convertFromUtc(body('承認を待機')?['completionDate'], 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] @{items('否認ログと否認コメントの生成')?['responder']?['displayName']}さんのコメント
@{items('否認ログと否認コメントの生成')?['comments']}
@{body('承認アクション時、登録されたアイテムの最新状態を取得')?[variables('動的列名用オブジェクト')['PathCommentTitle']]}
現在のコメントを取得している部分で、動的列名用オブジェクトから列名を取得している部分ですが、 1 周目だと下記の文字列になります
variables('動的列名用オブジェクト')['PathCommentTitle']
には「Path1Comment」
承認登録データ、否認登録データ
登録処理はまとめて行うので、登録データを生成しています
「承認登録データ生成」の時
{
"Log": "@{variables('ログ')}",
"CountResult": @{variables('承認数一時保持変数')},
"CountResultTitle": "@{variables('動的列名用オブジェクト')['PathAcceptTitle']}",
"Comment": "@{variables('コメント一時保持変数')}",
"CommentResultTitle": "@{variables('動的列名用オブジェクト')['PathCommentTitle']}"
}
「否認登録データ生成」の時
{
"Log": "@{variables('ログ')}",
"CountResult": @{variables('承認数一時保持変数')},
"CountResultTitle": "@{variables('動的列名用オブジェクト')['PathRejectTitle']}",
"Comment": "@{variables('コメント一時保持変数')}",
"CommentResultTitle": "@{variables('動的列名用オブジェクト')['PathCommentTitle']}"
}
オブジェクトのプロパティを説明すると次のようになります
- Log には、生成されたログ
- CountResult には、カウントアップ後の承認数(or 否認数)
- CountResultTitle には、カウントアップ後の数値を更新する列名
- Comment には、ユーザーが記入したコメント
- CommentResultTitle には、コメントを更新する列名
承認・否認データの更新
更新は今まで同様に、SharePoint コネクタの「SharePoint に HTTP 要求を送信します」を使います
今までとの違いはボディだけですが、周回や条件(承認 or 否認)により、登録する列が違うため、更新する列名も動的に作られているのは今までと違います
ボディの例
{
'__metadata': {'type': 'SP.Data.ApplyListItem'},
'Log': '@{variables('登録用データ')['Log']}',
'@{variables('登録用データ')['CountResultTitle']}': '@{variables('登録用データ')['CountResult']}',
'@{variables('登録用データ')['CommentResultTitle']}': '@{variables('登録用データ')['Comment']}'
}
これで承認者分のメールとチャットを送る部分は終わりです
承認数が設定値以上の時、次の承認経路へ進む
最新の情報を取得
承認ルートに設定されたすべての承認者のアクションが終わった後、承認した人数が、必要承認数を越えているかの判定を行います
まずはその前に、今まで同様、最新のアイテムを取得する必要があります
承認数が設定値以上か
承認数が設定値以上か判定します
左辺は、最新のアイテムから、現在周回の承認数を取得しています
@body('最新の情報を取得')?[variables('動的列名用オブジェクト')['PathAcceptTitle']]
右辺は、承認ルートの設定から、必要承認数を取得しています
@body('作成されたアイテムに設定された承認ルートの取得')?[variables('動的列名用オブジェクト')['PathApprovalsTitle']]
はいの場合
ログを生成して、ログを更新しています
ログに設定している値の例
[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] 承認されたので次の承認経路に移ります
@{body('最新の情報を取得')?['Log']}
更新時のボディの例
{
'__metadata': {'type': 'SP.Data.ApplyListItem'},
'Log': '@{variables('ログ')}'
}
いいえの場合
いいえの場合は、否認とみなしてステータスとログを更新後、終了フラグに true を設定しています
ログに設定している値の例
[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] 承認数が足りないため否認されました
@{body('最新の情報を取得')?['Log']}
更新時のボディの例
{
'__metadata': {'type': 'SP.Data.ApplyListItem'},
'Log': '@{variables('ログ')}',
'Status': '@{variables('ステータス用オブジェクト')['Rejected']}'
}
承認ルートのループカウンターを 1 プラス
「承認ルートの階層分繰り返す」処理の最後に、変数の承認ルートカンターに 1 足します
変数コネクタの「変数の値を増やす」を使います
これで、承認されている時には次のループに移ることができます
次回予告
改めて見直すと直したいところが多数ありますが、気にせず次回は終了処理部分の説明を行います
ディスカッション
コメント一覧
まだ、コメントがありません