Отчеты и Аналитика · 12 мин
Как передать таблицу значений в СКД 1С
Как передать таблицу значений в СКД 1С: настройка внешнего набора данных, код подключения, типизация колонок, ошибки и проверка результата.
Таблица значений в СКД передаётся через объект ВнешниеНаборыДанных при программной компоновке результата отчёта. Это стандартный механизм: вы заполняете таблицу любым способом — запросом, загрузкой из файла, расчётом в коде — а система компоновки использует её как источник данных наравне с запросами.
Главная сложность не в передаче таблицы, а в подготовке: схема компоновки должна знать структуру набора данных заранее, а сама таблица должна быть типизирована. Если колонки не описаны в схеме или типы данных «плавающие», отчёт либо не сформируется, либо покажет пустые строки без внятной ошибки.
Ниже разобран полный цикл: создание внешнего набора данных в схеме, подготовка и типизация таблицы, программный вывод результата, а также типичные ошибки, из-за которых механизм «молча» не работает.
Когда нужна передача таблицы значений в СКД
Стандартный запрос в схеме компоновки закрывает большинство задач, но есть ситуации, где без внешнего набора данных не обойтись. Самая частая — данные получены не запросом к базе: загружены из Excel, получены через веб-сервис, рассчитаны сложным алгоритмом на встроенном языке или собраны из нескольких информационных баз.
Вторая причина — производительность и гибкость. Иногда проще сначала отобрать и обработать данные кодом, поместить результат в таблицу значений, а группировки, итоги, отборы и оформление отдать СКД. Тогда пользователь получает привычные настройки отчёта, а разработчик не выносит сложную логику в запрос.
Важно понимать ограничение: внешний набор данных — это уже готовый «снимок» данных. СКД не может применить к нему отбор на уровне источника, как к запросу. Отборы и параметры будут фильтровать уже переданную таблицу в памяти, поэтому при больших объёмах имеет смысл отсекать лишнее ещё до передачи.
Настройка схемы компоновки: набор данных типа «Объект»
Откройте схему компоновки данных отчёта и на закладке «Наборы данных» добавьте новый набор — «Добавить набор данных — объект». В поле «Имя объекта, содержащего данные» укажите произвольное имя, например ТаблицаДанных. Именно по этому имени СКД будет искать таблицу в переданной коллекции внешних наборов.
Дальше обязательный шаг, который часто пропускают: добавьте поля набора данных. Для каждой колонки будущей таблицы создайте поле с точным именем и укажите тип. Если колонка называется Номенклатура, поле в схеме должно называться так же — регистр и буква «ё» тоже имеют значение.
Тип поля лучше задавать максимально точно. Если в поле «Сумма» разрешить и строку, и число, итоги по нему могут не посчитаться или посчитаются неверно. Для ссылочных полей указывайте конкретный тип ссылки — это даст корректные отборы и расшифровку.
После описания полей настройте ресурсы, роли полей и нужные варианты отчёта как обычно. Со стороны схемы внешний набор ничем не отличается от набора-запроса: доступны группировки, вычисляемые поля, связи наборов и условное оформление.
Подготовка и типизация таблицы значений
Таблица значений перед передачей в СКД должна иметь явно описанные колонки. Если таблица получена запросом (Запрос.Выполнить().Выгрузить()), типизация уже есть — запрос сам формирует типы колонок. Если таблица строится кодом, колонки нужно добавить вручную с указанием типа.
ОписаниеЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
ОписаниеСсылка = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
ТаблицаДанных = Новый ТаблицаЗначений;
ТаблицаДанных.Колонки.Добавить("Номенклатура", ОписаниеСсылка);
ТаблицаДанных.Колонки.Добавить("Количество", ОписаниеЧисло);
ТаблицаДанных.Колонки.Добавить("Сумма", ОписаниеЧисло);
Частая ситуация: данные загружены из файла, и все колонки имеют строковый тип. Перед передачей в СКД такие значения нужно привести к целевым типам — числам, датам, ссылкам. Иначе группировка по «дате»-строке даст неожиданный порядок, а итоги по «сумме»-строке не посчитаются.
Ещё один нюанс — значения NULL и незаполненные ссылки. СКД корректно обрабатывает пустые значения, но смешение NULL и пустой ссылки в одной колонке иногда даёт лишние группировки. Перед передачей полезно пройтись по таблице и нормализовать пустые значения.
Программный вывод отчёта с внешним набором
Передача таблицы выполняется при формировании отчёта кодом. Последовательность: загрузить схему, инициализировать компоновщик макета, выполнить его с передачей внешних наборов, вывести результат процессором вывода.
Схема = Отчеты.МойОтчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = Схема.НастройкиПоУмолчанию;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Настройки);
ВнешниеНаборы = Новый Структура;
ВнешниеНаборы.Вставить("ТаблицаДанных", ТаблицаДанных);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборы);
Результат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Ключевая строка — ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборы). Вторым параметром передаётся структура, где ключ — имя набора данных из схемы, а значение — подготовленная таблица значений. Если в схеме один набор-объект, в структуре один элемент.
- 1Добавьте в схему набор данных типа «Объект» и задайте имя объекта
- 2Опишите поля набора с точными именами и типами колонок
- 3Сформируйте таблицу значений с типизированными колонками
- 4Создайте структуру ВнешниеНаборыДанных с ключом, равным имени объекта
- 5Инициализируйте процессор компоновки макетом и внешними наборами
- 6Выведите результат в табличный документ и проверьте итоги
Использование в отчёте на управляемых формах
Если отчёт построен на СКД без собственной формы, платформа сама формирует его стандартным механизмом — и тогда внешние наборы «из коробки» не передать. Решение — переопределить формирование в модуле объекта отчёта через событие ПриКомпоновкеРезультата.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТаблицаДанных = СформироватьТаблицуДанных();
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);
ВнешниеНаборы = Новый Структура("ТаблицаДанных", ТаблицаДанных);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборы, ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Обратите внимание: настройки берутся из КомпоновщикНастроек объекта отчёта, а не из настроек по умолчанию — так отчёт реагирует на то, что выбрал пользователь. Отключение СтандартнаяОбработка обязательно, иначе отчёт сформируется дважды или упадёт с ошибкой из-за отсутствующего набора данных.
Если нужна расшифровка, передайте ДанныеРасшифровки и в компоновщик макета, и в процессор компоновки, как показано выше. Пропуск параметра в одном из вызовов — частая причина неработающей расшифровки.
Удобно вынести формирование таблицы значений в отдельную функцию модуля отчёта. Тогда её легко тестировать в отладке отдельно от СКД: достаточно проверить, что функция возвращает таблицу с нужными колонками и типами, прежде чем искать ошибку в схеме.
Типичные ошибки и их признаки
Самая распространённая проблема — отчёт формируется, но пустой. Причины почти всегда одни и те же: не совпадает имя ключа структуры с именем объекта в схеме, не описаны поля набора данных либо таблица значений фактически пустая в момент передачи. Проверяйте по порядку, начиная с имён.
Вторая группа ошибок связана с типами. Если числовые итоги не считаются — смотрите тип колонки и тип поля в схеме. Если ссылочные поля выводятся как строки без возможности открыть объект — в колонке лежит строковое представление, а не ссылка.
Третья группа — поведение отборов. Пользователь ставит отбор, а данные не фильтруются ожидаемым образом. Обычно это происходит, когда поле отбора не входит в набор данных или отбор применён к вычисляемому полю с некорректным выражением.
Проверка результата и ограничения механизма
После внедрения проверьте три вещи: количество строк в детальных записях совпадает с количеством строк исходной таблицы (при отключённых отборах), итоги по числовым полям сходятся с контрольной суммой по таблице, отборы и группировки пользователя работают. Простейшая контрольная сумма — ТаблицаДанных.Итог("Сумма") до передачи и итог в отчёте после.
Помните об ограничениях. Таблица значений целиком находится в памяти сервера: при сотнях тысяч строк с множеством колонок расход памяти станет ощутимым. Если объём большой, отсекайте данные параметрами до формирования таблицы либо возвращайтесь к набору-запросу.
Ещё одно ограничение — производительность отборов. Фильтрация по внешнему набору выполняется в памяти и не использует индексы СУБД. На больших таблицах отчёт с отборами будет работать медленнее, чем аналогичный отчёт на запросе. Это нормальное поведение платформы, а не ошибка в коде.
Как проверить результат
Совпадает с числом строк переданной таблицы
Строк меньше или ноль — проверять имена набора и ключи
Сходятся с ТаблицаДанных.Итог() до передачи
Итоги нулевые или не считаются — проблема с типом колонки
Фильтруют данные по полям набора
Отбор не влияет на результат — поле не описано в схеме
Альтернативы передаче таблицы значений
Передача таблицы — не единственный способ скормить СКД произвольные данные. Если данные уже есть в базе, почти всегда выгоднее использовать набор-запрос: он быстрее и поддерживает отборы на уровне СУБД. Внешний набор оправдан только когда источник принципиально не запросный.
Для объединения результата запроса и таблицы значений используйте несколько наборов данных с объединением или связью. Например, основные данные — запросом, а рассчитанные в коде показатели — внешним набором, связанным по ключевому полю. Это стандартный приём для отчётов с план-фактным анализом.
Сравнение вариантов
Данные в базе, нужны быстрые отборы и большие объёмы. Не подходит для внешних источников
Данные из файла, сервиса или расчёта кодом. Ограничение — весь объём в памяти
Нужно дополнить данные базы рассчитанными показателями. Требует связи наборов по ключу
Частые вопросы
Можно ли передать в СКД несколько таблиц значений?
Да. Создайте в схеме несколько наборов данных типа «Объект» с разными именами и передайте структуру с соответствующим числом ключей. Наборы можно объединять или связывать между собой стандартными средствами СКД.
Почему отчёт пустой, хотя таблица заполнена?
Почти всегда причина в несовпадении имени: ключ в структуре ВнешниеНаборыДанных должен посимвольно совпадать с именем объекта, указанным в наборе данных схемы. Также проверьте, что поля набора описаны в схеме и что таблица не очищается перед передачей.
Нужно ли типизировать колонки, если таблица получена запросом?
Нет. Результат метода Выгрузить() у результата запроса уже содержит типизированные колонки. Ручная типизация нужна только когда таблица строится программно или данные загружаются из внешних источников как строки.
Работают ли отборы СКД по внешнему набору данных?
Работают, но фильтрация выполняется в памяти уже после передачи таблицы, а не на уровне запроса к базе. Поэтому на больших объёмах лучше отсекать лишние данные до формирования таблицы.
Можно ли передать табличную часть документа вместо таблицы значений?
Да, платформа принимает табличную часть как внешний набор данных напрямую. Однако для контроля типов и состава колонок часто удобнее выгрузить табличную часть в таблицу значений методом Выгрузить() и передать её.
Почему не работает расшифровка в отчёте с внешним набором?
Объект ДанныеРасшифровки нужно передать и в метод Выполнить компоновщика макета, и в метод Инициализировать процессора компоновки. Пропуск параметра в любом из двух вызовов отключает механизм расшифровки.
Что важно запомнить
Таблица значений передаётся в СКД через структуру ВнешниеНаборыДанных при инициализации процессора компоновки. Условия успеха: набор данных типа «Объект» с описанными полями, типизированные колонки таблицы и точное совпадение имён. Проверяйте результат контрольными итогами и помните про ограничения по памяти на больших объёмах.