При разработке интерфейсов в 1С часто возникает задача отображения оперативных данных, которые требуют сложных расчетов. В частности, вывод информации о произведенной и заказанной продукции с обновлением в реальном времени кажется идеальной задачей для ДинамическогоСписка. Однако, использование сложных запросов с временными таблицами и группировками внутри самого списка часто приводит к серьезным проблемам с производительностью.
Рассмотрим, почему такая реализация является нежелательной и какие архитектурные альтернативы существуют в среде 1С.
Хотя техническая возможность использовать временные таблицы в запросе ДинамическогоСписка существует в платформе 8.3, следование этой практике считается плохим тоном по ряду причин:
ДинамическогоСписка часто делает работу со списком нестабильной, вызывая ошибки при отборах, сортировках или попытках программного взаимодействия с данными списка.Согласно рекомендациям ИТС, самым правильным подходом при необходимости отображения рассчитанных данных является предварительный расчет и хранение этих данных в специализированном РегистреСведений. Вместо того чтобы «мучить» базу данных сложными вычислениями в момент открытия формы, мы должны подготовить эти данные заранее.
Рассмотрим пошагово, как реализовать данный подход:
СостоянияПроизводства. Его структура должна соответствовать тем данным, которые вы хотите выводить в список.РегламентноеЗадание, которое будет пересчитывать состояния продукции с нужной вам периодичностью.ДинамическийСписок становится «плоским» и максимально быстрым. Вы просто выбираете данные из вашего РегистраСведений. Запрос будет выглядеть максимально просто, что гарантирует мгновенный отклик системы.Рассмотрим простейший пример того, как можно обновить данные в регистре сведений при проведении документа. Предположим, что расчет состояния — это результат выполнения сложного запроса:
// В модуле объекта документа
Процедура ОбработкаПроведения(Отказ, Режим)
// Выполняем расчет состояния продукции
ДанныеДляРегистра = РассчитатьСостояниеПродукции(ЭтотОбъект.Ссылка);
// Записываем результат в регистр сведений
НаборЗаписей = РегистрыСведений.СостоянияПроизводства.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(ЭтотОбъект.Номенклатура);
Запись = НаборЗаписей.Добавить();
Запись.Номенклатура = ЭтотОбъект.Номенклатура;
Запись.КоличествоЗаказано = ДанныеДляРегистра.Заказано;
Запись.КоличествоПроизведено = ДанныеДляРегистра.Произведено;
НаборЗаписей.Записать();
КонецПроцедуры
Таким образом, когда пользователь открывает форму с ДинамическимСписком, система просто считывает готовые строки из таблицы регистра. Это избавляет сервер от тяжелых операций по созданию временных таблиц и группировке данных на лету.
Если вы все же решаете, что периодическое обновление является приоритетом, помните о следующих моментах:
ДинамическогоСписка на управляемой форме вы можете задать свойство Автообновление. При работе с предрассчитанными данными в регистре, даже обновление каждые 30 секунд не будет нагружать систему, так как запрос к одной таблице является «тривиальной» операцией для SQL.РегистреСведений правильно расставлены индексы по измерениям, которые вы планируете использовать в фильтрах ДинамическогоСписка.В завершение, подчеркнем: избегайте соблазна реализовать сложную логику «на месте». Инвестиции времени в настройку РегистраСведений окупятся высокой производительностью и отсутствием жалоб пользователей на медленную работу интерфейса.