Почему простой отчет на СКД долго формируется при выборе данных из регистра сведений?

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

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

Рассмотрим подробно причины такого поведения платформы 1С:Предприятие, проанализируем узкие места и разберем конкретные способы оптимизации скорости формирования отчетов.

Выясняем причину: влияние представлений и скрытых запросов

Когда мы выбираем данные из регистра сведений, подчиненного регистратору, или обращаемся к реквизитам ссылочного типа (справочники, документы), платформа 1С автоматически выполняет дополнительные действия для получения их представлений в интерфейсе. Основная задержка возникает по следующим причинам:

  1. Неявный вызов процедур модуля менеджера: Если у документа-регистратора или ссылочного реквизита в модуле менеджера определена процедура ОбработкаПолученияПредставления(), платформа вызывает её при формировании строк отчета. Если в этой процедуре содержится тяжелый код или запросы к базе данных, время выполнения отчета увеличивается пропорционально количеству выводимых записей.
  2. Скрытые соединения в запросах: При активированном режиме автозаполнения СКД или получении представлений ссылочных объектов платформа формирует дополнительные LEFT JOIN к таблицам ссылок для чтения даты, номера, кода или наименования.
  3. Автозаполнение схемы СКД: Флаг «Автозаполнение» в наборе данных автоматически добавляет доступность всех реквизитов объектов, что провоцирует платформу на считывание излишних данных.

Шаг 1. Перенос логики из ОбработкаПолученияПредставления

Проанализируем модуль менеджера объекта, ссылка на который присутствует в выгружаемой таблице (например, документ-регистратор). Если в нем определен обработчик генерации представления, убедимся, что он не выполняет тяжелых операций при каждом обращении.

Частая ошибка — формирование сложного заголовка с обращениями к другим таблицам прямо в модуле менеджера:


// Неоптимальный код в модуле менеджера документа
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Тяжелый запрос или обращение к связанным объектам
    Представление = "Заявка № " + СокрЛП(Данные.Номер) + " от " + Формат(Данные.Дата, "ДФ=dd.MM.yyyy");
КонецПроцедуры

Если такое представление требуется только для отображения формы документа, вынесем эту логику непосредственно в форму или оптимизируем обработчик, исключив любые дозапросы к СУБД. При переносе логики формирования заголовка из модуля менеджера скорость построения отчета в СКД возрастает в разы.

Шаг 2. Настройка «Выражения представления» в СКД

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

  1. Откроем схему компоновки данных и перейдем на вкладку Наборы данных.
  2. Найдем нужное ссылочное поле (например, Регистратор или Заявка).
  3. В колонке Выражение представления укажем явное текстовое выражение, которое будет формироваться средствами запроса без дополнительных вызовов программного кода.

Пример выражения представления для ссылочного поля:

Строка(Регистратор.Номер) + " от " + Формат(Регистратор.Дата, "ДФ=dd.MM.yyyy")

Шаг 3. Отключение автозаполнения и оптимизация списка полей

Если отчет предназначен исключительно для вывода простой таблицы («простыни»), рекомендуется отключить автоматическое определение полей платформой:

  1. В наборе данных-запрос снимем флаг Автозаполнение.
  2. Явно добавим в список полей только те реквизиты, которые действительно нужны пользователю в отчете.
  3. Для ссылочных полей, по которым не требуется построение иерархии или переход по расшифровке, установим ограничения доступности (запретим поле для отбора или группировки, если оно используется только для вывода текста).

Шаг 4. Отключение генерации расшифровки при программном выводе

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

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


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// Передаем Неопределено вместо объекта ДанныеРасшифровки
МакетКомпоновки = КомпоновщикМакета.Выполнить(
    СхемаКомпоновкиДанных, 
    КомпоновщикНастроек.ПолучитьНастройки(), 
    Неопределено
);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаОбъектаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(РезультатТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Рекомендации по работе с большими объемами данных

При выгрузке выборок объемом свыше 50 000–100 000 строк в интерфейс 1С учтем следующие особенности платформы:

← На главную