К статье
Практический материал

Отчеты и Аналитика · 11 мин

Как передать таблицу значений в СКД в 1С

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

Система компоновки данных (СКД) умеет работать не только с запросами к базе данных, но и с произвольными наборами данных, сформированными программно. Самый частый сценарий — передать в СКД готовую таблицу значений, которую вы заполнили в коде: данные из файла, результаты расчётов, данные из нескольких источников или из веб-сервиса. Для этого используется тип набора данных «Объект» и механизм внешних наборов данных.

Задача решается в три шага: создать в схеме компоновки набор данных типа «Объект», описать в нём поля, а затем при формировании отчёта передать таблицу значений через объект «ВнешниеНаборыДанных» в процессор компоновки. Ниже разобран каждый шаг с кодом, который можно перенести в свой отчёт почти без изменений.

Материал рассчитан на разработчиков и продвинутых пользователей, знакомых с конфигуратором и встроенным языком 1С. Примеры приведены для управляемых форм и подходят как для внешних отчётов, так и для отчётов, встроенных в конфигурацию.

Когда нужна передача таблицы в СКД

Стандартный набор данных «Запрос» покрывает большинство отчётов, но есть ситуации, где запрос не подходит. Типичный случай — данные нужно предварительно обработать в коде: рассчитать показатели сложным алгоритмом, дозаполнить из внешнего источника, объединить данные, которые нельзя соединить одним запросом.

Вторая группа сценариев — данные вообще не хранятся в базе: загрузка из Excel, обмен с сайтом, результаты работы COM-объектов или HTTP-запросов. Третий случай — отчёт строится по временной таблице, которую пользователь редактирует на форме перед формированием отчёта.

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

Шаг 1. Создание набора данных «Объект» в схеме

Откройте схему компоновки данных отчёта. На закладке «Наборы данных» нажмите «Добавить» и выберите «Добавить набор данных — объект». В поле «Имя» задайте понятное имя, например ТаблицаДанных — именно по этому имени вы будете передавать таблицу в коде.

Далее добавьте поля набора: для каждой колонки будущей таблицы значений создайте поле с тем же именем и укажите тип. Имена полей в схеме должны точно совпадать с именами колонок таблицы значений — сопоставление идёт по именам, регистр не важен, но написание должно быть идентичным.

Если поле содержит ссылочный тип (например, «СправочникСсылка.Номенклатура»), укажите его явно — тогда в отчёте будут работать стандартные отборы по ссылкам и расшифровка. Для строк и чисел тоже лучше указывать точные типы, чтобы итоги и сортировка работали корректно.

Шаг 2. Формирование таблицы значений в коде

Таблицу значений можно создать программно или получить запросом с последующей выгрузкой. Пример программного создания:

ТаблицаДанных = Новый ТаблицаЗначений;

ТаблицаДанных.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТаблицаДанных.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

ТаблицаДанных.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

// Заполнение строк

НоваяСтрока = ТаблицаДанных.Добавить();

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000001");

НоваяСтрока.Количество = 10;

НоваяСтрока.Сумма = 15000;

Если данные получаются запросом, но требуют доработки, используйте метод Выгрузить() результата запроса — полученную таблицу можно дополнить вычисляемыми колонками и затем передать в СКД.

Перед передачей убедитесь, что таблица заполнена: пустая таблица не вызовет ошибку, но отчёт сформируется без единой строки, и это часто путают с нерабочей схемой.

Шаг 3. Передача таблицы процессору компоновки

Ключевой этап — программное формирование отчёта. В модуле объекта отчёта используется событие ПриКомпоновкеРезультата, либо формирование вызывается полностью из своего кода. Пример для события отчёта:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

ТаблицаДанных = СформироватьТаблицуДанных(); // ваша функция

СхемаКомпоновки = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

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

МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки,

КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);

ВнешниеНаборы = Новый Структура("ТаблицаДанных", ТаблицаДанных);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы, ДанныеРасшифровки);

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

ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

ПроцессорВывода.Вывести(ПроцессорКомпоновки);

КонецПроцедуры

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

Порядок действий
  1. 1
    Создайте в схеме набор данных типа «Объект» и задайте ему имя
  2. 2
    Добавьте поля набора в точном соответствии с колонками таблицы значений
  3. 3
    Сформируйте таблицу значений в коде и заполните её данными
  4. 4
    Создайте структуру, где ключ — имя набора, значение — таблица
  5. 5
    Передайте структуру вторым параметром в ПроцессорКомпоновки.Инициализировать
  6. 6
    Сформируйте отчёт и проверьте, что строки выведены

Передача таблицы во внешнем отчёте и на форме

Внешний отчёт

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

Отчёт на произвольной форме

Если отчёт формируется по кнопке на собственной форме, весь код из примера выше можно выполнить в обработчике команды, не используя событие ПриКомпоновкеРезультата. Настройки в этом случае берите из компоновщика на форме или создайте их программно.

Несколько таблиц

В схеме может быть несколько наборов-объектов, и в структуру внешних наборов добавляются все нужные таблицы под разными ключами. Наборы можно связывать между собой на закладке «Связи наборов данных» — например, таблицу товаров связать с таблицей цен по полю «Номенклатура».

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

Типичные ошибки и их устранение

Самая частая ошибка — «Не найден внешний набор данных». Причины: ключ структуры не совпадает с именем набора в схеме, либо таблица не передана в Инициализировать. Проверьте написание имени в обоих местах посимвольно.

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

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

Типичные ошибки
01
Имя ключа структуры не совпадает с именем набора данных — СКД не находит таблицу и выдаёт ошибку
02
Имена колонок отличаются от имён полей в схеме — поля выводятся пустыми
03
Не задан тип колонки таблицы значений — некорректно работают итоги, отборы и сортировка
04
Забыт параметр СтандартнаяОбработка = Ложь — отчёт формируется стандартно и код игнорируется
05
В схеме остался старый набор-запрос вместе с набором-объектом — смешение данных и лишние обращения к базе

Проверка результата и альтернативы

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

Контрольные точки

Как проверить результат

Число строк в отчёте
Норма

Равно числу строк таблицы значений без отборов

Тревожный признак

Строк меньше или отчёт пуст

Итоги по числовым полям
Норма

Суммы совпадают с ручным расчётом по таблице

Тревожный признак

Итоги нулевые или не считаются

Отборы пользователя
Норма

Отбор по полю фильтрует строки

Тревожный признак

Отбор не влияет на результат

Расшифровка
Норма

Двойной щелчок показывает детальные данные

Тревожный признак

Расшифровка пустая или с ошибкой

Передача таблицы — не единственный способ дать СКД программные данные. Альтернативы: запрос с временными таблицами (менеджер временных таблиц можно передать в набор-запрос), объединение запроса и объекта в одной схеме, а для иерархических данных — набор «Объект» с передачей дерева значений и указанием полей связи.

Выбирайте внешний набор, когда логика подготовки данных сложнее, чем уместно в запросе, и когда объём данных умеренный. Для простых выборок из базы запрос остаётся предпочтительным — он быстрее и не требует программного формирования отчёта.

Итог

Что важно запомнить

Таблица передаётся в СКД тремя элементами: набор «Объект» в схеме, таблица значений в коде и структура ВнешниеНаборыДанных при инициализации процессора. Совпадение имён набора, ключа структуры и колонок таблицы — главное условие работоспособности.

Частые вопросы

Можно ли передать в СКД дерево значений вместо таблицы?

Да. Набор данных «Объект» принимает и дерево значений. В схеме нужно указать поле связи иерархии (родитель и подчинённый элемент), а в коде передать дерево в структуре внешних наборов так же, как таблицу. В настройках отчёта тогда доступен вывод с иерархией.

Как передать таблицу, если отчёт формируется стандартной кнопкой «Сформировать»?

Используйте событие ПриКомпоновкеРезультата в модуле объекта отчёта: установите СтандартнаяОбработка = Ложь и выполните компоновку программно, как в примере выше. Таблицу можно сформировать прямо в этом обработчике или получить из данных формы.

Работают ли параметры и отборы СКД с внешней таблицей?

Да, отборы, сортировки, группировки и вычисляемые поля применяются к внешнему набору так же, как к результату запроса. Параметры, используемые в отборах и выражениях, тоже работают; не работают только параметры, встроенные в текст запроса, — ведь запроса нет.

Что делать, если СКД выдаёт ошибку «Не найден внешний набор данных»?

Сверьте имя набора данных «Объект» в схеме с ключом структуры, передаваемой в Инициализировать. Убедитесь, что структура передаётся именно вторым параметром, а не третьим. Также проверьте, что в макете компоновки используется именно та схема, где создан набор.

Можно ли в одной схеме использовать и запрос, и переданную таблицу?

Да, схема может содержать несколько наборов: запрос и объект одновременно. Их можно связать на закладке «Связи наборов данных» по общему полю, например по ссылке на номенклатуру. В структуру внешних наборов тогда передаётся только таблица для набора-объекта.

Есть ли ограничение на размер передаваемой таблицы?

Жёсткого ограничения платформой не установлено, но вся таблица размещается в памяти сервера или клиента. При очень больших объёмах возможны замедление формирования и рост потребления памяти, поэтому для сотен тысяч строк лучше рассмотреть запрос с временными таблицами.