Всем привет.
Как на проекте, так и на Аксфоруме, встречается код использующий расширенные запросы:
X++:
qbr.value(StrFmt("((%1.%3 != 0) || (%1.%2 != 0))"...
Если с точки зрения из поддержки вопросов особо не возникает, то процесс их написания, как правило, превращается в какое-то испытание.
Во вложении проект содержащий класс QueryBuildRangeCondition. Он упрощает разработку, но обратной стороной является снижение читабельности и быстродействия. Как оформить код, чтобы она не страдала - вопрос открытый. Текущее решение - прототип. Вероятно, это скорее "строитель" корректных запросов.
Реализованные функции...
create - конструктор. Намеренно один и принимает QBDS + FieldName.
toString - результат. Результат ее выполнения необходимо передать в экземпляр QueryBuildRange как value.
value/
link- задает оператор сравнения и само значение. В качестве значения можно передать другой QueryBuildRangeCondition.
add/
or - добавляют еще один объект QueryBuildRangeCondition через оператор И/ИЛИ.
Пример использования:
X++:
Query q = new Query();
QueryBuildDataSource qbds = q.addDataSource(tableNum(CustTable));
QueryBuildRange qbr = qbds.addRange(fieldNum(CustTable, RecId));
QueryBuildRangeCondition qbrc = QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, InvoiceAccount))
.and(
QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).value(QueryBuildRangeOperator::Equal, 403387)
.or(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, Name)).value(QueryBuildRangeOperator::NonEqual, CustTable::findRecId(403387).Name))
)
.and(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).link(QueryBuildRangeOperator::Equal, qbds, fieldStr(CustTable, RecId)));
;
qbds.addRange(fieldNum(CustTable, RecId)).value(qbrc.toString());
Результатом работы toString в данном случае будет:
Код:
((CustTable_1.InvoiceAccount)&&((CustTable_1.RecId=403387)||((CustTable_1.Name!="\"Василий\"")))&&((CustTable_1.RecId=((CustTable_1.RecId)))))
Отдельная благодарность товарищу Logger'у за помощь в создании данного решения.