月別アーカイブ: 2024年8月

Power Appsで関数の実行時間を計測する

PowerAppsではユーザーの操作に対して処理を行うのであまり待ち時間を長くしたくありません。処理に要する時間が関数の書き方で大きく変わります。この記事では、関数の処理時間を計測する方法を示します。

まず実行時間を計測したい処理を以下のようなUpdateContext関数で挟みます。

//計測開始
UpdateContext({startime : Now()});

ここに計測したい関数を書く

//計測終了
UpdateContext({endtime : Now()});

得られた実行時間を表示するため、ラベルコントロールなどのTextを以下のように設定します。TimeUnitを秒またはミリ秒にしておくと良いです。

"実行時間 " & DateDiff(startime, endtime, TimeUnit.Milliseconds)  & "ms"

個人的には5秒を超える待ち時間は長いと思います。

処理時間を短縮する指針として、コネクションを呼び出す回数を極力減らす、コネクションを呼び出すにしても一括処理することが有効です。コレクションに対してForAll関数で愚直に繰り返し処理をするのをAddColumns関数で書き換えるだけで10分の1以下の時間で処理できることもあります。

PowerAppsから直接Teamsで20人以上に@メンションする投稿を行う

Teamsの投稿にはひとつの投稿でメンションできる宛先に上限があります。具体的な上限は、ユーザー20名、タグ20個です。PowerAppsを使ってTeamsに投稿するときも例外でなく、Teamsコネクタを介して20個以上のメンションを埋め込んだ投稿を行おうとするとエラーが返されます。

PowerAppsで定型的な作業を自動化する際に数の制限は困りものです。たとえばSharePointリストに登録されたユーザー全員に対してメンションする定型投稿を行うようなケースを実行しようとすると困ります。

本稿では、伝えたいメッセージ本文を親投稿としてスレッドを立てた上で、スレッドに返信する形で多数のメンションを追加することを考えます。これにより、通知を送りたい相手にもれなくメンションできます。

以下ではユーザーのコレクションからメールアドレスをThisRecord.Mailで取り出して上でUPNを取得し@mentionトークンを文字列として形成します。@メンショントークンの上限である20件ごとにコレクションを切り分けるため、GroupBy関数を用います。また、実行時間を短縮するため、Office365ユーザーコネクタを介してUPNを取得する処理をAddColumns関数で一括処理しています。

//多数のユーザーが入ったコレクション(配列)allusersからグループ分け用のコレクションallusersandindexを作成する。20行ごとにグループ分けする想定。
Clear(allusersandindex);
ForAll(allusers,
    Collect(allusersandindex,
        {
            numberofgroup: RoundUp( (CountRows(allusersandindex) + 1)/numberDivede,0),
            usermail : ThisRecord.Mail
        }
    )
);

//指定した行数ごとにグループ分けしたうえで、メンションタグを文字列結合した列concatmentiontagを作成する
ClearCollect(allusersmentiontags,AddColumns(GroupBy( AddColumns(allusersandindex, usermensiontag, "<at>" & Office365ユーザー.UserProfileV2( ThisRecord.usermail).userPrincipalName & "</at>" ), numberofgroup, assingedgroup ), concatmentiontag, Concat(assingedgroup,usermensiontag,",")));

コレクションの準備ができたら、これを使ってTeamsに投稿します。PowerAppsからPowerAutomateを介さずに直接Teamsに投稿したりスレッドに返信したりする方法は他のページで紹介しています。

groupIdをDropdownTeamID.Selected.id, channelIdをDropdownChannelID.Selected.idで与えています。

//新規スレッドの投稿内容を作成
UpdateContext(
    {
        newPostMessage:
        {
            recipient:{
                groupId: DropdownTeamID.Selected.id,
                channelId: DropdownChannelID.Selected.id
            },
            messageBody: TextInputMessage.Text
        }
    }
);
//新規スレッドを立てる
With(
    {
        newPostResult: MicrosoftTeams.PostMessageToConversation(
                    "user",
                    "Channel",
                    ParseJSON(JSON(newPostMessage))
                    )
    },
    //新規スレッドを立てるのに成功した場合、返信でメンションをつける
    If(IsBlankOrError(newPostResult), 
        Notify("error on new post", NotificationType.Error),
        ForAll(allusersmentiontags,
            With(
                { replyPostMessage:
                    {
                        recipient:{
                            groupId: DropdownTeamID.Selected.id,
                            channelId: DropdownChannelID.Selected.id
                        },
                        parentMessageId: newPostResult.id,
                        messageBody: "スレッドの親投稿を確認してください" & ThisRecord.concatmentiontag
                    }
                },
                MicrosoftTeams.ReplyWithMessageToConversation(
                        "user",
                        "Channel",
                        ParseJSON(JSON(replyPostMessage))
                    )
                );
        )
    )
)