30.11.2008, 16:03 | #1 |
Участник
|
Как избежать отмены фильтра на форме
Имеется форма, которая, в частности, показывает количество доступной номенклатуры на складе. Она вызывается из формы по созданию строк в складском журнале. При открытии формы с доступной номенклатурой, в методе run() накладывается фильтр на склад, указанный в вызывающей форме. Но если вдруг пользователь нажимает кнопку сброса фильтра, наложенный фильтр сбрасывается, и становится доступна номенклатура с других складов. Собственно вопрос, как сделать так, чтобы этот фильтр нельзя было сбросить? Может накладывать его надо в другом месте, или восстанавливать в каком-то другом методе?
|
|
30.11.2008, 16:11 | #2 |
Участник
|
Если я правильно помню, то вам необходимо наложить фильтр в методе excuteQuery() на datasource. Тогда даже кнопка сброса фильтра изначально тоже станет недоступной.
|
|
30.11.2008, 16:27 | #3 |
MCITP
|
а может лучше диналинк таки прикрутить к складу? красивее будет, мне кажется.
ну либо, как отметил longson, пробивайте фильтр на executeQuery(), только проверьте, что нет других условий на склад, иначе будет "или". Должно быть только одно условие на склад - ваше. Так как executeQuery() выполняется собственно в момент выполнения запроса, то перебить этот фильтр уже никто не сможет.
__________________
Zhirenkov Vitaly |
|
30.11.2008, 20:20 | #4 |
Участник
|
Цитата:
Диналинк при просмотре остатков срабатывает на InventSum по буферу InventJournalTrans ... В обоих склада нету в принципе - он в при-joinen-ом InventDim. Вывести в форму отображения остатков галчонку "фильтр по складу", по ее значению/изменению в executeQuery() у InventDim либо добавлять залоченный range по складу из соотвествующего InventDim'у от InventJournalTrans либо не добавлять. И овцы сыты, и волки целы |
|
30.11.2008, 21:15 | #5 |
Участник
|
При сбросе фильтра используется запрос, хранящийся в ds.Query(), т.е. то, что добавлено в _ds.QueryRun().Query() теряется.
Для формирования фильтров используйте метод Init() датасорса - он вызывается один раз при его создании.
__________________
Axapta v.3.0 sp5 kr2 |
|
30.11.2008, 22:17 | #6 |
MCITP
|
Сорри, я условие невнимательно протитал похоже...
Да, в стандарте такое сложновато будет так сделать. Можно сделать это всё и в ините датасорса, но тогда нужно блокировать этот range().
__________________
Zhirenkov Vitaly |
|
30.11.2008, 23:50 | #7 |
MCITP
|
Если на инит датасорса, то выглядит так:
X++: public void init() { QueryBuildRange qbr; ; super(); qbr = this.query().dataSourceNo(1).findRange(fieldNum(InventLocation, InventLocationId)); if (! qbr ) qbr = this.query().dataSourceNo(1).addRange(fieldNum(InventLocation, InventLocationId)); qbr.value(queryValue("ля-ля-ля")); //qbr.status(RangeStatus::Locked); } В принципе то же самое можно сделать и на executeQuery(), но этот вариант не считается "бест практис": X++: public void executeQuery() { QueryBuildRange qbr; ; qbr = this.query().dataSourceNo(1).findRange(fieldNum(InventLocation, InventLocationId)); if (! qbr ) qbr = this.query().dataSourceNo(1).addRange(fieldNum(InventLocation, InventLocationId)); qbr.value(queryValue("ля-ля-ля")); //qbr.status(RangeStatus::Locked); super(); } Как ни странно (я тоже не ожидал), оба этих варианта оказались с точки зрения пользователя одинаковые. (Либо я что-то не заметил)
__________________
Zhirenkov Vitaly |
|
01.12.2008, 09:25 | #8 |
Участник
|
Точно.
|
|
01.12.2008, 09:32 | #9 |
Участник
|
Цитата:
X++: SysQuery::findOrCreateRange(this.query().dataSourceTable(tablenum(InventLocation)),fieldNum(InventLocation, InventLocationId)); |
|
|
За это сообщение автора поблагодарили: ZVV (1), aidsua (1). |
01.12.2008, 09:45 | #10 |
MCITP
|
Цитата:
Это просто был тестовый пример, совсем не на это. А SysQuery::findOrCreateRange - действительно интерестно, не знал (или забыл). надо запомнить
__________________
Zhirenkov Vitaly |
|
01.12.2008, 09:57 | #11 |
Участник
|
DAX 4.0 - реализация примера одной строкой
Цитата:
X++: qbr = this.query().dataSourceNo(1).findRange(fieldNum(InventLocation, InventLocationId)); if (! qbr ) qbr = this.query().dataSourceNo(1).addRange(fieldNum(InventLocation, InventLocationId)); qbr.value(queryValue("ля-ля-ля")); //qbr.status(RangeStatus::Locked); будет выгдядеть как: X++: ... findOrCreateRange_W( this.query().dataSourceTable(tablenum(InventLocation)), fieldNum(InventLocation, InventLocationId), queryValue("ля-ля-ля") ).status(RangeStatus::Locked); ... |
|
01.12.2008, 10:58 | #12 |
Участник
|
2 zvv
Что будет срабатывать - это понятно. Только executeQuery() срабатывает каждый раз, когда запрос отправляется на сервер, в том числе и при фильтрации или сортировке. Будут избыточные вызовы.
__________________
Axapta v.3.0 sp5 kr2 |
|
01.12.2008, 11:14 | #13 |
MCITP
|
Цитата:
Просто изночально думалось, что сброс фильтра не будет оставлять это, а оказалось оставляет. Это раз. А второй прикол, который я заметил в этом случае такой: Когда нажимешь сброс фильтра, то код, добавляющий рэндж на executeQuery(), отрабатывает и добавляет ещё один (прикольно, если не делать findOrCreate ). А если просто делать "фильтр" и выполнять запрос ещё раз, то код на executeQuery() как бы отрабатывает, но на действующую кверю это не "возымевает" никакого действия - все рэнджи остаются как в фильтре! Вот так-то.
__________________
Zhirenkov Vitaly |
|
01.12.2008, 11:27 | #14 |
Участник
|
Тут надо помнить про такую вещь - пользовательские фильтры добавляются на _ds.QueryRun().Query(). При вызове пользовательского фильтра или при программном вызове research() во вновь создаваемый QueryRun передается _ds.QueryRun().Query() (в отличие от простого вызова ExecuteQuery() - там передается _ds.Query()).
По-этому, если делать какие-либо изменения в _ds.Query() внутри метода ExecuteQuery(), то есть вероятность рассогласования с пользовательским фильтром.
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: ZVV (1). |
01.12.2008, 21:45 | #15 |
Участник
|
Какая дискуссия получилась, не ожидал. Буду осмысливать написанное, спасибо
|
|
|
|