|
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() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
__________________
С уважением, Вячеслав |
|
15.05.2011, 12:46 | #3 |
newborn in DAX
|
|
|
15.05.2011, 12:57 | #4 |
Участник
|
Можно сразу же там где вы настраиваете фильтр.
Метод toString() класса QueryBuildDataSource просто возвращает строку, содержащую текст SQL запроса. Далее вы можете его присвоить какой-нибудь переменной, чтобы посмотреть её значение в дебагере, или просто вывести в инфолог. X++: info(this.query().dataSourceTable(tableNum(MyTable)).toString()); |
|
|
За это сообщение автора поблагодарили: timaluhs (1). |
15.05.2011, 13:28 | #5 |
newborn in DAX
|
добавила info
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще |
|
15.05.2011, 13:43 | #6 |
Участник
|
|
|
05.05.2011, 11:54 | #7 |
Участник
|
Значения фильтров с интервалом дат должны иметь формат (пример):
Цитата:
"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 | #8 |
северный Будда
|
А причём тут интервал дат? Надо отобрать строки, в которых первая дата меньше заданной, а вторая больше. Тут надо 2 Range накладывать на разные поля вообще-то.
Или я чего-то не понял...
__________________
С уважением, Вячеслав |
|
|
За это сообщение автора поблагодарили: Ivanhoe (1). |
05.05.2011, 12:00 | #9 |
Участник
|
Обратите внимание, что у автора range ставится на поле begin_date, а в самом фильтре еще и finish_date участвует. Почему было не сделать два range - по одному на каждое поле??
__________________
Ivanhoe as is.. |
|
05.05.2011, 12:00 | #10 |
Участник
|
Если не заморачиваться с возможным пустым значением полей, то, в данном случае, надо просто создать два отдельных 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 | #11 |
северный Будда
|
Согласен с Владимиром.
Единственное - не вижу необходимости в переменной firstOpen. По-моему, вполне достаточно внутри executeQuery получать TerminationDate.value(), а затем сравнивать его с dateNull(). Это тем более справедливо, если надо будет открывать форму с установленной заранее датой
__________________
С уважением, Вячеслав Последний раз редактировалось pitersky; 05.05.2011 в 12:12. |
|
19.05.2011, 20:57 | #12 |
Участник
|
Честно говоря, в первый раз слышу про фиктивные условия. Вроде как, если строка условия начинается с открывающейся круглой скобки, то аксапта всегда переключается в режим расширенного синтаксиса и интерпретирует условие "как есть", а не как пользовательский фильтр отдельно взятого поля.
http://www.axaptapedia.com/Expressions_in_query_ranges Цитата:
To specify the range value itself, certain rules must be followed:
|
|
22.05.2011, 12:28 | #13 |
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 | #14 |
Участник
|
Цитата:
X++: date2strxpp(FromDate.DateValue()) |
|
22.05.2011, 13:04 | #15 |
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))))) |
|
22.05.2011, 19:49 | #16 |
Участник
|
|
|
23.05.2011, 12:23 | #17 |
Участник
|
К примеру.
X++: qbrEmployDate.value( '(EmplTable.PayEmploymentDate_RU != '+date2StrXpp(datenull())+')' +'&&' +'(EmplTable.PayEmploymentDate_RU <= '+date2StrXpp(systemdateget())+')' ); qbrResignDate.value( '(EmplTable.PayResignedDate_RU !='+date2StrXpp(datenull())+')' +'&&' +'(EmplTable.PayResignedDate_RU < '+date2StrXpp(systemdateget())+')');
__________________
В подводной охоте главное вдох ... |
|
23.05.2011, 16:28 | #18 |
Участник
|
Ага. Можно и через display-метод. Только сдаётся мне, что display-метод может вызываться чаще чем ExecuteQuery.
|
|
24.05.2011, 09:08 | #19 |
newborn in DAX
|
|
|
24.05.2011, 09:17 | #20 |
Участник
|
Потому что executeQuery вызывается только в случае изменения параметров запроса. Именно в этот момент число выбранных записей может измениться. Например когда вы накладываете новый фильтр или убираете старый.
display-метод вызывается всякий раз, когда есть необходимость перерисовки содержимого окна. Например вы свернули и развернули окно. Это просто буде чуть больше нагружать систему. Т.е. это уже вопрос оптимизации. |
|
Теги |
query, querybuildrange, range, фильтр |
|
|