Часто при разработке на управляемых формах мы сталкиваемся с тем, что динамический список, который должен быстро выводить документы, начинает «зависать» на 20–30 секунд. Особенно остро это проявляется, когда в основной запрос динамического списка добавляются тяжелые соединения с виртуальными таблицами остатков или оборотов. Давайте разберемся, почему это происходит и как оптимизировать работу формы, сохранив при этом весь необходимый функционал.
Основная причина медленной работы заключается в том, что платформа 1С пытается выполнить весь сложный запрос целиком. Даже если у вас установлена галочка Динамически считывать данные, оптимизатор СУБД при наличии сложных соединений (например, ЛЕВОЕ СОЕДИНЕНИЕ с ОстаткиИОбороты) часто вынужден анализировать значительные объемы данных регистра, чтобы корректно отобразить состояние для всех строк. Чем больше данных в базе, тем дольше строится этот запрос, что мы и наблюдаем в виде длительного ожидания при открытии формы.
Чтобы ускорить работу, мы предлагаем разделить задачу на два этапа: быстрое получение списка документов и «дообогащение» каждой конкретной строки нужными данными (в нашем случае — НомерКартинки) только тогда, когда она попадает в поле зрения пользователя.
Для этого мы воспользуемся обработчиком ПриПолученииДанныхНаСервере динамического списка. Разберем по шагам, как это реализовать:
ПриПолученииДанныхНаСервере мы будем дозапрашивать необходимые данные только для той порции записей, которые 1С уже подготовила к отображению.Рассмотрим, как это выглядит на практике. В модуле формы создаем обработчик:
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Получаем массив ссылок из текущей порции данных
СписокСсылок = Строки.ПолучитьКлючи();
// Выполняем запрос только для конкретных документов
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗНП.Ссылка КАК Ссылка,
| ЗНП.Проведен КАК Проведен,
| ЗНП.ВариантЗавершения КАК ВариантЗавершения,
| ЗНП.СостояниеЗаказа КАК СостояниеЗаказа,
| ЗНП.Финиш КАК Финиш,
| ЗНП.Старт КАК Старт
|ПОМЕСТИТЬ Вт_ЗНП
|ИЗ Документ.ЗаказНаПроизводство КАК ЗНП
|ГДЕ ЗНП.Ссылка В(&Ссылка)
|;
|ВЫБРАТЬ
| ВЫБОР КОГДА НЕ Вт_ЗНП.Проведен ТОГДА -1 ... КОНЕЦ КАК НомерКартинки,
| Вт_ЗНП.Ссылка КАК Ссылка
|ИЗ Вт_ЗНП КАК Вт_ЗНП
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗаказыНаПроизводство.ОстаткиИОбороты КАК Остатки
|ПО Вт_ЗНП.Ссылка = Остатки.ЗаказНаПроизводство";
Запрос.УстановитьПараметр("Ссылка", СписокСсылок);
// ... выполнение запроса и обход результата ...
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтрокаСписка = Строки[Выборка.Ссылка];
СтрокаСписка.Данные["НомерКартинки"] = Выборка.НомерКартинки;
КонецЦикла;
КонецПроцедуры
Когда вы используете ПриПолученииДанныхНаСервере, запрос к регистру ОстаткиИОбороты выполняется не для всей таблицы документов, а только для 40–50 позиций, которые отображаются на экране. СУБД мгновенно находит записи по индексу ссылки, что исключает долгое сканирование больших массивов данных. В результате пользователь получает отзывчивый интерфейс без потери функциональности.
ПриЗаписи документа) или в отдельном регистре сведений, который будет обновляться при проведении.Применяя этот подход, вы сможете добиться существенного ускорения работы форм, сохранив привычный для пользователей интерфейс. Это стандартная практика оптимизации, которая позволяет сделать работу в конфигурации комфортной даже на больших объемах данных.