При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача: необходимо установить значение отбора или параметра по умолчанию так, чтобы пользователь увидел его сразу при открытии отчета. Если у отчета создана собственная форма, задача решается в ее обработчиках. Однако в современных конфигурациях на платформе 1С:Предприятие 8.3 отчеты часто используют стандартную форму, предоставляемую платформой или Библиотекой стандартных подсистем (БСП). В этом случае у разработчика нет прямого доступа к модулю формы отчета в дереве конфигурации.
В данной статье мы подробно разберем, как реализовать программную установку отборов (в том числе сложных типов, таких как «В списке») для отчетов без явной формы. Мы проанализируем механизмы работы КомпоновщикаНастроек и выясним, в каких модулях лучше всего размещать код.
Прежде чем переходить к коду, давайте разберем теорию, без которой правильная работа с отборами невозможна. В СКД существует три ключевых уровня настроек, которые хранятся в КомпоновщикеНастроек:
Если мы хотим, чтобы пользователь видел установленное нами значение и мог его изменить, нам нужно работать именно с Пользовательскими настройками.
Рассмотрим ситуацию, когда нам нужно установить в отбор текущего пользователя. Это можно сделать без написания кода. Для этого выполним следующие шаги:
1. Откроем схему компоновки данных и перейдем на вкладку Параметры. Если мы используем параметр для фильтрации, в колонке Выражение напишем: ПараметрыСеанса.ТекущийПользователь.
2. На вкладке Настройки, в разделе Отбор, добавим поле Менеджер. Нажмем на кнопку свойств элемента пользовательских настроек (иконка с шестеренкой или звездочкой) и установим флажок Включать в пользовательские настройки.
3. В режиме «1С:Предприятие» при открытии отчета система автоматически вычислит выражение и подставит текущего пользователя в поле отбора.
Если логика установки значения сложнее (например, нужно найти пользователя по определенному условию или заполнить список значений), воспользуемся модулем объекта отчета. Разберем работу в процедуре ПриКомпоновкеРезультата. Это стандартное событие СКД, которое срабатывает в момент начала формирования отчета.
Рассмотрим пример кода, который устанавливает отбор по полю Менеджер с видом сравнения В списке:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Если настройки уже модифицированы пользователем, возможно, не стоит их перезаписывать
// Однако для первоначальной установки при открытии выполним следующий код:
Настройки = ЭтотОбъект.КомпоновщикНастроек.Настройки;
ПользовательскиеНастройки = ЭтотОбъект.КомпоновщикНастроек.ПользовательскиеНастройки;
// Найдем нужный отбор в пользовательских настройках по имени поля
ИдентификаторНастройки = "";
Для Каждого ЭлементОтбора Из Настройки.Отбор.Элементы Цикл
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И Строка(ЭлементОтбора.ЛевоеЗначение) = "Менеджер" Тогда
ИдентификаторНастройки = ЭлементОтбора.ИдентификаторПользовательскойНастройки;
Прервать;
КонецЕсли;
КонецЦикла;
// Если нашли идентификатор, меняем значение в пользовательских настройках
Если ЗначениеЗаполнено(ИдентификаторНастройки) Тогда
ЭлементПользовательскойНастройки = ПользовательскиеНастройки.Элементы.Найти(ИдентификаторНастройки);
Если ЭлементПользовательскойНастройки <> Неопределено Тогда
// Устанавливаем вид сравнения "В списке"
ЭлементПользовательскойНастройки.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
ЭлементПользовательскойНастройки.Использование = Истина;
// Создаем и заполняем список значений
СписокМенеджеров = Новый СписокЗначений;
СписокМенеджеров.Добавить(ПараметрыСеанса.ТекущийПользователь);
// Назначаем список в качестве значения отбора
ЭлементПользовательскойНастройки.ПравоеЗначение = СписокМенеджеров;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализируем этот код: мы не просто меняем настройки компоновщика, мы ищем связь между основной схемой и пользовательским интерфейсом через ИдентификаторПользовательскойНастройки. Это критически важно, так как прямое изменение КомпоновщикНастроек.Настройки.Отбор может не отобразиться на форме, если отчет уже был открыт ранее и сохранил свои настройки.
Если отчет является внешним или вы не хотите менять модуль объекта, можно воспользоваться механизмом расширений. Поскольку у отчета нет своей формы, он открывается через ОбщаяФорма.ФормаОтчета (в случае БСП). Мы можем создать После-обработчик для метода ПриСозданииНаСервере этой формы.
Выясним причину, почему это удобно: в параметрах этой формы передается объект отчета, и мы можем дотянуться до его компоновщика еще до того, как форма будет отрисована. Пример логики в расширении:
&НаСервере
Процедура Расш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Проверяем, что это нужный нам отчет
Если ЭтаФорма.Отчет.Метаданные().Имя = "РеестрРеализаций" Тогда
Компановщик = ЭтаФорма.Отчет.КомпоновщикНастроек;
// Логика поиска и установки значения аналогична предыдущему примеру
// Работаем напрямую с Компановщик.ПользовательскиеНастройки
КонецЕсли;
КонецПроцедуры
Многие начинающие разработчики совершают ошибку, пытаясь передать в ПравоеЗначение отбора просто ссылку на элемент справочника, когда выбран вид сравнения ВСписке. Проанализируем ситуацию: СКД строго типизирована. Если выбран вид сравнения ВСписке или ВИерархическомСписке, система ожидает объект типа СписокЗначений.
Важные моменты:
Использование = Истина для элемента отбора, иначе настройка будет установлена, но не активна.СправочникСсылка.Пользователи).Очистить() у списка значений.Мы рассмотрели несколько способов программного управления отборами в СКД без использования кастомных форм. Для простых случаев идеально подходят Выражения в параметрах схемы. Для динамической подстановки значений при каждом запуске лучше использовать процедуру ПриКомпоновкеРезультата в модуле объекта. Работа через Пользовательские настройки гарантирует, что установленные значения будут корректно отображены в интерфейсе пользователя и приняты системой при формировании результата.