31.07.2023, 13:23 | #1 |
Участник
|
Lookup задваиваются значения
Делаю Lookup на контроле формы (надо вывести все уникальные значения поля таблицы)
X++: SysTableLookup sysTableLookup = SysTableLookup::newParameters(tablenum(VendTrans), this); Query query; QueryBuildDataSource queryBuildDataSource; QueryBuildRange queryBuildRange; ; query = new Query(); queryBuildDataSource = query.addDataSource(tablenum(VendTrans)); queryBuildDataSource.addSortField(fieldnum(VendTrans, FIELD)); queryBuildDataSource.addGroupByField(fieldnum(VendTrans, FIELD)); sysTableLookup.addLookupfield(fieldnum(VendTrans, FIELD)); sysTableLookup.parmQuery(query); sysTableLookup.performFormLookup(); Как правильно это сделать? |
|
31.07.2023, 13:38 | #2 |
Участник
|
Вроде был баг в какой-то из версий, когда в лукапах сбрасывался group by
Вроде бы можно было обойти если расположить метод лукапа не на поле датасорса а на контроле. Но точно уже не помню. |
|
31.07.2023, 13:52 | #3 |
Мрачный тип
|
Стандартный SysTableLookup крайне криво работает с переданным запросом - если есть хоть одно пересечение м-ду полями группировки в запросе и полями в лукапе, группировка сбрасывается.
Вся "радость" происходит в buildSelectionList() , можете сравнить свой queryBuildDataSource в своем lookup() и в buildSelectionList() в конце его исполнения - будете удивлены (group by исчезнет). Решение - контролировать добавление полей ТАМ на каждой итерации цикла на отсутствие их в queryBuildDataSource fields()
__________________
Мы летаем, кружимся, нагоняем ужасы ... |
|
31.07.2023, 14:09 | #4 |
Участник
|
Если не вдаваться в подробности решения технической проблемы, а решать бизнес задачу, то лукап по проводкам лучше не делать, а сделать по справочнику, где значения уникальны, и если есть потребность проверить участвовало ли данное значение в проводках, то проверить на этапе сохранения значения
|
|
|
За это сообщение автора поблагодарили: Logger (3). |
31.07.2023, 14:36 | #5 |
Участник
|
Цитата:
Сообщение от TasmanianDevil
Стандартный SysTableLookup крайне криво работает с переданным запросом - если есть хоть одно пересечение м-ду полями группировки в запросе и полями в лукапе, группировка сбрасывается.
Вся "радость" происходит в buildSelectionList() , можете сравнить свой queryBuildDataSource в своем lookup() и в buildSelectionList() в конце его исполнения - будете удивлены (group by исчезнет). Решение - контролировать добавление полей ТАМ на каждой итерации цикла на отсутствие их в queryBuildDataSource fields() Мне казалось бага где-то в ядре сидит. |
|
31.07.2023, 15:15 | #6 |
Участник
|
Попробуйте добавить
X++: sysTableLookup.parmUseLookupValue(false); |
|
|
За это сообщение автора поблагодарили: Logger (3). |
01.08.2023, 11:24 | #7 |
Участник
|
Если поле Field - это ссылка на справочник, то можно сделать Query по этому справочнику и через Exists Join добавить ограничение на факт наличия проводки. Можно, кстати, параметризировать добавление Exists. Т.е. по дополнительному параметру или выдавать все записи справочника или только с ограничением
Если совсем уж ничего не поможет, то вместо Query, можно наполнить временную таблицу и через parmTmpBuffer() передать как источник данных LookUp Хотя, все-таки соглашусь с ice. Если это действительно ссылка на справочник, то лучше не фильтровать выпадающий список, а проверять уже выбранное значение.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
01.08.2023, 12:18 | #8 |
Мрачный тип
|
А почему нет ?
SysTableLookup - открытый класс. X++: protected void buildSelectionList(Query _query) { QueryBuildDataSource queryBuildDataSource = _query.dataSourceTable(tableId); QueryBuildFieldList selectedFields; boolean returnItem; str method; int fieldId; int i; //+ ТумОВ 02.12.2022 boolean fieldSelected(FieldId _id) { int j; FieldId selectedFieldId; for( j = 1 ; j <= selectedFields.fieldCount() ; j++ ) { selectedFieldId = selectedFields.field(j); if(selectedFieldId == _id) return true; } return false; }; //- ТумОВ 02.12.2022 if (!queryBuildDataSource) { return; } selectedFields = queryBuildDataSource.fields(); for (i = 1; i <= conlen(lookupItems); i++) { [fieldId, returnItem, method] = conpeek(lookupItems, i); // // FieldId could be 0 if current element represents a display method used // to return values for a lookup column. // If fieldId is 0 then there is no sense to add it to the selection list of the query. // //+ ТумОВ 02.12.2022 //todo А если, <censored>, поле уже выбрано как агрегат в ранее переданном запросе - на<censored> агрегацию ? //if (fieldId) if (fieldId && !fieldSelected(fieldId)) //- ТумОВ 02.12.2022 { queryBuildDataSource.addSelectionField(fieldId); } } }
__________________
Мы летаем, кружимся, нагоняем ужасы ... |
|
|
За это сообщение автора поблагодарили: Logger (10). |
02.08.2023, 13:28 | #9 |
северный Будда
|
У меня была такая ситуация на одном из проектов
Решил банальной очисткой контрола перед запуском лукапа Присоединяюсь к предыдущим ораторам, что лукап с группировкой решение очень плохое, надо его делать только по уникальному полю таблицы
__________________
С уважением, Вячеслав |
|
03.08.2023, 10:56 | #10 |
Мрачный тип
|
Почему же ?
Задача ограничения списка выбора значений какого-либо классификатора по набору его "засветившихся" позиций из какой-то порции транзакционных данных - регулярно возникающая задача, решаемая при минимуме трудозатрат именно так
__________________
Мы летаем, кружимся, нагоняем ужасы ... |
|
03.08.2023, 12:39 | #11 |
Участник
|
Цитата:
Т.е. как решение "по быстрому", чтобы "отвязаться" - пойдет. Но позже, сам же будешь это все исправлять
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: S.Kuskov (5). |
04.08.2023, 10:30 | #12 |
Мрачный тип
|
addLookupMethod() - и баба с возу, и волки сыты
__________________
Мы летаем, кружимся, нагоняем ужасы ... |
|
05.08.2023, 18:37 | #13 |
Участник
|
Для себя я как-то решил, что в таких программных лукапах, где есть группировка, использовать временные таблицы (конечно, в 2012 те, что TempDB) или вьюхи.
Конечно, можно программно заткнуть описанные в теме проблемы, но практически любое их таких решений выключает возможности хоть как-то влиять на скорострельность. В общем, что-то сделано, вроде работает, но как оптимизировать скорость работы таких частичных "затычек" непонятно в принципе. |
|
05.08.2023, 21:46 | #14 |
северный Будда
|
Ну вообще-то кмк решаться она должна через exists join классификатора и транзакций. Так и работать быстрее будет, и идеологически корректно
__________________
С уважением, Вячеслав |
|
Теги |
lookup, законченный пример |
|
|