AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.02.2024, 19:22   #1  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
SysLookupMultiselectCtrl отметить значения
D365 id

На форме добавлен фильтр (используется для фильтрации данных в нижерасположенном гриде)
При нажатии на него выпадает multiselect lookup. Состоит он из одной колонки значений.
Запрос, который передается при создании этого лукапа, он с группировками, поэтому recid там нет.

Как заставить SysLookupMultiselectCtrl при переоткрывании фильтра отметить ранее выбранные значения?
(из того, что вижу в SysLookupMultiselectGrid->markSelected(), кажется, что невозможно отметить без recid, но надежда умирает последней)

И еще вопрос: для отлавливания lookup события создан класс-handler формы, где есть handler myFilterControl_onLookup. Когда использовала обычный systablelookup , то этот myFilterControl_onLookup вызывался . Когда заменила на SysLookupMultiselectCtrl , то почему-то это событие перестало отлавливаться. Как так? Оно же от контрола формы, а не типа выпадающего лукапа зависеть должно

Спасибо

Последний раз редактировалось Lankey; 16.02.2024 в 19:48.
Старый 16.02.2024, 20:05   #2  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Lankey Посмотреть сообщение
Запрос, который передается при создании этого лукапа, он с группировками, поэтому recid там нет.
В качестве идеи:
А если в запрос добавить агрегатную функцию по RecId, например maxof(RecId), не поможет?
За это сообщение автора поблагодарили: Lankey (1).
Старый 16.02.2024, 22:41   #3  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Гениально! Спасибо
Да, так работает, но добавляется колонка с RecId в лукап
Получается не очень user friendly (
Старый 17.02.2024, 10:14   #4  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Имхо, системный SysLookupMultiselectGrid сделан с багом
Его метод markSelected позволяет отметить строки на основании любого поля, то есть не обязательно recId (он для этого использует ds.positionRecordByValue())
Но! это работает только, если контейнер с RecId выбранных строк пуст

А он никогда не будет пуст, тк даже если поле RecID отсутствует в запросе (как в моем случае с группировкой) , то в методе getSelected просто забивается 0 в контейнер : selectedID +=common.RecId. То есть, создается контейнер с количеством нулей равным количеству выбранных строк .. и он поэтому никогда пустым не будет
---

Если же, как workaround, явно добавить RecID в запрос через max(recID), то RecID, как и все другие поля datasource, автоматически добавляются в grid в методе buildDesign, поэтому скрыть его невозможно.
Старый 17.02.2024, 17:50   #5  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Lankey Посмотреть сообщение
Гениально! Спасибо
Да, так работает, но добавляется колонка с RecId в лукап
Можно создать View на основе такого сгруппировано запроса с RecId. И уже по этому View строить лукап. RecId не нужно будет явно указывать в списке полей, но в выборке по View он будет. Должно сработать
Старый 17.02.2024, 21:28   #6  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Хорошая идея, спасибо
Я попробовала, но, когда указываю Max (RecId) в запросе, что использую потом во view, то view создается с константным значением(1010 в моем случае) в колонке RecId, а не результатом агрегатной функции
(я посмотрела сформированный запрос на стороне sql server select....Myfield as Myfield, 1010 as RecId from MyTable group by Myfield)
Пробовала поменять на Min - то же самое происходит.

Попробовала без запроса, т.е напрямую во view выбрать max(RecId), но он тогда колонку переименовывает в RecId1 (и выдает ошибку "Cannot rename RecId1 to RecId . Table field name cannot be the same as system defined name")
Старый 19.02.2024, 21:23   #7  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Попробовала с временной таблицей, но не понимаю, каким образом ее буфер передать в SysLookupMultiselectGrid? (Тут нет parmTmpBuffer() как на SysTableLookup )
Есть какая-то возможность это обойти?

Последний раз редактировалось Lankey; 19.02.2024 в 22:36.
Старый 20.02.2024, 07:32   #8  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
365 / 542 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Если говорить про техническую реализацию, то примеры есть в стандарте - класс EREnumLookupMultiSelectGrid, метод new, передача через QueryRun.

X++:
        container selectedFields = [tableNum(SysOperationMultiSelectTmp), fieldName2id(tableNum(SysOperationMultiSelectTmp), fieldStr(SysOperationMultiSelectTmp, Values))];

        selectTableTmp = this.getMultiSelectTableForEnum(_enumId, _valuesToSkip);

        QueryRun localQueryRun = SysOperationHelper::getMultiSelectQueryRun(selectTableTmp);
        
        this.parmCallingControl(_targetStringControl);
        this.parmQuery(localQueryRun.query());
        this.parmQueryRun(localQueryRun);
Правда использовать временные таблички в лукапах, имеет смысл, если условно там выбор из десятка значений, иначе тормоза при открытии лукапа, будут раздражать куда больше, чем recId в колонке справа.

Также можно в качестве времянки использовать TempDB, заполнять ее прямым запросом через Query::insert_recordset, будет работать быстро, но выглядит это все как какой то Overengineering, ради лукапа.

Я бегло посмотрел по перекрестным ссылкам в стандарте, есть пример (да там нет группировки, может быть можно сделать примерно так же - скрытый контрол с recId - StatisticsOnInvoiceUIBuilder?).

X++:
    private void initPostingProfilesDialogField()
    {
        DialogField postingProfilesField = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(StatisticsOnInvoiceDataContract, parmPostingProfiles));
        postingProfilesField.registerOverrideMethod(
            methodStr(FormDateControl, lookup),
            methodStr(StatisticsOnInvoiceUIBuilder, postingProfilesLookup),
            this);
        postingProfilesField.lookupButton(FormLookupButton::Always);

        SysOperationDialog reportDialogBox = this.dialog();
        postingProfilesRecIdsControl = reportDialogBox.formRun().design().addControl(FormControlType::String, PostingProfilesRecIdsControlName);
        postingProfilesRecIdsControl.visible(false);
    }

    private void postingProfilesLookup(FormStringControl _postingProfilesControl)
    {
        Query query = new Query();
        QueryBuildDataSource qbds = query.addDataSource(tableNum(VendLedger));
        QueryBuildFieldList qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(fieldNum(VendLedger, PostingProfile));
        qbfl.addField(fieldNum(VendLedger, Name));

        container selectFields = [ tableNum(VendLedger), fieldNum(VendLedger, PostingProfile) ];

        SysLookupMultiSelectGrid::lookup(
            query,
            _postingProfilesControl,
            postingProfilesRecIdsControl,
            _postingProfilesControl,
            selectFields);
    }
Если все же нельзя, то может сделать свою лукап-форму ? расширить функционал базового класса, чтобы можно было скрыть контрол с recId ?
__________________
Sergey Nefedov

Последний раз редактировалось SRF; 20.02.2024 в 07:39.
За это сообщение автора поблагодарили: Lankey (1).
Старый 20.02.2024, 11:07   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Lankey Посмотреть сообщение
Имхо, системный SysLookupMultiselectGrid сделан с багом
Его метод markSelected позволяет отметить строки на основании любого поля, то есть не обязательно recId (он для этого использует ds.positionRecordByValue())
Но! это работает только, если контейнер с RecId выбранных строк пуст

А он никогда не будет пуст, тк даже если поле RecID отсутствует в запросе
А если принудительно обнулять после каждого выбора? Например, вызывать метод установки значений с переопределением по выбранному, но контейнер с RecId передавать пустой
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 01.03.2024, 09:46   #10  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Цитата:
Сообщение от SRF Посмотреть сообщение
Если говорить про техническую реализацию, то примеры есть в стандарте - класс EREnumLookupMultiSelectGrid, метод new, передача через QueryRun.
Гениально. Спасибо большое! Сделала, опираясь на этот пример. Все работает!

А какая раница между Lookup vs OnLookup в 365?

На контроле формы (форма тут моя, в моей модели, т.е кастомная) доступен метод Lookup() и его можно переопределить в коде формы. В вышеуказанных примерах стандарта именно он используется.

Я делала изначально через класс event handler и там описала OnLookup контрола. Вроде, оба, и Lookup и OnLookup, отрабатывают. То есть, нет разницы. Только писать лишний класс ради одного метода-обработника события как-то слишком. Думаю оставить подход через lookup
Старый 01.03.2024, 11:21   #11  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,275 / 3476 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Lankey Посмотреть сообщение
А какая раница между Lookup vs OnLookup в 365?
Для своей формы технически разницы нет. Однако с т.з. дальнейших раскопок кода всё-таки лучше как-то договориться внутри команды разработки об использовании единого подхода (мне, лично нравится Lookup)

Разница появляется тогда, когда надо сделать расширение и нет возможности сделать / использовать Lookup. Тогда использование event handler-а очень помогает. Правда тут опять-таки подводный камень в том, чтобы договориться внутри команды разработки об использовании единого подхода. Иначе можно написать много разных Event Handler-ов в разных классах, после чего они все дружно вызовутся, пользователь удивится, а разработчик, который будет искать эту ошибку - долго будет искать причину проблемы.
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: Lankey (1).
Старый 07.03.2024, 22:47   #12  
Lankey is offline
Lankey
Участник
 
53 / 13 (1) ++
Регистрация: 19.05.2020
Так, все работает, но другой глупый вопрос появился:

Этот multiselect фильтрует данные на форме. То есть, в init я на DS добавляю range и в executeQuery на этот query().datasource().range добавляю условие. Вроде. стандартный подход. Все работает. Ок

На этой форме грид, в нем колонка, и, соответственно, стандартная созможность добавить по ней фильтр.
И это та же колонка, по которой фильтрует отдельно существующий в шапке формы multiselect.

То есть, по факту, на форме две возможности фильтровать одну и ту же колонку : мой мультиселект и стандартный фильтр в шапке грида.

Теперь : Если пользователь меняет стд фильтр, то они хотят , чтобы это изменение отражалось в мультиселекте. Например, убрал один из критериев, и в мультиселекте он должен исчезнуть тоже.

Ну ок, я после super() в executeQuery отлавливаю range.value , что пользователь установил, и передаю в mymultiselect.text()

Меня озадачивает, что пользовательские фильтры накладываются на queryRun, а не query. То есть, получается, мне надо изменить мой подход для multiselect - не создавать range в init на query().datasource(), а создавать range и меня ть только на queryRun в executeQuery.
Это правильный подход?
Теги
d365

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Сохранение и подстановка значения multi-select control с последующим использованием в запросах Cardagant DAX: Программирование 1 05.04.2015 22:58
dax-lessons: On dialogs – SysLookupMultiSelectCtrl in Dynamics AX 6.0 Blog bot DAX Blogs 0 09.06.2011 03:27
dax-lessons: SysLookupMultiSelectCtrl in Dynamics AX 6.0 [AX 2012, X++] Blog bot DAX Blogs 0 08.06.2011 21:11
где хранятся значения полей удаленных строк? chanchala DAX: Программирование 16 04.09.2008 10:45
Как получить значения полей (modifiedDate, modifiedTime, modifiedBy и др.) при работе с объектами AOT типа Map? LRA DAX: База знаний и проекты 15 02.04.2007 13:37
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:20.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.