概要
仮想テーブルを利用したモデル駆動型アプリで、データの保存時にユーザーのメールアドレスや名前をフィールドに保存し、作成者や修正者の情報を管理する方法です。
これが正解というやり方ではないので、参考程度の方法です。
前置き
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で記述できる日も近いかもしれません。