Как вывести данные из табличной части в шапку печатной формы 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

При разработке или модификации печатных форм в системе 1С часто возникает задача: вывести в область шапки данные, которые физически расположены не в реквизитах самого документа, а в его табличной части. Классический пример — печатная форма ТОРГ-12 для документа «Возврат товаров от покупателя», где в поле «Основание» нужно указать номер и дату документа партии (поступления), взятого из первой строки списка товаров.

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

Анализ проблемы и типичной ошибки «Поле объекта не обнаружено»

Рассмотрим типичную ситуацию: программист пытается получить данные через запрос, но при заполнении параметров макета система выдает ошибку Поле объекта не обнаружено. Проанализируем причину на примере кода из обсуждения:


Запрос.Текст = "ВЫБРАТЬ ВозвратТоваровОтПокупателя.Товары.(ДокументПартии.Номер, ДокументПартии.Дата) ...";
// ...
ОбластьМакета.Параметры.ПартияНомер = ДокументПартии.ДокументПартииНомер;

Почему это не работает?

  1. Вложенные таблицы в запросе: Когда вы выбираете Товары.(...), запрос возвращает внутри основной строки выборки специальный объект типа РезультатЗапроса (вложенную таблицу). К ней нельзя обращаться просто через точку для получения номера документа.
  2. Имена полей: Если в запросе вы выбираете ДокументПартии.Номер, то в структуре результата поле будет называться либо Номер, либо иметь псевдоним, который вы назначили. Поля ДокументПартииНомер в выборке не существует, если оно не задано явно словом КАК.

Способ №1: Прямое обращение к объектной модели (через Ссылку)

Если вы уже находитесь в контексте модуля печати и у вас есть доступ к ссылке на документ (СсылкаНаОбъект), проще всего обратиться к табличной части напрямую. Это избавит вас от написания лишних запросов и сделает код более читаемым. В 1С табличные части ведут себя как коллекции, к элементам которых можно обращаться по индексу.

Разберем реализацию этого метода. Поскольку нам нужна информация только из первой строки, мы обратимся к индексу 0.


// Проверяем, что табличная часть "Товары" не пуста
Если СсылкаНаОбъект.Товары.Количество() > 0 Тогда
    
    // Получаем первую строку (индексация начинается с нуля)
    ПерваяСтрока = СсылкаНаОбъект.Товары[0];
    
    // Проверяем, заполнено ли поле "ДокументПартии"
    Если ЗначениеЗаполнено(ПерваяСтрока.ДокументПартии) Тогда
        
        // Заполняем параметры макета
        // Обратите внимание: Номер и Дата берутся через точку от ссылки на документ партии
        ОбластьМакета.Параметры.ПартияНомер = ПерваяСтрока.ДокументПартии.Номер;
        ОбластьМакета.Параметры.ПартияДата  = ПерваяСтрока.ДокументПартии.Дата;
        
    КонецЕсли;

КонецЕсли;

Преимущества: Высокая скорость написания кода и простота отладки. Недостатки: Если документ партии — это ссылка, обращение ДокументПартии.Номер вызовет дополнительное неявное обращение к базе данных (разыменование ссылки). Для формирования одной печатной формы это не критично, но в массовой печати может снизить производительность.

Способ №2: Использование языка запросов (Оптимальный для сложных форм)

Если ваша печатная форма строится на сложном запросе, или вам нужно выводить данные, которых нет в текущем объекте, правильнее всего будет получить данные из ТЧ отдельным запросом или соединением. Выясним, как правильно составить запрос к табличной части.

Рассмотрим вариант запроса, который вернет данные только первой строки:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ ПЕРВЫЕ 1
|   Т.ДокументПартии.Номер КАК НомерПартии,
|   Т.ДокументПартии.Дата КАК ДатаПартии
|ИЗ
|   Документ.ВозвратТоваровОтПокупателя.Товары КАК Т
|ГДЕ
|   Т.Ссылка = &СсылкаНаОбъект
|УПОРЯДОЧИТЬ ПО
|   Т.НомерСтроки";

Запрос.УстановитьПараметр("СсылкаНаОбъект", СсылкаНаОбъект);
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    ОбластьМакета.Параметры.ПартияНомер = Выборка.НомерПартии;
    ОбластьМакета.Параметры.ПартияДата  = Выборка.ДатаПартии;
КонецЕсли;

Важные моменты в запросе:

Форматирование строки «Основание»

Зачастую в печатных формах (особенно в ТОРГ-12) требуется вывести не просто номер и дату в разные ячейки, а сформировать красивую строку вида "Возврат по накладной № 123 от 01.01.2023". Для этого в типовых конфигурациях 1С рекомендуется использовать встроенные функции общих модулей.

Проанализируем пример формирования такой строки:


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

Если вы работаете в конфигурации, где такой функции нет, можно собрать строку вручную, используя Формат() для даты:


ПредставлениеДаты = Формат(ПерваяСтрока.ДокументПартии.Дата, "ДФ=dd.MM.yyyy");
ТекстОснования = СтрШаблон("№ %1 от %2", ПерваяСтрока.ДокументПартии.Номер, ПредставлениеДаты);

Как вывести данные из последней строки (Вопрос №24)

В ходе обсуждения возник вопрос о том, как получить номер последней строки. Это часто требуется для заполнения итоговых показателей в подвалах или шапках (например, "Всего наименований").

Рассмотрим решение:

  1. Через объект: КоличествоСтрок = СсылкаНаОбъект.Товары.Количество();. Последняя строка будет иметь индекс КоличествоСтрок - 1.
  2. Через запрос: Использовать агрегатную функцию МАКСИМУМ(НомерСтроки) или КОЛИЧЕСТВО(*).

Пример получения номера последней строки для шапки:


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

Подведем итоги

Мы выяснили, что для корректного вывода данных из табличной части в шапку необходимо:

Использование этих подходов позволит вам создавать гибкие и отказоустойчивые печатные формы, которые корректно отображают информацию из любой части документа.

← На главную