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