2

在我们的云托管 CRM 2011 中,我在机会表上有 3 个字段

  • 合同期限(查找)
  • 服务开始日期(日期和时间)
  • 服务结束日期(日期和时间)

新表单的默认值

合同条款是对称为合同条款的自定义实体的查找。项目如下:

所有合同条款记录

我想根据另外两个中的条目计算和填充服务关闭日期字段。我的合同期限和服务开始日期的 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;
}

当用户填充计算所需的两个值时,代码会按预期运行。但是,如果其中一个字段(在本例中为合同期限)在创建新记录时在 javascript 中分配了默认值,则当用户为服务开始日期提供值时,不会发生计算:

计算没有发生

在我的函数中抛出调试器允许我调试 javascript 并且我看到了问题所在。但是,我不明白为什么这是一个问题。

例外

为什么当用户手动填充这两个字段时,这个确切的代码会起作用,但当其中一个字段被自动填充时却不行?该错误告诉我该对象为空,但显然它在任何一种情况下都不为空。为什么当用户手动输入一个值时这会起作用,但当该值通过 javascript 代码预先填充到表单 OnLoad 方法中时却不起作用?

更新

上面抛出异常的部分是访问 po_months 属性 - 调试器告诉我该属性为空:

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

2 回答 2

3

我认为错误很简单:要么 Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues没有财产po_months,要么Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months === null

您的代码在一行中浏览了许多属性。如果你不能保证这些属性中的每一个都存在某些东西,那么你就是在自找麻烦。

由于我认为您仍然有些困惑,因此请在错误行之前设置一个断点,然后查看以下所有可能的表达式中失败的地方。

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 回答
3

我想我现在明白这个问题了。

简而言之:您假设查找字段将使您能够访问查找记录的字段。这是不正确的。

为了对此进行扩展,让我们从 Crm 在查找字段中实际为您提供的内容开始。

如果您在此处查看 MSDN 。我们可以看到,当对查找属性执行 getValue() 时,我们会返回一个包含三个字符串属性的数组。

entityType String:查找中显示的实体的名称

id String:查找中显示的记录的 GUID 值的字符串表示形式。

name 字符串:表示要在查找中显示的记录的文本。

注意事项:

没有keyValues财产(我不确定你从哪里得到这个 - 如果我在这里遗漏了什么,请告诉我)。

除了名称字段,我们没有任何其他记录数据。例如:如果这是对联系人的查找,我们可以告诉它的全名(来自 name 属性),但不能告诉它的地址或电话号码。

因此,总结一下当 Crm 设置查找时它失败的原因是因为它只提供来自上面的信息,它不会填充keyValues或来自查找记录的任何字段,例如po_months

我猜测设置查找时它起作用的原因是因为您keyValues在代码中的其他位置创建属性。

如果您想要通过查找相关的记录中的信息,则必须执行 Web 服务调用以获取该信息 - 使用查找中的 id。

于 2012-10-29T10:42:57.723 回答