Почему при программном открытии формы выбора открываются сразу два окна и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартного механизма выбора значения недостаточно. Мы пишем код в обработчике события НачалоВыбора, устанавливаем СтандартнаяОбработка = Ложь, вызываем ОткрытьФорму, но вместо одного ожидаемого окна получаем два: одно — пустое или стандартное, а второе — наше, с нужными отборами. Разберем эту ситуацию подробно, проанализируем причины и найдем надежные решения.

Анализ исходного кода и типичной реализации

Рассмотрим пример кода, который часто становится источником проблемы. Программист пытается наложить сложный фильтр на справочник, запрашивая данные с сервера перед открытием формы. Проанализируем типичный обработчик события на клиенте:


&НаКлиенте
Процедура ВидДоговораНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    Работы = Новый Массив;
    // Получаем массив ссылок для отбора на сервере
    ВидДоговораНачалоВыбораНаСервере(Работы);
    
    ОтборПоГруппе = Новый Структура("Ссылка", Работы);
    ПараметрыВыбора = Новый Структура("Отбор", ОтборПоГруппе);
    
    // Открываем форму программно
    ОткрытьФорму("Справочник.КлассификаторВидовРабот.ФормаВыбора", ПараметрыВыбора, Элемент, УникальныйИдентификатор);
КонецПроцедуры

Для полноты картины посмотрим на серверную часть, где формируется массив для отбора.


&НаСервереБезКонтекста
Процедура ВидДоговораНачалоВыбораНаСервере(Работы)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    КлассификаторВидовРаботГруппы.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.КлассификаторВидовРабот.Группы КАК КлассификаторВидовРаботГруппы";
    
    Результат = Запрос.Выполнить();
    Если НЕ Результат.Пустой() Тогда
        Работы = Результат.Выгрузить().ВыгрузитьКолонку("Ссылка");
    КонецЕсли; 
КонецПроцедуры

Несмотря на то что в коде явно прописано СтандартнаяОбработка = Ложь, платформа все равно может инициировать стандартное действие. Рассмотрим по шагам, почему это происходит.

Причина 1: Специфика расширений конфигурации

Если вы работаете в расширении, очень важно обратить внимание на аннотацию метода. В 1С существует три основных типа перехвата событий:

  1. &Перед (&Before): Код расширения выполняется до кода основной конфигурации. Если вы установите СтандартнаяОбработка = Ложь в расширении, это может не повлиять на логику основной конфигурации, если там тоже прописаны обработчики.
  2. &После (&After): Код выполняется после основного. Здесь отменять стандартную обработку уже поздно.
  3. &Вместо (&InsteadOf): Полная замена стандартного метода.

Решение: Если ваша задача — полностью контролировать процесс выбора, используйте аннотацию &Вместо. Это гарантирует, что оригинальный обработчик (в котором может отсутствовать блокировка стандартного действия) не будет вызван.

Причина 2: Свойство «Быстрый выбор»

Проанализируем свойства элемента формы в конфигураторе. У полей ввода есть свойство Быстрый выбор (Quick Choice). Если оно установлено в значение Авто или Да, платформа пытается самостоятельно подобрать значения или вывести выпадающий список при нажатии на кнопку выбора.

В этот момент происходит конфликт: система одновременно пытается построить список быстрого выбора и выполнить ваш программный код ОткрытьФорму. В итоге «выскакивают» два интерфейсных элемента.

Решение: Установите в свойствах поля ввода значение Быстрый выбор — Нет. Для оперативной проверки и изменения настроек элементов формы непосредственно в сеансе пользователя можно использовать обработку для редактирования свойств форм в режиме предприятия.

Причина 3: Параметр «Владелец» в методе ОткрытьФорму

Обратим внимание на синтаксис вызова: ОткрытьФорму(..., ..., Элемент, ...);. Передавая Элемент (само поле ввода) в качестве владельца, вы связываете новую форму с этим полем. В некоторых версиях платформы и при определенных настройках метаданных это может спровоцировать автоматический механизм «помощи» платформы, который открывает стандартное окно, игнорируя флаг отмены.

Решение: Попробуйте заменить владельца. Вместо конкретного элемента передайте саму форму или Неопределено:


// Вместо Элемент используем ЭтаФорма
ОткрытьФорму("Справочник.КлассификаторВидовРабот.ФормаВыбора", ПараметрыВыбора, ЭтаФорма, УникальныйИдентификатор);

Причина 4: Режим «Выбор из списка»

Если у поля включено свойство РежимВыбораИзСписка, платформа ожидает, что выбор будет сделан из выпадающего меню. При нажатии кнопки выбора система инициирует открытие этого списка. Ваш программный вызов ОткрытьФорму создает полноценное диалоговое окно поверх этого списка или параллельно с ним.

Решение: Проверьте, не включен ли РежимВыбораИзСписка. Если он вам не нужен для реализации подбора, его следует отключить.

Причина 5: Кэш метаданных и ошибки привязки обработчиков

Иногда проблема кроется в «зависании» настроек в кэше сервера или клиента, особенно после интенсивной разработки в расширении. Проанализируем ситуацию: код верный, свойства настроены, но форма все равно двоится.

Решение: Выполните следующие действия по шагам:

  1. Зайдите в свойства элемента формы в конфигураторе.
  2. Очистите поле события НачалоВыбора (удалите привязку к процедуре).
  3. Сохраните форму/расширение.
  4. Заново выберите процедуру-обработчик в списке событий.
  5. Если это не помогло, попробуйте очистить кэш метаданных (параметр запуска /ClearCache).

Итоговые рекомендации

Для того чтобы избежать двойного открытия форм, придерживайтесь следующего алгоритма действий:

  1. Всегда проверяйте, что СтандартнаяОбработка = Ложь вызывается в самом начале процедуры НачалоВыбора.
  2. В расширениях используйте &Вместо для полной подмены логики.
  3. Отключайте Быстрый выбор и Режим выбора из списка в свойствах элемента, если планируете открывать форму программно.
  4. Внимательно следите за тем, что передается в качестве владельца в метод ОткрытьФорму.
  5. Используйте точку останова в процедуре ПриСозданииНаСервере вызываемой формы выбора и изучите Стек вызовов. Это позволит точно увидеть, какой механизм (системный или ваш программный) инициировал открытие каждого из окон.

Следуя этим правилам, мы обеспечим корректную работу интерфейса и исключим появление лишних окон, мешающих работе пользователя.

← На главную