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