AXForum  
Go Back   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Forgotten Your Password?
Register Forum Rules FAQ Members List Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Old 05.05.2011, 11:29   #1  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
как правильно построить фильтр
Есть таблица, в которой для каждого сотрудника есть несколько строк с разницей в датах.
Весь период разбит на части по датам типа нашал работать - ушёл в отпуск(последн день перед отпуском)
нач отпуска - конец отпуска

ФИО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());
}

игнорирует фильтр и показывает все строчки для каждого сотрудника
что и где я не права? Спасибо
Old 05.05.2011, 11:46   #2  
pitersky is offline
pitersky
северный Будда
pitersky's Avatar
Ex AND Project
Соотечественники
 
1,518 / 435 (18) +++++++
Join Date: 26.09.2007
Location: Солнечная система
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
__________________
С уважением,
Вячеслав
Old 05.05.2011, 11:54   #3  
samolalex is offline
samolalex
Участник
samolalex's Avatar
Самостоятельные клиенты AX
 
259 / 107 (4) +++++
Join Date: 18.06.2010
Location: Москва
Значения фильтров с интервалом дат должны иметь формат (пример):
Quote:
"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));
__________________
С уважением, Александр.
Old 05.05.2011, 11:58   #4  
pitersky is offline
pitersky
северный Будда
pitersky's Avatar
Ex AND Project
Соотечественники
 
1,518 / 435 (18) +++++++
Join Date: 26.09.2007
Location: Солнечная система
А причём тут интервал дат? Надо отобрать строки, в которых первая дата меньше заданной, а вторая больше. Тут надо 2 Range накладывать на разные поля вообще-то.
Или я чего-то не понял...
__________________
С уважением,
Вячеслав
This post has been rated by: Ivanhoe (1).
Old 05.05.2011, 12:00   #5  
Ivanhoe is offline
Ivanhoe
Участник
Ivanhoe's Avatar
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2161 (81) +++++++++
Join Date: 29.09.2005
Location: Санкт-Петербург
Обратите внимание, что у автора range ставится на поле begin_date, а в самом фильтре еще и finish_date участвует. Почему было не сделать два range - по одному на каждое поле??
__________________
Ivanhoe as is..
Old 05.05.2011, 12:00   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,724 / 1208 (44) ++++++++
Join Date: 13.01.2004
Blog Entries: 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()))
}

Если же значения полей могут быть пустыми (есть дата начала, но нет даты конца или наоброт), то все значительно сложнее.
This post has been rated by: timaluhs (1).
Old 05.05.2011, 12:10   #7  
pitersky is offline
pitersky
северный Будда
pitersky's Avatar
Ex AND Project
Соотечественники
 
1,518 / 435 (18) +++++++
Join Date: 26.09.2007
Location: Солнечная система
Согласен с Владимиром.
Единственное - не вижу необходимости в переменной firstOpen. По-моему, вполне достаточно внутри executeQuery получать TerminationDate.value(), а затем сравнивать его с dateNull(). Это тем более справедливо, если надо будет открывать форму с установленной заранее датой
__________________
С уважением,
Вячеслав

Last edited by pitersky; 05.05.2011 at 12:12.
Old 15.05.2011, 12:46   #8  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
Quote:
Originally Posted by pitersky View Post
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
pitersky а где это? в каком методе?
Old 15.05.2011, 12:57   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,450 / 1792 (66) ++++++++
Join Date: 28.04.2007
Location: Калуга
Quote:
Originally Posted by timaluhs View Post
а где это? в каком методе?
Можно сразу же там где вы настраиваете фильтр.
Метод toString() класса QueryBuildDataSource просто возвращает строку, содержащую текст SQL запроса. Далее вы можете его присвоить какой-нибудь переменной, чтобы посмотреть её значение в дебагере, или просто вывести в инфолог.
X++:
info(this.query().dataSourceTable(tableNum(MyTable)).toString());
This post has been rated by: timaluhs (1).
Old 15.05.2011, 13:28   #10  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
добавила info
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Old 15.05.2011, 13:43   #11  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,450 / 1792 (66) ++++++++
Join Date: 28.04.2007
Location: Калуга
Quote:
Originally Posted by timaluhs View Post
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Вы исправили ошибки, на которые вам указали участники обсуждения? Приведите ваш вариант кода, уже после исправлений.
Old 15.05.2011, 14:03   #12  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
Сделала два фильтра как советовал выше Владимир Максимов. Делает выборку как надо. Осталось проверить, что остальные фильтры не пострадали.
Огромное спасибо
Old 19.05.2011, 14:59   #13  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
А как соорудить фильтр чтобы там было ИЛИ

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

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

т.е. чтобы одно из двух полей попало в интервал дат
Old 19.05.2011, 15:26   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,724 / 1208 (44) ++++++++
Join Date: 13.01.2004
Blog Entries: 3
Quote:
Originally Posted by timaluhs View Post
А как соорудить фильтр чтобы там было ИЛИ

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

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

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

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

Проблема с подобными условиями в том, что никогда заранее не скажешь, сработает или нет. Надо добавить скобки или не надо. Надо добавить фиктивное условие или и так сработает. В общем, это из разряда "пальцем придерживать".
Old 19.05.2011, 16:30   #15  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
Посмотрела я ссылочку - спасибо. Дела совсем не весело.
А про какое фиктивное условие Вы говорите? и чем это может помочь?
В какую сторону мыслить?
Old 19.05.2011, 17:14   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,724 / 1208 (44) ++++++++
Join Date: 13.01.2004
Blog Entries: 3
Quote:
Originally Posted by timaluhs View Post
Посмотрела я ссылочку - спасибо. Дела совсем не весело.
А про какое фиктивное условие Вы говорите? и чем это может помочь?
В какую сторону мыслить?
При формировании сложно-составных условий через символьную строку Axapta все-таки пытается распарсить указанное там значение именно как Value. Чтобы выделить возможные спец.символы диапазонов и отрицаний. Ну, Axapta ведь как-то "догадывается", что если в условии указать "1..2", то подобную строку надо преобразовать в условие SQL вроде "Field >= 1 AND Field <= 2"

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

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

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

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

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

http://www.axaptapedia.com/Expressions_in_query_ranges
Quote:
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().
Old 22.05.2011, 12:28   #18  
timaluhs is offline
timaluhs
newborn in DAX
timaluhs's Avatar
 
102 / 10 (1) +
Join Date: 16.12.2010
Location: Израиль
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.
Old 22.05.2011, 12:46   #19  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,450 / 1792 (66) ++++++++
Join Date: 28.04.2007
Location: Калуга
Quote:
Originally Posted by timaluhs View Post
[Date values should be formatted using Date2StrXpp() ]

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

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

 

Similar Threads
Thread Thread Starter Forum Replies Last Post
Как правильно хранить статичный набор начальных данных в классах? 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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Рейтинг@Mail.ru
All times are GMT +3. The time now is 00:51.
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Contacts E-mail, Advertising.