Как правильно настроить Построитель отчета и вывести результат в собственный макет в 1С?

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

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

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

Последовательность инициализации построителя при открытии формы

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

  1. Назначаем исходный текст запроса в свойство Построитель.Текст. Текст должен содержать фигурные скобки {} для секций динамического отбора ({ГДЕ ...}), полей выбора ({ВЫБРАТЬ ...}) и группировок.
  2. Вызываем метод Построитель.ЗаполнитьНастройки(). Обратите внимание: этот метод сбрасывает текущие коллекции отборов и параметров, создавая их заново на основе текста запроса. Поэтому вызывать его нужно строго до заполнения параметров и пользовательских фильтров.
  3. Заполняем начальные значения параметров через Построитель.Параметры и настраиваем доступные поля отбора.

Посмотрим на пример инициализации в модуле формы:


Процедура ПриОткрытии()
    Построитель.Текст = 
        "ВЫБРАТЬ
        |   СредстваИзмерений.Ссылка КАК СредствоИзмерения,
        |   СредстваИзмерений.ВидИзмерения КАК ВидИзмерения,
        |   УчетСИСрезПоследних.Подразделение КАК Подразделение
        |ИЗ
        |   Справочник.СредстваИзмерений КАК СредстваИзмерений
        |ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.УчетСИ.СрезПоследних(&ДатаКонца) КАК УчетСИСрезПоследних
        |   ПО УчетСИСрезПоследних.СредствоИзмерения = СредстваИзмерений.Ссылка
        |{ГДЕ
        |   СредстваИзмерений.Ссылка.* КАК СредствоИзмерения,
        |   УчетСИСрезПоследних.Подразделение.* КАК Подразделение,
        |   СредстваИзмерений.ВидИзмерения.* КАК ВидИзмерения}";
        
    // Обязательно инициализируем структуру настроек построителя
    Построитель.ЗаполнитьНастройки();
    
    // Добавляем доступные строки в табличное поле отбора на форме
    Построитель.Отбор.Добавить("СредствоИзмерения", "Ссылка", "Средства измерений");
    Построитель.Отбор.Добавить("ВидИзмерения", "ВидИзмерения", "Виды измерений");
    Построитель.Отбор.Добавить("Подразделение", "Подразделение", "Подразделение");
КонецПроцедуры

Вывод данных в собственный макет через результат построителя

Если стандартный механизм Построитель.Вывести() не подходит из-за необходимости сформировать нестандартную шапку, дополнительные подвалы или особый дизайн, результат формируют вручную. Проанализируем, как получить секции собственного макета, выполнить построитель и обойти результат запроса.

В процедуре формирования отчета мы устанавливаем актуальные значения параметров с формы, выполняем построитель, обращаемся к его свойству Результат и последовательно выводим области макета в результирующий ТабличныйДокумент:


Процедура ДействияФормыСформировать(Кнопка)
    // 1. Подготавливаем результирующий табличный документ и макет
    ТабДок = ЭлементыФормы.ПолеТабличногоДокумента;
    ТабДок.Очистить();
    
    Макет = ПолучитьМакет("Макет");
    
    // 2. Заполняем параметры запроса перед выполнением
    Построитель.Параметры.Вставить("ДатаКонца", КонецДня(ДатаКонца));
    
    // 3. Выводим шапку отчета
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьШапка.Параметры.ПредставлениеПериода = "На дату: " + Формат(ДатаКонца, "ДФ=dd.MM.yyyy");
    ТабДок.Вывести(ОбластьШапка);
    
    // 4. Выполняем построитель и получаем выборку
    Построитель.Выполнить();
    РезультатЗапроса = Построитель.Результат;
    
    Если Не РезультатЗапроса.Пустой() Тогда
        ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
        Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
        
        Пока Выборка.Следующий() Цикл
            ОбластьСтрока.Параметры.Заполнить(Выборка);
            ТабДок.Вывести(ОбластьСтрока);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Почему параметр виртуальной таблицы не учитывается построителем?

Нередко возникает ситуация, когда запрос в консоли запросов выдает одни данные с учетом даты, а при выполнении через построитель параметр среза последних игнорируется. Разберем основные причины такого поведения:

  1. Неправильный момент вызова ЗаполнитьНастройки(): Если метод ЗаполнитьНастройки() вызывается после того, как в коллекцию Построитель.Параметры было записано значение даты, коллекция параметров будет очищена. Заполнять параметры следует непосредственно перед вызовом метода Выполнить().
  2. Синтаксис параметров виртуальных таблиц в построителе: Если требуется управлять периодом среза как необязательным параметром через механизм настроек, в тексте запроса параметр обрамляется в фигурные скобки: СрезПоследних({&ДатаКонца}). Если же дата жестко зафиксирована в запросе как &ДатаКонца, убедитесь, что имя параметра в коде вставки Построитель.Параметры.Вставить("ДатаКонца", ...) полностью совпадает с именем в запросе без опечаток.
  3. Проверка сгенерированного запроса: Чтобы проверить, какой именно SQL/1C-текст сформировал построитель с учетом наложенных отборов, воспользуйтесь методом Построитель.ПолучитьЗапрос(). В точке останова отладчика можно посмотреть Построитель.ПолучитьЗапрос().Текст и проверить реальные значения параметров в коллекции Построитель.ПолучитьЗапрос().Параметры.

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

← На главную