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