Как запретить выбор определенных элементов справочника во всех формах конфигурации 1С?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача ограничить видимость или возможность выбора определенных элементов справочника (например, НоменклатурныеГруппы) для конкретных пользователей. Казалось бы, достаточно настроить отбор в динамическом списке основной формы или использовать готовые решения для настройки видимости объектов пользователями в списке, но на практике программист сталкивается с проблемой: пользователи продолжают выбирать "запрещенные" элементы через механизм ввода по строке (автоподбор), из истории выбора (кэша) или просто копированием (Ctrl+C / Ctrl+V) из старых документов. В этой статье мы подробно разберем, как комплексно решить эту задачу, не прибегая к тяжеловесному механизму RLS (Row Level Security), полноценная реализация которого требует глубокого анализа прав и ролей.

Анализируем проблему: почему обычных отборов в списках недостаточно?

Когда мы устанавливаем отбор в динамическом списке формы выбора, даже применяя гибкие ограничения на уровне СКД, мы влияем только на визуальный перечень элементов, который открывается при нажатии на кнопку выбора (три точки). Однако современный интерфейс 1С предоставляет пользователю множество других путей:

  1. Ввод по строке: Пользователь начинает набирать название прямо в поле, и платформа предлагает подходящие варианты.
  2. История выбора: Платформа хранит последние выбранные значения для каждого типа данных.
  3. Быстрый выбор: Выпадающий список, формируемый платформой автоматически.

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

Решение 1: Использование обработчика ОбработкаПолученияДанных

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

Проанализируем пример кода для модуля менеджера:


Процедура ОбработкаПолученияДанных(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    // Если нужно ограничить выбор только для определенных условий
    СтандартнаяОбработка = Ложь;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 50
        |   НоменклатурныеГруппы.Ссылка КАК Ссылка,
        |   НоменклатурныеГруппы.Наименование КАК Наименование
        |ИЗ
        |   Справочник.НоменклатурныеГруппы КАК НоменклатурныеГруппы
        |ГДЕ
        |   НоменклатурныеГруппы.Наименование ПОДОБНО &ТекстЗапроса
        |   И НоменклатурныеГруппы.ПометкаУдаления = ЛОЖЬ
        |   И НоменклатурныеГруппы.ДополнительныйРеквизитОграничения = ЛОЖЬ"; // Ваше условие
    
    Запрос.УстановитьПараметр("ТекстЗапроса", "%" + Параметры.СтрокаПоиска + "%");
    
    ДанныеВыбора = Новый СписокЗначений;
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;

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

Этот обработчик гарантирует, что при наборе текста в поле ввода пользователь никогда не увидит элементы, не соответствующие вашему условию ДополнительныйРеквизитОграничения = ЛОЖЬ.

Решение 2: Очистка истории выбора и отключение кэша

Даже если мы ограничили выборку, старые значения могут "выплывать" из истории выбора пользователя. Чтобы этого избежать, мы можем воздействовать на свойства реквизитов или очищать историю программно.

Рассмотрим два способа управления историей:

  1. Свойство конфигурации: В свойствах поля ввода на форме или в свойствах самого справочника можно установить значение параметра ИсторияВыбора в "Не использовать". Это самый простой способ, но он отключает удобство для всех элементов.
  2. Программная очистка: Если нам нужно точечно сбросить кэш, мы можем воспользоваться методом ИсторияВыбора.Очистить().

Посмотрим на пример программной очистки при запуске системы или открытии формы:


// Очистка истории выбора для конкретного типа данных
ИсторияВыбора.Очистить(Тип("СправочникСсылка.НоменклатурныеГруппы"));

Решение 3: Глобальное наложение параметров выбора через БСП

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

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


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

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

Решение 4: Подписка на событие для контроля записи

Выясним причину, по которой интерфейсных методов может быть недостаточно. Продвинутый пользователь может попытаться обойти ограничения через внешние обработки или групповое изменение реквизитов. Чтобы поставить окончательный заслон, необходимо использовать Подписку на событие ОбработкаПроверкиЗаполнения или ПередЗаписью. Этот механизм контроля данных на уровне записи является более гибким, чем полная блокировка изменений объектов.

Рассмотрим алгоритм работы подписки:

  1. Создаем подписку на событие для необходимых объектов (Документы, Справочники), где используется наша НоменклатурнаяГруппа.
  2. В обработчике проверяем значение реквизита.
  3. Если выбрано недопустимое значение, устанавливаем Отказ = Истина и выводим сообщение пользователю.

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

Резюме и рекомендации

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

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

← На главную