|  05.12.2008, 13:36 | #1 | 
| Участник | Не получается сформировать lookup по запросу с outer join 
			
			Здравствуйте. Может кто-нибудь подсказать, как реализовать лукап, для такого запроса: while select EmployeeTable where EmployeeTable.IsNotInUse == NoYes::No && EmployeeTable.EmployeeId != FCurrentEmployeeId /* var */ outer join TimeSheetTable where TimeSheetTable.EmployeeId == EmployeeTable.EmployeeId && TimeSheetTable.CurrentDate == FCurrentDate /* var */ { if ((!TimeSheetTable) || (EmploymentTable::find(TimeSheetTable.EmploymentAssessment).Value == 0) { // Нужно получить эти значения } } Условно схема такая: Таблица сотрудников: EmployeeTable; // EmployeeId, FullName Табель учета сотрудников: TimeSheetTable; // EmployeeId, EmploymentId, CurrentTime Таблица оценок занятости: EmploymentTable; // EmploymentId, Value Проблема состоит в том, что я не знаю, как отфильтровать условие ...if (!TimeSheetTable), которое в данном случае является необходимым. Пример кода: // 1 query = new Query(); masterSource = query.addDataSource(tableNum(EmployeeTable)); masterSource.orderMode(OrderMode::GroupBy); masterSource.addSortField(fieldNum(EmployeeTable, EmployeeId)); masterSource.addSortField(fieldNum(EmployeeTable, ScheduledNumber)); masterSource.addSortField(fieldNum(EmployeeTable, FullName)); masterSource.addRange(fieldNum(EmployeeTable, IsNotInUse)).value(StrFmt('%1', NoYes::No)); filterString = StrFmt('(%1 != "%2")', fieldStr(EmployeeTable, EmployeeId), TimeSheetTable.EmployeeId); // TimeSheetTable = ds masterSource.addRange(fieldNum(EmployeeTable, EmployeeId)).value(filterString); // 2 slaveSource = masterSource.addDataSource(tableNum(TimeSheetTable)); slaveSource.orderMode(OrderMode::GroupBy); slaveSource.joinMode(JoinMode::OuterJoin); slaveSource.addLink(fieldNum(EmployeeTable, EmployeeId), fieldNum(TimeSheetTable, EmployeeId)); filterString = Date2Str(FCurrentDate, 123, 2, 2, 2, 2, 2); slaveSource.addRange(fieldNum(TimeSheetTable, CurrentDate)).value(filterString); filterString = StrFmt('(%1 != "")', fieldStr(TimeSheetTable, EmploymentAssessment)); while select tEmploymentTable where (tEmploymentTable.Value == 0) { filterString += StrFmt(' || (%1 == "%2")', fieldStr(TimeSheetTable, EmploymentAssessment), tEmploymentTable.EmploymentId); } // Получается, что этот фильтр не работает... slaveSource.addRange(fieldNum(TimeSheetTable, EmploymentAssessment)).value(filterString); // 3 sysTableLookup = SysTableLookup::newParameters(tableNum(EmployeeTable), _formControl); sysTableLookup.addLookupfield(fieldNum(EmployeeTable, EmployeeId)); sysTableLookup.addLookupfield(fieldNum(EmployeeTable, ScheduledNumber)); sysTableLookup.addLookupfield(fieldNum(EmployeeTable, FullName)); sysTableLookup.parmQuery(query); sysTableLookup.performFormLookup(); Возможно я в чем-то ошибаюсь... Заранее спасибо. | 
|  | 
|  05.12.2008, 13:46 | #2 | 
| Программатор | 
			
			почему тут StrFmt(' || (%1 == "%2")',.......... а не StrFmt(' || ("%1" == "%2")',........... к примеру. Может загвоздка в кавычках или иных знаках? в инфолог выведите запрос и тут нам запостите. Сможем сказать больше | 
|  | 
|  05.12.2008, 14:20 | #3 | 
| Участник | 
			
			Применил кавычки - не получилось. Вообще, filterString получается такой: (EmploymentAssessment == "") || ("EmploymentAssessment" == "-") || ("EmploymentAssessment" == "н\а") Здесь "н\а" и "-" - какие-то оценки, имеющие ценность 0 . Расскажу подробней: Есть, табель учета, сформированный по штатному расписанию. Есть список сотрудников магазина. В общем случае, список сотрудников магазина больше штата (временные работники, штат другого магазина и пр.). Сотрудник из штата может не выйти на работу - для этого предуссмотрен инструмент, позволяющий выбрать из списка доступных сотрудников ему замену. Было желание в этом инструменте на лукап выводить список только тех сотрудников, которым еще не проставлены оценки занятости в табеле учета, чтобы исключить возможные махинации работников магазина. Но с другой стороны, в этот лукап должны попадать и сотрудники не входящие в штат. Отсюда и получается outer join табеля учета по отношению к полному списку сотрудников. В результате запроса получим такие элементы, где табличная переменная табеля будет не определена: (!TimeSheetTable) - временные работники, и те, где она определена, но оценка не выставлена: (EmploymentTable::find(TimeSheetTable.EmploymentAssessment).Value == 0) - свободные работники. В реализации этого кода лукап получается пустой. PS. Допустил в тексте ошибку: filterString = StrFmt('(%1 == "")', fieldStr(TimeSheetTable, EmploymentAssessment)); while select tEmploymentTable... | 
|  | 
|  05.12.2008, 14:27 | #4 | 
| Участник | 
			
			Поправка: Лукап получился пустым, потому что я применил кавычки =) - они не нужны там. НО: 1) в списке нет внештатных работников; 2) выпадают только те, у кого, оценка "-". "н\а" не выпадает. Такое ощущение, что это логическая ошибка, только не могу понять где =( | 
|  | 
|  05.12.2008, 14:59 | #5 | 
| Участник | 
			
			Не вникая в суть кода, скажу, что мне бросился в глаза символ \. Он там ничего в самой СУБД не экранирует?
		 
				__________________ | 
|  | 
|  05.12.2008, 15:00 | #6 | 
| Участник | SysQuery 
			
			2 dawl: Замените конструкции filterString = .. ; masterSource.addRange(...).value(filterString) там где возможно на использование SysQuery::value() и прочие static методы этого класса - код будет проще читаться: Цитата: 
		
			filterString    = StrFmt('(%1 != "%2")', fieldStr(EmployeeTable, EmployeeId), TimeSheetTable.EmployeeId); // TimeSheetTable = ds masterSource.addRange(fieldNum(EmployeeTable, EmployeeId)).value(filterString); X++: ...
masterSource.addRange( fieldNum(EmployeeTable, EmployeeId) ).value( SysQuery::valueNot( FCurrentEmployeeId ) );
...Цитата: 
		
			// 2 filterString = Date2Str(FCurrentDate, 123, 2, 2, 2, 2, 2); slaveSource.addRange(fieldNum(TimeSheetTable, CurrentDate)).value(filterString); X++: ...
slaveSource.addRange(fieldNum(TimeSheetTable, CurrentDate)).value( SysQuery::value( FCurrentDate ) );
...Цитата: 
		
			EmployeeTable.EmployeeId != FCurrentEmployeeId /* var */
		
	 Цитата: 
		
			filterString    = StrFmt('(%1 != "%2")', fieldStr(EmployeeTable, EmployeeId), TimeSheetTable.EmployeeId); // TimeSheetTable = ds masterSource.addRange(fieldNum(EmployeeTable, EmployeeId)).value(filterString); Последний раз редактировалось petergunn; 05.12.2008 в 15:07. | 
|  | |
| За это сообщение автора поблагодарили: dawl (1). | |
|  05.12.2008, 15:12 | #7 | 
| Участник | класс SysTableLookup 
			
			В данном классе есть метод parmTmpBuffer - в него передается временная таблица, из которой и будут браться данные для lookup-а. P.S. Единственный минус данного решения - это производительность, поскольку временную таблицу нужно заполнить. | 
|  | |
| За это сообщение автора поблагодарили: dawl (1). | |