В процессе разработки интерфейсов на управляемых формах 1С (программное изменение форм значительно ускоряет этот процесс) часто возникает задача: предоставить пользователю список готовых значений (например, адресов доставки контрагента), но при этом оставить возможность ввести произвольный текст, если нужного значения в списке не оказалось. Стандартное свойство РежимВыбораИзСписка при включении накладывает жесткое ограничение, блокируя любой ввод, кроме элементов из списка. Разберем, как обойти это ограничение и сделать интерфейс максимально удобным.
Когда мы устанавливаем для элемента формы (например, поля ввода типа "Строка") свойство РежимВыбораИзСписка в значение Истина, платформа 1С переводит это поле в режим фиксированного выбора. В этом состоянии пользователь видит выпадающий список и не может печатать в поле произвольные символы. Если мы программно заполняем этот список (например, при смене контрагента), но пользователю требуется ввести новый адрес, система просто не даст этого сделать.
Проанализируем ситуацию: нам нужно сохранить удобство быстрого выбора, но динамически отключать ограничение, когда оно мешает. Рассмотрим несколько способов решения этой задачи.
Этот метод был предложен и успешно реализован участниками форума. Если вы используете программную модификацию форм через текучий конструктор, реализовать логику будет ещё проще. Суть заключается в том, чтобы добавить в программно формируемый список специальный элемент-маркер. При его выборе мы будем переключать программные свойства элемента формы.
Рассмотрим алгоритм реализации по шагам:
ПриИзменении контрагента) добавляем строку "...Другой адрес".РежимВыбораИзСписка = Истина, чтобы изначально пользователь мог только выбирать.ОбработкаВыбора проверяем, что именно выбрал пользователь.Посмотрим на пример кода, который решает эту задачу:
&НаКлиенте
Процедура АдресДоставкиОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
// Проверяем, выбрал ли пользователь пункт для ручного ввода
Если ВыбранноеЗначение = "...Другой" Тогда
// Отключаем жесткое ограничение списка
Элемент.РежимВыбораИзСписка = Ложь;
// Очищаем значение, чтобы пользователь мог начать ввод с нуля
Объект.АдресДоставки = "";
// Устанавливаем фокус на поле для немедленного ввода
ТекущийЭлемент = Элемент;
КонецЕсли;
КонецПроцедуры
Важный нюанс: при смене контрагента или сбросе формы не забудьте вернуть состояние элемента в исходное, иначе для следующего объекта поле останется доступным для свободного ввода без списка.
Существует более элегантный способ, который часто используется в типовых конфигурациях, где часто применяется добавление реквизитов и элементов формы без изменения кода. Мы можем не включать РежимВыбораИзСписка, а настроить поведение поля так, чтобы оно визуально напоминало список, но не ограничивало ввод. Для этого проанализируем настройки свойств элемента формы:
Да. Это добавит привычную стрелочку вниз.Да. При нажатии на поле или на кнопку будет сразу открываться выпадающий список.Ложь.При такой комбинации настроек пользователь может нажать на кнопку и выбрать адрес из списка, либо просто начать печатать свой адрес в поле. Платформа не будет выдавать ошибку "Значение не входит в список".
Для создания действительно современного интерфейса рассмотрим использование события Автоподбор. Это позволяет реализовать механизм, похожий на поисковые подсказки в браузерах. Когда пользователь начинает вводить адрес, мы предлагаем ему варианты, но не ограничиваем его в написании чего-то своего.
Разберем пример реализации в коде:
&НаКлиенте
Процедура АдресДоставкиАвтоподбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
// Если пользователь уже что-то ввел, подберем похожие адреса
Если ЗначениеЗаполнено(Текст) Тогда
СтандартнаяОбработка = Ложь;
// Формируем список подходящих значений (например, из истории или данных контрагента)
СписокПодходящихАдресов = ПолучитьСписокАдресовПоСтроке(Текст);
ДанныеВыбора = СписокПодходящихАдресов;
КонецЕсли;
КонецПроцедуры
Этот метод хорош тем, что он не требует от пользователя лишних кликов на пункт "Другой". Система всегда готова принять как ввод из списка, так и ручной текст.
Выясним причину, по которой иногда ввод нового значения блокируется, даже если режим выбора из списка выключен. Это может происходить, если у реквизита в метаданных установлено свойство "Выбирать из списка". В этом случае полезно использовать событие ОкончаниеВводаТекста.
Проанализируем ситуацию: пользователь ввел текст, которого нет в списке, и нажал Enter. Платформа пытается сопоставить текст со списком и, не найдя его, может очистить поле. Чтобы этого избежать, используем следующий код:
&НаКлиенте
Процедура АдресДоставкиОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
// Разрешаем платформе принять введенный текст как конечное значение,
// даже если его нет в выпадающем списке выбора
СтандартнаяОбработка = Ложь;
КонецПроцедуры
При выборе метода реализации советуем придерживаться следующих правил:
СправочникСсылка.Адреса), то свободный ввод строки невозможен без создания нового элемента справочника. В данной теме мы рассматриваем тип Строка.Элементы.АдресДоставки.СписокВыбора.Очистить() всегда проверяйте, нужно ли переустановить свойства видимости кнопок или доступности поля.QuickChoice) работает более стабильно и плавно.Таким образом, мы рассмотрели различные подходы к решению проблемы выбора из списка в 1С. Выбор конкретного метода зависит от требований к интерфейсу: от простого программного переключения режима до продвинутого автоподбора данных "на лету".