|
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). |