При разработке отчетов с использованием объекта ПостроительОтчета разработчики часто сталкиваются с ситуацией: в тексте запроса прописаны фигурные скобки для расширения языка запросов (секции {ВЫБРАТЬ}, {ГДЕ}, параметры {&ДатаНачалаЗапроса} и фильтры виртуальных таблиц), затем вызывается метод ЗаполнитьНастройки(), но при проверке в отладчике коллекции Отбор и Параметры остаются пустыми. При этом заполняются только доступные или выбранные поля.
Разберем подробно внутреннюю логику работы объекта ПостроительОтчета, выясним причину такого поведения и рассмотрим, как правильно инициализировать параметры и настраивать отборы.
Метод ЗаполнитьНастройки() предназначен для синтаксического анализа (парсинга) переданного текста запроса и формирования метаструктуры отчета, доступной для дальнейшей настройки. При его вызове платформа 1С выполняет следующие действия:
{...}.ДоступныеПоля, определяя все поля выборки, реквизиты виртуальных таблиц и поля секций {ГДЕ}, по которым потенциально можно накладывать фильтры, сортировки и группировки.ВыбранныеПоля на основе основной секции ВЫБРАТЬ и блока {ВЫБРАТЬ}.ИзмеренияСтроки и ИзмеренияКолонки, если в запросе присутствует блок {ИТОГИ ПО}.Важно понимать: метод ЗаполнитьНастройки() создает каркас доступных возможностей, но не заполняет сами значения условий и параметров. Повторный вызов этого метода в процессе работы полностью сбрасывает все ранее установленные пользовательские или программные настройки к значениям по умолчанию.
Проанализируем назначение коллекции Отбор. В объекте ПостроительОтчета коллекция Отбор хранит исключительно активные (примененные) условия фильтрации, а не весь перечень полей, доступных для отбора. Список всех полей, по которым фильтрация в принципе возможна, находится в свойстве ДоступныеПоля.
Поскольку при инициализации запроса никакие конкретные фильтры еще не были установлены ни пользователем, ни кодом, коллекция Отбор остается пустой. Для работы с отборами применяются два основных подхода.
Если требуется жестко или по определенному алгоритму ограничить выборку в коде, элементы отбора добавляются в коллекцию вручную через метод Добавить(). Рассмотрим пример:
ПостроительОтчета = Новый ПостроительОтчета;
ПостроительОтчета.Текст = ТекстЗапроса;
ПостроительОтчета.ЗаполнитьНастройки();
// Добавляем конкретный отбор по полю
ЭлементОтбора = ПостроительОтчета.Отбор.Добавить("Склад");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = ВыбСклад;
ЭлементОтбора.Использование = Истина;
После добавления условия построитель отчета автоматически подставит соответствующую конструкцию в секцию ГДЕ или в параметры виртуальной таблицы при вызове метода Выполнить().
В обычном приложении отборы построителя часто выводятся на форму отчета. Разберем по шагам, как это работает:
ПостроительОтчета.Отбор (тип Отбор).Отбор и модифицирует итоговый SQL-запрос к базе данных.Коллекция Параметры у объекта ПостроительОтчета представляет собой структуру соответствий имен параметров и их значений. Построитель не инициализирует параметры автоматически из текста запроса.
Все параметры, используемые в запросе (как обязательные &Параметр, так и опциональные {&ИмяПараметра}), разработчик должен явно передавать в коллекцию:
ПостроительОтчета.Параметры.Вставить("ДатаНачалаЗапроса", ПериодНачало);
ПостроительОтчета.Параметры.Вставить("ДатаОкончанияЗапроса", ПериодКонец);
Обратите внимание на фигурные скобки: конструкция {&ДатаНачалаЗапроса} обозначает необязательный параметр. Если разработчик не добавит такой параметр в коллекцию Параметры, построитель отчета при формировании итогового запроса просто вырежет эту конструкцию без генерации синтаксической ошибки выполнения.
Посмотрим на полный и корректный порядок действий при работе с построителем отчета:
ПостроительОтчета = Новый ПостроительОтчета;
ПостроительОтчета.Текст =
"ВЫБРАТЬ
| ПартииТоваровНаСкладах.Номенклатура КАК Номенклатура,
| ПартииТоваровНаСкладах.КоличествоОстаток КАК КоличествоОстаток
|{ВЫБРАТЬ
| Номенклатура.*,
| КоличествоОстаток}
|ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Остатки({&Период}, {Номенклатура.*, Склад.*}) КАК ПартииТоваровНаСкладах
|{ГДЕ
| ПартииТоваровНаСкладах.Номенклатура.* КАК Номенклатура,
| ПартииТоваровНаСкладах.Склад.* КАК Склад}";
// 1. Инициализируем структуру доступных полей и группировок
ПостроительОтчета.ЗаполнитьНастройки();
// 2. Устанавливаем параметры запроса
ПостроительОтчета.Параметры.Вставить("Период", ТекущаяДата());
// 3. Устанавливаем программные отборы (если требуются)
ОтборНоменклатура = ПостроительОтчета.Отбор.Добавить("Номенклатура");
ОтборНоменклатура.ВидСравнения = ВидСравнения.ВИерархии;
ОтборНоменклатура.Значение = ВыбраннаяГруппаНоменклатуры;
ОтборНоменклатура.Использование = Истина;
// 4. Выполняем построитель и получаем результат
ПостроительОтчета.Выполнить();
Соблюдение этой последовательности гарантирует, что метаструктура отчета будет корректно сформирована, а параметры и условия отбора успешно применятся при выполнении запроса.