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