Как в отчете на СКД сделать отбор по выбранному сотруднику или текущему пользователю?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Способ 1. Реализация через служебные параметры СКД (без программного кода)

Если требуется обойтись без вмешательства в модули формы или модуля объекта отчета, наилучшим решением выступает использование встроенного механизма выражений параметров схемы компоновки данных. Разберем по шагам настройку двух взаимосвязанных параметров на вкладке Параметры схемы:

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

Посмотрим на пример выражения для скрытого служебного параметра:


ВЫБОР 
    КОГДА ЗначениеЗаполнено(&СотрудникПользователя) ТОГДА &СотрудникПользователя 
    ИНАЧЕ ОбщийМодуль.ПолучитьСотрудникаПользователя() 
КОНЕЦ

Проанализируем важные технические нюансы этого метода:

  1. Прямое обращение вида ПараметрыСеанса.ТекущийПользователь в выражениях СКД платформой не поддерживается и вызовет исключение. Необходимо вызывать только экспортные серверные функции общих модулей, например, штатные функции БСП вроде Пользователи.ТекущийПользователь().
  2. Вызываемый общий модуль обязательно должен быть скомпилирован на стороне сервера (флаг Сервер), иначе выполнение в клиент-серверном режиме или регламентном задании завершится ошибкой.
  3. В тексте запроса набора данных условие строится исключительно по служебному параметру: ГДЕ Таблица.Сотрудник = &ИтоговыйСотрудник.

Способ 2. Обработка условия в языке запросов СКД

Если в конфигурации нет готовой функции, возвращающей сразу элемент справочника Сотрудники для текущего сеанса, сопоставление можно полностью делегировать тексту запроса. В конфигурациях связь между пользователем и сотрудником чаще всего реализуется через промежуточный справочник ФизическиеЛица.

Разберем, как выглядит такое условие в тексте запроса. Получив ссылку на текущего пользователя через системную функцию или параметр сеанса, соединяем данные и накладываем проверку:


ВЫБРАТЬ
    Таблица.Период КАК Период,
    Таблица.Сотрудник КАК Сотрудник,
    Таблица.Сумма КАК Сумма
ИЗ
    РегистрНакопления.Начисления КАК Таблица
ГДЕ
    Таблица.Сотрудник = ВЫБОР
        КОГДА ЗначениеЗаполнено(&СотрудникОтбор) ТОГДА &СотрудникОтбор
        ИНАЧЕ (ВЫБРАТЬ ПЕРВЫЕ 1 Сотр.Ссылка 
               ИЗ Справочник.Сотрудники КАК Сотр 
               ГДЕ Сотр.ФизическоеЛицо = &ТекущийПользователь.ФизическоеЛицо)
    КОНЕЦ

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

Способ 3. Программная инициализация в событии «ПриКомпоновкеРезультата»

Если структура запроса сложная либо требуется динамически управлять не параметрами, а непосредственно коллекцией элементов отбора компоновщика, используем событие ПриКомпоновкеРезультата в модуле объекта отчета.

Разберем типовой код переопределения отбора перед выводом отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    ЭлементОтбораСотрудник = Неопределено;
    
    // Ищем отбор по сотруднику в настройках компоновщика
    Для Каждого Элемент Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Сотрудник") Тогда
            ЭлементОтбораСотрудник = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Если отбор не заполнен или отключен, устанавливаем текущего сотрудника
    Если ЭлементОтбораСотрудник <> Неопределено Тогда
        Если НЕ ЭлементОтбораСотрудник.Использование ИЛИ НЕ ЗначениеЗаполнено(ЭлементОтбораСотрудник.ПравоеЗначение) Тогда
            ЭлементОтбораСотрудник.Использование = Истина;
            ЭлементОтбораСотрудник.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
            ЭлементОтбораСотрудник.ПравоеЗначение = ПолучитьСотрудникаПользователя(ПараметрыСеанса.ТекущийПользователь);
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Если ваша конфигурация разработана с использованием Библиотеки стандартных подсистем (БСП), рекомендуется выполнять программную подготовку в модуле менеджера отчета внутри процедуры ПередКомпоновкойМакета(ПараметрыОтчета, Схема, КомпоновщикНастроек). Это позволит отчету штатно функционировать в фоновом режиме и в механизме рассылки отчетов.

Ошибки при реализации отборов

Выясним частые ошибки, с которыми сталкиваются разработчики при решении этой задачи:

  1. Фильтрация по строковому представлению (ФИО): попытка искать сотрудников по текстовой строке с ФИО приводит к коллизиям при наличии полных однофамильцев, изменении фамилий или различиях в расстановке инициалов. Всегда используйте ссылки на справочники Сотрудники или ФизическиеЛица.
  2. Проверка только флага «Использование»: пользователь может включить отбор флажком, но оставить само поле пустым. В коде и выражениях обязательно проверяйте функцию ЗначениеЗаполнено(), а не только свойство Использование.
  3. Кэширование пользовательских настроек: если пользователь однажды выбрал сотрудника вручную, платформа сохранит эту настройку. При повторных запусках значение автоматически заполнится из кэша, пока пользователь явно не нажмет кнопку очистки поля или сброса настроек варианта.
← На главную