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