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