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