Как программно установить параметры и отборы в Универсальном отчете (1С:УТ 10.3)?

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

При разработке в конфигурациях на базе обычных форм, таких как 1С:Управление торговлей 10.3, часто возникает задача автоматизировать формирование отчетов. Одной из самых распространенных проблем является попытка программно установить фильтры в Универсальном отчете. Сложность заключается в том, что этот отчет построен не на Системе компоновки данных (СКД), а на более старой технологии — Построителе отчета. Тем не менее, на этой базе можно создавать мощные инструменты, такие как анализ продаж по часам и номенклатурным группам или сложные системы для анализа прироста или убыли продаж. В этой статье мы подробно разберем, как правильно управлять параметрами и отборами, чтобы отчет формировался с нужными данными без участия пользователя.

Различие между параметрами и отборами

Прежде всего, проанализируем ситуацию: почему стандартный метод УниверсальныйОтчет.ПостроительОтчета.Параметры.Вставить() часто не дает результата? — для отладки подобных алгоритмов пригодится инструмент отладки кода 1С в режиме Предприятие. Параметры в Построителе отчета — это жестко заданные в тексте запроса переменные (например, &НачалоПериода). Большинство полей, которые пользователь видит в настройках (Контрагент, Склад, Номенклатура), являются элементами коллекции Отбор. Построитель формирует их динамически. Поэтому для программной установки значений нам нужно работать именно с коллекцией Отбор.

Установка простого отбора по значению

Рассмотрим самый простой случай, когда поле уже присутствует в настройках отчета (например, «Контрагент» в отчете «Продажи»). Это базовое действие необходимо, когда мы настраиваем, например, анализ прибыли по типу цен и продавцам. Для того чтобы установить значение, нам нужно обратиться к соответствующему элементу коллекции. Выясним, как это сделать правильно:


// Получаем доступ к нужному полю отбора
ОтборКонтрагент = УниверсальныйОтчет.ПостроительОтчета.Отбор.Контрагент;

// Устанавливаем активность отбора
ОтборКонтрагент.Использование = Истина;

// Указываем вид сравнения (Равно, ВГруппе, НеРавно и т.д.)
ОтборКонтрагент.ВидСравнения = ВидСравнения.Равно;

// Присваиваем значение (ссылку на объект)
ОтборКонтрагент.Значение = Справочники.Контрагенты.НайтиПоНаименованию("НашКлиент");

Важный момент: если вы программно меняете настройки, убедитесь, что ваш код выполняется после того, как отчет инициализировал свои стандартные настройки (обычно это метод УстановитьНачальныеНастройки()), иначе ваши изменения могут быть стерты значениями по умолчанию.

Работа со сложными (вложенными) полями

Часто возникает ситуация, когда нужного поля нет в списке доступных отборов «верхнего уровня». Например, вам нужно сделать отбор по Складу, но в структуре запроса отчета «Продажи» склад находится «внутри» документа. С похожими задачами часто сталкиваются при работе с расширенным отчетом по продажам, где требуется извлекать артикулы, характеристики или менеджеров из карточек контрагентов. Посмотрим на решение: если поле извлекается «через точку», его нужно добавить в коллекцию Отбор вручную с указанием пути к данным.

Разберем по шагам, как добавить отбор по складу документа:


// Используем метод Добавить(ПутьКДанным, ИмяПоля, Представление)
// ПутьКДанным — это то, как поле называется в схеме запроса
// ИмяПоля — уникальный идентификатор для обращения к этому отбору позже
УниверсальныйОтчет.ПостроительОтчета.Отбор.Добавить("ДокументПродажи.Склад", "Склад", "Склад");

// Теперь мы можем работать с ним как с обычным полем
УниверсальныйОтчет.ПостроительОтчета.Отбор.Склад.Использование = Истина;
УниверсальныйОтчет.ПостроительОтчета.Отбор.Склад.Значение = Справочники.Склады.НайтиПоКоду("00001");

Этот же подход применим и к более глубоким вложенностям. Рассмотрим пример, когда нужно отобрать данные по родителю категории номенклатуры:


УниверсальныйОтчет.ПостроительОтчета.Отбор.Добавить("Номенклатура.Категория.Родитель", "РодительКатегории", "Родитель категории");
УниверсальныйОтчет.ПостроительОтчета.Отбор.РодительКатегории.Использование = Истина;
УниверсальныйОтчет.ПостроительОтчета.Отбор.РодительКатегории.Значение = СсылкаНаНужнуюГруппу;

Использование списка значений в отборах

Если перед нами стоит задача отфильтровать отчет сразу по нескольким элементам (например, по группе контрагентов или списку складов), что часто требуется в отчетах по неходовым товарам, нам потребуется объект СписокЗначений. Проанализируем, как правильно передать этот список в Построитель отчета:

  1. Создаем объект СписокЗначений и наполняем его нужными ссылками.
  2. Устанавливаем ВидСравнения в значение ВидСравнения.ВСписке или ВидСравнения.ВГруппеИзСписка.
  3. Передаем список в свойство Значение.

Посмотрим на пример кода:


СписокСкладов = Новый СписокЗначений;
СписокСкладов.Добавить(СкладОптовый);
СписокСкладов.Добавить(СкладРозничный);

// Проверяем наличие поля в отборе
ИмяПоля = "Склад";
ЭлементОтбора = УниверсальныйОтчет.ПостроительОтчета.Отбор.Найти(ИмяПоля);

Если ЭлементОтбора = Неопределено Тогда
    ЭлементОтбора = УниверсальныйОтчет.ПостроительОтчета.Отбор.Добавить("ДокументПродажи.Склад", ИмяПоля);
КонецЕсли;

ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; 
ЭлементОтбора.Значение = СписокСкладов;

Программная установка периода отчета

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


УниверсальныйОтчет.ДатаНачала = НачалоДня(ВыбраннаяДата);
УниверсальныйОтчет.ДатаКонца  = КонецДня(ВыбраннаяДата);

Скрытие программных настроек от пользователя

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


ЭлементОрг = УниверсальныйОтчет.ПостроительОтчета.Отбор.Организация;
ЭлементОрг.Значение = Справочники.Организации.НайтиПоНаименованию("НашаОрганизация");
ЭлементОрг.Использование = Истина;

// Запрещаем пользователю менять этот отбор в окне настроек
ЭлементОрг.Доступность = Ложь;

Управление группировками строк

Помимо фильтрации, мы можем программно управлять и тем, какие разрезы (группировки) будут отображаться в отчете. Это делается через коллекцию ГруппировкиСтрок. Проанализируем пример настройки иерархии "Контрагент - Номенклатура":


// Очищаем текущие группировки, если нужно задать их заново
УниверсальныйОтчет.ПостроительОтчета.ГруппировкиСтрок.Очистить();

// Добавляем новые уровни группировки
УниверсальныйОтчет.ПостроительОтчета.ГруппировкиСтрок.Добавить("Контрагент");
УниверсальныйОтчет.ПостроительОтчета.ГруппировкиСтрок.Добавить("Номенклатура");

Заключение и вызов формирования

После того как все параметры, отборы и группировки установлены, остается только вызвать метод формирования отчета. Помните, что Универсальный отчет выводит результат в ТабличныйДокумент, который обычно является реквизитом формы или создается программно.


// Пример вызова формирования
ТабДок = Новый ТабличныйДокумент;
УниверсальныйОтчет.СформироватьОтчет(ТабДок);
ТабДок.Показать("Отчет по продажам");

Подводя итог, можно сказать, что работа с Универсальным отчетом требует четкого понимания структуры Построителя отчета. Главные инструменты разработчика здесь — это методы Найти() и Добавить() в коллекции Отбор, а также правильное использование свойства ПутьКДанным для обращения к реквизитам через точку. Используя эти приемы, вы сможете гибко управлять любыми типовыми отчетами в конфигурациях на обычных формах.

← На главную