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

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

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

Мы проанализируем различные подходы — от классического использования параметров запроса до современных методов с использованием Библиотеки стандартных подсистем (БСП), а также обсудим важные нюансы производительности и безопасности данных.

Способ 1. Фильтрация данных через параметры запроса динамического списка

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

Разберем этот вариант по шагам:

  1. Откройте форму списка нужного документа в конфигураторе.
  2. Перейдите в свойства реквизита формы Список (тип ДинамическийСписок) и установите флаг Произвольный запрос.
  3. Нажмите гиперссылку Открыть схему компоновки данных или откройте конструктор запроса. В текст запроса добавьте условие фильтрации в секцию ГДЕ.

Посмотрим на пример текста запроса для динамического списка:


ВЫБРАТЬ
    ДокументРасход.Ссылка КАК Ссылка,
    ДокументРасход.Дата КАК Дата,
    ДокументРасход.Номер КАК Номер,
    ДокументРасход.Пользователь КАК Пользователь,
    ДокументРасход.СуммаДокумента КАК СуммаДокумента
ИЗ
    Документ.Расход КАК ДокументРасход
ГДЕ
    ДокументРасход.Пользователь = &ТекущийПользователь

Обратите внимание: мы объявили параметр &ТекущийПользователь. Теперь наша задача — инициализировать этот параметр при открытии формы на сервере.

Перейдем в модуль управляемой формы и найдем обработчик события ПриСозданииНаСервере. Нам нужно передать значение текущего пользователя в параметры динамического списка. Выясним, как это сделать правильно:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Передаем текущего пользователя в параметр динамического списка
    Список.Параметры.УстановитьЗначениеПараметра("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
    
КонецПроцедуры

В данном примере мы использовали стандартные ПараметрыСеанса.ТекущийПользователь. Это классический механизм платформы для получения ссылки на текущего авторизованного пользователя в системе.

Способ 2. Программная установка отбора через систему компоновки данных (СКД)

Иногда изменение текста запроса динамического списка нежелательно или невозможно (например, если динамический список формируется автоматически или вы не хотите перегружать текст запроса условиями). В таких случаях мы можем воспользоваться возможностями настройки компоновки данных динамического списка.

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

Рассмотрим пример кода, который устанавливает отбор программно в обработчике ПриСозданииНаСервере:


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

КонецПроцедуры

Обратите внимание на свойство РежимОтображения. Установив значение Недоступный, мы гарантируем, что пользователь не сможет случайно или намеренно отключить этот отбор через стандартное меню «Настроить список». Если же вам, наоборот, нужно вывести этот отбор на форму для удобства пользователя, вы можете использовать значение БыстрыйДоступ.

Способ 3. Использование функций Библиотеки стандартных подсистем (БСП)

Если вы разрабатываете решение на базе типовой конфигурации 1С (например, 1С:Бухгалтерия, 1С:ERP или 1С:Управление торговлей), то в вашем распоряжении есть готовые программные интерфейсы БСП. Использование БСП позволяет существенно сократить объем кода и сделать его более читаемым.

Для установки отбора воспользуемся общим модулем ОбщегоНазначенияКлиентСервер. Разберем, как выглядит этот код:


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

КонецПроцедуры

В этом примере мы также применили функцию Пользователи.ТекущийПользователь() вместо прямого обращения к параметрам сеанса. Это рекомендуемый стандарт БСП, обеспечивающий безопасное и платформонезависимое получение текущего пользователя.

Важные нюансы и лучшие практики

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

  1. Безопасность данных (Отборы vs RLS): Установка отборов на уровне формы (любым из вышеперечисленных способов) — это исключительно инструмент интерфейсного удобства. Он защищает от случайного просмотра чужих документов. Однако, если пользователю действительно запрещено просматривать чужие данные по соображениям конфиденциальности, этот метод не поможет. Продвинутый пользователь сможет открыть чужие документы через универсальный отчет, консоль запросов или навигационную ссылку. Для жесткого разграничения прав доступа необходимо настраивать механизм RLS (Record Level Security) в ролях конфигурации.
  2. Влияние на производительность (Индексирование полей): Когда база данных вырастает до сотен тысяч записей, динамические списки с установленными отборами могут начать сильно замедлять работу СУБД. Если вы накладываете постоянный отбор по реквизиту Пользователь (или «Ответственный»), этот реквизит обязательно должен быть проиндексирован. Откройте свойства реквизита в конфигураторе и в поле Индексировать выберите значение Индексировать или Индексировать с дополнительным упорядочиванием. Это позволит СУБД мгновенно находить нужные строки.
  3. Передача отборов при открытии формы: Если вам необходимо открыть форму списка с уже установленным отбором из другого места программы (например, по нажатию кнопки в другой форме), можно передать параметры отбора непосредственно при вызове метода ОткрытьФорму. Платформа самостоятельно применит эти параметры к динамическому списку:
    
    ПараметрыФормы = Новый Структура;
    ЗначенияОтбора = Новый Структура("Пользователь", ТекущийПользователь);
    ПараметрыФормы.Вставить("Отбор", ЗначенияОтбора);
    
    ОткрытьФорму("Документ.Расход.ФормаСписка", ПараметрыФормы);
    

Используя данные методы и рекомендации, вы сможете создавать быстрые, удобные и надежные интерфейсы в ваших решениях на платформе 1С:Предприятие 8.3.

← На главную