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