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