В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 (особенно в типовых решениях, таких как «Бухгалтерия предприятия 3.0») часто возникает задача управления пользовательским интерфейсом. Одной из таких задач является программное ограничение списка выбора. Например, когда на форме документа есть поле, которое должно содержать строго определенный набор значений (или вовсе одно конкретное), хотя изначально список может заполняться из справочника или перечисления более широким набором данных.
В этой статье мы подробно разберем, как сделать так, чтобы в выпадающем списке оставались только нужные нам позиции, рассмотрим механику работы со списком выбора и изучим сопутствующие настройки элементов формы, которые обеспечат стабильную работу вашего кода.
Рассмотрим ситуацию, когда у нас есть поле ввода, связанное с реквизитом. Чтобы ограничить выбор пользователя, нам необходимо воздействовать не на сам реквизит (данные), а на элемент управления формы (интерфейс). Список выбора — это свойство элемента формы, которое представляет собой объект типа СписокЗначений.
Проанализируем первый и самый логичный шаг: если мы хотим, чтобы в списке были только «Бананы», нам нужно сначала избавиться от «Помидоров» и «Овощей», которые попали туда ранее или подтянулись автоматически. Для этого используется метод Очистить().
Разберем алгоритм программного заполнения в обработчике события ПриСозданииНаСервере. Это наиболее подходящее место, так как список сформируется до того, как пользователь увидит форму.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем элемент формы по его имени
ЭлементСписка = Элементы.ИмяВашегоПоляВыбора;
// 1. Полностью очищаем текущий список выбора
ЭлементСписка.СписокВыбора.Очистить();
// 2. Добавляем только нужное значение
// Метод Добавить(Значение, Представление)
ЭлементСписка.СписокВыбора.Добавить("Бананы", "Бананы");
КонецПроцедуры
Обратите внимание на важный нюанс, который прозвучал в обсуждении: внутри списка могут храниться не просто строки, а ссылки на справочники или числовые индексы. Если ваше поле связано со справочником «Номенклатура», то в метод Добавить() нужно передавать именно ссылку на элемент справочника, а не текстовую строку.
Просто ограничить список недостаточно. Если мы оставим в списке только один элемент, поле все равно останется пустым, пока пользователь не нажмет на кнопку выбора. Чтобы сделать работу с документом удобнее, мы можем сразу подставить «Бананы» в реквизит объекта. Проанализируем, как это сделать правильно:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Ограничиваем список
Элементы.Продукт.СписокВыбора.Очистить();
Элементы.Продукт.СписокВыбора.Добавить("Бананы");
// Если это новый документ, сразу заполняем значение
Если Объект.Ссылка.Пустая() Тогда
Объект.Продукт = "Бананы";
КонецЕсли;
КонецПроцедуры
Таким образом, при открытии нового документа пользователь сразу увидит заполненное поле, а при попытке изменить его — увидит в выпадающем списке только один вариант.
Выясним причину, по которой пользователь иногда может «обмануть» систему и вписать в поле произвольный текст. По умолчанию многие поля ввода позволяют вводить текст вручную. Чтобы запретить это и заставить программу работать строго со сформированным списком, необходимо настроить свойства элемента формы. Это можно сделать как в конфигураторе, так и программно.
Рассмотрим необходимые свойства:
Истина. Это превратит обычное поле ввода в выпадающий список, куда нельзя вписать ничего постороннего.Программно это выглядит так:
Элементы.Продукт.РежимВыбораИзСписка = Истина;
Иногда логика приложения требует, чтобы список формировался динамически прямо в момент нажатия на кнопку выбора. В этом случае нам поможет обработчик события НачалоВыбора. Посмотрим на пример реализации:
&НаКлиенте
Процедура ПродуктНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартное открытие формы выбора справочника
СтандартнаяОбработка = Ложь;
// Создаем свой список
Список = Новый СписокЗначений;
Список.Добавить("Бананы");
// Предлагаем пользователю выбрать из нашего списка
ВыбранныйЭлемент = ВыбратьИзСписка(Список, Элемент);
Если ВыбранныйЭлемент <> Неопределено Тогда
Объект.Продукт = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецПроцедуры
Этот метод особенно полезен, если набор допустимых значений зависит от других реквизитов формы, заполненных пользователем ранее.
Если ваша задача — не просто оставить одно текстовое значение, а отфильтровать элементы справочника (например, показывать только товары из категории «Фрукты»), то писать код на форме не обязательно. Рассмотрим механизм Параметров выбора (ChoiceParameters).
В конфигураторе, в свойствах реквизита объекта (документа), можно найти поле «Параметры выбора». Там можно задать фиксированный отбор. Например: Отбор.Родитель(Наименование="Фрукты"). В этом случае система сама применит фильтр к списку, и программировать очистку списка на форме не придется. Это более «чистый» подход с точки зрения архитектуры 1С.
Важно помнить, что любые манипуляции со списками выбора на форме — это лишь интерфейсные ограничения. Опытный пользователь или внешняя обработка могут записать в документ «Помидоры» в обход вашей формы. Чтобы гарантировать, что в поле всегда будут только «Бананы», рекомендуется добавить проверку в модуле объекта в процедуре ПередЗаписью.
Проанализируем пример кода в модуле документа:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если Продукт <> "Бананы" Тогда
Сообщить("В данном документе можно выбрать только Бананы!");
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Подведем итог: для реализации задачи наиболее эффективным является сочетание программной очистки СписокВыбора.Очистить(), установки РежимВыбораИзСписка = Истина и автоматической подстановки значения при создании формы. Это обеспечит корректное поведение интерфейса и удобство для конечного пользователя.