Показать сообщение отдельно
Старый 20.11.2023, 16:28   #1  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
268 / 829 (28) +++++++
Регистрация: 23.10.2012
Post Объект упрощающий создание расширенных запросов
Всем привет.
Как на проекте, так и на Аксфоруме, встречается код использующий расширенные запросы:
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'у за помощь в создании данного решения.

Последний раз редактировалось Товарищ ♂uatr; 27.11.2023 в 22:23.
За это сообщение автора поблагодарили: Logger (5), S.Kuskov (10), PavelX (4), Pandasama (3).