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