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