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