Как запретить выбор групп (папок) справочника в 1С:Предприятие 8

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

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

В этой статье мы подробно разберем, как решить задачу запрета выбора групп справочника. Мы проанализируем как простые декларативные методы настройки в конфигураторе, так и мощные программные механизмы, позволяющие реализовать этот запрет глобально для всей системы «в одном месте», включая ввод текста с клавиатуры (автоподбор).

---

Решение 1. Декларативная настройка свойств реквизитов и элементов формы

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

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

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Ограничиваем выбор только элементами для конкретного поля ввода
    Элементы.ДоговорКонтрагента.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы;
КонецПроцедуры

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

---

Решение 2. Контроль ввода по строке через модуль менеджера справочника

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

Разберем по шагам, как перехватить генерацию списка автоподбора с помощью обработчика ОбработкаПолученияДанныхВыбора в модуле менеджера справочника:

  1. Откроем модуль менеджера нужного справочника (например, Справочник.Номенклатура).
  2. Создадим шаблон предопределенной процедуры ОбработкаПолученияДанныхВыбора.
  3. Переопределим параметры получения данных, принудительно запретив выбор групп.

Проанализируем пример кода, который решает эту задачу:


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

Использование этого обработчика гарантирует, что в каком бы месте системы пользователь ни пытался ввести название группы справочника текстом, система отфильтрует подсказки и не позволит выбрать папку.

---

Решение 3. Глобальный запрет через общую подписку на события

Что делать, если иерархических справочников в системе много, и мы хотим внедрить единое правило запрета выбора групп сразу для всех или для выбранного списка справочников? Писать код в модуле менеджера каждого объекта неудобно.

Для решения этой задачи мы можем использовать механизм Подписок на события:

  1. Создадим в конфигураторе новый объект типа Подписка на событие.
  2. Назовем ее, например, ЗапретитьВыборГруппСправочников.
  3. В качестве источника выберем менеджеры необходимых нам справочников через зажатую клавишу Ctrl (например, СправочникМенеджер.Номенклатура, СправочникМенеджер.Контрагенты и т.д.).
  4. В качестве события выберем ОбработкаПолученияДанныхВыбора.
  5. Укажем общий модуль, в котором будет располагаться обработчик (модуль должен быть серверным).

Посмотрим на пример реализации обработчика в общем модуле:


Процедура ЗапретитьВыборГруппСправочниковОбработкаПолученияДанныхВыбора(Источник, ДанныеВыбора, Параметры, СтандартнаяОбработка) Экспорт
    
    // Устанавливаем ограничение выбора групп для любого справочника, вошедшего в подписку
    Параметры.Вставить("ВыборГруппИЭлементов", ИспользованиеГруппИЭлементов.Элементы);
    
КонецПроцедуры

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

---

Решение 4. Автоматический программный обход элементов формы

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

Разберем пример функции, которая выполняет автоматический обход всех элементов формы и настраивает ограничение:


Процедура ОграничитьВыборГруппНаФормеПрограммно(Форма) Экспорт
    
    Для Каждого Элемент Из Форма.Элементы Цикл
        
        // Проверяем, является ли элемент полем ввода
        Если ТипЗнч(Элемент) = Тип("ПолеФормы") И Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
            
            // Получаем путь к данным элемента
            ПутьКДанным = Элемент.ПутьКДанным;
            
            // Нам интересны только те поля, которые связаны с иерархическими справочниками
            Попытка
                ТипДанных = Форма.УстановитьДействие(ПутьКДанным); // Проверяем доступность связи
                // Определяем тип значения по метаданным
                // Если тип поля является ссылкой на справочник и этот справочник иерархический:
                МетаданныеОбъекта = Метаданные.НайтиПоТипу(Элемент.ОграничениеТипа.Типы()[0]);
                
                Если МетаданныеОбъекта <> Неопределено 
                    И Метаданные.Справочники.Содержит(МетаданныеОбъекта) 
                    И МетаданныеОбъекта.Иерархический Тогда
                    
                    // Устанавливаем свойство ограничения выбора программно
                    Элемент.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы;
                    
                КонецЕсли;
            Исключение
                Продолжить;
            КонецПопытки;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

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

---

Важные нюансы: Иерархия элементов без групп

Нам важно помнить об одном техническом нюансе платформы «1С:Предприятие 8». Справочники могут иметь два принципиально разных вида иерархии:

  1. Иерархия групп и элементов: Классический вариант, где есть папки (группы) и конечные элементы. Свойство ВыборГруппИЭлементов работает здесь безупречно.
  2. Иерархия элементов: В этом случае папок как таковых не существует. Родителем для одного элемента выступает другой обычный элемент этого же справочника. В такой структуре свойство ЭтоГруппа всегда возвращает значение Ложь для всех записей.

Если в вашей конфигурации используется иерархия элементов, стандартное свойство ВыборГруппИЭлементов работать не будет. В таком случае запретить выбор «родительских» элементов можно только программно при помощи запроса, проверяющего наличие подчиненных элементов у выбранной ссылки в обработчике проверки заполнения или перед записью документа.

Подведем итоги: Для точечной настройки используйте декларативное свойство ВыборГруппИЭлементов реквизита. Для масштабных проектов и гарантированного исключения ошибок ввода по строке идеальным решением будет комбинация Подписки на событие ОбработкаПолученияДанныхВыбора и программного обхода элементов форм при их создании.

← На главную