Как программно открыть выпадающий список вместо формы выбора в 1С 8.3

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

При разработке интерфейсов на управляемых формах 1С часто возникает задача: перехватить выбор значения в поле ввода, чтобы задать пользователю уточняющий вопрос или выполнить проверку, и при этом сохранить привычный интерфейс выпадающего списка (QuickChoice). Стандартное поведение платформы при установке СтандартнаяОбработка = Ложь часто сбивает разработчиков с толку, так как после выполнения своего кода им приходится либо открывать громоздкую форму выбора, либо вручную эмулировать выпадающий список. В этой статье мы подробно разберем, как реализовать программный вызов списка выбора, сохранив единообразие интерфейса.

Анализ проблемы: почему открывается форма выбора?

Когда мы работаем в событии НачалоВыбора, платформа ожидает, что мы либо позволим ей отработать штатно, либо полностью возьмем управление на себя. Если мы задаем вопрос через ПоказатьВопрос (используя ОписаниеОповещения), выполнение кода становится асинхронным. Это означает, что процедура НачалоВыбора завершается до того, как пользователь нажмет кнопку в окне вопроса. Чтобы предотвратить немедленное открытие стандартного списка или формы, мы пишем СтандартнаяОбработка = Ложь. Однако после подтверждения пользователем своего намерения в процедуре обратного вызова, нам нужно как-то вернуть «выпадающее меню». Если просто вызвать ОткрытьФорму, откроется полноценное окно справочника, что нарушает логику быстрого выбора.

Решение №1: Использование метода ВыбратьИзСписка

Рассмотрим самый надежный способ — использование метода элемента формы ВыбратьИзСписка(). Этот метод позволяет визуально привязать список значений к конкретному полю ввода, имитируя стандартный выпадающий список. Разберем по шагам, как это реализовать.

Сначала перехватим событие начала выбора и зададим вопрос пользователю:


&НаКлиенте
Процедура ОрганизацияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    Если Объект.ТабЧасть.Количество() > 0 Тогда
        // Останавливаем стандартный механизм
        СтандартнаяОбработка = Ложь;
        
        ПараметрыВопроса = Новый Структура("Элемент", Элемент);
        Оповещение = Новый ОписаниеОповещения("ОрганизацияПослеВопроса", ЭтотОбъект, ПараметрыВопроса); 
        
        ТекстВопроса = "При смене организации табличная часть будет очищена. Продолжить?"; 
        ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
    КонецЕсли;    
    
КонецПроцедуры

Теперь проанализируем процедуру завершения вопроса. Здесь нам нужно программно сформировать список организаций и показать его пользователю именно как выпадающее меню:


&НаКлиенте
Процедура ОрганизацияПослеВопроса(Результат, ДополнительныеПараметры) Экспорт
    
    Если Результат = КодВозвратаДиалога.Да Тогда
        // Очищаем табличную часть, как и планировалось
        Объект.ТабЧасть.Очистить();
        
        // Получаем список организаций для выбора
        СписокДляВыбора = ПолучитьСписокОрганизацийСервер();
        
        // Открываем выпадающий список программно
        ЭлементФормы = ДополнительныеПараметры.Элемент;
        ЭлементФормы.ВыбратьИзСписка(СписокДляВыбора);
    КонецЕсли;
    
КонецПроцедуры

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


&НаСервереБезКонтекста
Функция ПолучитьСписокОрганизацийСервер()
    Список = Новый СписокЗначений;
    Выборка = Справочники.Организации.Выбрать();
    Пока Выборка.Следующий() Цикл
        Список.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;
    Возврат Список;
КонецФункции

Решение №2: Использование свойства СписокВыбора и быстрого выбора

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

Преимущество: Список выглядит максимально нативно, поддерживает поиск по строке и не требует сложных манипуляций с асинхронностью для формирования данных в момент клика.

  1. Установите у поля ввода свойство РежимВыбораИзСписка в значение Истина.
  2. В событии ПриСозданииНаСервере заполните Элементы.Организация.СписокВыбора актуальными данными.
  3. В обработчике вопроса просто вызывайте метод Элементы.Организация.ВыбратьИзСписка(Элементы.Организация.СписокВыбора).

Решение №3: Перенос логики в событие ПриИзменении

Проанализируем альтернативный сценарий, который часто оказывается более удобным для пользователя. Вместо того чтобы прерывать начало выбора, мы позволяем пользователю выбрать организацию привычным способом (через стандартный список), а вопрос задаем уже после выбора, в событии ПриИзменении.

Для этого нам понадобится хранить предыдущее значение организации, чтобы иметь возможность откатить изменения, если пользователь нажмет «Нет».


&НаКлиенте
Перем ТекущаяОрганизация; // Переменная модуля для хранения старого значения

&НаКлиенте
Процедура ОрганизацияПриИзменении(Элемент)
    
    Если Объект.ТабЧасть.Количество() > 0 Тогда
        Оповещение = Новый ОписаниеОповещения("ПослеВопросаОбОчистке", ЭтотОбъект, ТекущаяОрганизация);
        ПоказатьВопрос(Оповещение, "Очистить таблицу?", РежимДиалогаВопрос.ДаНет);
    Иначе
        ТекущаяОрганизация = Объект.Организация;
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопросаОбОчистке(Результат, СтароеЗначение) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        Объект.ТабЧасть.Очистить();
        ТекущаяОрганизация = Объект.Организация;
    Иначе
        // Возвращаем старое значение, если пользователь передумал
        Объект.Организация = СтароеЗначение;
    КонецЕсли;
КонецПроцедуры

Этот метод считается более «чистым», так как он не ломает стандартные механизмы платформы 1С по отображению выпадающих списков, истории выбора и автоподбора.

Важные нюансы работы в 1С 8.3.12 и выше

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

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

← На главную