Dynamics CRM 2011 読み取り専用フィールドと JScript

みなさん、こんにちは。

今日は、最近お問合せが多い内容として、読み取り専用フィールドと
JScript の情報をお届けします。

概要

JScript を利用して、OnLoad、OnSave、Onchange イベント等で
読み取り専用フィールドに値を設定している場合、レコードの新規
作成では設定した値が保存されるが、更新処理では既存の値と
異なる値を設定しても、反映されません。

原因

Microsoft Dynamics CRM ではレコードの保存時に、変更があった
フィールドのみ、データベースに反映するようにしています。それに
より、ネットワークやデータベース処理等のパフォーマンスを節約
することが可能であると同時に、値の変更をトリガーに動作する
処理が無駄に実行されることを防いでいます。

一方、新規レコード作成時には、すべてのフィールドの情報が
新規の値であることが明らかであるため、フォーム上のデータ
すべてがデータベースに保存されます。

IsDirty プロパティ

Microsoft Dynamics CRM は IsDirty プロパティを利用して、値が
更新されているかを確認します。しかし読み取り専用フィールドは
値をスクリプトで変えても、このプロパティが True にならないため
保存対象となりません。

IsDirty プロパティは attributeObj.getIsDirty() 関数で取得できます。

対策

Xrm.Page オブジェクトモデルを利用すれば、以下のコードを利用
して、特定のフィールドを強制保存することが可能です。

attribute.setSubmitMode("always");

サンプルと検証

では早速検証してみましょう。今回は取引先企業のフォームを
利用してみます。

スクリプトの開発と設定

1. 設定 | カスタマイズ | システムのカスタマイズをクリックします。

2. エンティティ | 取引先企業 | フィールドをクリックします。

3. 1 行テキストフィールドを 2 つ作成します。
image

4. Web リソースをクリックし、新規ボタンをクリックします。

5. 名前と表示名を ReadOnlyTest.js として、種類よりスクリプトを選択します。

6. テキストエディターボタンをクリックして、以下のスクリプトを入力します。

function ReadOnlyTest()
{
// フィールドの取得
var readonly1 = Xrm.Page.data.entity.attributes.get("new_readonly1");
var readonly2 = Xrm.Page.data.entity.attributes.get("new_readonly2");

// 値の設定
readonly1.setValue(Date());
readonly2.setValue(Date());

// new_readonly1 のみ強制保存
readonly1.setSubmitMode("always");
}

7. OK ボタンをクリックして、上書き保存ボタンをクリックします。

8. エンティティ | 取引先企業 | フォームよりメインフォームを開きます。

9. フォームのプロパティボタンをクリックします。フォームライブラリに作成した
Web リソースを指定し、OnSave イベントハンドラーに ReadOnlyTest 関数を
指定します。
image

10. OK ボタンをクリックします。

11. フォーム上に作成したフィールドを配置し、いずれも読み取り専用とします。
image

12. 保存して閉じるをクリックします。

13. すべてのカスタマイズの公開ボタンをクリックします。

検証

1. 新規に取引先企業レコードを作成します。

2. 作成した取引先企業レコードを開き、両方のフィールドに正しい時刻が
ひょ字されていることを確認します。
image

3. 名前を変更して、レコードを保存します。ReadOnly1 フィールドだけ
新しい時刻が保存されています。
image

まとめ

読み取り専用フィールドの扱いは多少特殊ですが、上記方法で変更を
保存することが可能です。パフォーマンスを考慮して、値が本当に
変更された場合のみ、強制保存を指定するようにしてください。

‐ Dynamics CRM サポート 中村 憲一郎