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, 21:57 | #5 |
Участник
|
Цитата:
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). |
12.09.2013, 22:46 | #6 |
Administrator
|
Цитата:
Цитата:
Если Вам надо решить задачу с временными таблицами - то вы ее не решите разумным способом за разумное время и так чтобы работало быстро. Будете изобретать велосипед и за ядро пытаться решать сколько записей выводить - так, чтобы было быстро для пользователя. Сделайте постоянную таблицу и периодическую операцию, которая будет ее рассчитывать. Периодическую операцию можно будет запускать в пакете на сервере - она будет очень шустро отрабатывать. Ну а форма, основанная на постоянной таблице - будет открываться быстро на любом объеме данных - это уже стандартное поведение ядра системы. Примеры в системе такого подхода тоже есть - закрытие склада, расчет сводного плана и т.д.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
13.09.2013, 12:46 | #7 |
Участник
|
Цитата:
В случае кубов это оправдано , по идее такие данные как можно было бы вообще с пом view вытянуть Но, к сожалению, вы правы часто в аксапте используется именно такой подход( |
|
13.09.2013, 12:53 | #8 |
Administrator
|
Цитата:
Сообщение от IKA
Я,конечно,почнимаю о чем вы , но если честно, то они именно для этого и предназначены, а подход - все пересчитывать и хранить - это идеологически всегда "средство по бедности" - тк сервер не тянет бытрые расчеты , то придумываются всякие извращенные workarounds.
В случае кубов это оправдано , по идее такие данные как можно было бы вообще с пом view вытянуть Но, к сожалению, вы правы часто в аксапте используется именно такой подход( Я же предлагаю просто перелить те же данные из постоянной в другую постоянную. И сделать это в пакетном задании (т.е. супербыстро даже на неторопливом сервере). После чего у Вас форма будет открываться быстро, т.к. будет основана на постоянной таблице. Т.е. с т.з. изменения кода - нужно просто заменить временную табличку на постоянную. Ну и конечно подкорректировать код, который относится исключительно к временной таблицы (синтаксис методов и т.д.). Кубы это отдельная тема, хотя и со схожей идеей.
__________________
Возможно сделать все. Вопрос времени |
|
13.09.2013, 13:06 | #9 |
NavAx
|
Ну вместо временной таблицы можно и нормальную таблицу использовать, просто разделять данные разных пользователей по какому то полю. При запуске формы заполнять, при закрытии очищать. Будет и скорость обычной таблицы, и не нужно периодическую опрерацию. В качестве поля для разделения можно использовать код транзакции или связку код пользователя + номер сессии.
|
|
13.09.2013, 13:13 | #10 |
Участник
|
|
|
13.09.2013, 13:26 | #11 |
Участник
|
К сожалению, в данном варианте, тк при открытии все равно все данные нужно будет рассчитать(а не вытянуть с сервера уже предрасчитанные, как предлагает sukhanchik) , то выигрыш за счет использования пост таблицы вместо временнной будет, но не столь уж значительный(вероятно, что даже не всегда будет)
Последний раз редактировалось IKA; 13.09.2013 в 13:29. |
|
13.09.2013, 13:30 | #12 |
Administrator
|
Он будет как минимум за счет скорости открытия формы. Да и если использовать класс RecordInsertList для вставки записей - то даже на этапе перелива уже будет выигрыш
__________________
Возможно сделать все. Вопрос времени |
|
13.09.2013, 18:20 | #13 |
Участник
|
Цитата:
Сообщение от 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 | #14 |
Участник
|
Цитата:
Сообщение от 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). |
15.09.2013, 22:30 | #15 |
Administrator
|
Цитата:
Цитата:
Сообщение от SRF
Почему? Все зависит от критериев(способ, время) и ожидаемого результата(скорость).
Вот вариант начальной реализации - открывалась форма и по всем номенклатурам начинался расчет, действительно не лучший вариант использования временной таблицы, но меняем реализацию на открытие пустой формы, добавления кнопки расчета - реализация не займет много времени, способ не разумный? или медленно работать будет ? Полный расчет для временной и постоянной таблицы на всем объеме данных будет сравним(как я понимаю, потому что основное время отъедает именно расчет полей), единственным по сути отличием будет то, что задание для постоянной таблицы можно поставить в пакет, НО это еще при условии, что в форме не нужно отображение актуальных данных, а-ля цена, остатки, еще что нибудь, в противном случае мы и в пакет то задание поставить не сможем. 1. В общем-то я говорил - что разница между переливом во временную таблицу и постоянную - небольшая. (Можно даже считать, что ее нету, хотя до тех пор, пока временная таблица не находится под управлением СУБД - я думаю - что разница будет заметна). За исключением возможности использовать класс RecordInsertList, что дает существенный прирост в скорости. 2. Если расчет полей (т.е. вышеуказанный перелив) можно поставить в пакет - то это будет быстрее в первую очередь психологически. Т.е. если нет потребностей видеть актуальных данных (пример которых Вы привели), то гораздо лучше (с т.з. пользователя) сделать периодическую операцию, которая предварительно рассчитывает данные, а уже форма быстро их выводит. Т.е. не будет негатива от пользователей - что форма тормозит при открытии. Ну и само собой пакетник будет быстрее считать - это я думаю понятно. 3. Если расчет полей нельзя поставить в пакет - то тут возможны следующие варианты решения задачи по оптимизации: а) Эмулировать пакет. Т.е. запустить расчет на сервере также, как он запускается, когда запускается из пакета (тут, возможно придется сделать класс-обертку, который делает эту эмуляцию, однако - это будет разовая доработка, применимая ко всем таким ситуациям). Можно получить все преимущества запуска в пакете без постановки задания в пакет. б) Сделать таблицу, заполняемую онлайн-данными. В определенном смысле - второй InventSum. Этот подход несет в себе конечно кучу рисков, но ... все зависит от постановки задачи. Например, финансовые отчеты, которые формируются генератором отчетности (баланс и т.д.) и которые требуется сделать супер-быстрыми можно реализовать через отдельную табличку, которую заполнять при каждой разноске. Понятное дело, что если дело коснется именно складских проводок и обновления InventSum - то тут рисков больше, чем плюсов. Ну и опять-таки - все зависит от количества одновременно работающих пользователей. Конечно главный критерий время и удовлетворенность пользователя.. Т.е. если объем данных позволяет выбрать Ваш вариант - не вопрос. Но как я понял из исходного поста - проблема-то именно в скорости - а Ваш вариант он просто чисто психологически ускоряет загрузку формы, после чего - скорость расчета не меняется, а проблема решения сколько записей выводить на экран, чтобы не тормозило - остается. Цитата:
Цитата:
И еще один важный момент. Все пользователи, когда хотят дать задание на доработку - ориентируются на существующие цифры в системе. Т.е. сегодня Вы с большим трудом оптимизировали форму, которая рассчитывает цифры, а завтра Вам сказали - что хочется часть этих цифр видеть там, там и вооон там (среди различных источников данных). Плюс применить к ним какие-то арифметические действия. При наличии предрасчитанных данных - Вам будет легко на них сориентировать новые запросы. В противном случае - Вы тормоза при расчете протянете в каждое место системы, где пользователь захочет видеть цифры. Ну или будете опять переделывать форму, за которую уже отчитались. Цитата:
Цитата:
Цитата:
Цитата:
В общем-то для нас - специалистов по системе - это хорошо, денежно. Наверное - так и надо делать. Но с т.з. пользователя - это будет негатив на предмет регулярного дергания разработчика по тем действиям, которые раньше он мог делать самостоятельно (накладывать фильтры и сортировку и делать те или иные выборки). Мне казалось, что такой подход как раз является неразумным, с т.з. времени, которое будет тратиться на обслуживание этой формы и то, чего из нее выросло и расползлось. Т.е. я считаю в данном случаем под временем не только время на решение конкретной задачи на оптимизацию формы, но и время, потраченное в дальнейшем на решение связанных задач, которое потенциально может быть увеличено из-за выбранного способа оптимизации формы. Впрочем - иногда кажущийся ошибочный путь на деле оказывается наиболее оптимальным.
__________________
Возможно сделать все. Вопрос времени |
|
15.09.2013, 23:15 | #16 |
Участник
|
Цитата:
Цитата:
Цитата:
Сообщение от sukhanchik
3. Если расчет полей нельзя поставить в пакет - то тут возможны следующие варианты решения задачи по оптимизации:
а) Эмулировать пакет. Т.е. запустить расчет на сервере также, как он запускается, когда запускается из пакета (тут, возможно придется сделать класс-обертку, который делает эту эмуляцию, однако - это будет разовая доработка, применимая ко всем таким ситуациям). Можно получить все преимущества запуска в пакете без постановки задания в пакет. б) Сделать таблицу, заполняемую онлайн-данными. В определенном смысле - второй InventSum. Этот подход несет в себе конечно кучу рисков, но ... все зависит от постановки задачи. Например, финансовые отчеты, которые формируются генератором отчетности (баланс и т.д.) и которые требуется сделать супер-быстрыми можно реализовать через отдельную табличку, которую заполнять при каждой разноске. Понятное дело, что если дело коснется именно складских проводок и обновления InventSum - то тут рисков больше, чем плюсов. Ну и опять-таки - все зависит от количества одновременно работающих пользователей. О! Вот он ключевой момент - ускорение предполагается выполнить за счет сокращения исходной выборки данных. Т.е. при скроллинге - расчет будет снова проводиться. На самом деле - такое решение вполне обоснованно имеет место быть. Но... без оглядки на будущее. Потому что следующим пожеланием пользователя будет желание накладывать 100500 видов фильтров и сортировок на выборку. Плюс, как я уже писал выше - вытащить часть этих цифр в 100500 различных отчетов. В общем-то для нас - специалистов по системе - это хорошо, денежно. Наверное - так и надо делать. Но с т.з. пользователя - это будет негатив на предмет регулярного дергания разработчика по тем действиям, которые раньше он мог делать самостоятельно (накладывать фильтры и сортировку и делать те или иные выборки). Поэтому, если пакетник сделать нельзя, то мне непонятно как пункт 3.а будет ускорять расчет полей для постоянной таблицы, относительно временной. ну т.е. никто не мешает сделать аналогичный класс обертку для временной таблицы и его использовать в отчетах и т.д. (может быть сложнее в реализации, чем с постоянной таблицей). И еще по поводу универсальности и пункта 3.б - поддержка такого решения вполне возможно будет проще, возможно какие то отчеты можно будет на основе данного механизма делать - ну т.е. надо будет подправить условно в одном месте, но изначально придется вложиться в эти механизмы в разы больше, чем при решении конкретной задачи, особенно по пункт 3.б, а в результате в реальности этот механизм будет использоваться только в одном месте, поэтому как мне кажется вопрос, что денежнее, не так однозначен)
__________________
Sergey Nefedov Последний раз редактировалось SRF; 15.09.2013 в 23:19. |
|
16.09.2013, 01:00 | #17 |
Administrator
|
Цитата:
Сам вот себя ловлю на том, что мне приятнее просматривать списки в интернет-магазинах целиком, нежели с предварительным фильтром. Конечно может сравнение и неудачное, но тем не менее. Цитата:
Цитата:
Сообщение от SRF
Вот тут не совсем понял, про скроллинг - доп расчетов никаких не будет, если нет каких то дисплей полей, ну т.е. накладывается запрос по таблице inventTable, для выбранных позиций выполняется расчет и они выводятся в грид, надо другие позиции перевыбрали, заново при этом выполнив расчет.
Цитата:
Сообщение от SRF
И еще по поводу универсальности и пункта 3.б - поддержка такого решения вполне возможно будет проще, возможно какие то отчеты можно будет на основе данного механизма делать - ну т.е. надо будет подправить условно в одном месте, но изначально придется вложиться в эти механизмы в разы больше, чем при решении конкретной задачи, особенно по пункт 3.б, а в результате в реальности этот механизм будет использоваться только в одном месте, поэтому как мне кажется вопрос, что денежнее, не так однозначен)
__________________
Возможно сделать все. Вопрос времени |
|
16.09.2013, 09:55 | #18 |
Участник
|
2 IKA
Отпишись, сколько времени "стоит" расчет всех полей для 1 номенклатуры. Есть вариант, при котором для большого кол-ва записей, и относительно недолгого расчета, реализовать без предварительного фильтра и с быстрым открытием. |
|
16.09.2013, 13:40 | #19 |
Участник
|
2 kair84:
Форма открывается 35 секунд на приблизит 1500 записей. Не очень трагично, но неприятно. Если отключить рассчет полей, то за 3 секунды. Именно поэтому выигрыш от переваливания все в пост таблицу в моем случае не оч очевиднен, тк все съедают именно рассчеты. Я сделала в результате по предложенному SRF варианту InventAdjTransaction->ButtonGroup->Choose (мне все-таки кажется. что не оч грамотно написанный пример, но рабочий(помимо описанных уже вопросов про неподобающие tts и prompt, также заметила. что там врем таблица "инициализируется" на сервере не вставкой записи , а выборкой ее =) ). Пользователи счастливы. Эта форма показывает прогнозируемые цены, рассчитываемые по местным волшебным алгоритмам. Обычно рассчеты делают на опред группы товаров, поэтому фильтр в люб случае нужен(никто махом не анализирует цены 1500 номенклатур). Даже сейчас никто не запрещает оставить критерии пустыми, все прекрасно будет работать, только в этих редких случаях пользователь будет "морально" готов ждать. SRF - благодарю, за ссылки на готовые примеры реализаций! |
|
16.09.2013, 16:01 | #20 |
Участник
|
Цитата:
Я сделала в результате по предложенному SRF варианту
Еще в таких случаях, для успокоения пользователей, и чтоб показать что форма (или другой процесс) не просто тормозит, а что то считает, полезно выводить Progress, пользователь видит, что, что то происходит, и видит сколько это еще будет продолжаться, хотя бы примерно. |
|
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|