PowerAppsの仮想テーブルで作成者や修正者の情報を管理する

概要

仮想テーブルを利用したモデル駆動型アプリで、データの保存時にユーザーのメールアドレスや名前をフィールドに保存し、作成者や修正者の情報を管理する方法です。
これが正解というやり方ではないので、参考程度の方法です。

前置き

Dataverseでそれ必要?

通常のカスタムテーブルでは全く必要ありません。
Dataverseは標準でレコードの作成者、修正者の情報を自動で管理してくれます。
ただし、仮想テーブルの場合はドキュメントにある以下の問題が発生します。

既定では、仮想テーブルには名前と ID 列のみが含まれます。 [状態] または [作成日/修正日] などの、他のシステム管理列はサポートされません。

Microsoft Dataverse を使用した仮想テーブルの作成および編集 - Power Apps | Microsoft Docs

仮想テーブルでの問題点

上記の通り、仮想テーブルでは、修正日/修正者などのシステム管理列が作成されません。

仮想テーブルは、オンプレ環境をデータベースにしながらフロントアプリをローコードで作成できる素晴らしい仕組みなのですが、誰がいつ変更したかといった、証跡情報を自動管理してくれないと、実用的ではありませんよね。

SharePointリストの場合は既定で「更新者」などの列が存在しますが、こちらでも問題が発生します。
利用者がモデル駆動型アプリからデータの編集を行う場合、SharePoint側の「更新者」は、実際の利用者ではなく、全て管理者の情報になってしまいます。
これは、仮想テーブルへの接続が利用者本人の接続情報ではなく、仮想コネクタを作成したユーザー=管理者の接続情報を利用するためです。

そのうち何等かの対応策がでてきそうですが、待ちきれませんでした。

実現方法

アプローチ

モデル駆動型アプリのフォームイベントを使ってJavaScriptのコードでEmailやユーザー名をセットします。
ビジネスルールなど他の仕組みだとユーザー情報を取得できないため、現状これしかない?と思います。

必要になるコード

今回は以下のコードを利用します。
jsファイルにしてローカルに保存します。

// ユーザー名をフィールドにセットします
function SetUserName(exeContext,fieldId){

    var formContext = exeContext.getFormContext();
    var userName = Xrm.Page.context.getUserName();

    formContext.getAttribute(fieldId).setValue(userName);
}

//ユーザーのEmailを指定したフィールドにセットします。
function SetUserEmail(exeContext,fieldId){
 
    var formContext = exeContext.getFormContext();  
    
    // ユーザーIDの取得
    var userid = String(Xrm.Page.context.getUserId()).replace(/{|}/g, "");

    // systemuserテーブルからuseridで検索
    Xrm.WebApi.online.retrieveRecord("systemuser", userid , "?$select=internalemailaddress").then(
        function success(result) {
            var userEmail = result["internalemailaddress"];
            // set a user email
            formContext.getAttribute(fieldId).setValue(userEmail);
        },
        function(error) {
            Xrm.Utility.alertDialog(error.message);
        }
    );         
}


解説

JavaScriptの登録

テーブルのメインフォームの編集画面で、フォームライブラリからスクリプトを登録します。

初回は、ライブラリの追加画面で新しいWebリソースを選択してローカルからJavaScriptファイルをアップロードします。

先ほど保存したjsファイルを追加して、最終的にフォームライブラリに登録されればOKです。

フォームのOnSaveイベントでスクリプトを実行

先ほどのスクリプトが実行されるよう、フォームのイベント登録を行います。

イベントの登録はツリービューから行います。
ツリートップの情報を選択し、右側サイドパネルのイベントから、保存時のイベントハンドラーを追加します。

以下のように設定します。
ライブラリ:先ほど追加したもの。
関数:SetUserEmail (JavaScript関数名)
実行コンテキストを~:オン (これ忘れると動きません)
関数に渡されるパラメータ:"cr8dc_editoremail" (セットする列の理論名)

同様に、SetUserNameについても設定し、ユーザー名が入るようにします。

動作確認

Dataverse側でデータを編集して保存すると、EditorEmailとEditorNameに値がセットされる。

SQL Server側にも反映されていることを確認。

更新日時情報はデータベース側のトリガーでやってもいいような気がしますが、同じくJavaScriptで実現可能です。

あとがき

他にもっといい方法があるかもしれません。

ユーザー情報は、本来はSharePointやDataverseのユーザーマスターに対してのLookUpで格納した方が良いと思います。
今後のアップデートで、このようなことをしなくても登録者、修正者の情報が自動管理されるようになってくれるといいですね。

最近のアップデートで計算列をPowerFxで表現できるようになったり、サーバーサイドで実行できる環境が整ってきておりますので、Dataverseやモデル駆動型アプリのビジネスロジックについてもPowerFxで記述できる日も近いかもしれません。