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 似乎几乎忽略了我输入的任何完整查询。
谢谢
我认为你的逻辑有问题,这可能就是它不起作用的原因!
我猜您想使用两个日期时间字段 start
和 end
进行时间点搜索,如果未结束,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(...)
应该工作。
尝试在 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 似乎几乎忽略了我输入的任何完整查询。
谢谢
我认为你的逻辑有问题,这可能就是它不起作用的原因!
我猜您想使用两个日期时间字段 start
和 end
进行时间点搜索,如果未结束,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(...)
应该工作。