none
検索フィールドへのデータ入力時におけるID取得について RRS feed

  • 質問

  • お世話になります。

    前回、「エンティティを参照している検索フィールドへのデータ入力について」で質問させて頂き、

    その際、ユーザーをセットする方法についてご教授頂きました。

    ユーザーエンティティの場合は、関数でユーザー名やIDを取得できましたが、

    カスタムエンティティの検索フィールドに値をセットする際、セットする値が決まっている場合のidの取得はどの様に行うのでしょうか。

    それとも根本的に間違っているのでしょうか。

    var country = new Array();
    country[0] = new Object();
    country[0].id =; ←この部分
    country[0].name = "JAPAN";
    country[0].entityType = "ent_country";
    Xrm.Page.getAttribute("countryName").setValue(country);
    2018年4月17日 6:47

回答

  • ご返信いただきありがとうございます。

    どのようなことを行いたいのかについては、理解しました。

    >・業務ルールの処理で「国名(検索)」フィールドに「通貨(検索)」フィールド設定をすると形式が違うので実行時エラーが発生

    この処理はエラーになってしまいますね。

    "JAPAN"という値が同じだから入れられそうだと思われたのかもしれませんが、それは検索フィールドのラベル(≒参照エンティティのプライマリフィールド名)が同じだけであって、内部で持っているGUIDが一致しなければ検索フィールドに値をセットすることはできません。

    通貨フィールドの値を国名フィールドに直接セットするのではなく、業務ルールを以下の様に書き換えることでご要望自体は実現可能だと思いますが、この方法のままだと例えば通貨に新しいレコードが増えた場合、業務ルールの条件と処理をいちいち追加しなければならないのが難点です。

    [業務ルールの設定]

     条件:通貨 が次の値と等しい "JAPAN" ←通貨エンティティに存在する"JAPAN"レコード

     処理:国名 を "JAPAN" に設定 ←国名エンティティに存在する "JAPAN"レコード

    そんなにバリエーションがなく、増える予定もないのであれば上記の業務ルールをレコード分作ってしまってもいいかと思います。

    これからもレコードが増えていく、もしくは上記の方法だと膨大な量の業務ルールを作成しなければならないということであれば、通貨フィールドの値(JAPAN)をもとにFetchXMLで検索条件を組み立てて、国名エンティティに対してSOAPでFetchXMLを飛ばしてレコードの情報を取得し、取得した情報からレコードのGUIDを取り出して国名フィールドにセットする…という方法で実現できなくもないですが、処理はかなり複雑になってしまいます。

    • 回答としてマーク rias.crm 2018年4月18日 4:16
    2018年4月18日 3:06
  • ちなみに、FetchXMLやSOAPで実装される際は、以下の様に実装します。

    シナリオ:とあるエンティティ上の取引先企業(検索)フィールドの値が変更されたら、同じエンティティ上の取引先担当者(検索)フィールドに変更した取引先企業名と同じ名前の取引先担当者をセットする(例えば「あいうえお」という取引先企業が選択されたら「あいうえお」という取引先担当者をセット)。

    function getContactGUID() {
        var account = Xrm.Page.getAttribute("new_account").getValue();
        if(account != null) {
            // FetchXML生成
            var fetchXml =
                '<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" page="1" count="1">' +
                '  <entity name="contact">' +
                '    <attribute name="fullname" />' +
                '    <attribute name="contactid" />' +
                '    <filter type="and">' +
                '        <condition attribute="statecode" operator="eq" value="0" />' +
                '        <condition attribute="fullname" operator="eq" value="' + account[0].name + '" />' +
                '    </filter>' +
                '  </entity>' +
                '</fetch>';
            // SOAP実行
            var soapObj;
            try {
                soapObj = XrmServiceToolkit.Soap.Fetch(fetchXml, false);
            } catch (e) {
                soapObj = null;
            }
            // 取引先担当者を設定
            var contact = new Array();
            contact[0] = new Object();
            contact[0].id = soapObj[0].id;
            contact[0].name = soapObj[0].attributes.fullname.value;
            contact[0].entityType = "contact";
            Xrm.Page.getAttribute("new_contact").setValue(contact);
        }
    }

    なお上記は、SOAPの検索結果が0件だった場合や複数件に合致した場合等の例外処理は行っていないとてもシンプルなコードになっています。

    必要に応じて、条件文を追加しながら使用してください。

    • 編集済み westcoastline 2018年4月19日 0:50
    • 回答としてマーク rias.crm 2018年4月20日 2:21
    2018年4月18日 7:00

すべての返信

  • こんにちは。

    .idの部分についてですが、そちらにはレコードのGUIDを設定する必要がありますので、以下の様なJavaScriptでGUIDを取得する必要があります。

    // カスタムエンティティの情報を取得
    var customObj = Xrm.Page.getAttribute("{検索フィールドの物理名}").getValue();
    // 取得したオブジェクト型の"id"要素にレコードのGUIDが登録されています
    var recordGuid = customObj[0].id;
    // GUIDを表示
    alert(recordGuid);


    2018年4月17日 7:07
  • お世話になります。

    ご記載いただきました方法の場合、現在フィールドに値がセットされているGUIDは取得できますが、

    例えば、特定のフィールドのOnChangeハンドラ時に検索フィールド値を変更させたい場合は、

    現在値のGUIDは取得できますが、新たに違う値を検索フィールド値にする場合GUIDは取得できません。

    // cityフィールドの値が変更された場合の実行される関数
    // cityフィールド値が変更時、countryNameフィールドに特定の値をセットする
    function changeCity(){
          :
          :
        // 条件処理の結果countryNameフィールドに"JAPAN"をセットする
        // この時点でcountryNameフィールドのGUIDを取得してidをセットする事が出来れば正常に値が反映されると思いますが
        var country = new Array();
        country[0] = new Object();
        country[0].id =; ←この部分
        country[0].name = "JAPAN";
        country[0].entityType = "ent_country";
        Xrm.Page.getAttribute("countryName").setValue(country);
    }

    2018年4月17日 9:37
  • 認識が間違っていたら申し訳ありませんが、今回実装したい内容というのは例えば以下の様な感じでしょうか?

    ・「通貨(プルダウン)」フィールドで"JPY"が選択されたら、「国名(検索)」フィールドに"JAPAN"を設定する

    もし上記のような実装なのであれば、JavaScriptを使わなくても業務ルールで対応できるかと思います。

    [業務ルールの設定方法]

    業務ルールに以下の様なロジックを追加

     条件:通貨 が次の値と等しい ”JPY

     処理:国名 を "JAPAN" に設定 ←業務ルールでは検索フィールドにも値を設定可能

    もし認識が異なるようでしたら、ご連絡いただければと思います。

    2018年4月18日 1:01
  • お世話になります。

    ・「通貨(検索)」フィールドが変更になったら、「国名(検索)」フィールドに「通貨(検索)」フィールドの値をセットする

     (例:「通貨(検索)」フィールドで"JAPAN"が選択されたら、「国名(検索)」フィールドに"JAPAN"を設定する)

    ・「通貨(検索)」フィールドと「国名(検索)」フィールドは違うエンティティ参照だが、値自体は同じ

    ・業務ルールの処理で「国名(検索)」フィールドに「通貨(検索)」フィールド設定をすると形式が違うので実行時エラーが発生

    希望動作等はおおむね上記の通りですが、根本的に処理方法が変な状況なので見直しするのが一番なのかもしれません。

    2018年4月18日 2:21
  • ご返信いただきありがとうございます。

    どのようなことを行いたいのかについては、理解しました。

    >・業務ルールの処理で「国名(検索)」フィールドに「通貨(検索)」フィールド設定をすると形式が違うので実行時エラーが発生

    この処理はエラーになってしまいますね。

    "JAPAN"という値が同じだから入れられそうだと思われたのかもしれませんが、それは検索フィールドのラベル(≒参照エンティティのプライマリフィールド名)が同じだけであって、内部で持っているGUIDが一致しなければ検索フィールドに値をセットすることはできません。

    通貨フィールドの値を国名フィールドに直接セットするのではなく、業務ルールを以下の様に書き換えることでご要望自体は実現可能だと思いますが、この方法のままだと例えば通貨に新しいレコードが増えた場合、業務ルールの条件と処理をいちいち追加しなければならないのが難点です。

    [業務ルールの設定]

     条件:通貨 が次の値と等しい "JAPAN" ←通貨エンティティに存在する"JAPAN"レコード

     処理:国名 を "JAPAN" に設定 ←国名エンティティに存在する "JAPAN"レコード

    そんなにバリエーションがなく、増える予定もないのであれば上記の業務ルールをレコード分作ってしまってもいいかと思います。

    これからもレコードが増えていく、もしくは上記の方法だと膨大な量の業務ルールを作成しなければならないということであれば、通貨フィールドの値(JAPAN)をもとにFetchXMLで検索条件を組み立てて、国名エンティティに対してSOAPでFetchXMLを飛ばしてレコードの情報を取得し、取得した情報からレコードのGUIDを取り出して国名フィールドにセットする…という方法で実現できなくもないですが、処理はかなり複雑になってしまいます。

    • 回答としてマーク rias.crm 2018年4月18日 4:16
    2018年4月18日 3:06
  • お世話になります。

    該当レコード数が数千件の為、ご記載いただきました業務ルールの方法は現実的ではない状況ですので、

    後記述の方法での検討し、難しい場合は根本的な所を見直して対応したいと思います。

    色々とご提案頂き誠にありがとうございました。

    2018年4月18日 4:16
  • ちなみに、FetchXMLやSOAPで実装される際は、以下の様に実装します。

    シナリオ:とあるエンティティ上の取引先企業(検索)フィールドの値が変更されたら、同じエンティティ上の取引先担当者(検索)フィールドに変更した取引先企業名と同じ名前の取引先担当者をセットする(例えば「あいうえお」という取引先企業が選択されたら「あいうえお」という取引先担当者をセット)。

    function getContactGUID() {
        var account = Xrm.Page.getAttribute("new_account").getValue();
        if(account != null) {
            // FetchXML生成
            var fetchXml =
                '<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" page="1" count="1">' +
                '  <entity name="contact">' +
                '    <attribute name="fullname" />' +
                '    <attribute name="contactid" />' +
                '    <filter type="and">' +
                '        <condition attribute="statecode" operator="eq" value="0" />' +
                '        <condition attribute="fullname" operator="eq" value="' + account[0].name + '" />' +
                '    </filter>' +
                '  </entity>' +
                '</fetch>';
            // SOAP実行
            var soapObj;
            try {
                soapObj = XrmServiceToolkit.Soap.Fetch(fetchXml, false);
            } catch (e) {
                soapObj = null;
            }
            // 取引先担当者を設定
            var contact = new Array();
            contact[0] = new Object();
            contact[0].id = soapObj[0].id;
            contact[0].name = soapObj[0].attributes.fullname.value;
            contact[0].entityType = "contact";
            Xrm.Page.getAttribute("new_contact").setValue(contact);
        }
    }

    なお上記は、SOAPの検索結果が0件だった場合や複数件に合致した場合等の例外処理は行っていないとてもシンプルなコードになっています。

    必要に応じて、条件文を追加しながら使用してください。

    • 編集済み westcoastline 2018年4月19日 0:50
    • 回答としてマーク rias.crm 2018年4月20日 2:21
    2018年4月18日 7:00
  • お世話になります。

    ご丁寧にソースコードまで記載頂きありがとうございます。

    とても参考になります。

    因みに、Webapiを使用してレコードGUIDを取得する方法等で検証しておりました。

    2018年4月20日 2:21
  • 確かに、WebAPIを利用した方がよりシンプルな実装になりそうですね。

    ちなみにWebAPIを利用する場合は、以下のretrieveMultipleRecordsのメソッドが使えそうです。

    https://docs.microsoft.com/ja-jp/dynamics365/customer-engagement/developer/clientapi/reference/xrm-webapi/retrievemultiplerecords

    (rias.crm様は上記について既にご存知かと思われますが、今後、本スレッドをご覧になった方の参考情報として掲載しておきます)

    2018年4月23日 2:34
  • お世話になります。

    現在は、WebAPIを使用して機能実装して運用している状況ですが、

    別の外部サイトを参考にしましたが、結構複雑な処理になりました。

    retrieveMultipleRecordsのメソッドは使用していませんが、

    処理がとても簡潔に出来そうですね。

    • 編集済み rias.crm 2018年4月24日 5:50
    2018年4月24日 5:49