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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.05.2011, 11:29   #1  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
как правильно построить фильтр
Есть таблица, в которой для каждого сотрудника есть несколько строк с разницей в датах.
Весь период разбит на части по датам типа нашал работать - ушёл в отпуск(последн день перед отпуском)
нач отпуска - конец отпуска

ФИО1 - прочие данные - начал работать - ушёл в отпуск(последн день перед отпуском)
ФИО1 - прочие данные - перв день отпуска - последн день отпуска
ФИО1 - прочие данные - перв день после отпуска - последн день перед отпуском
....и т.д.

надо показать только корректные данные на выбранный день. Т.е. для каждого сотрудника будет только одна запись

classDeclaration:
QueryBuildRange rangeTermination;

init:
rangeTermination = this.query().dataSourceTable(tableNum(MyTable)).addRange(fieldNum(mlm_EmployeesTable, begin_date));

executeQuery:
if(firstOpen == True)
{//в перв раз данные на сегодня
rangeTermination.value("<=" + date2strxpp(SystemDateGet()) + "&& mlm_EmployeesTable.finish_date>= " + date2strxpp(SystemDateGet()));
}
else
{//TerminationDate.valueStr() дата выбранная на форме
rangeTermination.value("<=" + TerminationDate.valueStr() + "&& (mlm_EmployeesTable.finish_date>= " + TerminationDate.valueStr());
}

игнорирует фильтр и показывает все строчки для каждого сотрудника
что и где я не права? Спасибо
Старый 05.05.2011, 11:46   #2  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,509 / 432 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
__________________
С уважением,
Вячеслав
Старый 05.05.2011, 11:54   #3  
samolalex is offline
samolalex
Участник
Аватар для samolalex
Самостоятельные клиенты AX
 
259 / 107 (4) +++++
Регистрация: 18.06.2010
Адрес: Москва
Значения фильтров с интервалом дат должны иметь формат (пример):
Цитата:
"01.01.2011..01.02.2011"
Таким образом, вам необходимо привести ваш фильтр к виду:
X++:
rangeTermination.value(strfmt("%1..%2", StartDate, EndDate));
Также в Axapta 3 есть метод класса SysQuery под названием Range(), который служит для ввода интервалов значений в фильтр:
X++:
rangeTermination.value(SysQuery::range(StartDate, EndDate));
__________________
С уважением, Александр.
Старый 05.05.2011, 11:58   #4  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,509 / 432 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
А причём тут интервал дат? Надо отобрать строки, в которых первая дата меньше заданной, а вторая больше. Тут надо 2 Range накладывать на разные поля вообще-то.
Или я чего-то не понял...
__________________
С уважением,
Вячеслав
За это сообщение автора поблагодарили: Ivanhoe (1).
Старый 05.05.2011, 12:00   #5  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2156 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Обратите внимание, что у автора range ставится на поле begin_date, а в самом фильтре еще и finish_date участвует. Почему было не сделать два range - по одному на каждое поле??
__________________
Ivanhoe as is..
Старый 05.05.2011, 12:00   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Если не заморачиваться с возможным пустым значением полей, то, в данном случае, надо просто создать два отдельных Range на поле, содержащее начало диапазона и на поле, содержащее конец диапазона.

Два Range, созданные по разным полям автоматически объединяются по "И", что, в данном случае и требуется

X++:
// init:
QueryBuildDataSource qbds;

qbds = this.query().dataSourceTable(tableNum(MyTable));
rangeBegin = qbds.addRange(fieldNum(mlm_EmployeesTable, begin_date));
rangeEnd = qbds.addRange(fieldNum(mlm_EmployeesTable, finish_date));
X++:
// executeQuery:

if(firstOpen == True)
{
    rangeBegin.value(global::QueryRange(dateNull(), systemDateGet()))
    rangeEnd.value(global::QueryRange(systemDateGet(), dateNull()))
}
else
{
    rangeBegin.value(global::QueryRange(dateNull(), TerminationDate.value()))
    rangeEnd.value(global::QueryRange(TerminationDate.value(), dateNull()))
}

Если же значения полей могут быть пустыми (есть дата начала, но нет даты конца или наоброт), то все значительно сложнее.
За это сообщение автора поблагодарили: timaluhs (1).
Старый 05.05.2011, 12:10   #7  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,509 / 432 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
Согласен с Владимиром.
Единственное - не вижу необходимости в переменной firstOpen. По-моему, вполне достаточно внутри executeQuery получать TerminationDate.value(), а затем сравнивать его с dateNull(). Это тем более справедливо, если надо будет открывать форму с установленной заранее датой
__________________
С уважением,
Вячеслав

Последний раз редактировалось pitersky; 05.05.2011 в 12:12.
Старый 15.05.2011, 12:46   #8  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Цитата:
Сообщение от pitersky Посмотреть сообщение
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
pitersky а где это? в каком методе?
Старый 15.05.2011, 12:57   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
а где это? в каком методе?
Можно сразу же там где вы настраиваете фильтр.
Метод toString() класса QueryBuildDataSource просто возвращает строку, содержащую текст SQL запроса. Далее вы можете его присвоить какой-нибудь переменной, чтобы посмотреть её значение в дебагере, или просто вывести в инфолог.
X++:
info(this.query().dataSourceTable(tableNum(MyTable)).toString());
За это сообщение автора поблагодарили: timaluhs (1).
Старый 15.05.2011, 13:28   #10  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
добавила info
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Старый 15.05.2011, 13:43   #11  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Вы исправили ошибки, на которые вам указали участники обсуждения? Приведите ваш вариант кода, уже после исправлений.
Старый 15.05.2011, 14:03   #12  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Сделала два фильтра как советовал выше Владимир Максимов. Делает выборку как надо. Осталось проверить, что остальные фильтры не пострадали.
Огромное спасибо
Старый 19.05.2011, 14:59   #13  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
А как соорудить фильтр чтобы там было ИЛИ

в SQL требуемая информация выдаётся по след запросу

select * from mlm_TemporaryLeaveReport
where STARTDATE between дате1 and дате2 or ENDDATE between дате1 and дате2

т.е. чтобы одно из двух полей попало в интервал дат
Старый 19.05.2011, 15:26   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от timaluhs Посмотреть сообщение
А как соорудить фильтр чтобы там было ИЛИ

в SQL требуемая информация выдаётся по след запросу

select * from mlm_TemporaryLeaveReport
where STARTDATE between дате1 and дате2 or ENDDATE between дате1 and дате2

т.е. чтобы одно из двух полей попало в интервал дат
По возможности, таких условий следует избегать. Сделать можно, но сложно, муторно и без каких-либо гарантий. Подробности можно посмотреть, например, здесь

Расширенный запрос по дате

Проблема с подобными условиями в том, что никогда заранее не скажешь, сработает или нет. Надо добавить скобки или не надо. Надо добавить фиктивное условие или и так сработает. В общем, это из разряда "пальцем придерживать".
Старый 19.05.2011, 16:30   #15  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Посмотрела я ссылочку - спасибо. Дела совсем не весело.
А про какое фиктивное условие Вы говорите? и чем это может помочь?
В какую сторону мыслить?
Старый 19.05.2011, 17:14   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от timaluhs Посмотреть сообщение
Посмотрела я ссылочку - спасибо. Дела совсем не весело.
А про какое фиктивное условие Вы говорите? и чем это может помочь?
В какую сторону мыслить?
При формировании сложно-составных условий через символьную строку Axapta все-таки пытается распарсить указанное там значение именно как Value. Чтобы выделить возможные спец.символы диапазонов и отрицаний. Ну, Axapta ведь как-то "догадывается", что если в условии указать "1..2", то подобную строку надо преобразовать в условие SQL вроде "Field >= 1 AND Field <= 2"

Все описанные "танцы с бубном" вокруг дополнительных скобок, особых символов и разных комбинаций призваны как раз-таки обмануть этот стандартный анализатор. Заставить Axapta принять условие "как есть". Без дополнительного разбора. Иногда это удается. Иногда - нет. Вот когда не удается, но "очень хочется" начинаются всевозможные уловки.

Ну, например, перед сложным условием дописать нечто вроде

X++:
strFmt('((%1) == (%1)) &&  ((%2 > 0))', ...)

Первая часть, вроде бы, абсолютно бессмысленна. Поле всегда равно самому себе. Однако без этого, вроде бы, бессмысленного условия, корректный запрос не получается...

PS: Народ, не надо писать опровержение, что "у меня получается". Это просто пример. У Вас получилось - и замечательно! Но, "в общем случае" - без гарантий...
Старый 19.05.2011, 20:57   #17  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Честно говоря, в первый раз слышу про фиктивные условия. Вроде как, если строка условия начинается с открывающейся круглой скобки, то аксапта всегда переключается в режим расширенного синтаксиса и интерпретирует условие "как есть", а не как пользовательский фильтр отдельно взятого поля.

http://www.axaptapedia.com/Expressions_in_query_ranges
Цитата:
To specify the range value itself, certain rules must be followed:
  • The entire expression must be enclosed within single-quotes, not double-quotes
  • The entire expression must be enclosed in parenthesis (brackets)
  • Each sub-expression must be enclosed in its own set of parenthesis
  • For fields in the current table, simply the field name can be used
  • For fields in other tables, a prefix of the relevant datasource name must be added. This is not always the same as the table name.
  • String values should be surrounded by double-quotes, and wrapped in a call to queryValue()
  • Enum values should be specified by their integer value
  • Date values should be formatted using Date2StrXpp()
  • Blank string like ‘ ’ will not work as expected, use sysquery::valueEmptyString().
Старый 22.05.2011, 12:28   #18  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Navision
закон Мэрфи опять сработал
почему-то если rangeStart - фильтр по одному полю
rangeStart = qbds.addRange(fieldnum(MyTBL, STARTDATE));
rangeStart.value(strfmt('%1..%2',FromDate.valueStr(),ToDate.valueStr()));
то работает и даты как положено воспринимает

SELECT * FROM MyTBL WHERE ... AND ((StartDate>={ts '2011-01-01 00:00:00.000'} AND StartDate<={ts '2011-05-22 00:00:00.000'})) AND .....

а если
str rangeDate = strfmt("(((STARTDATE>=%1) and (STARTDATE<=%2)) or ((ENDDATE>=%1) and (ENDDATE<=%2)))", FromDate.valueStr(), ToDate.valueStr());
rangeDates = qbds.addRange(fieldNum(MyTBL ,RecId));
rangeDates.value(rangeDate); - фильтр по RecID

то даты имеют вид другой
SELECT * FROM MyTBL WHERE ... AND (((((STARTDATE>=01/01/2011) and (STARTDATE<=22/05/2011)) or ((ENDDATE>=01/01/2011) and (ENDDATE<=22/05/2011)))))
ещё ругается что какой-то скобки не хватает.

[Date values should be formatted using Date2StrXpp() ]

пыталась вместо FromDate.valueStr() - date2strxpp(FromDate) ругается
Argument '_date' ia incompatible with required type.
Старый 22.05.2011, 12:46   #19  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
[Date values should be formatted using Date2StrXpp() ]

пыталась вместо FromDate.valueStr() - date2strxpp(FromDate) ругается
Argument '_date' ia incompatible with required type.
Аргумент функции date2strxpp должен иметь тип дата. Попробуйте чтото вроде
X++:
date2strxpp(FromDate.DateValue())
Старый 22.05.2011, 13:04   #20  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
поставила
date2strxpp(FromDate.DateValue())
теперь SQL вообще какой-то кривой

(((((STARTDATE>=01\01\2011) and (STARTDATE<=22\05\2011)) or ((ENDDATE>=01\01\2011) and (ENDDATE<=22\05\2011)))))
Теги
query, querybuildrange, range, фильтр

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как правильно хранить статичный набор начальных данных в классах? mazzy DAX: Программирование 58 14.04.2011 12:10
Статистика по каждому коду номенклатуры. Как правильно построить Query? dynamax DAX: Программирование 17 14.10.2009 11:27
ERP-BLOG: Axapta, фильтр по сетке Blog bot DAX Blogs 26 05.02.2009 15:56
Исполнить сформированный фильтр radya DAX: Программирование 14 26.07.2007 20:47
Как правильно построить Query Bukovka DAX: Программирование 0 25.03.2004 11:55
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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