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