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