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

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

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

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

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

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

Что такое СписокЗначений и где он применяется

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

Типичные места применения на форме:

  • выпадающий список поля ввода (свойство СписокВыбора);
  • реквизит формы типа СписокЗначений, отображаемый таблицей с флажками;
  • параметр отбора динамического списка или отчёта на СКД (условие «В списке»);
  • диалог ВыбратьИзСписка() и меню ПоказатьВыборИзСписка();
  • подбор элементов справочника с пометками.

Создание реквизита формы типа СписокЗначений

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

После этого перетащите реквизит на дерево элементов формы. Платформа автоматически создаст таблицу с колонками «Пометка» и «Значение» — пользователь сможет видеть содержимое списка и отмечать строки. Если таблица на форме не нужна, а список используется только программно (например, как хранилище отбора), элемент создавать не обязательно: реквизит будет существовать и без визуального представления.

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

Программное заполнение списка: Добавить и ЗагрузитьЗначения

Базовый способ наполнения — метод Добавить(). Он принимает значение, необязательное представление, пометку и картинку. Заполнять список удобнее всего в обработчике ПриСозданииНаСервере, чтобы к моменту открытия формы данные уже были готовы:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

СписокСкладов.Добавить(Справочники.Склады.НайтиПоНаименованию("Основной"), , Истина);

СписокСкладов.Добавить(Справочники.Склады.НайтиПоНаименованию("Резервный"), "Резервный склад", Ложь);

КонецПроцедуры

Когда данные уже собраны в массив, удобнее метод ЗагрузитьЗначения(Массив) — он полностью заменяет содержимое списка. Типичный пример — заполнение из запроса:

&НаСервере

Процедура ЗаполнитьСписокОрганизаций()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Организации.Ссылка КАК Ссылка

|ИЗ

| Справочник.Организации КАК Организации

|ГДЕ

| НЕ Организации.ПометкаУдаления";

МассивОрганизаций = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

СписокОрганизаций.ЗагрузитьЗначения(МассивОрганизаций);

КонецПроцедуры

Обратите внимание: ЗагрузитьЗначения очищает список перед загрузкой. Если нужно добавить элементы к существующим, используйте цикл с Добавить() или предварительно сохраните текущие значения. Для полной очистки вручную служит метод Очистить().

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

Заполнение списка выбора поля ввода

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Элементы.СпособДоставки.СписокВыбора.Добавить("Курьер", "Курьерская доставка");

Элементы.СпособДоставки.СписокВыбора.Добавить("Самовывоз", "Самовывоз со склада");

Элементы.СпособДоставки.СписокВыбора.Добавить("ТК", "Транспортная компания");

КонецПроцедуры

Чтобы пользователь не мог ввести произвольное значение вне списка, установите у поля ввода свойство РежимВыбораИзСписка в Истина или включите «КнопкаСпискаВыбора» и запретите редактирование текста. Если список выбора статичен и известен на этапе разработки, его можно заполнить и без кода — прямо в палитре свойств элемента формы, кнопка «…» у свойства «СписокВыбора».

Для динамических списков выбора, зависящих от контекста (например, перечень договоров зависит от выбранного контрагента), заполняйте СписокВыбора в обработчике изменения связанного поля, предварительно вызывая Элементы.Поле.СписокВыбора.Очистить().

Передача списка в отбор динамического списка и СКД

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

&НаКлиенте

Процедура ПрименитьОтбор(Команда)

Отмеченные = Новый СписокЗначений;

Для Каждого ЭлементСписка Из СписокСкладов Цикл

Если ЭлементСписка.Пометка Тогда

Отмеченные.Добавить(ЭлементСписка.Значение);

КонецЕсли;

КонецЦикла;

УстановитьОтборПоСкладам(Отмеченные);

КонецПроцедуры

&НаСервере

Процедура УстановитьОтборПоСкладам(Отмеченные)

Список.Параметры.УстановитьЗначениеПараметра("Склады", Отмеченные);

КонецПроцедуры

В тексте запроса динамического списка условие записывается как ГДЕ Товары.Склад В (&Склады). Если отмеченных элементов нет, решите заранее, что должно произойти: либо отбор снимается (показываются все записи), либо передаётся пустой список, и тогда результат будет пустым. Первый вариант обычно понятнее пользователю.

Если список содержит сотни значений, передавайте его в параметр запроса целиком через ЗагрузитьЗначения, а не склейкой условий ИЛИ в цикле — запрос с одним параметром-списком выполняется заметно быстрее и проще сопровождается.
ПЗ
Практическое замечание

Интерактивный выбор: ВыбратьИзСписка и ПоказатьВыборИзСписка

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

&НаКлиенте

Процедура ВыбратьДействие(Команда)

Меню = Новый СписокЗначений;

Меню.Добавить("Печать", "Печать документа");

Меню.Добавить("Отправить", "Отправить по почте");

Меню.Добавить("Архив", "Переместить в архив");

ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораДействия", ЭтотОбъект);

ПоказатьВыборИзСписка(ОписаниеОповещения, Меню, Элементы.КнопкаДействия);

КонецПроцедуры

&НаКлиенте

Процедура ПослеВыбораДействия(ВыбранныйЭлемент, ДопПараметры) Экспорт

Если ВыбранныйЭлемент = Неопределено Тогда

Возврат; // пользователь отменил выбор

КонецЕсли;

// ВыбранныйЭлемент.Значение — выбранное значение списка

КонецПроцедуры

Обязательно обрабатывайте ситуацию отмены: если пользователь нажал Escape или кликнул вне меню, в обработчик придёт Неопределено. Пропуск этой проверки — распространённая причина ошибок «Значение не является значением объектного типа».

Проверка результата и типичные ошибки

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

Контрольные точки

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

Содержимое списка при открытии формы
Норма

Все ожидаемые элементы присутствуют, представления читаемы

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

Список пуст или содержит пустые строки — проверьте, что заполнение выполняется на сервере и запрос возвращает данные

Пометки элементов
Норма

Флажки устанавливаются и сохраняются после серверных вызовов

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

Пометки сбрасываются — вероятно, список перезаполняется при каждом обращении к серверу

Отбор по списку
Норма

Динамический список показывает только записи по отмеченным значениям

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

Отбор не срабатывает — проверьте тип параметра и условие В (&Параметр) в запросе

Представления ссылок
Норма

Показываются наименования элементов

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

Отображаются нечитаемые строки — задайте Представление при добавлении

Типичные ошибки
01
Заполнение реквизита в клиентской процедуре обращением к запросу — на клиенте запросы недоступны, нужен серверный вызов
02
Повторное заполнение списка в ПриОткрытии после каждого обновления формы — пользовательские пометки стираются
03
Передача в параметр СКД строки вместо СписокЗначений — условие В списке не работает или падает с ошибкой
04
Дублирование элементов из-за отсутствия Очистить() перед повторным заполнением СписокВыбора
05
Отсутствие проверки на Неопределено после ПоказатьВыборИзСписка — ошибка при отмене выбора пользователем

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

Часто задаваемые вопросы

Как получить только отмеченные пользователем элементы списка?

Пройдите по списку циклом и проверяйте свойство Пометка каждого элемента. Отмеченные значения удобно собирать в новый СписокЗначений или массив для дальнейшей передачи в запрос или параметр отбора.

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

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

Чем СписокЗначений отличается от массива для отбора в запросе?

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

Почему после серверного вызова пропадают пометки в списке?

Чаще всего потому, что список перезаполняется в серверной процедуре, которая вызывается при каждом обращении. Заполняйте список один раз в ПриСозданииНаСервере, а при необходимости обновления сохраняйте текущие пометки во временную структуру и восстанавливайте их после загрузки.

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

Используйте метод СортироватьПоЗначению() или СортироватьПоПредставлению() с указанием направления через объект НаправлениеСортировки. Сортировку удобно выполнять сразу после заполнения, до показа списка пользователю.

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

Технически да — СписокЗначений допускает разнотипные элементы. Но для отборов и передачи в запросы лучше держать однородные данные: смешанные типы усложняют сравнение и могут приводить к неожиданным результатам условия «В списке».

Итог

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

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