|  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, фильтр | 
|  | 
| 
 |