|
12.09.2013, 18:03 | #1 |
Участник
|
Ограничение выборки перед открытием формы - как лучше сделать?
Есть форма на основе временной таблицы, она показывает вычисленные значения для каждой номенклатуры(около 15 полей на каждую номенклатуру).
Нужно ограничить количество записей в нее попадающих. Открывать сразу все, а потом накладывать фильтры - не вариант, тк она 100 лет рассчитываться будет + да и пользователю не нужны все записи. Они бы предпочли сразу указывать критерии,т.е какие номенклатуры им нужно рассчитать и показать. Как по бест-практис правильней сделать? Я пока думаю так: 1) класс MyClass- наследник runBase, кот показывает диалог для выбора критериев накладываемых на InventTable. Сформированный запрос по InventTable будет использоваться для ограничения количества номенклатур , попадающих в расчет врем талицы. 2) в его MyClass.run() по X++: new MenuFunction(menuitemdisplaystr(MyForm),MenuItemType::Display); 3) в init() MyForm через MyClass.parmQuery() достать и передать его в метод MyTmpTable:opulate(), который вставляет (на сервере) записи во врем таблицу и передает курсор обратно в форму. Все, вроде, хорошо и должно, думаю, работать, но: 1) Может, лучше просто открывать сразу MyForm, но пустой и сделать кнопку на ней для задания критериев inventTable. По OK в диалоге критериев заполнять врем таблицу и заполнять форму данными. Все-таки для аксапты не оч типично запрашивать критерии запроса перед открытием формы. 2) Не лучше ли в классе runBase сразу же заполнять на основе inventTable буфер врем талицы и уже по сути заполненную таблицу передавать в форму MyForm . (а не передавать запрос inventTable в форму , а потом уже в метод MyTmpTable:opulate, как указано выше). Т.о, если класс на сервере выполняется и врем таблица на сервере создается, то мы избегаем передачи запроса по inventTable на клиент в форму MyForm 3)Еще варианты/предложения/альтернативы? Спасибо AX2009 RU2 Последний раз редактировалось IKA; 12.09.2013 в 19:33. |
|
12.09.2013, 18:39 | #2 |
Участник
|
Посмотрите, как сделано при открытии формы InventOnHand (list page), которая остатки по номенклатуре показывает.
Перед открытием там (в последних версиях системы) показывается диалог запроса, в котором отфильтровываются записи, после подтверждения открывается сама форма с уже отфильтрованными строками |
|
12.09.2013, 19:36 | #3 |
Участник
|
Прошу прощения, не указала версию: AX2009 RU2
Не вижу формы параметров, когда открываю InventOnHand. Можете вкратце описать реализацию? |
|
12.09.2013, 20:26 | #4 |
Участник
|
Вариант 1 предпочтительнее, как мне кажется, поскольку он как минимум удобнее для пользователей, ведь что делать пользователю, если он вдруг решил другие номенклатуры посмотреть? Закрывать форму и открывать заново. А если будет кнопка, то можно перевыбрать только нажав на нее и указав другие фильтры, такие реализации есть в системе - например форма в закрытии и коррекции - УЗ\Периодические операции\Закрытие и коррекция\Корректировка, там кнопки в Наличии или Проводки(кнопка выбрать). В стандарте есть и другие места сделанные аналогично.
Вариант 2 тоже имеет право на жизнь, по крайней мере лучше уж сразу заполнять в классе, а не тащить сам квери в форму и там с ним как то возиться. И еще такой момент, как правило формы с пред фильтром реализованы в узле запросов, например ГК\Запросы\Коды Операций, Банк\Запросы\Банковские проводки, но там постоянные таблицы. ПС. Форма, о которой писал Иван, использует те же механизмы, что и форма ГК\Запросы\Коды Операций, в форме отображаются данные из постоянных таблиц.
__________________
Sergey Nefedov Последний раз редактировалось SRF; 12.09.2013 в 21:27. |
|
|
За это сообщение автора поблагодарили: IKA (1). |
12.09.2013, 22:46 | #5 |
Administrator
|
Цитата:
Цитата:
Если Вам надо решить задачу с временными таблицами - то вы ее не решите разумным способом за разумное время и так чтобы работало быстро. Будете изобретать велосипед и за ядро пытаться решать сколько записей выводить - так, чтобы было быстро для пользователя. Сделайте постоянную таблицу и периодическую операцию, которая будет ее рассчитывать. Периодическую операцию можно будет запускать в пакете на сервере - она будет очень шустро отрабатывать. Ну а форма, основанная на постоянной таблице - будет открываться быстро на любом объеме данных - это уже стандартное поведение ядра системы. Примеры в системе такого подхода тоже есть - закрытие склада, расчет сводного плана и т.д.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.09.2013, 12:46 | #6 |
Участник
|
Цитата:
В случае кубов это оправдано , по идее такие данные как можно было бы вообще с пом view вытянуть Но, к сожалению, вы правы часто в аксапте используется именно такой подход( |
|
13.09.2013, 18:20 | #7 |
Участник
|
Цитата:
Сообщение от SRF
А если будет кнопка, то можно перевыбрать только нажав на нее и указав другие фильтры, такие реализации есть в системе - например форма в закрытии и коррекции - УЗ\Периодические операции\Закрытие и коррекция\Корректировка, там кнопки в Наличии или Проводки(кнопка выбрать). В стандарте есть и другие места сделанные аналогично.
Хотя сакральный смысл транзакции в InventAdjTransactSelect -> run () мне не ясен (вроде, для врем таблиц ttsbegin - как мертвому припарка, как и проверки на дедлоки). Я так понимаю, просто вслепую шаблоном для runBase->run воспользовались... + не совсем не понимаю, почему нельзя было вызвать по menuItemButton этот класс на форме InventAdjTransaction->ButtonGroup->Choose , зачем под кнопкой в clicked пишут prompt() и run() (да и executeQuery на DS можно было бы в классе выполнять)? Последний раз редактировалось IKA; 13.09.2013 в 18:38. |
|
15.09.2013, 21:08 | #8 |
Участник
|
Цитата:
Сообщение от IKA
Спасибо за пример. Как раз то, что надо!
Хотя сакральный смысл транзакции в InventAdjTransactSelect -> run () мне не ясен (вроде, для врем таблиц ttsbegin - как мертвому припарка, как и проверки на дедлоки). Я так понимаю, просто вслепую шаблоном для runBase->run воспользовались... + не совсем не понимаю, почему нельзя было вызвать по menuItemButton этот класс на форме InventAdjTransaction->ButtonGroup->Choose , зачем под кнопкой в clicked пишут prompt() и run() (да и executeQuery на DS можно было бы в классе выполнять)? А вот если у вас пункт меню будет серверный, то разница уже будет, как минимум в том, что метод executeQuery придется дергать серверу(доп. взаимодействие клиента и сервера), возможно, что-то придется поменять в передаче временной таблицы. Цитата:
Вот вариант начальной реализации - открывалась форма и по всем номенклатурам начинался расчет, действительно не лучший вариант использования временной таблицы, но меняем реализацию на открытие пустой формы, добавления кнопки расчета - реализация не займет много времени, способ не разумный? или медленно работать будет ? Полный расчет для временной и постоянной таблицы на всем объеме данных будет сравним(как я понимаю, потому что основное время отъедает именно расчет полей), единственным по сути отличием будет то, что задание для постоянной таблицы можно поставить в пакет, НО это еще при условии, что в форме не нужно отображение актуальных данных, а-ля цена, остатки, еще что нибудь, в противном случае мы и в пакет то задание поставить не сможем. Цитата:
Цитата:
Цитата:
Я это к тому (грубые прикидки): что вот форма предположим сейчас открывается 3 часа для 1000 позиций, переделываем на постоянную - получаем скажем 30 минут расчета в пакете, теперь форма для всех позиций открывается 0,5 секунд(но это в случае, если скажем нет необходимости в оперативных данных). Если мы просто фильтруем рассчитываемые позиции по 10-20, то получаем, что на каждую выборку мы тратим 100-200 секунд, что естественно гораздо больше 0,5, но в тоже время существенно меньше 3 часов.
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: IKA (1). |
12.09.2013, 21:57 | #9 |
Участник
|
Цитата:
X++: //when opening from back/forward (history) do not display query form if (this.args().dataset() != tableNum(InventSum)) { queryRunCriteria = new SysQueryRun(inventSum_ds.query()); queryRunCriteria.promptAllowAddDataSource(false); //we display form to modify query criteria in order to mitigate problems with bad performance when large amount of data //a user can set up filtering that will be used when the form is opened - this way the user can limit amount of data to be processed //the performance problem is due to the query being 'heavy' because of aggregation if (queryRunCriteria.prompt()) { inventSum_ds.query(queryRunCriteria.query()); } } inventSum_ds.executeQuery(); |
|
|
За это сообщение автора поблагодарили: IKA (1). |
13.09.2013, 13:13 | #10 |
Участник
|
|
|
13.09.2013, 13:06 | #11 |
NavAx
|
Ну вместо временной таблицы можно и нормальную таблицу использовать, просто разделять данные разных пользователей по какому то полю. При запуске формы заполнять, при закрытии очищать. Будет и скорость обычной таблицы, и не нужно периодическую опрерацию. В качестве поля для разделения можно использовать код транзакции или связку код пользователя + номер сессии.
|
|
13.09.2013, 13:26 | #12 |
Участник
|
К сожалению, в данном варианте, тк при открытии все равно все данные нужно будет рассчитать(а не вытянуть с сервера уже предрасчитанные, как предлагает sukhanchik) , то выигрыш за счет использования пост таблицы вместо временнной будет, но не столь уж значительный(вероятно, что даже не всегда будет)
Последний раз редактировалось IKA; 13.09.2013 в 13:29. |
|
13.09.2013, 13:30 | #13 |
Administrator
|
Он будет как минимум за счет скорости открытия формы. Да и если использовать класс RecordInsertList для вставки записей - то даже на этапе перелива уже будет выигрыш
__________________
Возможно сделать все. Вопрос времени |
|
16.09.2013, 09:55 | #14 |
Участник
|
2 IKA
Отпишись, сколько времени "стоит" расчет всех полей для 1 номенклатуры. Есть вариант, при котором для большого кол-ва записей, и относительно недолгого расчета, реализовать без предварительного фильтра и с быстрым открытием. |
|
16.09.2013, 13:40 | #15 |
Участник
|
2 kair84:
Форма открывается 35 секунд на приблизит 1500 записей. Не очень трагично, но неприятно. Если отключить рассчет полей, то за 3 секунды. Именно поэтому выигрыш от переваливания все в пост таблицу в моем случае не оч очевиднен, тк все съедают именно рассчеты. Я сделала в результате по предложенному SRF варианту InventAdjTransaction->ButtonGroup->Choose (мне все-таки кажется. что не оч грамотно написанный пример, но рабочий(помимо описанных уже вопросов про неподобающие tts и prompt, также заметила. что там врем таблица "инициализируется" на сервере не вставкой записи , а выборкой ее =) ). Пользователи счастливы. Эта форма показывает прогнозируемые цены, рассчитываемые по местным волшебным алгоритмам. Обычно рассчеты делают на опред группы товаров, поэтому фильтр в люб случае нужен(никто махом не анализирует цены 1500 номенклатур). Даже сейчас никто не запрещает оставить критерии пустыми, все прекрасно будет работать, только в этих редких случаях пользователь будет "морально" готов ждать. SRF - благодарю, за ссылки на готовые примеры реализаций! |
|
16.09.2013, 16:01 | #16 |
Участник
|
Цитата:
Я сделала в результате по предложенному SRF варианту
Еще в таких случаях, для успокоения пользователей, и чтоб показать что форма (или другой процесс) не просто тормозит, а что то считает, полезно выводить Progress, пользователь видит, что, что то происходит, и видит сколько это еще будет продолжаться, хотя бы примерно. |
|