AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.11.2023, 16:28   #1  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
299 / 866 (29) +++++++
Регистрация: 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).
Старый 23.11.2023, 07:31   #2  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
А более сложные конструкции с различными вложенностями AND и OR и NOT он делать позволяет?
Старый 23.11.2023, 13:52   #3  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
299 / 866 (29) +++++++
Регистрация: 23.10.2012
Позволяет, вложенному QueryBuildRangeCondition указываете доп. критерии - рекурсия.
Исходный пример выглядел бы примерно так:
X++:
QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, InvoiceAccount))
                         .and(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).value(QueryBuildRangeOperator::Equal, 403387)
                                                       .and(
                                                               ...
                                                           )
                             )
.
NOT - оператор, за это отвечает перечисление QueryBuildRangeOperator. Оно передается как параметр в функции value и link. Больше или равно, просто больше и тд - там же.

Последний раз редактировалось Товарищ ♂uatr; 23.11.2023 в 14:03.
Старый 23.11.2023, 14:13   #4  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Товарищ ♂uatr Посмотреть сообщение
NOT - оператор, за это отвечает перечисление QueryBuildRangeOperator. Оно передается как параметр в функции value и link.
Вы не путаете 'NOT' и 'не равно'?

Можно ли, например, собрать вот такое условие:
Код:
NOT((Table1.Field1 == "aaa") OR (Table2.Field2 == "aaa"))
или нужно обязательно преобразовывать его в
Код:
((Table1.Field1 != "aaa") AND (Table2.Field2 != "aaa"))
?
Старый 23.11.2023, 14:24   #5  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
299 / 866 (29) +++++++
Регистрация: 23.10.2012
Да, путаю. Не рассматриваю расширенные запросы в рамках чистого TSQL. Спасибо.
Верно пишите, в рамках текущей реализации возможность реверса логики не была заложена и условие нужно будет развернуть.
Добавить можно.
К исправлениям - очевидно, что функция link лишние скобки создает.
Старый 23.11.2023, 15:56   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Ещё можно добавить тип сравнения LIKE. Вроде он поддерживается в расширенном синтаксисе начиная с AX2009
За это сообщение автора поблагодарили: Logger (1).
Старый 23.11.2023, 19:40   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Там еще всякие нюансы были, типа для dimension поля обязательно указывать датасорс итп.
На аксаптапедии было расписано.
Старый 27.11.2023, 22:49   #8  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
299 / 866 (29) +++++++
Регистрация: 23.10.2012
Привет.
-добавил "реверс" логики блока. Для использования необходимо применять новый конструктор "createNegation". Т.е. добавлена возможность написать:
Код:
NOT((Table1.Field1 == "aaa") OR (Table2.Field2 == "aaa"))
-упразднил избыточные скобки при "линковке" полей источников данных.

Актуальная версия во вложении (предыдущую удалил).

На тему массивов - функционал не расширял, он и так поддерживается:
X++:
QueryBuildRangeCondition::createNegation(qbds, fieldId2Name(tableNum(LedgerTrans), fieldId2ext(fieldNum(LedgerTrans, Dimension), 4))).value(QueryBuildRangeOperator::Equal, 'Что-то');
Код:
!((LedgerTrans_1.Dimension[4]="Что-то"))
Вложения
Тип файла: xpo PrivateProject_QueryBuildRangeCondition.xpo (11.9 Кб, 86 просмотров)

Последний раз редактировалось Товарищ ♂uatr; 27.11.2023 в 23:00.
За это сообщение автора поблагодарили: ashu (2), Logger (10), Ace of Database (10), Pandasama (3), SRF (2).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AX2012: Разработка. Открыть используемый объект sukhanchik DAX: Программирование 0 18.09.2020 14:12
AIF права доступа на создание COM-объекта ex3em DAX: Программирование 1 07.10.2014 19:11
Проверка ВР не заглядывает внутрь расширенных типов-массивов glibs DAX: Программирование 0 26.01.2010 20:16
RLS и программное создание запросов Arahnid DAX: Программирование 3 11.10.2007 18:17
aEremenko: Использование прямых запросов SQL Blog bot DAX Blogs 4 18.07.2007 10:09

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:42.