СКД в 1С

Набор данных — Объект в СКД 1С: таблица значений как источник

Коротко

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

Сама таблица передаётся программно в событии модуля отчёта ПриКомпоновкеРезультата: создайте ВнешниеНаборыДанных = Новый Структура("ТаблицаДанных", ТЗ) и передайте эту структуру вторым параметром в метод ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки).

1. Когда в СКД нужен «Набор данных — объект»

В 90% задач отчёты на системе компоновки данных строятся на НаборДанныхЗапросСхемыКомпоновкиДанных, когда все данные выбираются языком запросов из текущей информационной базы. Однако есть целый класс задач, где данные невозможно или нерационально получить одним запросом 1С:

  • Внешние источники: загрузка прайс-листов и актов сверки из файлов XLSX/CSV, получение остатков или курсов из REST API / HTTP-сервисов, чтение данных через COM или ADO из сторонней СУБД.
  • Сложные алгоритмы расчёта на встроенном языке: рекурсивный обход дерева спецификаций, пошаговое распределение партий по FIFO с нетиповой логикой, парсинг строк JSON/XML или вызов функций БСП, возвращающих готовую ТаблицаЗначений.
  • Дообогащение данных базы: соединение выгруженной из файла таблицы с реальными справочниками и регистрами 1С в одном отчёте с пользовательскими группировками, отборами и расшифровкой.

Вместо того чтобы вручную рисовать макет табличного документа и программировать итоги в цикле, достаточно подать подготовленную ТаблицаЗначений в НаборДанныхОбъектСхемыКомпоновкиДанных — и пользователь получит все возможности стандартного отчёта СКД: отборы, сортировки, условное оформление, кросс-таблицы и диаграммы.

2. Настройка в конструкторе СКД: ИмяОбъекта и обязательный ТипЗначения

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

  1. Имя набора данных (свойство Имя) — внутреннее имя набора внутри схемы (по умолчанию НаборДанных1), используется при настройке связей наборов данных.
  2. Имя объекта, содержащего данные (свойство ИмяОбъекта) — строковый идентификатор ключа в структуре ВнешниеНаборыДанных, по которому процессор компоновки найдёт вашу таблицу значений при исполнении (например, ТаблицаДанных). Рекомендуется давать осмысленное имя без пробелов.
  3. Таблица полей — добавьте каждую колонку будущей ТаблицаЗначений. Поле Путь к данным и Поле должны строго совпадать с программным именем колонки в ТаблицаЗначений.Колонки.
  4. Тип значения (свойство ТипЗначения) — обязательная колонка для каждого поля. Укажите точный тип (СправочникСсылка.Номенклатура, Число(15, 2), Строка(100), Дата).

Почему нельзя оставлять колонку Тип значения пустой в конструкторе? Для набора-объекта у компоновщика макета нет метаданных запроса при формировании макета компоновки:

  • без указания числового типа ОписаниеТипов("Число", ...) агрегатные функции ресурсов Сумма(...) и Среднее(...) не сработают либо выдадут пустые итоги;
  • без ссылочного типа в пользовательских отборах нельзя будет выбрать элемент из справочника и обращаться к реквизитам через точку (например, Номенклатура.Артикул или Контрагент.ИНН);
  • при типизации самой ТаблицаЗначений в коде также обязательно задавайте ОписаниеТипов при вызове ТЗ.Колонки.Добавить(...) — нетипизированная колонка в ряде режимов приводит к пустым строкам при выводе.
// Поля в конструкторе НаборДанныхОбъект (ИмяОбъекта = "ТаблицаДанных"):
// 1. Поле: Склад        | ТипЗначения: СправочникСсылка.Склады
// 2. Поле: Номенклатура | ТипЗначения: СправочникСсылка.Номенклатура
// 3. Поле: Количество   | ТипЗначения: Число(15, 3)
// 4. Поле: СуммаПродаж  | ТипЗначения: Число(15, 2)

// Ресурсы на вкладке "Ресурсы":
// Поле: Количество  | Выражение: Сумма(Количество)
// Поле: СуммаПродаж | Выражение: Сумма(СуммаПродаж)
НаборДанныхОбъектСхемыКомпоновкиДанных
ИмяСтрока — имя набора данных в схеме
ИмяОбъектаСтрока — ключ в структуре ВнешниеНаборыДанных
ПоляПоляНабораДанныхСхемыКомпоновкиДанных — коллекция полей
ИсточникДанныхСтрока — имя источника данных схемы
→ Элемент коллекции НаборыДанных

3. Передача ТаблицаЗначений в ПриКомпоновкеРезультата

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

Поэтому в модуле объекта отчёта необходимо определить обработчик события ПриКомпоновкеРезультата, отключить стандартную обработку (СтандартнаяОбработка = Ложь) и самостоятельно выполнить конвейер компоновки, передав структуру ВнешниеНаборыДанных во второй параметр метода ПроцессорКомпоновкиДанных.Инициализировать(...).

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

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

    // 1. Получаем актуальные настройки с учётом выбора пользователя на форме
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();

    // 2. Собираем типизированную ТаблицуЗначений (из расчёта, файла или API)
    ТаблицаДанных = ПодготовитьТаблицуДанных(Настройки);

    // Ключ структуры строго совпадает со свойством ИмяОбъекта в схеме СКД!
    ВнешниеНаборыДанных = Новый Структура;
    ВнешниеНаборыДанных.Вставить("ТаблицаДанных", ТаблицаДанных);

    // 3. Формируем макет компоновки данных
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(
        СхемаКомпоновкиДанных,
        Настройки,
        ДанныеРасшифровки
    );

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

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

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

Функция ПодготовитьТаблицуДанных(Настройки)

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

    // Заполнение строк ТЗ по данным расчёта или внешнего файла...
    Возврат ТЗ;

КонецФункции
ПроцессорКомпоновкиДанных.Инициализировать
МакетМакетКомпоновкиДанных — сформированный макет компоновки
ВнешниеНаборыДанныхСтруктура — ключ = ИмяОбъекта, значение = ТаблицаЗначений
ДанныеРасшифровкиДанныеРасшифровкиКомпоновкиДанных — объект расшифровки
ВозможностьИспользованияВнешнихФункцийБулево — разрешить вызовы общих модулей
→ Процедура (без возвращаемого значения)

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

Задавать вручную типы каждой колонки на вкладке «Наборы данных» в Конфигураторе, сверять их с кодом модуля объекта и отлаживать ПриКомпоновкеРезультата вручную долго и чревато ошибками типизации. В ИИ Консоли отчётов 1С агент сам изучает метаданные вашей базы, настраивает поля и типы в схеме компоновки данных, пишет модуль объекта, собирает готовый внешний отчёт .erf и проверяет его формирование в 1С.

4. Полностью программная сборка НаборДанныхОбъектСхемыКомпоновкиДанных

Иногда состав колонок таблицы значений заранее неизвестен на этапе разработки (например, динамическая загрузка произвольного файла или формирование универсальной печатной ведомости). В этом случае схему компоновки данных вместе с НаборДанныхОбъектСхемыКомпоновкиДанных можно собрать полностью в коде 1С без макета в Конфигураторе.

&НаСервере
Процедура СформироватьОтчетПоПроизвольнойТЗ(ТаблицаДанных, ДокументРезультат)

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

    // 1. Источник данных схемы
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "ЛокальнаяБаза";
    Источник.ТипИсточникаДанных = "Local";

    // 2. Создаём НаборДанныхОбъектСхемыКомпоновкиДанных
    НаборОбъект = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
    НаборОбъект.Имя = "НаборТаблица";
    НаборОбъект.ИсточникДанных = "ЛокальнаяБаза";
    НаборОбъект.ИмяОбъекта = "ТаблицаДанных";

    // 3. Автоматически переносим колонки и их типы из ТаблицаЗначений в поля набора
    Для Каждого КолонкаТЗ Из ТаблицаДанных.Колонки Цикл
        ПолеНабора = НаборОбъект.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
        ПолеНабора.Поле = КолонкаТЗ.Имя;
        ПолеНабора.ПутьКДанным = КолонкаТЗ.Имя;
        ПолеНабора.Заголовок = ?(ЗначениеЗаполнено(КолонкаТЗ.Заголовок), КолонкаТЗ.Заголовок, КолонкаТЗ.Имя);
        ПолеНабора.ТипЗначения = КолонкаТЗ.ТипЗначения;

        // Числовые колонки автоматически регистрируем как суммовые ресурсы
        Если КолонкаТЗ.ТипЗначения.СодержитТип(Тип("Число")) Тогда
            ПолеИтога = Схема.ПоляИтога.Добавить();
            ПолеИтога.ПутьКДанным = КолонкаТЗ.Имя;
            ПолеИтога.Выражение = "Сумма(" + КолонкаТЗ.Имя + ")";
        КонецЕсли;
    КонецЦикла;

    // 4. Настраиваем структуру вывода: группировка "Детальные записи" и все поля в Выбор
    КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
    КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
    КомпоновщикНастроек.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
    Настройки = КомпоновщикНастроек.Настройки;

    Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
    Группировка.Использование = Истина;

    Для Каждого КолонкаТЗ Из ТаблицаДанных.Колонки Цикл
        ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
        ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(КолонкаТЗ.Имя);
        ВыбранноеПоле.Использование = Истина;
    КонецЦикла;

    АвтоПоле = Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
    АвтоПоле.Использование = Истина;

    // 5. Собираем макет и выводим результат
    ВнешниеНаборы = Новый Структура("ТаблицаДанных", ТаблицаДанных);
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроек.ПолучитьНастройки());

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

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

КонецПроцедуры
ПолеНабораДанныхСхемыКомпоновкиДанных
ПолеСтрока — имя поля в наборе данных
ПутьКДаннымСтрока — путь к полю в схеме СКД
ЗаголовокСтрока — представление колонки в отчёте
ТипЗначенияОписаниеТипов — допустимые типы данных поля
РольРольКомпоновкиДанных — измерение, счёт и др.
→ Элемент коллекции Поля

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

5. Связь НаборДанныхОбъект с НаборДанныхЗапрос в одной схеме

Одно из главных преимуществ СКД — возможность соединить внешнюю ТаблицаЗначений с данными информационной базы без записи временных объектов в БД. В одной схеме вы создаёте два набора данных:

  • НаборОбъект (тип НаборДанныхОбъектСхемыКомпоновкиДанных, например ИмяОбъекта = "ПланИзExcel") — содержит поля Номенклатура и ПланПродаж, прочитанные из файла.
  • НаборЗапрос (тип НаборДанныхЗапросСхемыКомпоновкиДанных) — выбирает из регистра накопления Продажи.Обороты фактические продажи за период по полю Номенклатура.

На вкладке Связи наборов данных (коллекция Схема.СвязиНаборовДанных) добавляется связь: Источник связи — НаборОбъект, Приёмник связи — НаборЗапрос, Выражение источника и Выражение приёмника — Номенклатура. Процессор компоновки выполнит левое соединение в памяти.

Чтобы запрос не выбирал обороты по всей базе, а фильтровал только позиции из вашей таблицы значений, используйте в запросе условие ГДЕ ПродажиОбороты.Номенклатура В (&СписокНоменклатуры) и укажите в связи Параметр связи (свойство Параметр) = СписокНоменклатуры с включённым флагом Параметры связи (свойство РазрешенСписокПараметров = Истина). Платформа сама соберёт массив значений Номенклатура из НаборОбъект и подставит его в параметр запроса.

Если же нужно не соединять колонки по горизонтали, а сложить строки из ТаблицаЗначений и запроса в единую таблицу (аналог ОБЪЕДИНИТЬ ВСЕ), поместите оба набора внутрь НаборДанныхОбъединениеСхемыКомпоновкиДанных.

6. Набор данных — объект или временная таблица в запросе: что выбрать

Передать ТаблицаЗначений в отчёт можно двумя путями: как НаборДанныхОбъект в процессор компоновки либо как параметр в НаборДанныхЗапрос с помещением во временную таблицу (ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ВнешняяТЗ КАК Данные). Выбор зависит от архитектуры отчёта:

Критерий НаборДанныхОбъект (ВнешниеНаборыДанных) ТаблицаЗначений через параметр в НаборДанныхЗапрос
Где выполняется соединение и отбор В оперативной памяти средствами процессора компоновки данных 1С На стороне СУБД внутри пакетного запроса с временной таблицей
Типы колонок Допускаются любые типы 1С, доступные в СКД (примитивные, ссылки, перечисления) Жёсткие требования СУБД: строго фиксированная длина строк (КвалификаторыСтроки) и точность чисел
Сложные соединения с регистрами (INNER JOIN, ВТ) Только левое соединение (LEFT JOIN) через «Связи наборов данных» или объединение в «Набор — объединение» Доступны любые конструкции языка запросов: ВНУТРЕННЕЕ СОЕДИНЕНИЕ, ПОЛНОЕ СОЕДИНЕНИЕ, индексация ВТ
Отчёт полностью без обращений к БД Да — работает даже для чисто расчётных данных или внешних файлов без единого запроса к информационной базе Нет — платформа всё равно создаёт временную таблицу в СУБД и выполняет запрос
Объём внешней таблицы Оптимально от десятков до 20–50 тыс. строк При больших объёмах передача ТЗ на сервер СУБД нагружает сеть и tempdb
Не знаете, что лучше подойдёт для вашего расчёта — НаборДанныхОбъект или пакетный запрос с временными таблицами? Опишите задачу в ИИ Консоли отчётов 1С: агент проанализирует структуру регистров вашей базы, выберет оптимальную архитектуру схемы СКД, соберёт отчёт .erf и сверит итоговые цифры на реальных данных.

Частые ошибки при работе с набором данных — объект

  • Не заполнена колонка «Тип значения» у полей набора в конструкторе СКД. Самая частая причина, почему таблица значений передана, но отчёт выводится с пустыми ячейками, не считает ресурсы Сумма() или не даёт раскрыть реквизиты справочника через точку. Для НаборДанныхОбъект тип каждого поля в схеме обязателен.
  • Несовпадение ИмяОбъекта в схеме и ключа в структуре ВнешниеНаборыДанных. Если в конструкторе СКД в поле «Имя объекта, содержащего данные» написано ТаблицаДанных, а в коде вы написали Новый Структура("НаборДанных1", ТЗ) (перепутав Имя набора и ИмяОбъекта), процессор компоновки не найдёт источник и выбросит исключение.
  • Колонки самой ТаблицаЗначений созданы без ОписаниеТипов. Конструкция ТЗ.Колонки.Добавить("Сумма") создаёт колонку с произвольным типом. Всегда передавайте второй параметр с точным типом: ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2))).
  • В КомпоновщикМакета.Выполнить передаются КомпоновщикНастроек.Настройки вместо КомпоновщикНастроек.ПолучитьНастройки(). В результате все отборы, сортировки и группировки, которые пользователь настроил в быстрых настройках на форме отчёта, игнорируются.
  • Забыли указать СтандартнаяОбработка = Ложь в ПриКомпоновкеРезультата. После вашего программного вывода платформа повторно запустит штатный механизм компоновки, который не знает про локальную переменную ВнешниеНаборыДанных, и упадёт с ошибкой.
  • Использование параметров СКД без чтения их из Настройки.ПараметрыДанных. В отличие от запроса, где параметр &Период подставляется платформой автоматически, функцию заполнения вашей ТаблицаЗначений вы вызываете сами в коде — поэтому значения периода и отборов нужно прочитать из Настройки.ПараметрыДанных и применить при сборке ТЗ.

Частые вопросы по набору данных — объект в СКД

Почему отчёт на СКД с набором данных — объект выводит пустые строки или не считает итоги?

Причина почти всегда в отсутствии типизации: проверьте, что в конструкторе схемы СКД у каждого поля набора заполнен реквизит ТипЗначения, а при создании колонок ТаблицаЗначений в коде 1С вторым параметром передан объект ОписаниеТипов. Без явного типа Число ресурсы Сумма и Среднее не рассчитываются, а без ссылочного типа не работают поля через точку.

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

Создайте в схеме компоновки данных несколько наборов типа НаборДанныхОбъектСхемыКомпоновкиДанных с разными значениями свойства ИмяОбъекта, например ТаблицаПланов и ТаблицаФакта, и настройте связь или объединение между ними. В обработчике ПриКомпоновкеРезультата поместите обе таблицы в одну структуру ВнешниеНаборыДанных под соответствующими ключами и передайте её в ПроцессорКомпоновкиДанных.Инициализировать.

Работают ли пользовательские отборы, группировки и расшифровка для ТаблицаЗначений в СКД?

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

Тарифы

ИИ Консоль отчётов 1С

Лайт

Бесплатно

Для ознакомления с возможностями

  • Все функции бесплатно на 2 дня +2 дня за подписку на Telegram или Max
  • Полный набор инструментов без урезаний
  • Без ввода карты

Ранний доступ

Популярный выбор
Бесплатно

Тестирование продукта в режиме разработки

  • Формирование панелей и виджетов в чате
  • Поддержка таблиц и популярных типов диаграмм
  • Приоритетный сбор обратной связи по развитию продукта