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