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