高度なフィルタリングを使用して Axe でクエリを作成する方法 (x++ を使用):
このようなフィルタ条件を On SalesTable フォームに表示するようにしたいと考えていますSalesTable.SalesId == "001" || SalesLine.LineAmount == 100
。
結果には、SalesOrder 001 と、LineAmount = 100 の SalesLine が少なくとも 1 つある他の salesOrders が表示されますか?
Janのソリューションは、販売注文「001」が販売ラインがある場合にのみ選択する必要がある場合に正常に機能します。行がない場合、出力には表示されません。
販売注文「001」が販売ラインがない場合でも常に出力に表示されることが重要な場合は、次のようにユニオンを介して行うことができます。
static void AdvancedFiltering(Args _args)
{
Query q;
QueryRun qr;
QueryBuildDataSource qbds;
SalesTable salesTable;
;
q = new Query();
q.queryType(QueryType::Union);
qbds = q.addDataSource(tablenum(SalesTable), identifierstr(SalesTable_1));
qbds.fields().dynamic(false);
qbds.fields().clearFieldList();
qbds.fields().addField(fieldnum(SalesTable, SalesId));
qbds.addRange(fieldnum(SalesTable, SalesId)).value(queryValue('001'));
qbds = q.addDataSource(tablenum(SalesTable), identifierstr(SalesTable_2), UnionType::Union);
qbds.fields().dynamic(false);
qbds.fields().clearFieldList();
qbds.fields().addField(fieldnum(SalesTable, SalesId));
qbds = qbds.addDataSource(tablenum(SalesLine));
qbds.relations(true);
qbds.joinMode(JoinMode::ExistsJoin);
qbds.addRange(fieldnum(SalesLine, LineAmount )).value(queryValue(100));
qr = new QueryRun(q);
while (qr.next())
{
salesTable = qr.get(tablenum(SalesTable));
info(salesTable.SalesId);
}
}
AX selectステートメントは、次のような存在する結合をサポートしています。
while select salesTable
exits join salesLine
where salesLine.SalesId == salesTable.SalesId &&
salesLine.LineAmount == 100
exists
X++ は、句のサブクエリとしての句をサポートしていませんwhere
。exists
したがって、と組み合わせてを表現することはできませんor
。
ただし、AX はクエリでクエリ式をサポートしています。
したがって、クエリは次のように表現できるはずです。
static void TestQuery(Args _args)
{
SalesTable st;
QueryRun qr = new QueryRun(new Query());
QueryBuildDataSource qst = qr.query().addDataSource(tableNum(SalesTable));
QueryBuildDataSource qsl = qst.addDataSource(tableNum(SalesLine));
str qstr = strFmt('((%1.SalesId == "%2") || (%3.LineAmount == %4))',
qst.name(), queryValue("001"),
qsl.name(), queryValue(100));
qsl.relations(true); // Link on SalesId
qsl.joinMode(JoinMode::ExistsJoin);
qsl.addRange(fieldNum(SalesLine,RecId)).value(qstr);
info(qstr); // This is the query expression
info(qst.toString()); // This is the full query
while (qr.next())
{
st = qr.get(tableNum(SalesTable));
info(st.SalesId);
}
}
ただし、販売注文 001 に行が含まれていない場合は選択されません。それ以外は、出力は要求どおりです。
((SalesTable_1.SalesId == "001") || (SalesLine_1.LineAmount == 100))
SELECT FIRSTFAST * FROM SalesTable EXISTS JOIN FIRSTFAST * FROM SalesLine WHERE SalesTable.SalesId = SalesLine.SalesId AND ((((SalesTable_1.SalesId == "001") || (SalesLine_1.LineAmount == 100))))
001
125
175