Работа с большими объемами данных в системе 1С:Предприятие 8.3 на управляемых формах часто преподносит сюрпризы в виде "фризов" и долгих ожиданий. Типичная ситуация: программист создает отчет на Системе Компоновки Данных (СКД), добавляет стандартный отбор по товару, а пользователь загружает в этот отбор список из 2000 позиций. После этого любое действие на форме — будь то клик по кнопке, сворачивание группы или просто попытка изменить другой параметр — вызывает длительное "зависание" интерфейса, даже если сам отчет еще не запущен на формирование. Рассмотрим подробно, почему так происходит и как правильно спроектировать такой отчет, чтобы он работал молниеносно.
Для начала проанализируем ситуацию с точки зрения архитектуры управляемого приложения. Когда мы работаем с управляемой формой, между клиентом и сервером происходит постоянная синхронизация контекста формы. В контекст формы отчета входит и объект КомпоновщикНастроек.
Разберем по шагам, что происходит внутри платформы:
КомпоновщикНастроек сериализуется в формат XML или JSON. Если в списке отбора находится 2000 ссылок, каждая из них превращается в текстовое описание типа и уникального идентификатора.Самый эффективный способ убрать тормоза — это вынести тяжелый список из стандартных настроек компоновщика, которые отображаются на форме. Вместо того чтобы позволять пользователю напрямую редактировать список в стандартном окне отборов, мы будем хранить этот список отдельно и подставлять его в запрос непосредственно в момент формирования отчета.
Проанализируем алгоритм действий:
СписокЗначений или используем загрузку из файла.ПриКомпоновкеРезультата.Посмотрим на пример кода в модуле объекта:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Отключаем стандартный вывод, так как будем управлять процессом вручную
СтандартнаяОбработка = Ложь;
// Получаем текущие настройки из компоновщика
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Находим нужный нам отбор. Допустим, мы храним список в параметре формы "СписокТоваров"
// Здесь мы программно добавляем элемент отбора, который не "светится" на форме постоянно
Если ЗначениеЗаполнено(СписокТоваровДляФильтра) Тогда
НовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товар");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
НовыйОтбор.ПравоеЗначение = СписокТоваровДляФильтра;
НовыйОтбор.Использование = Истина;
КонецЕсли;
// Далее стандартный код инициализации макета и выполнения компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Благодаря этому подходу, пока менеджер работает с формой, список из 2000 элементов не "гоняется" в составе компоновщика настроек. Он лежит в отдельном реквизите или во временном хранилище и используется только в момент формирования.
Если специфика отчета позволяет, лучше использовать Параметры СКД вместо Отборов. Параметры более жестко типизированы и зачастую работают быстрее при передаче в запрос. В настройках параметра в СКД можно снять галочку "Включать в пользовательские настройки", а заполнять его программно перед формированием.
Рассмотрим важный момент: если список элементов действительно огромен (более 5000–10000), использование условия ГДЕ Ссылка В (&Список) может привести к деградации производительности уже на стороне SQL-сервера. Оптимизатор запросов СУБД может выбрать неэффективный план при слишком длинном операторе IN.
Для максимально тяжелых случаев (десятки тысяч элементов в списке) рекомендуется использовать Внешний набор данных. Проанализируем, как это работает:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ.Это не только уберет тормоза интерфейса, но и заставит SQL-сервер работать максимально эффективно, так как он будет соединять две таблицы, а не перечислять тысячи условий в секции WHERE.
При разработке сложных отчетов всегда обращайте внимание на следующие моменты:
СправочникСсылка.Товары), а не оставлять составной тип. Это ускоряет сериализацию.ПриИзменении и время выполнения контекстных вызовов.CALL. Там будет виден реальный объем данных (в байтах), передаваемый между клиентом и сервером.Резюме: Главная проблема "тормозов" — это не количество данных в базе, а попытка платформы сделать эти данные частью интерактивного контекста формы. Скрывайте большие коллекции данных от стандартных механизмов отрисовки управляемой формы, и ваши отчеты будут работать стабильно и быстро.