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

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

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

Вариант 1. Использование параметров динамического списка в запросе

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

Для настройки произвольного запроса выполним следующие шаги:

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

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

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


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

Вариант 2. Программный отбор через Компоновщик настроек (рекомендуемый)

Использование параметров напрямую в тексте запроса имеет недостаток: если пользователю необходимо дать возможность просматривать все записи (или если у него есть роль ПолныеПрава), текст запроса придется усложнять условиями вида &ПолныеПрава ИЛИ Ответственный.Наименование = &ТекущийПользователь. Подобное условие существенно снижает производительность СУБД, так как блокирует использование индексов.

Более правильным и гибким решением является использование стандартного механизма отборов динамического списка через Список.Отбор. Текст запроса остается стандартным (без секции ГДЕ), а отбор накладывается программно в зависимости от прав доступа.

Рассмотрим алгоритм реализации:

  1. Проверяем, доступна ли текущему пользователю роль с полными правами через функцию РольДоступна().
  2. Если полные права отсутствуют, находим ссылку на соответствующего сотрудника в справочнике Сотрудники по полному имени пользователя ИБ.
  3. Формируем элемент отбора в компоновщике настроек динамического списка.

Проанализируем пример кода для процедуры ПриСозданииНаСервере:


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

Ограничения и возможные риски программного отбора в форме

При проектировании системы важно учитывать подводные камни, связанные с программным отбором в форме списка:

  1. Ненадежность поиска по строковому наименованию: Поиск сотрудников по строке Наименование или ПолноеИмя чувствителен к опечаткам, лишним пробелам, изменению фамилии или наличию сотрудников-однофамильцев. Для точной привязки рекомендуется добавить в справочник Сотрудники реквизит ИдентификаторПользователяИБ и хранить в нем GUID пользователя (полученный через ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор).
  2. Безопасность и разграничение доступа: Отбор, установленный только на уровне формы списка, не является защитой данных. Пользователь может получить доступ к чужим документам через внешние отчеты, консоль запросов или связанные формы.
  3. Механизм RLS (Record Level Security): Для обеспечения реальной безопасности и ограничения прав на уровне СУБД следует использовать механизм RLS в свойствах роли. В этом случае ограничение права «Чтение» для объекта Документ.Табель будет действовать глобально во всей системе, а пользователи с полными правами автоматически получат доступ ко всем записям без написания дополнительного кода в формах.
← На главную