AX2012的表属性中可以设置ValidTimeStateFieldType来创建一个具有有效期状态的表,系统自动给表添加ValidFrom和ValidTo两个字段。这个属性及字段有什么用呢?假如有一笔贷款第一年的利率是5%,第二年变成了6%,在第二年我们仍想知道它在第一年的利率,当然可以使用其他的逻辑和表来保存过去时间段有效的数据,使用ValidTimeStateFieldType可以简化这样的问题。
表的ValidTimeStateFieldType属性有三个选项,NONE、Date和UtcDateTime三个选项,选择后面两个的任意一个系统会自动为表添加ValidFrom和ValidTo两个字段,系统会自动保证这些日期段不会重复。还需要做的动作是设置包含时间的Index,比如我们的表有一个字段ID为唯一的主key,还需要创建一个至少包含ValidFrom的替代Index:
一旦设置索引的ValidtimestateKey为yes,索引里的ValidFrom就不能再被删除。标记为ValidTimeStateFieldType 属性的表是不能够多纪录SQL批量操作的,即使X++中使用了多纪录操作,内部也是转化成单条纪录操作的。
在SELECT中可以使用validTimeState关键字来过滤时间段:
SELECT validTimeState(dateFrom, dateTo) count(RecID) from Table1;
validTimeState还可以只带一个参数,返回的纪录是那些日期范围内包含这个日期的纪录:
While SELECT validTimeState(dateTarget) * from Table1 { .... }
需要注意的是如果SELECT中不包含validTimeState是等同于validTimeState(Today())的。
使用update_recordset更新纪录时,会受到表变量ValidTimeStateUpdateMode方法的影响,这是一个enum的类型ValidTimeStateUpdate,有Correction、CreateNewTimePeriod和EffectiveBased三个选项,前两选项分别表示自动更新重叠日期纪录、创建新纪录,EffectiveBased首先强制使用CreateNewTimePeriod来扩展当前日期,否则使用Correction方法。
dateFrom = 01\01\1900; dateTo = 31\12\2154; table1.ValidTimeStateUpdateMode(ValidTimeStateUpdate::Correction); SELECT forUpdate validTimeState(dateFrom, dateTo) * from table1 where table1.ID == "ID1"; UPDATE_RECORDSET table1 setting ValidTo = 2\2\2004 where table1.ID == "ID1";
这里我们更新ID为ID1纪录的截止日期,如果调整后有条纪录和这个新的截止日期有冲突,AX会自动调整那条纪录的起始日期。
Query类有几个方法来处理有效期状态:validTimeStateAsOfDate、validTimeStateAsOfDateTime、validTimeStateDateRange、validTimeStateDateTimeRange。
Table1 table1; Query qry; QueryRun qRun; QueryBuildDataSource qBDSource; date dateMinimum = 1\1\1900, dateMaximum = 31\12\2154; qry = new Query(); qry.validTimeStateDateRange(dateMinimum, dateMaximum); qBDSource = qry.addDataSource(tablenum(Table1)); qBDSource.addOrderByField(fieldNum(Table1,ID)); qRun = new QueryRun(qry); while (qRun.next()) { table1 = qRun.get(Table1); ... }
更多有关有效时间状态表的信息可以在MSDN上找到:http://msdn.microsoft.com/en-us/library/gg861781.aspx