При разработке отчетов в системе «1С:Предприятие» программисты часто сталкиваются с необходимостью вывести данные, полученные не прямым запросом к базе данных, а сформированные программно в виде ТаблицыЗначений. Одним из наиболее быстрых инструментов для решения этой задачи является ПостроительОтчета. Однако при его использовании часто возникает ошибка: «Ошибка при вызове конструктора (ОписаниеИсточникаДанных): Несоответствие типов (параметр номер '1')». Рассмотрим подробно, почему это происходит и как правильно организовать передачу данных.
Разберем типичную ситуацию. Программист пытается передать данные из экранной формы в построитель, используя следующий код:
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Объект.тзТрансакции);
Выясним причину возникновения ошибки. В данном контексте Объект.тзТрансакции является объектом типа ТабличнаяЧасть. Несмотря на внешнее сходство с таблицей, с точки зрения платформы 1С — это разные типы объектов. Конструктор объекта ОписаниеИсточникаДанных жестко ограничен и принимает в качестве первого параметра только следующие типы:
ТаблицаЗначенийРезультатЗапросаОбластьЯчеекТабличногоДокументаЧтобы исправить ситуацию, нам необходимо преобразовать табличную часть в «чистую» таблицу значений. Проанализируем правильный вариант вызова:
// Используем метод Выгрузить(), чтобы получить объект типа ТаблицаЗначений
ТаблицаДляПостроителя = Объект.тзТрансакции.Выгрузить();
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДляПостроителя);
Теперь рассмотрим более сложный и практичный пример. Представим, что мы получили данные из внешнего источника (например, SQL-запросом) в объект ТаблицаЗначений и хотим вывести их пользователю с группировками, итогами и оформлением. Посмотрим на алгоритм реализации универсальной функции на стороне сервера.
Для корректной работы ПостроителяОтчета крайне важно соблюдать последовательность действий. Проанализируем шаги настройки:
ТаблицеЗначений имеют явно заданные типы данных. Если колонка будет иметь тип Произвольный, построитель может не понять, как по ней итожить данные.ИсточникДанных.ЗаполнитьНастройки() должен вызываться сразу после установки источника, но до того, как мы начнем вручную менять состав группировок или ресурсов.Рассмотрим пример реализации такой функции:
&НаСервере
Функция ПолучитьОтчетИзТЗ(ТЗ, ЗаголовокОтчета, СписокИзмерений, СписокРесурсов)
Построитель = Новый ПостроительОтчета;
Построитель.ТекстЗаголовка = ЗаголовокОтчета;
// Передаем ТЗ в описание источника данных
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ);
// Сначала заполняем настройки по умолчанию на основании источника
Построитель.ЗаполнитьНастройки();
// Теперь настраиваем измерения (группировки строк)
Для Каждого Элемент Из СписокИзмерений Цикл
// Элемент.Ключ - это имя колонки в ТЗ
Построитель.ИсточникДанных.Колонки[Элемент.Ключ].Измерение = Истина;
КонецЦикла;
// Настраиваем ресурсы (поля, по которым считаются итоги)
Для Каждого Элемент Из СписокРесурсов Цикл
// Указываем агрегатную функцию, например, СУММА
Построитель.ИсточникДанных.Колонки[Элемент.Ключ].Итог = "СУММА(" + Элемент.Ключ + ")";
КонецЦикла;
// Настройка оформления
Построитель.ЗаполнениеРасшифровки = ВидЗаполненияРасшифровкиПостроителяОтчета.ЗначенияГруппировок;
Построитель.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
// Выполняем расчет и выводим в табличный документ
Построитель.Выполнить();
ТабДокумент = Новый ТабличныйДокумент;
Построитель.Вывести(ТабДокумент);
Возврат ТабДокумент;
КонецФункции
Выясним еще одну причину, по которой ПостроительОтчета может вести себя некорректно. Если вы создаете ТаблицуЗначений программно, обязательно используйте объект ОписаниеТипов. Если построитель встретит колонку с неопределенным типом, он не сможет построить по ней итоги.
Рассмотрим пример правильного создания колонки:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
КЧ = Новый КвалификаторыЧисла(15, 2);
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , КЧ);
ТЗ.Колонки.Добавить("СуммаТранзакции", ОписаниеТипаЧисло);
Если данные приходят из SQL-запроса, проанализируем ситуацию наличия значений NULL. ПостроительОтчета не умеет складывать NULL с числами в итогах. Перед передачей таблицы в построитель рекомендуется пройтись по числовым колонкам и заменить все пустые значения на 0.
Посмотрим на контекст выполнения кода. ПостроительОтчета — это объект, доставшийся нам в наследство от обычных форм (версии 8.0 и 8.1). В современном интерфейсе «Такси» и на управляемых формах работа с ним имеет свои ограничения:
ПостроительОтчета не существует на клиенте. Все манипуляции должны происходить в процедурах с директивой &НаСервере.ПостроительОтчета с сервера на клиент. Мы должны сформировать ТабличныйДокумент на сервере и только его вернуть на клиентскую часть для отображения пользователю.Несмотря на удобство ПостроителяОтчета для простых задач, разберем, почему в современных конфигурациях лучше использовать Систему компоновки данных (СКД) с типом источника «Внешний набор данных»:
Однако, если вам нужно быстро вывести временную таблицу "в два клика" без создания схем компоновки, использование метода Объект.ТабличнаяЧасть.Выгрузить() в связке с ПостроителемОтчета остается вполне рабочим и эффективным инструментом.