К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как заполнить список выбора в управляемой форме 1С

Как заполнить список выбора в управляемой форме 1С: СписокВыбора, Элементы, программное добавление значений, типовые ошибки и примеры кода.

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

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

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

Где хранится список выбора и как к нему обратиться

У каждого поля ввода в управляемой форме есть свойство СписокВыбора типа «СписокЗначений». Обратиться к нему из модуля формы можно так: Элементы.СпособДоставки.СписокВыбора, где «СпособДоставки» — имя элемента формы, а не реквизита объекта. Это частая путаница: имя элемента формы и имя реквизита данных могут совпадать, но обращение идёт именно к элементу.

У списка значений есть методы Добавить(), Вставить(), Очистить(), НайтиПоЗначению() и Удалить(). Метод Добавить принимает значение, необязательное представление (то, что увидит пользователь) и необязательную картинку. Если представление не задано, пользователь увидит строковое представление самого значения.

Статическое заполнение в конфигураторе

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

Этот способ подходит для реквизитов типа «Строка» или «Число», где варианты известны заранее: «Наличный расчёт» / «Безналичный расчёт», «Первичный» / «Повторный». Плюс — никакого кода и никаких проблем с контекстом выполнения. Минус — чтобы изменить список, придётся снова открывать конфигуратор и обновлять конфигурацию.

Для реквизитов типа «ПеречислениеСсылка» статический список обычно не нужен вовсе: платформа сама показывает все значения перечисления. Список выбора в этом случае используют, чтобы ограничить видимые варианты — например, скрыть устаревшие статусы.

Программное заполнение при создании формы

Самый распространённый сценарий — заполнить список в обработчике ПриСозданииНаСервере. Этот обработчик выполняется на сервере до того, как форма показана пользователю, поэтому здесь можно обращаться к данным информационной базы: справочникам, перечислениям, запросам.

bsl
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список = Элементы.СпособДоставки.СписокВыбора;
	Список.Добавить("Самовывоз", "Самовывоз со склада");
	Список.Добавить("Курьер", "Доставка курьером");
	Список.Добавить("ТК", "Транспортная компания");
КонецПроцедуры

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

Если значения нужно взять из перечисления, удобно пройтись по нему циклом и добавить все или часть значений. Так код не придётся править при добавлении нового значения перечисления в конфигурацию.

Заполнение из перечисления

bsl
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Для Каждого ЗначениеПеречисления Из Перечисления.СтатусыЗаказа Цикл
		Элементы.Статус.СписокВыбора.Добавить(ЗначениеПеречисления, Строка(ЗначениеПеречисления));
	КонецЦикла;
КонецПроцедуры

Чтобы исключить часть значений, добавьте проверку внутри цикла — например, пропускайте устаревшие статусы через Если ... Тогда Продолжить;. Это безопаснее, чем заполнять список вручную: при появлении нового актуального статуса он попадёт в форму автоматически.

Динамическое обновление списка при изменении данных

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

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

Порядок динамического обновления
  1. 1
    В обработчике ПриИзменении управляющего поля вызовите серверную процедуру заполнения
  2. 2
    Очистите список: Элементы.Поле.СписокВыбора.Очистить()
  3. 3
    Заполните список новыми значениями по текущим условиям
  4. 4
    Проверьте, есть ли текущее значение реквизита в новом списке через НайтиПоЗначению
  5. 5
    Если значения нет — сбросьте реквизит в Неопределено или пустое значение

Если обработчик ПриИзменении работает на клиенте, а данные для списка лежат в базе, потребуется вызов серверной процедуры без контекста или с контекстом. Учитывайте, что каждый серверный вызов — это обращение к серверу; при частых изменениях поля (например, при вводе с клавиатуры) лучше заполнять список по событию окончания ввода, а не на каждое нажатие.

Заполнение списка из запроса к справочнику

Когда варианты хранятся в справочнике — например, список складов, доступных текущему пользователю, — список заполняется результатом запроса. Запрос выполняется на сервере, поэтому такой код размещают в серверной процедуре.

bsl
&НаСервере
Процедура ЗаполнитьСписокСкладов()
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Склады ГДЕ НЕ ПометкаУдаления";
	Список = Элементы.Склад.СписокВыбора;
	Список.Очистить();
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Список.Добавить(Выборка.Ссылка, Выборка.Наименование);
	КонецЦикла;
КонецПроцедуры

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

Ограничение ввода только значениями из списка

Сам по себе заполненный СписокВыбора лишь предлагает варианты, но не запрещает ввести произвольный текст. Чтобы пользователь мог выбрать только из списка, установите у элемента формы свойство РежимВыбораИзСписка в Истина — в палитре свойств или программно: Элементы.Статус.РежимВыбораИзСписка = Истина;.

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

Даже с включённым режимом выбора из списка не пренебрегайте серверной проверкой при записи объекта. Данные могут попасть в базу не только через эту форму — обменом, загрузкой из файла, другой формой. Проверка в модуле объекта надёжно отсекает недопустимые значения независимо от источника.

Типичные ошибки и как их проверить

Чаще всего список оказывается пустым по одной из трёх причин: код написан в клиентском обработчике и обращается к данным, недоступным на клиенте; обращение идёт по имени реквизита, а не по имени элемента формы; либо список заполняется в обработчике, который в данном сценарии не вызывается (например, при открытии существующего объекта логика завязана только на обработку нового).

Вторая группа ошибок — дубли значений при повторном заполнении без Очистить() и «зависшее» старое значение реквизита, которого уже нет в списке. Третья — несовпадение типов: в список добавили строку, а реквизит имеет тип ссылки; визуально выбор срабатывает, но при записи возникает ошибка преобразования.

Типичные ошибки
01
Заполнение списка на клиенте с обращением к запросам — код падает или список пуст; перенесите заполнение на сервер
02
Отсутствие Очистить() перед повторным заполнением — значения дублируются при каждом изменении условия
03
Обращение Элементы.ИмяРеквизита, когда элемент формы назван иначе — ошибка «Поле объекта не обнаружено»
04
Добавление значения одного типа в реквизит другого типа — ошибка при записи объекта
05
Забытый сброс текущего значения — в поле остаётся вариант, которого нет в новом списке
Контрольные точки

Как проверить результат

Открытие формы
Норма

Список заполнен сразу, без действий пользователя

Тревожный признак

Список пуст до первого клика по полю

Повторное изменение управляющего поля
Норма

Список обновляется, значений не больше, чем ожидалось

Тревожный признак

Появляются дубли строк

Запись объекта после выбора
Норма

Документ записывается без ошибок преобразования типов

Тревожный признак

Ошибка несоответствия типов при записи

Ручной ввод при включённом РежимВыбораИзСписка
Норма

Поле не принимает произвольный текст

Тревожный признак

Можно ввести значение вне списка

Когда список выбора не подходит: альтернативы

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

Сравнение вариантов

СписокВыбора

Небольшой фиксированный набор значений; не подходит для сотен элементов и частых изменений

Параметры выбора (СвязиПараметровВыбора)

Отбор в стандартной форме выбора по данным других полей; работает без ручного заполнения списка

Перечисление

Закрытый набор значений, заданный в конфигурации; платформа показывает список автоматически

Форма выбора справочника

Большие и изменчивые списки с поиском; требует больше действий от пользователя

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

Итог

Что важно запомнить

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

Частые вопросы

Почему список выбора пустой, хотя код заполнения написан?

Чаще всего код находится в клиентском обработчике и обращается к серверным данным, либо обращение идёт по имени реквизита, а не по имени элемента формы. Проверьте директиву компиляции процедуры (&НаСервере / &НаКлиенте) и имя элемента в дереве элементов формы.

Как сделать, чтобы пользователь мог выбрать только из списка?

Установите у элемента формы свойство РежимВыбораИзСписка = Истина. После этого ручной ввод блокируется. Дополнительно проверяйте значение при записи объекта, так как данные могут попасть в базу минуя эту форму.

Как убрать дубли значений в списке при повторном заполнении?

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

Можно ли заполнить список выбора значениями перечисления автоматически?

Да, циклом по Перечисления.ИмяПеречисления с добавлением каждого значения в список. Но если реквизит сам имеет тип этого перечисления, платформа уже показывает все значения — ручное заполнение нужно только для ограничения набора.

Чем список выбора отличается от параметров выбора?

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

Где правильно заполнять список: на клиенте или на сервере?

Если для заполнения нужны данные базы (запросы, справочники) — только на сервере, обычно в ПриСозданииНаСервере или в серверной процедуре, вызываемой из клиентского обработчика. Простой статический список можно заполнять и на клиенте, но единообразие проще поддерживать, заполняя всё на сервере.