Dynamics AX 2012 复杂 QueryBuild 对象

Dynamics AX 2012 Complex QueryBuild Object

尝试在 AX 中筛选特定数据范围但遇到问题。

这就是我想用伪代码做的事情..

(start >= now-30 && (end == null || end >= now-30))
||
(end >= now-30 && (start == null || start >= now-30))
||
(start >= now-30 && end >= now-30)

这是我尝试过的方法

CLASS 宣言

QueryBuildRange filterDates;

DS 初始化方法

filterDates=this.query().dataSourceName('LogTable').addRange(fieldNum(LogTable,startDateTime));    
filterDates=this.query().dataSourceName('LogTable').addRange(fieldNum(LogTable,endDateTime));    

DS 执行方法

filterDates.value(strFmt("(%1 >= %3 && (%2 == %4 || %2 >= %3)) || (%2 >= %3 && (%1 == %4 || %1 >= %3)) || (%1 >= %3 && %2 >= %3)", fieldStr(LogTable, startDateTime), fieldStr(LogTable, endDateTime), currentTimeMinus30Mins, DateTimeUtil::minValue()));

AX 似乎几乎忽略了我输入的任何完整查询。

谢谢

我认为你的逻辑有问题,这可能就是它不起作用的原因!

我猜您想使用两个日期时间字段 startend 进行时间点搜索,如果未结束,end 为空白。

要搜索 30 天前有效的记录, 需要的条件是:

(start <= now-30 && (end == null || end >= now-30))

在数据源的 executeQuery 中实现:

public void executeQuery()
{
    QueryBuildDataSource qds = this.query().dataSourceTable(tableNum(LogTable));        
    SysQuery::findOrCreateRange(qds, fieldNum(LogTable,StartDateTime)).value('..'+queryValue(currentTimeMinus30Mins));
    SysQuery::findOrCreateRange(qds, fieldNum(LogTable,EndDateTime)).value('"",'+queryValue(currentTimeMinus30Mins+'..');
    super();
}

以上适用于日期字段,我认为它也适用于日期时间字段。

如果你的伪代码逻辑是正确的,我仍然可以看出你的 DS EXECUTEQUERY METHOD 中的一些缺陷:

  • 整个表达式必须括在括号中。
  • 每个子表达式都必须用自己的一组括号括起来。
  • DateTimeUtil::toStr(...) 缺失。

尝试按如下方式更改您的代码:

filterDates.value(strFmt("(((%1 >= %3) && ((%2 == %4) || (%2 >= %3))) || ((%2 >= %3) && ((%1 == %4) || (%1 >= %3))) || ((%1 >= %3) && (%2 >= %3)))",
                        fieldStr(LogTable, startDateTime),
                        fieldStr(LogTable, endDateTime),
                        DateTimeUtil::toStr(currentTimeMinus30Mins),
                        DateTimeUtil::toStr(DateTimeUtil::minValue())));

你应该可以稍微简化一下:

filterDates.value(strFmt("(((%1 >= %3) || (%1 == %4)) && ((%2 >= %3) || (%2 == %4)) && !((%1 == %4) && (%2 == %4)))",
                        fieldStr(LogTable, startDateTime),
                        fieldStr(LogTable, endDateTime),
                        DateTimeUtil::toStr(currentTimeMinus30Mins),
                        DateTimeUtil::toStr(DateTimeUtil::minValue())));

此外,我看不出有任何理由在 DS INIT METHOD 中将 filterDates 初始化两次。您实际上可以在此范围内使用不同的字段,它不必是 startDateTime 或 endDateTime:

filterDates = SysQuery::findOrCreateRange(this.query().dataSourceTable(tableNum(LogTable)), fieldNum(LogTable, RecId));

P.S. 我不太记得在这样的表达式中应该如何使用 utcDateTime 值 - 据我记得,DateTimeUtil::toStr(...) 应该工作。