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

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

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

Анализ основных ошибок в коде внешнего отчета

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

  1. Некорректное обращение к макету внешнего отчета: вызов Отчеты.ВидыОплатККМ.ПолучитьМакет("Макет") завершается ошибкой, так как внешний отчет не входит в дерево метаданных конфигурации и не доступен через коллекцию Отчеты.
  2. Неправильная работа с контекстом формы: при вызове функции СформироватьНаСервере создается локальная переменная Новый ТабличныйДокумент, которая затем возвращается на клиент, но никуда не присваивается. В результате табличный документ на форме остается пустым.
  3. Ошибки при передаче параметров периода: попытка получить реквизиты через конструкции вида ЭтотОбъект.ЭтаФорма или неполные имена приводит к синтаксическим ошибкам. Кроме того, если дата окончания передается без времени (по умолчанию 00:00:00), документы за последний день периода не попадают в результат запроса.
  4. Синтаксические неточности: вызов методов без круглых скобок (например, Запрос.Выполнить или ТабДок.Очистить) является ошибкой в платформе 1С:Предприятие 8.3.

Решение 1. Формирование отчета с прямым выводом в реквизит формы

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

Если на форме отчета уже создан реквизит с типом ТабличныйДокумент (например, с именем Результат или ТабличныйДокумент), размещенный в виде поля табличного документа, мы можем напрямую изменять его на сервере. Преобразовывать процедуру в функцию и возвращать значение на клиент не требуется.

Разберем по шагам реализацию модуля управляемой формы внешнего отчета:


&НаКлиенте
Процедура Сформировать(Команда)
    СформироватьНаСервере();
КонецПроцедуры

&НаСервере
Процедура СформироватьНаСервере()
    
    // Получаем макет внешнего отчета через преобразование реквизита формы в прикладной объект
    ОбъектОтчет = РеквизитФормыВЗначение("Отчет");
    Макет = ОбъектОтчет.ПолучитьМакет("Макет");
    
    // Инициализируем и настраиваем запрос
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ЧекККМОплата.ВидОплаты КАК ВидОплаты,
        |	ЧекККМОплата.Сумма КАК Сумма
        |ИЗ
        |	Документ.ЧекККМ.Оплата КАК ЧекККМОплата
        |ГДЕ
        |	ЧекККМОплата.Ссылка.Проведен = ИСТИНА
        |	И ЧекККМОплата.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
    
    // Устанавливаем параметры, используя реквизиты формы ДатаНачала и ДатаОкончания
    Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
    Запрос.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода));
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // Получаем области макета
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    ОбластьШапкаТаблицы = Макет.ПолучитьОбласть("ШапкаТаблицы");
    ОбластьДетальныхЗаписей = Макет.ПолучитьОбласть("Детали");
    ОбластьПодвалТаблицы = Макет.ПолучитьОбласть("ПодвалТаблицы");
    ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
    
    // Работаем напрямую с реквизитом формы ТабличныйДокумент
    ТабличныйДокумент.Очистить();
    ТабличныйДокумент.Вывести(ОбластьЗаголовок);
    ТабличныйДокумент.Вывести(ОбластьШапкаТаблицы);
    
    ТабличныйДокумент.НачатьАвтогруппировкуСтрок();
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        ОбластьДетальныхЗаписей.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
        ТабличныйДокумент.Вывести(ОбластьДетальныхЗаписей, ВыборкаДетальныеЗаписи.Уровень());
    КонецЦикла;
    
    ТабличныйДокумент.ЗакончитьАвтогруппировкуСтрок();
    
    ТабличныйДокумент.Вывести(ОбластьПодвалТаблицы);
    ТабличныйДокумент.Вывести(ОбластьПодвал);
    
    ТабличныйДокумент.Защита = Истина;
    ТабличныйДокумент.ОтображатьСетку = Ложь;
    
КонецПроцедуры

Особенности оптимизации запроса и работы с датами

Посмотрим на важные моменты, которые обеспечивают корректную работу отчета:

  1. Учет времени границы периода: функция КонецДня() устанавливает время на 23:59:59, что гарантирует попадание в выборку всех документов, проведенных в течение финального дня выбранного интервала.
  2. Упрощение структуры запроса: обращение к реквизитам шапки через точку от табличной части (например, ЧекККМОплата.Ссылка.Проведен) исключает необходимость ручного написания оператора ЛЕВОЕ СОЕДИНЕНИЕ, что делает текст запроса более компактным и понятным.
  3. Доступ к макету внешнего объекта: метод РеквизитФормыВЗначение("Отчет") создает экземпляр внешнего отчета в памяти сервера, позволяя получить доступ ко всем его макетам и методам модуля объекта.

Решение 2. Использование Схемы компоновки данных (СКД)

Выясним причину, по которой ручное формирование макета в коде часто является избыточным. Платформа 1С:Предприятие предоставляет механизм Системы компоновки данных (СКД), который автоматизирует построение отчетов.

При использовании СКД достаточно:

  1. Добавить в отчет макет с типом Схема компоновки данных.
  2. Вставить текст запроса в набор данных.
  3. На вкладке Настройки добавить группировку детальных записей или группировку по полю ВидОплаты.
  4. Включить параметры НачалоПериода и КонецПериода в состав пользовательских настроек.

В этом случае платформа автоматически сгенерирует форму, обработает параметры периода и выведет отчет в табличный документ без написания серверного кода обхода выборок.

← На главную