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

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

Разработчики 1С часто сталкиваются с парадоксальной ситуацией: тяжелый запрос в консоли выполняется за считанные минуты, но тот же самый запрос в составе Системы компоновки данных (СКД) заставляет пользователя ждать отчет часами или вовсе приводит к падению рабочего процесса с ошибкой «Превышен максимальный расход памяти». Особенно остро эта проблема проявляется в отчетах с типом настройки Таблица, где используется большое количество статических и динамических колонок. В этой статье мы подробно разберем причины такого поведения и проанализируем методы оптимизации, которые позволяют ускорить вывод данных в десятки раз.

Анализ причины: почему «быстрый» запрос превращается в «медленный» отчет?

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

  1. Исполнение запроса: получение «сырых» данных из базы данных.
  2. Компоновка данных: расчет итогов, ресурсов и группировок в оперативной памяти.
  3. Вывод результата: генерация визуального представления (обычно в ТабличныйДокумент).

Основная проблема кросс-таблиц с вложенными группировками заключается в так называемом комбинаторном взрыве. Если у вас есть 20 колонок и каждая из них имеет вложенную динамическую группировку, количество ячеек в итоговой матрице может исчисляться миллионами. Для каждой ячейки 1С должна рассчитать не только значение, но и параметры оформления, расшифровку и иерархические связи. Рассмотрим подробнее, как с этим бороться.

Решение 1: Полное отключение расшифровки

Как отмечают участники обсуждения, одним из самых «прожорливых» механизмов является расшифровка (та самая «лупа», которая появляется при наведении на ячейку). Когда расшифровка включена, СКД создает в памяти огромный объект ДанныеРасшифровкиКомпоновкиДанных. Этот объект хранит связи между каждой ячейкой ТабличныйДокумент и исходными записями запроса.

Проанализируем ситуацию: если в таблице 1 000 000 ячеек, то объект расшифровки будет содержать 1 000 000 записей о соответствии. Это колоссальный объем памяти. Если пользователю не требуется детализация каждой цифры в огромном сводном отчете, расшифровку следует отключить.

Для этого в настройках СКД на вкладке Другие настройки нужно найти параметр Доступные поля расшифровки и убрать оттуда все поля или программно инициализировать процессор компоновки без использования расшифровки.

Решение 2: Программный вывод без передачи данных расшифровки

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

В модуле объекта отчета (или в обработчике команды) мы можем реализовать следующий алгоритм:


// 1. Получаем схему и настройки
Схема = Отчеты.МойМегаОтчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = Отчет.КомпоновщикНастроек.ПолучитьНастройки();

// 2. Компонуем макет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляРезультатаКомпоновкиДанных"));

// 3. Инициализируем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// ВАЖНО: Второй параметр - ДанныеРасшифровки. Передаем Неопределено!
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , Неопределено, Истина);

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

Передавая Неопределено вторым параметром метода Инициализировать, мы экономим до 70% оперативной памяти и существенно ускоряем процесс «сборки» ячеек. Отчет, который строился часами, в таком режиме может сформироваться за те же 5-10 минут, что и сам запрос. Для более компактного программного управления структурой схемы можно применить модуль-обертку для программного создания СКД.

Решение 3: Оптимизация оформления и макетов

Разберем еще один фактор замедления — оформление. Стандартные макеты оформления (например, «Античный» или «Море») заставляют процессор вывода вычислять цвета, шрифты и границы для каждой ячейки. В условиях огромной таблицы это создает колоссальную нагрузку.

Чтобы ускорить вывод, рекомендуется:

  1. В настройках СКД установить Макет оформления в значение Без оформления.
  2. Если оформление все же нужно, применять его точечно только к итоговым строкам, используя Условное оформление, а не ко всему отчету сразу.
  3. Использовать параметр МакетОформления = "БезОформления" при программном формировании макета компоновки.

Проанализируем пример кода для установки макета оформления в «Минимальный» или его полное отключение:


ПараметрыВывода = Настройки.ПараметрыВывода;
ЗначениеПараметра = ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("AppearanceTemplate"));
Если ЗначениеПараметра <> Неопределено Тогда
    ЗначениеПараметра.Значение = "NoAppearance"; // Или "Минимальный"
    ЗначениеПараметра.Использование = Истина;
КонецЕсли;

Решение 4: Настройка расчета ресурсов («Рассчитывать по...»)

Часто тормоза вызваны тем, что СКД пытается рассчитать итоги по всем доступным группировкам, даже если это не имеет смысла. Если у вас сложная структура колонок, загляните на вкладку Ресурсы в схеме СКД. Посмотрите на колонку Рассчитывать по....

Если оставить это поле пустым, 1С будет считать ресурс для всех возможных пересечений строк и колонок. Если же явно указать только те группировки, по которым действительно нужен итог (например, только по «Контрагенту» и «Общий итог»), нагрузка на процессор компоновки снизится, так как он пропустит лишние циклы вычислений для вложенных динамических колонок. При необходимости ограничить вывод итогов по колонкам можно использовать способ вывода ресурса СКД только в одной колонке.

Решение 5: Борьба с нехваткой памяти сервера

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

Резюме

Подводя итоги, отметим: если запрос выполняется быстро, а отчет — долго, проблема всегда кроется в визуализации и расчете иерархии. Основными инструментами оптимизации для программиста являются отключение ДанныеРасшифровки, минимизация визуального оформления через МакетОформления и жесткое ограничение расчета ресурсов по группировкам. Применяя эти методы, можно добиться комфортной работы даже с самыми объемными и сложными кросс-таблицами.

← На главную