05.05.2011, 11:29 | #1 |
newborn in DAX
|
как правильно построить фильтр
Есть таблица, в которой для каждого сотрудника есть несколько строк с разницей в датах.
Весь период разбит на части по датам типа нашал работать - ушёл в отпуск(последн день перед отпуском) нач отпуска - конец отпуска ФИО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 |
северный Будда
|
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
__________________
С уважением, Вячеслав |
|
05.05.2011, 11:54 | #3 |
Участник
|
Значения фильтров с интервалом дат должны иметь формат (пример):
Цитата:
"01.01.2011..01.02.2011"
X++: rangeTermination.value(strfmt("%1..%2", StartDate, EndDate)); X++: rangeTermination.value(SysQuery::range(StartDate, EndDate));
__________________
С уважением, Александр. |
|
05.05.2011, 11:58 | #4 |
северный Будда
|
А причём тут интервал дат? Надо отобрать строки, в которых первая дата меньше заданной, а вторая больше. Тут надо 2 Range накладывать на разные поля вообще-то.
Или я чего-то не понял...
__________________
С уважением, Вячеслав |
|
|
За это сообщение автора поблагодарили: Ivanhoe (1). |
05.05.2011, 12:00 | #5 |
Участник
|
Обратите внимание, что у автора range ставится на поле begin_date, а в самом фильтре еще и finish_date участвует. Почему было не сделать два range - по одному на каждое поле??
__________________
Ivanhoe as is.. |
|
05.05.2011, 12:00 | #6 |
Участник
|
Если не заморачиваться с возможным пустым значением полей, то, в данном случае, надо просто создать два отдельных 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 |
северный Будда
|
Согласен с Владимиром.
Единственное - не вижу необходимости в переменной firstOpen. По-моему, вполне достаточно внутри executeQuery получать TerminationDate.value(), а затем сравнивать его с dateNull(). Это тем более справедливо, если надо будет открывать форму с установленной заранее датой
__________________
С уважением, Вячеслав Последний раз редактировалось pitersky; 05.05.2011 в 12:12. |
|
15.05.2011, 12:46 | #8 |
newborn in DAX
|
|
|
15.05.2011, 12:57 | #9 |
Участник
|
Можно сразу же там где вы настраиваете фильтр.
Метод toString() класса QueryBuildDataSource просто возвращает строку, содержащую текст SQL запроса. Далее вы можете его присвоить какой-нибудь переменной, чтобы посмотреть её значение в дебагере, или просто вывести в инфолог. X++: info(this.query().dataSourceTable(tableNum(MyTable)).toString()); |
|
|
За это сообщение автора поблагодарили: timaluhs (1). |
15.05.2011, 13:28 | #10 |
newborn in DAX
|
добавила info
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще |
|
15.05.2011, 13:43 | #11 |
Участник
|
|
|
15.05.2011, 14:03 | #12 |
newborn in DAX
|
Сделала два фильтра как советовал выше Владимир Максимов. Делает выборку как надо. Осталось проверить, что остальные фильтры не пострадали.
Огромное спасибо |
|
19.05.2011, 14:59 | #13 |
newborn in DAX
|
А как соорудить фильтр чтобы там было ИЛИ
в SQL требуемая информация выдаётся по след запросу select * from mlm_TemporaryLeaveReport where STARTDATE between дате1 and дате2 or ENDDATE between дате1 and дате2 т.е. чтобы одно из двух полей попало в интервал дат |
|
19.05.2011, 15:26 | #14 |
Участник
|
Цитата:
Расширенный запрос по дате Проблема с подобными условиями в том, что никогда заранее не скажешь, сработает или нет. Надо добавить скобки или не надо. Надо добавить фиктивное условие или и так сработает. В общем, это из разряда "пальцем придерживать". |
|
19.05.2011, 16:30 | #15 |
newborn in DAX
|
Посмотрела я ссылочку - спасибо. Дела совсем не весело.
А про какое фиктивное условие Вы говорите? и чем это может помочь? В какую сторону мыслить? |
|
19.05.2011, 17:14 | #16 |
Участник
|
Цитата:
Все описанные "танцы с бубном" вокруг дополнительных скобок, особых символов и разных комбинаций призваны как раз-таки обмануть этот стандартный анализатор. Заставить Axapta принять условие "как есть". Без дополнительного разбора. Иногда это удается. Иногда - нет. Вот когда не удается, но "очень хочется" начинаются всевозможные уловки. Ну, например, перед сложным условием дописать нечто вроде X++: strFmt('((%1) == (%1)) && ((%2 > 0))', ...) Первая часть, вроде бы, абсолютно бессмысленна. Поле всегда равно самому себе. Однако без этого, вроде бы, бессмысленного условия, корректный запрос не получается... PS: Народ, не надо писать опровержение, что "у меня получается". Это просто пример. У Вас получилось - и замечательно! Но, "в общем случае" - без гарантий... |
|
19.05.2011, 20:57 | #17 |
Участник
|
Честно говоря, в первый раз слышу про фиктивные условия. Вроде как, если строка условия начинается с открывающейся круглой скобки, то аксапта всегда переключается в режим расширенного синтаксиса и интерпретирует условие "как есть", а не как пользовательский фильтр отдельно взятого поля.
http://www.axaptapedia.com/Expressions_in_query_ranges Цитата:
To specify the range value itself, certain rules must be followed:
|
|
22.05.2011, 12:28 | #18 |
newborn in DAX
|
закон Мэрфи опять сработал
почему-то если 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 |
Участник
|
Цитата:
X++: date2strxpp(FromDate.DateValue()) |
|
22.05.2011, 13:04 | #20 |
newborn in DAX
|
поставила
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, фильтр |
|
|