汇总字段介绍以及在汇率变化后货币数据类型的汇总字段怎么变的实践研究

Posted luoyong0201

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇总字段介绍以及在汇率变化后货币数据类型的汇总字段怎么变的实践研究相关的知识,希望对你有一定的参考价值。

我是微软Dynamics 365 & Power Platform方面的工程师/顾问罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复439或者20210425可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

关于汇总字段的官方文档请参考 Define rollup columns that aggregate values ,我就不翻译介绍了,融入到后面的实践演示与研究中。

首先我建立一个汇总字段,如下,主要是 Field Type 要选择 Rollup,保存。


保存后点击 Field Type旁边的Edit按钮进行编辑字段使用的公式,我这里设置如下,是一个常见的中规中矩的设置,汇总关联的有效的(Status = Active)的子实体(Demo Sub Entity)中一个货币字段的值,我这里用的是SUM,当然还支持COUNT, AVG, MIN, MAX操作符. 从界面上看,汇总字段不能启用Auditing属性。

每个汇总字段会额外增加两个字段,分别是汇总字段名加上 _state 和 _date,分别记录汇总字段的刷新状态和最近刷新时间,这两个字段虽然在实体的所有字段清单中看不到,但是可以拉动到界面上的。表单上展示效果如下:

这个 State结尾的字段含义如下,我从官方文档摘录过来的:

TABLE 1
ValueStateDescription
0NotCalculatedThe column value is yet to be calculated.
1CalculatedThe column value has been calculated per the last update time in _date column.
2OverflowErrorThe column value calculation resulted in overflow error.
3OtherErrorThe column value calculation failed due to an internal error. The following run of the calculation job will likely fix it.
4RetryLimitExceededThe column value calculation failed because the maximum number of retry attempts to calculate the value was exceeded due to high number of concurrency and locking conflicts.
5HierarchicalRecursionLimitReachedThe column value calculation failed because the maximum hierarchy depth limit for the calculation was reached.
6LoopDetectedThe column value calculation failed because a recursive loop was detected in the hierarchy of the row.

因为是货币汇总字段,所以会增加一个字段名后面加上_Base的字段,如下,可以看到也是汇总类型字段,但是不允许编辑,也不能启用Audit。


正如我们知道的,实体中添加一个货币类型的字段后就会自动增加一个名称为Exchange Rate的字段和一个名称为Currency的字段,如下。

为了方便测试多币种,我先在系统中增加一种货币,也就是人民币,如下:


录入货币字段的时候虽然不能看到或者修改Exchange Rate 或者其对应的基础货币(Base)字段的值,但是保存后就有了。

我们知道汇总字段不是实时计算的,而是定时更新的,最快速度是每小时更新一次,这背后是系统作业(system job)的功能。我们导航到Advanced Settings > Settings > System > System Jobs,切换到 All Rollup Field Calculation Jobs,会看到每个包含汇总字段的实体有两个类型的System Job,分别是 Mass Calculate Rollup Field 和 Calculate Rollup Field。前面这个类型的系统作业默认在字段创建后12小时运行一次,然后就会设置下一次运行时间为比较长的时间之后,应该是10年。

如果要查看下次汇总时间是什么时候,可以切换到 Recurring System Jobs 这个视图,筛选 System Job Type 为 Mass Calculate Rollup Field 或者 Calculate Rollup Field 就可以看到。


这个界面就可以更改系统作业的下次运行时间,特别是类型为Mass Calculate Rollup Field 的运行时间以便它第一次运行在系统空闲时间。双击打开这条记录,然后点击命令栏的 Actions > Postpone ,在弹出窗口中设置要运行的时间保存即可,默认的时间是当前时间。对于Calculate Rollup Field类型的系统作业,可以执行的操作则更多,包括Modify Recurrence,这个执行频率默认是1小时,可以修改为2小时运行一次或者更加的不频繁,但是不能比一小时一次的频率更高,比如说半小时运行一次是不行的。

设置后在这个时间你就可以在 All System Jobs这个视图看到这个system job的运行。


运行成功后,就会看到这个实体的这个汇总字段的信息也刷新了,如下:


在All System Jobs视图进行筛选,用System Job Name 进行筛选可以看到定期运行的刷新汇总字段值的system job运行,示例如下。


当然汇总字段是可以手动刷新重新计算值的,点击字段旁边的计算器按钮会出来 Recalculate 按钮,点击下就可以刷新了,点击刷新后哪怕值没有变,Last Updated的值也会更改为操作时间。


现在我去改下汇率,将汇率从 6.54 改成 6.5,然后更改Demo 1 Sub 1这个子记录货币字段的值,可以看到这条记录的汇率Exchange Rate的值也变了。其他两条子记录的汇率并没有变化。


这时候我去手动刷新下父记录汇总字段的值,值如下(货币汇总字段其对应Base字段的值需要页面或者表单刷新后才会看到更新):


我之前以为计算得不对,看下面汇总的三条子记录的汇率不尽相同,有一条记录的汇率是6.5,其余两条的汇率是6.54,父记录的汇率也是 6.54 。

我的理解,汇总记录计算出来的值应该是 100+20+30=150,但是实际上汇总记录算出来的值却是 150.62 有点儿差距,咋回事呢?汇总记录的base字段值(换算成基础货币这里是美元后的值)应该是 15.38+3.06+4.59=23.03 ,这个和父记录货币汇总字段的对应base字段的值是相等的。这个值如果用父记录的汇率 6.54 换算下,刚好是 23.03 * 6.54 = 153.6162,四舍五入后就是界面显示的 150.62元人民币。

至此我明白了货币类型汇总字段值的算法,就是先汇总其子记录货币字段对应的base字段的值,然后用这个值作为父记录的货币汇总字段对应的base字段的值,用父记录的货币汇总字段对应的base字段的值乘以父记录的汇率作为父记录的货币汇总字段的值。


顺便提一句,记录上的汇率字段用代码来更新是没有用的,可以通过更新货币字段的值来更新。汇率变了,记录上的货币数据类型字段的值没有变是不会更改该条记录的汇率的,当然也就不会影响到其对应的base字段的值了。如果要同步汇率可以考虑下面类似的代码来更新,可以将这个货币字段的新值和旧值设置为相等,从Audit记录来看,不会看到这个字段的变化,但是可以看到这个记录的汇率同步了最新的汇率,而且这个字段对应的base字段值也更新了。

var data =
    {
        ly_currency:102
    }
Xrm.WebApi.updateRecord("ly_demoentity", "b3ab4ca1-8b8b-eb11-a812-000d3a8f9086", data).then(
    function success(result) {
        console.log("updated");
    },
    function (error) {
        console.log(error.message);
    }
);


以上是关于汇总字段介绍以及在汇率变化后货币数据类型的汇总字段怎么变的实践研究的主要内容,如果未能解决你的问题,请参考以下文章

汇总篇 | MySQL数据库设计开发规范

C# DataTable多条件汇总

abap alv 不同字段 分类汇总

MySQL实战必备文章。DDL常用命令汇总及登录数据库相关命令!

在 postgres 中,如何从事件日志类型表(具有时间戳)中获取特定时间范围内字段的总和(或汇总)

EXCEL中多级分类汇总空白字段填充