Почему тормозит отчет СКД при большом количестве элементов в отборе и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с большими объемами данных в системе 1С:Предприятие 8.3 на управляемых формах часто преподносит сюрпризы в виде "фризов" и долгих ожиданий. Типичная ситуация: программист создает отчет на Системе Компоновки Данных (СКД), добавляет стандартный отбор по товару, а пользователь загружает в этот отбор список из 2000 позиций. После этого любое действие на форме — будь то клик по кнопке, сворачивание группы или просто попытка изменить другой параметр — вызывает длительное "зависание" интерфейса, даже если сам отчет еще не запущен на формирование. Рассмотрим подробно, почему так происходит и как правильно спроектировать такой отчет, чтобы он работал молниеносно.

Выясним причину: почему возникают тормоза на ровном месте?

Для начала проанализируем ситуацию с точки зрения архитектуры управляемого приложения. Когда мы работаем с управляемой формой, между клиентом и сервером происходит постоянная синхронизация контекста формы. В контекст формы отчета входит и объект КомпоновщикНастроек.

Разберем по шагам, что происходит внутри платформы:

  1. Сериализация в XDTO: При любом серверном вызове (даже неявном, например, при проверке прав или обновлении доступности кнопок) платформа должна передать состояние данных формы на сервер. Для этого объект КомпоновщикНастроек сериализуется в формат XML или JSON. Если в списке отбора находится 2000 ссылок, каждая из них превращается в текстовое описание типа и уникального идентификатора.
  2. Объем данных: Пакет данных, пересылаемый на сервер, раздувается до нескольких мегабайт. Процесс превращения объектной модели в текст на клиенте и обратный парсинг на сервере нагружают процессор.
  3. Получение представлений: Платформа 1С старается отобразить пользователю понятные наименования ссылок. Если в отборе 2000 элементов, система может пытаться кэшировать или проверять актуальность представлений этих объектов для отрисовки интерфейса, что также вызывает серверные вызовы.
  4. Отрисовка интерфейса: Управляемая форма тяжело переваривает таблицы с тысячами строк. Даже если список отбора свернут, механизмы платформы по расчету геометрии элементов управления продолжают учитывать объем данных, находящихся в коллекции.

Решение 1: Программное управление отбором при компоновке

Самый эффективный способ убрать тормоза — это вынести тяжелый список из стандартных настроек компоновщика, которые отображаются на форме. Вместо того чтобы позволять пользователю напрямую редактировать список в стандартном окне отборов, мы будем хранить этот список отдельно и подставлять его в запрос непосредственно в момент формирования отчета.

Проанализируем алгоритм действий:

  1. Создадим на форме отчета отдельный реквизит с типом СписокЗначений или используем загрузку из файла.
  2. В схеме СКД уберем поле, по которому планируется большой отбор, из раздела "Доступные поля пользовательских настроек".
  3. В модуле объекта отчета переопределим событие ПриКомпоновкеРезультата.

Посмотрим на пример кода в модуле объекта:


Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартный вывод, так как будем управлять процессом вручную
    СтандартнаяОбработка = Ложь;
    
    // Получаем текущие настройки из компоновщика
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Находим нужный нам отбор. Допустим, мы храним список в параметре формы "СписокТоваров"
    // Здесь мы программно добавляем элемент отбора, который не "светится" на форме постоянно
    Если ЗначениеЗаполнено(СписокТоваровДляФильтра) Тогда
        НовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товар");
        НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
        НовыйОтбор.ПравоеЗначение = СписокТоваровДляФильтра;
        НовыйОтбор.Использование = Истина;
    КонецЕсли;
    
    // Далее стандартный код инициализации макета и выполнения компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Благодаря этому подходу, пока менеджер работает с формой, список из 2000 элементов не "гоняется" в составе компоновщика настроек. Он лежит в отдельном реквизите или во временном хранилище и используется только в момент формирования.

Решение 2: Использование параметров вместо отборов

Если специфика отчета позволяет, лучше использовать Параметры СКД вместо Отборов. Параметры более жестко типизированы и зачастую работают быстрее при передаче в запрос. В настройках параметра в СКД можно снять галочку "Включать в пользовательские настройки", а заполнять его программно перед формированием.

Рассмотрим важный момент: если список элементов действительно огромен (более 5000–10000), использование условия ГДЕ Ссылка В (&Список) может привести к деградации производительности уже на стороне SQL-сервера. Оптимизатор запросов СУБД может выбрать неэффективный план при слишком длинном операторе IN.

Решение 3: Использование временных таблиц и внешних наборов данных

Для максимально тяжелых случаев (десятки тысяч элементов в списке) рекомендуется использовать Внешний набор данных. Проанализируем, как это работает:

  1. Вы загружаете данные из Excel в таблицу значений на стороне сервера.
  2. Помещаете эту таблицу во Временное хранилище.
  3. В СКД создаете второй набор данных (набор данных - объект).
  4. Связываете ваш основной запрос с этим набором данных через ВНУТРЕННЕЕ СОЕДИНЕНИЕ.

Это не только уберет тормоза интерфейса, но и заставит SQL-сервер работать максимально эффективно, так как он будет соединять две таблицы, а не перечислять тысячи условий в секции WHERE.

Дополнительные рекомендации по оптимизации

При разработке сложных отчетов всегда обращайте внимание на следующие моменты:

Резюме: Главная проблема "тормозов" — это не количество данных в базе, а попытка платформы сделать эти данные частью интерактивного контекста формы. Скрывайте большие коллекции данных от стандартных механизмов отрисовки управляемой формы, и ваши отчеты будут работать стабильно и быстро.

← На главную