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

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

📊 Какой способ передачи таблиц в СКД вы используете чаще?
Через параметры отчета
Временные таблицы
Программное формирование схемы
Другой вариант

1. Основные способы передачи таблиц в СКД

В 1С:Предприятие 8.3 существует несколько подходов к передаче табличных данных в систему компоновки. Выбор метода зависит от задачи:

  • 📊 Через параметры отчета — простейший способ для небольших таблиц, когда данные формируются заранее и передаются как коллекция.
  • 🗃️ Временные таблицы — оптимально для больших наборов данных, так как СКД работает с ними напрямую через запросы.
  • 💻 Программное формирование схемы — гибкий, но сложный метод, позволяющий динамически создавать структуру отчета.

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

⚠️ Внимание: При использовании временных таблиц убедитесь, что в настройках информационной базы разрешено создание временных таблиц (параметр РазрешитьВременныеТаблицы в конфигурации). В противном случае СКД не сможет к ним подключиться.

2. Передача таблицы через параметры отчета

Это самый простой метод, подходящий для таблиц с фиксированной структурой. Алгоритм действий:

  1. Создайте в модуле отчета параметр типа ТаблицаЗначений.
  2. Заполните таблицу данными перед вызовом СКД.
  3. Передайте таблицу как параметр в схему компоновки.

Пример кода для передачи таблицы с данными о продажах:

Процедура СформироватьОтчет()

ТаблицаПродаж = Новый ТаблицаЗначений;

ТаблицаПродаж.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));

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

// Заполнение данными

Для Каждого Продажа Из ВыборкаПродаж Цикл

Строка = ТаблицаПродаж.Добавить();

Строка.Дата = Продажа.Дата;

Строка.Сумма = Продажа.Сумма;

КонецЦикла;

// Передача в СКД

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

Отчет.Параметры.Данные.Установить(ТаблицаПродаж);

Результат = Отчет.СкомпоноватьРезультат();

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

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

Совпадение имен колонок в таблице и схеме СКД

Соответствие типов данных полей

Отсутствие пустых значений в обязательных полях

Правильная сортировка данных (если требуется)-->

3. Использование временных таблиц

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

  • Высокая производительность — данные не передаются через параметры, а извлекаются напрямую.
  • 🔍 Гибкая фильтрация — можно применять сложные условия в запросах СКД.
  • 🔄 Динамическое обновление — таблицу можно модифицировать перед компоновкой.

Пример создания временной таблицы и её использования в СКД:

Процедура ПодготовитьДанныеДляСКД()

// Создание временной таблицы

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ТоварКакОбъект.Ссылка КАК Товар,

| СУММА(Документ.Количество) КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

|ГДЕ

| Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

|СГРУППИРОВАТЬ ПО

| ТоварКакОбъект.Ссылка";

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ТекущаяДата()));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(ТекущаяДата()));

// Создание временной таблицы

ВременнаяТаблица = Запрос.Выполнить().Выгрузить();

ВременнаяТаблица.Записать();

// Передача имени таблицы в СКД

Отчет = КомпоновщикМакета.ПолучитьМакет("ОтчетПоПродажам");

Отчет.Параметры.Данные.Установить(ВременнаяТаблица.Имя);

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

⚠️ Внимание: Временные таблицы автоматически удаляются после завершения сеанса. Если отчет формируется в фоновом задании, убедитесь, что таблица существует на момент компоновки.
Как проверить существование временной таблицы?

Используйте запрос к системному каталогу:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ 1 ИЗ _ВременныеТаблицы ГДЕ Имя = &ИмяТаблицы";

Запрос.УстановитьПараметр("ИмяТаблицы", ИмяВременнойТаблицы);

Результат = Запрос.Выполнить();

Если НЕ Результат.Пустой() Тогда

// Таблица существует

КонецЕсли;

4. Программное формирование схемы компоновки

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

Основные шаги:

  1. Создать объект СхемаКомпоновкиДанных.
  2. Добавить источники данных (таблицы или запросы).
  3. Определить наборы данных и связи между ними.
  4. Настроить параметры и макеты.

Пример динамического создания схемы для таблицы с произвольными колонками:

Процедура СоздатьДинамическуюСхему(ТаблицаДанных)

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

// Создание источника данных

Источник = Схема.ИсточникиДанных.Добавить("ОсновнойИсточник");

Источник.Тип = Тип("ТаблицаЗначений");

Источник.Таблица = ТаблицаДанных;

// Добавляем колонки динамически

Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл

Поле = Схема.Поля.Добавить(Колонка.Имя);

Поле.ПутьКДанным = "ОсновнойИсточник." + Колонка.Имя;

Поле.ТипЗначения = Колонка.ТипЗначения;

КонецЦикла;

// Настройка набора данных

НаборДанных = Схема.НаборыДанных.Добавить("ОсновнойНабор");

НаборДанных.Источники.Добавить("ОсновнойИсточник");

Возврат Схема;

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

Этот подход полезен для отчетов с пользовательскими настройками, где колонки выбираются в интерфейсе. Например, в отчете по остаткам товаров пользователь может выбрать, какие поля отображать (цена, количество, резерв и т.д.).

💡

Для ускорения работы с динамическими схемами используйте кэширование. Если структура отчета меняется редко, сохраняйте сгенерированную схему в ХранилищеЗначения и переиспользуйте её.

5. Типичные ошибки и их решение

При передаче таблиц в СКД разработчики часто сталкиваются с типичными проблемами. Рассмотрим самые распространенные:

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

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

6. Оптимизация производительности

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

  • 🚀 Используйте временные таблицы вместо передачи через параметры — это ускоряет обработку в 5-10 раз.
  • 🗑️ Очищайте ненужные колонки перед передачей: Таблица.Колонки.Удалить("НенужноеПоле").
  • 🔄 Применяйте серверные процедуры для предварительной агрегации данных.
  • 📊 Настраивайте индексы во временных таблицах для ускорения запросов СКД.

Пример оптимизированного кода для передачи больших данных:

Процедура ОптимизированнаяПередачаДанных()

// 1. Получаем данные с агрегацией на сервере

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товар.Ссылка КАК Товар,

| СУММА(Документ.Количество) КАК ИтогоКоличество,

| СУММА(Документ.Сумма) КАК ИтогоСумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Товар

| ПО Документ.Товар = Товар.Ссылка

|ГДЕ

| Документ.Дата МЕЖДУ &Начало И &Конец

|СГРУППИРОВАТЬ ПО

| Товар.Ссылка";

РезультатЗапроса = Запрос.Выполнить();

// 2. Создаем временную таблицу с минимальным набором полей

ВременнаяТаблица = РезультатЗапроса.Выгрузить();

ВременнаяТаблица.Колонки.Удалить("Ссылка"); // Удаляем служебное поле

// 3. Передаем в СКД

Отчет = КомпоновщикМакета.ПолучитьМакет("АнализПродаж");

Отчет.Параметры.Данные.Установить(ВременнаяТаблица);

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

⚠️ Внимание: При использовании временных таблиц в кластерных базах (например, 1С:Предприятие 8.3 с PostgreSQL) убедитесь, что таблица создается на том же сервере, где выполняется компоновка. В противном случае СКД не сможет к ней подключиться.
💡

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

7. Практический пример: отчет по остаткам товаров

Рассмотрим полный пример создания отчета по остаткам товаров с передачей таблицы в СКД через временную таблицу.

Шаг 1. Подготовка данных:

Процедура ПодготовитьДанныеПоОстаткам()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Наименование КАК Товар,

| ОстаткиТоваровОстатки.КоличествоОстаток КАК Количество,

| ОстаткиТоваровОстатки.СуммаОстаток КАК Сумма

|ИЗ

| РегистрНакопления.ОстаткиТоваров.Остатки(&ДатаОтчета,) КАК ОстаткиТоваровОстатки

| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура

| ПО ОстаткиТоваровОстатки.Номенклатура = Номенклатура.Ссылка";

Запрос.УстановитьПараметр("ДатаОтчета", ТекущаяДата());

Результат = Запрос.Выполнить();

// Создание временной таблицы

ВременнаяТаблица = Результат.Выгрузить();

ВременнаяТаблица.Записать();

Возврат ВременнаяТаблица.Имя;

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

Шаг 2. Настройка СКД:

В схеме компоновки создаем набор данных с запросом к временной таблице:

ВЫБРАТЬ

Товар КАК Товар,

Количество КАК Количество,

Сумма КАК Сумма

ИЗ

&ИмяВременнойТаблицы

Шаг 3. Формирование отчета:

Процедура СформироватьОтчетПоОстаткам()

ИмяТаблицы = ПодготовитьДанныеПоОстаткам();

Отчет = КомпоновщикМакета.ПолучитьМакет("ОстаткиТоваров");

Отчет.Параметры.Данные.Установить(ИмяТаблицы);

Результат = Отчет.СкомпоноватьРезультат();

Результат.Показать();

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

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

FAQ: Частые вопросы по передаче таблиц в СКД

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

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

  1. Анализирует структуру передаваемой таблицы (ТаблицаЗначений.Колонки).
  2. Динамически добавляет поля в схему компоновки (СхемаКомпоновкиДанных.Поля.Добавить()).
  3. Настраивает набор данных с учетом новых полей.

Пример кода смотрите в разделе "Программное формирование схемы компоновки".

Почему СКД не видит временную таблицу, хотя она существует?

Вероятные причины:

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

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

Как передать в СКД таблицу с вложенными таблицами (иерархические данные)?

СКД не поддерживает прямую работу с вложенными таблицами. Решения:

  1. Денормализация: "разверните" вложенные таблицы в плоскую структуру с повторяющимися данными.
  2. Отдельные наборы данных: создайте несколько наборов в схеме и свяжите их по ключевым полям.
  3. Представление в JSON: сериализуйте вложенные данные в строку и разбирайте их в вычисляемых полях СКД.

Пример денормализации:

Запрос.Текст =

"ВЫБРАТЬ

| Заказ.Номер КАК НомерЗаказа,

| Товары.Номенклатура КАК Товар,

| Товары.Количество КАК Количество

|ИЗ

| Документ.ЗаказКлиента КАК Заказ

| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.Товары КАК Товары

| ПО Заказ.Ссылка = Товары.Ссылка";

Какие ограничения на размер передаваемой таблицы?

Ограничения зависят от способа передачи:

  • Параметры отчета: до 100 000 строк (может варьироваться в зависимости от памяти клиента).
  • Временные таблицы: ограничены только лимитами СУБД (например, для PostgreSQL — миллионы строк).

Для больших данных рекомендуется:

  • Использовать серверную агрегацию (GROUP BY в запросах).
  • Разбивать отчет на части (по периодам, складам и т.д.).
  • Применять ЛенивыеЗапросы для постраничной загрузки.
Как передать в СКД данные из внешнего источника (Excel, JSON)?

Алгоритм:

  1. Загрузите данные во временную таблицу :
    Таблица = Новый ТаблицаЗначений;
    

    // Загрузка из Excel через COM или JSON через ЧтениеJSON

  2. Создайте временную таблицу в базе:
    ВременнаяТаблица = Новый ВременнаяТаблица(Таблица);
        
  3. Передайте имя таблицы в СКД как параметр.

Для JSON используйте ЧтениеJSON:

ЧитательJSON = Новый ЧтениеJSON;

ЧитательJSON.УстановитьСтроку(JSONСтрока);

Таблица = ПрочитатьJSON(ЧитательJSON);