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