SharePoint と Power Automate で稟議書を実装してみたメモ 4

2020/05/07

経緯

前回の SharePoint と Power Automate で稟議書を実装してみたメモ 3 では、Power Automate の前半部分、利用する変数の紹介を行いました

今回はメインの処理部分に入りますが、やってることは大したことないのにアクションの量が多いので、分けて説明します

今回は下図の赤枠の部分を説明します

上部の赤枠の説明

作成されたアイテムに設定された承認ルートを取得

申請ワークフローリストに登録した時、申請経路を設定します
その申請経路に設定された承認ルートを取得する処理です

この処理を SharePoint コネクタの「項目の取得」 で行います

ID にセットする値は、承認経路 Id を使います (承認経路は参照列になっているので ID が取得できます)

承認ルートの階層分繰り返す

承認経路にあるグループを、順次承認処理を通していきます

これをコントロールコネクタの「Do until」を使って、次のように表します

ループの条件は「承認ルートカウンターが 20 以上、または、終了フラグが true になったら抜ける」としています

それを条件式で表すと次のようになります

@or(greater(variables('承認ルートカウンター'), 20), equals(variables('終了フラグ'), true))

ループ回数はデフォルトのままで 60 、タイムアウトは 7 日間としています

続きまして、「承認ルートの階層分繰り返す」の中に、繰り返し処理を設定していきます

動的列名を設定


現在の承認経路が参照する列名やプロパティ名を動的に組み立てています

組み立てには、式 concat を使って文字列を結合しています

なぜ全てを変数として作らないのか?というのは、先に説明したワークフローのアクション数の制限の通りです

各プロパティの説明は次の通りです

  • PathTitle は承認経路マスタの経路の内部列名
    concat('Path', variables('承認ルートカウンター'))
  • PathApprovalsTitle は承認経路マスタの経路必要承認数の内部列名
    concat('Path', variables('承認ルートカウンター'),'Approvals')
  • PathAcceptTitle は申請ワークフローの経路承認数の内部列名
    concat('Path', variables('承認ルートカウンター'),'Accept')
  • PathRejectTitle は申請ワークフローの経路否認数の内部列名
    concat('Path', variables('承認ルートカウンター'),'Reject')
  • PathCommentTitle は申請ワークフローの経路コメントの内部列名
    concat('Path', variables('承認ルートカウンター'),'Comment')
  • Route はステータス用オブジェクトのプロパティ名
    concat('Route', variables('承認ルートカウンター'))

各リストに設定された内部列名は SharePoint と Power Automate でワークフローを実装してみたメモ 1 で記載した通りになっています

内部的には次のようになっています

{
  "PathTitle": "@{concat('Path', variables('承認ルートカウンター'))}",
  "PathApprovalsTitle": "@{concat('Path', variables('承認ルートカウンター'),'Approvals')}",
  "PathAcceptTitle": "@{concat('Path', variables('承認ルートカウンター'),'Accept')}",
  "PathRejectTitle": "@{concat('Path', variables('承認ルートカウンター'),'Reject')}",
  "PathCommentTitle": "@{concat('Path', variables('承認ルートカウンター'),'Comment')}",
  "Route": "@{concat('Route', variables('承認ルートカウンター'))}"
}

ログの出力とステータスの更新

ログの出力とステータスの更新 (申請ワークフローに登録されたアイテムの更新時) は次の手順で行います

  1. アイテムの最新状態を取得
  2. 最新状態を加味した値を変数に設定
  3. アイテムの更新

まずは、申請ワークフローで、今回登録されたアイテムの最新状態を取得します
SharePoint コネクタの「項目の取得」を使います

続いて、ログ変数に出力するログを設定します

日時を利用する時には、日本時間にしたいので、次のように式 convertFromUtc を使って、日本時間に変換しています

convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')

値の中はこのようになっており、今回のログに過去のログを付けるようにしています

[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] 承認ルート @{variables('承認ルートカウンター')} 回目の処理が開始されました
@{body('登録されたアイテムの最新状態を取得')?['Log']}

最後にログとステータスをアイテムに書き込みます
項目直撃で更新したいので、SharePoint コネクタの「SharePoint に HTTP 要求を送信します」を使います

ポイントは次の通り

  • 方法を POST にします
  • URI を下記のようにします(※ リストの内部名ではなく、表示名を使います)
    _api/web/lists/getByTitle('申請ワークフロー')/Items(@{variables('アイテムID')})
  • ヘッダーを次のようにします
    {
    "IF-MATCH": "*",
    "X-HTTP-Method": "MERGE",
    "Accept": "application/json;odata=verbose",
    "Content-Type": "application/json;odata=verbose"
    }

    ヘッダーは、右にある T というアイコンをクリックすると JSON を直接入力できるようになるので、上記コードをコピペで OK です

  • ボディで更新するリストの内部名(Apply)の最後に ListItem とつけて、メタデータにセットします
    {
    '__metadata': {'type': 'SP.Data.ApplyListItem'},
    'Log': '@{variables('ログ')}',
    'Status': '@{variables('ステータス用オブジェクト')[variables('動的列名用オブジェクト')['Route']]}'
    }

    ステータスは少しややこしいことになっていますが、1 周目だと、 variables('動的列名用オブジェクト')['Route']「Route1」という文字列になり、 variables('ステータス用オブジェクト')['Route1']「第1承認経路で確認中です」という文字列になります

次の承認ルートがあるか確認


承認ルートを 1 -> 2 -> 3 … と続けていき、設定がされていない時にループを抜けるようにします

左辺は下記のようになっています

@body('作成されたアイテムに設定された承認ルートの取得')?[variables('動的列名用オブジェクト')['PathTitle']]?['Id']

1 週目だと variables('動的列名用オブジェクト')['PathTitle'] は「Path1」という文字列になり、body('作成されたアイテムに設定された承認ルートの取得')?['Path1'] で参照列の値「グループ1」となり、グループ1?['Id'] で参照列の ID を取得しています

その ID が null かどうかを判定しています

左の赤枠の説明

次の承認ルートがない時

承認ルートがない時は、次の手順を設定しました

  1. アイテムの最新状態を取得
  2. 最新状態を加味した値を変数に設定
  3. アイテムの更新
  4. 終了フラグを true にすることでループを抜ける

アイテムの最新状態を取得は、前回と同じです

最新状態を加味した値を変数に設定もほぼ同じです

値はこの様になっています

[@{convertFromUtc(utcNow(), 'Tokyo Standard Time', 'yyyy-MM-dd HH:mm:ss')}] 承認ルートないためループ処理を終了します
@{body('承認ルートが無い時、登録されたアイテムの最新状態を取得')?['Log']}

アイテムの更新もほぼ同じで、ボディの値だけが違います

ボディはこの様になっています

{
    '__metadata': {'type': 'SP.Data.ApplyListItem'},
    'Log': '@{variables('ログ')}',
    'Status': '@{variables('ステータス用オブジェクト')['Completed']}'
}

ステータスを variables('ステータス用オブジェクト')['Completed'] としています

現在のところ、Power Automate ではループ処理を抜ける break がないので、最後に終了フラグを true にして、次のループで抜けるようにしています

次回予告

ループに入りログを残す部分と、承認ルートがなくなり正常終了する部分の説明を行いました
次回は、承認処理部分の説明となります