2

クラウドでホストされている CRM 2011 では、商談フォームに 3 つのフィールドがあります。

  • 契約期間(参照)
  • サービス開始日(日時)
  • サービス終了日(日時)

新しいフォームのデフォルト値

契約条件は、契約条件と呼ばれるカスタム エンティティのルックアップです。項目は次のとおりです。

すべての契約条件の記録

他の 2 つのエントリに基づいて、Service Close Date フィールドを計算して入力したいと考えています。契約期間とサービス開始日の OnChange イベントの JavaScript コードは次のとおりです。

function UpdateAgreementCloseDate() {
    //debugger;
    if (Xrm.Page.getAttribute("po_contractterm").getValue() != null && Xrm.Page.getAttribute("po_agreementstartdate").getValue() != null) 
        {
            //Get Months from agreement term
            var ContractTermMonths = 0;
            ContractTermMonths = Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months.value;

            //Get Start Date
            var currentAgreementStartDate;
            currentAgreementStartDate = Xrm.Page.getAttribute("po_agreementstartdate").getValue();

            //Add contract term monthsto start date
            var AgreementCloseDate = getExpirationDate(currentAgreementStartDate, parseFloat(ContractTermMonths));

Xrm.Page.data.entity.attributes.get("po_agreementclosedate").setValue(AgreementCloseDate);
Xrm.Page.data.entity.attributes.get("po_agreementclosedate").setSubmitMode("always"); // Save the Disabled Field
        }
}


function getExpirationDate(tempdate, numberofmonths) {
    var next_month = tempdate.getMonth() + numberofmonths;
    var next_year = tempdate.getFullYear();
    if (next_month > 11) {

        if (numberofmonths > 11) {
            var extrayears = parseInt(next_month / 12);
            var remainingmonths = next_month % 12;
            next_month = remainingmonths;
            next_year = next_year + extrayears;
        }
        else {
            next_month = 0;
            next_year++;
        }
    }

    tempdate.setMonth(next_month);
    tempdate.setYear(next_year);
    return tempdate;
}

ユーザーが計算に必要な 2 つの値を入力すると、コードは期待どおりに実行されます。ただし、フィールドの 1 つ (この場合は契約期間) に新しいレコードの作成時に JavaScript で割り当てられたデフォルト値がある場合、ユーザーがサービス開始日に値を指定しても計算は行われません。

計算は行われませんでした

関数でデバッガーをスローすると、javascript をデバッグできるようになり、問題が何であるかがわかります。しかし、なぜそれが問題なのか理解できません。

例外

ユーザーが両方のフィールドを手動で入力すると、この正確なコードが機能するのに、一方が自動入力された場合は機能しないのはなぜですか? このエラーは、オブジェクトが null であることを示していますが、どちらの場合も明らかに null ではありません。ユーザーが値を手動で入力したときにこれが機能するのはなぜですか?

アップデート

上記の例外をスローする行の部分は、po_months プロパティにアクセスしています。デバッガーは、プロパティが null であることを通知します。

ContractTermMonths = Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months
4

2 に答える 2

3

私は今この問題を理解していると思います。

つまり、ルックアップフィールドを使用すると、ルックアップされたレコードのフィールドにアクセスできると想定しています。これは正しくありません。

それを拡張するために、Crmがルックアップフィールドで実際に提供するものから始めましょう。

こちらのMSDNをご覧ください。getValue()がルックアップ属性で実行されると、3つの文字列プロパティを持つ配列が返されることがわかります。

entityType文字列:ルックアップに表示されるエンティティの名前

id文字列:ルックアップに表示されるレコードのGUID値の文字列表現。

name文字列:ルックアップに表示されるレコードを表すテキスト。

注意事項:

プロパティはありませんkeyValues(これをどこから入手したかわかりません。ここで何かが足りない場合はお知らせください)。

名前フィールドを除いて、他のレコードデータはありません。例:これが連絡先の検索である場合、そのフルネーム(nameプロパティから)はわかりますが、住所や電話番号はわかりません。

したがって、Crmがルックアップを設定するときに失敗する理由を要約すると、Crmは上記の情報のみを提供するため、ルックアップさkeyValuesれたレコードのフィールドやフィールドは入力されませんpo_months

ルックアップを設定したときに機能する理由はkeyValues、コード内の別の場所にプロパティを作成しているためだと思います。

ルックアップを介して関連付けられたレコードからの情報が必要な場合は、ルックアップからのIDを使用して、その情報を取得するためにWebサービス呼び出しを実行する必要があります。

于 2012-10-29T10:42:57.723 に答える
3

エラーは非常に簡単だと思います。 Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValuesプロパティがないpo_monthsか、Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months === null

あなたのコードは、1 行で多くのプロパティをナビゲートしています。これらのプロパティのすべてに何かが存在することを保証できない場合は、問題が発生しています。

あなたはまだ少し混乱していると思うので、エラー行の直前にブレークポイントを設定して、次のすべての可能な式のうち、何が失敗したかを確認してください。

Xrm.Page.getAttribute("po_contractterm").getValue()  //this shouldn't be null
Xrm.Page.getAttribute("po_contractterm").getValue()[0]
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months  //this probably doesn't exist or is null.
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months.value

Xrm.Page.getAttribute("po_contractterm").getValue()その部分は でテストされるため、式の一部のチェックを省略できifます。ただし、正気を保つためだけにチェックしても害はありません。Visual Studio デバッガーを使用すると、オブジェクトが大きすぎない限り、これらのそれぞれをクリックしてナビゲートできるはずです。あなたのコメントのいくつかはあなたが信じていることを示唆しているように見えるので、デバッガーがあなたに嘘をついているかどうかを知ることも役に立ちます。デバッガーはときどき嘘をついたり、(はるかに頻繁に) 非常に鈍感に情報を提示したりします。

これは怠けてはいけないことです。おそらく、 JSONPathのようなものを使用する場合は、少し怠惰になる可能性がありますが、そのようなツールを使用しない場合は、必要なときにパスが存在することを確認するか、存在しないかもしれません。

于 2012-10-29T05:02:12.047 に答える