Как вывести табличную часть обработки на печать в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе разработки в среде «1С:Предприятие» часто возникает задача вывода данных, находящихся в табличной части обработки, в печатную форму (макет). Начинающие разработчики часто пытаются построить запрос напрямую к табличной части обработки, как если бы это была таблица справочника или документа в базе данных. Однако табличные части обработок не хранятся в физических таблицах СУБД, поэтому работа с ними имеет свои особенности. Разберем пошагово, как правильно решить эту задачу разными способами.

Метод 1. Прямой обход табличной части (наиболее эффективный)

Проанализируем ситуацию: если нам нужно просто вывести строки «как они есть» на экран или принтер, нет необходимости использовать механизм запросов. Запрос — это мощный инструмент для извлечения данных из базы или сложной агрегации, но для обхода уже заполненной на форме таблицы он избыточен. Рассмотрим самый простой и быстрый программный код для решения этой задачи.

Для начала получим область макета, которую мы будем многократно выводить в цикле. Предположим, у нас есть макет с именем Макет и в нем определена область СтрокаТаблицы. Мы будем обращаться к табличной части обработки напрямую через объект ЭтотОбъект.


// Получаем макет и нужную область
Макет = ЭтотОбъект.ПолучитьМакет("Макет");
ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТаблицы");

// Создаем табличный документ, куда будем выводить результат
ТабДокумент = Новый ТабличныйДокумент;

// Перебираем строки табличной части "Комплект" напрямую
Для Каждого ТекущаяСтрока Из ЭтотОбъект.Комплект Цикл
    
    // Заполняем параметры области данными из текущей строки
    ОбластьСтрока.Параметры.Номенклатура = ТекущаяСтрока.Номенклатура;
    ОбластьСтрока.Параметры.Количество = ТекущаяСтрока.Количество;
    ОбластьСтрока.Параметры.Цена = ТекущаяСтрока.Цена;
    ОбластьСтрока.Параметры.Сумма = ТекущаяСтрока.Сумма;
    
    // Выводим область в итоговый документ
    ТабДокумент.Вывести(ОбластьСтрока);
    
КонецЦикла;

// Показываем результат пользователю
ТабДокумент.Показать("Печать комплекта");

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

Метод 2. Использование запроса к таблице значений

Рассмотрим случай, когда данные перед печатью необходимо сгруппировать, отсортировать по сложному условию или соединить с данными из других таблиц базы данных. В этом случае нам действительно понадобится объект Запрос. Посмотрим, как передать данные из памяти (из табличной части) в механизм запросов.

Выясним причину, по которой нельзя просто написать в тексте запроса ИЗ Обработка.МояОбработка.Комплект. Механизм запросов работает с данными, хранящимися в базе, а данные обработки существуют только «здесь и сейчас» в оперативной памяти. Поэтому мы должны сначала выгрузить их в ТаблицаЗначений, а затем передать эту таблицу в запрос как параметр.

Разберем реализацию этого метода:


// 1. Выгружаем табличную часть в таблицу значений (ТЗ)
ТаблицаДанных = ЭтотОбъект.Комплект.Выгрузить();

// 2. Создаем запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВТ_Данные.Номенклатура КАК Номенклатура,
    |   ВТ_Данные.Количество КАК Количество,
    |   ВТ_Данные.Цена КАК Цена,
    |   ВТ_Данные.Сумма КАК Сумма
    |ПОМЕСТИТЬ ВТ_Комплект
    |ИЗ
    |   &ТаблицаПараметр КАК ВТ_Данные
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |   ВТ_Комплект.Номенклатура,
    |   СУММА(ВТ_Комплект.Количество) КАК Количество,
    |   ВТ_Комплект.Цена,
    |   СУММА(ВТ_Комплект.Сумма) КАК Сумма
    |ИЗ
    |   ВТ_Комплект КАК ВТ_Комплект
    |ГРУППИРОВАТЬ ПО
    |   ВТ_Комплект.Номенклатура,
    |   ВТ_Комплект.Цена
    |УПОРЯДОЧИТЬ ПО
    |   Номенклатура";

// 3. Передаем таблицу значений в запрос
Запрос.УстановитьПараметр("ТаблицаПараметр", ТаблицаДанных);

// 4. Выполняем запрос и получаем результат
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

// 5. Вывод в макет (аналогично первому методу)
ТабДокумент = Новый ТабличныйДокумент;
Макет = ЭтотОбъект.ПолучитьМакет("Макет");
Область = Макет.ПолучитьОбласть("Строка");

Пока Выборка.Следующий() Цикл
    Область.Параметры.Заполнить(Выборка);
    ТабДокумент.Вывести(Область);
КонецЦикла;

Обратите внимание на использование временной таблицы (ПОМЕСТИТЬ ВТ_Комплект). При работе с внешними источниками данных в запросе (которым является ТаблицаЗначений), помещение данных во временную таблицу является хорошим тоном и часто необходимо для выполнения последующих операций соединения или группировки.

Оптимизация кода: метод ЗаполнитьЗначенияСвойств

Проанализируем рутинную часть работы: присваивание каждого параметра области макета вручную. Если имен колонок в табличной части и имен параметров в макете много, код становится громоздким. Мы можем использовать встроенную функцию ЗаполнитьЗначенияСвойств. Она автоматически сопоставляет имена свойств источника и приемника и копирует значения там, где имена совпадают.

Посмотрим на пример оптимизированного цикла:


Для Каждого СтрокаТЧ Из ЭтотОбъект.Комплект Цикл
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    // Одной командой заполняем все совпадающие параметры (Номенклатура, Количество и т.д.)
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаТЧ);
    
    // Если нужны дополнительные расчеты, делаем их отдельно
    ОбластьСтрока.Параметры.ЦенаСНаценкой = СтрокаТЧ.Цена * 1.2;
    
    ТабДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

Типичные ошибки при работе с запросами к ТЗ

Разберем основные грабли, на которые наступают новички:

  1. Отсутствие типизации колонок. Если вы создаете таблицу значений программно (через Новый ТаблицаЗначений), а не методом Выгрузить(), обязательно указывайте типы колонок. Запрос не сможет обработать колонку с типом Произвольный.
  2. Группировка по всем полям. Как было замечено в обсуждении, если вы используете СГРУППИРОВАТЬ ПО и включаете туда НомерСтроки, уникальность каждой строки сохраняется, и реальной агрегации (суммирования) не произойдет. Используйте группировку только тогда, когда это действительно нужно для свертки данных.
  3. Задвоение строк. Выясним причину: часто это происходит из-за неправильного соединения (JOIN) во временных таблицах запроса. Если же вы используете только одну таблицу, проверьте, не вызывается ли метод Вывести() дважды в теле цикла.

Итоги

Подводя итог, можно сказать: для простых печатных форм встроенных обработок используйте прямой обход коллекции табличной части. Это сделает ваш код чище, понятнее и быстрее. К запросам стоит прибегать только в тех случаях, когда требуется сложная аналитическая обработка данных перед выводом на печать.

← На главную