Разработка и Конфигурация · 13 мин
1С: как работать со списком значений
Как работать со списком значений в 1С: создание, добавление и удаление элементов, поиск, сортировка, выгрузка в массив и типичные ошибки разработчиков.
Список значений в 1С — это универсальная коллекция, в которой каждый элемент хранит не только само значение, но и представление, картинку и пометку. Разработчики используют его для передачи наборов данных между формами, организации множественного выбора, заполнения табличных частей и параметров запросов. В отличие от массива, список значений отображается пользователю в виде удобного диалога и поддерживает отметки флажками.
Объект доступен и на толстом, и на тонком клиенте, и на сервере, поэтому его часто выбирают как «транспортный» формат данных. Однако у него есть ограничения: список нельзя сериализовать в строку напрямую, а поиск по значению работает медленнее, чем обращение к соответствию. Понимание этих особенностей помогает выбрать правильный инструмент и избежать типовых ошибок.
Ниже разобраны основные сценарии: создание и заполнение списка, обход элементов, поиск и удаление, сортировка, выгрузка в массив, использование в запросах и формах, а также частые ошибки с пояснениями.
Создание списка значений и добавление элементов
Список создаётся стандартным конструктором. После создания он пуст, и элементы добавляются методом Добавить(). Метод принимает до четырёх параметров: значение, представление (строка, которую увидит пользователь), пометка (булево, состояние флажка) и картинка.
// Создание и заполнение списка
СписокСкладов = Новый СписокЗначений;
СписокСкладов.Добавить(СкладОсновной, "Основной склад", Истина);
СписокСкладов.Добавить(СкладРозничный, "Розничный склад", Ложь);
// Добавление в нужную позицию
СписокСкладов.Вставить(0, СкладРезервный, "Резервный");
Если представление не указано, платформа сформирует его автоматически из значения — для ссылок это будет строковое представление объекта. Пометка по умолчанию равна Ложь, поэтому при множественном выборе её нужно выставлять явно, если элемент должен быть отмечен сразу.
Метод Вставить(Индекс, ...) добавляет элемент в произвольную позицию, а ЗаполнитьЗначения(Массив) и ЗагрузитьЗначения(Массив) позволяют быстро наполнить список из готового массива. Разница между ними в том, что ЗагрузитьЗначения предварительно очищает список, а ЗаполнитьЗначения дополняет существующий.
Обход элементов и доступ по индексу
К элементам списка можно обращаться двумя способами: циклом Для Каждого и по числовому индексу. Индексация начинается с нуля, а общее количество элементов возвращает метод Количество(). Обращение по несуществующему индексу вызывает ошибку выполнения, поэтому при работе с индексами всегда проверяйте границы.
// Вариант 1: цикл Для Каждого — предпочтительный
Для Каждого Элемент Из СписокСкладов Цикл
Если Элемент.Пометка Тогда
ОбработатьСклад(Элемент.Значение);
КонецЕсли;
КонецЦикла;
// Вариант 2: по индексу
Для Инд = 0 По СписокСкладов.Количество() - 1 Цикл
Элемент = СписокСкладов[Инд];
Сообщить(Элемент.Представление);
КонецЦикла;
Получить элемент можно также методом Получить(Индекс) — он эквивалентен обращению через квадратные скобки. Для изменения значения существующего элемента используйте Установить(Индекс, НовоеЗначение) или просто присвойте свойству Элемент.Значение новое значение.
Цикл Для Каждого читается легче и безопаснее, но у него есть ограничение: внутри такого цикла нельзя удалять или добавлять элементы той же коллекции — это приведёт к непредсказуемому поведению. Если нужно модифицировать список во время обхода, идите по индексам с конца или собирайте элементы для удаления во временный массив.
Поиск, проверка наличия и удаление элементов
Для поиска элемента по значению служит метод НайтиПоЗначению(Значение). Он возвращает найденный элемент либо Неопределено, если значения в списке нет. Типичный шаблон защиты от дублей выглядит так:
Если СписокСкладов.НайтиПоЗначению(НовыйСклад) = Неопределено Тогда
СписокСкладов.Добавить(НовыйСклад);
КонецЕсли;
Учтите, что сравнение идёт по значению: две разные ссылки на один и тот же объект базы считаются равными, а вот строки «Склад» и «склад» различаются регистром. Для сложных составных типов поиск может работать медленно на больших списках — при объёмах в тысячи элементов и частых проверках наличия эффективнее использовать соответствие.
Удаление выполняется методами Удалить(Элемент) и Удалить(Индекс) — обе сигнатуры поддерживаются. Полная очистка делается методом Очистить(). Если нужно удалить все элементы с определённым условием, надёжнее идти по индексам от конца к началу:
Для Инд = -СписокСкладов.Количество() + 1 По 0 Цикл
РеальныйИндекс = -Инд;
Если Не СписокСкладов[РеальныйИндекс].Пометка Тогда
СписокСкладов.Удалить(РеальныйИндекс);
КонецЕсли;
КонецЦикла;
Сортировка, сдвиг и управление порядком элементов
Список поддерживает сортировку методами СортироватьПоЗначению() и СортироватьПоПредставлению(). Оба принимают необязательный параметр направления — НаправлениеСортировки.Возр или НаправлениеСортировки.Убыв.
СписокСкладов.СортироватьПоПредставлению(НаправлениеСортировки.Возр);
СписокСкладов.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
Сортировка по значению возможна только если значения сравнимы между собой. Смешанный список, где часть элементов — строки, а часть — ссылки на разные типы объектов, может вызвать ошибку сравнения. В таких случаях сортируйте по представлению или приводите значения к одному типу заранее.
Для ручного изменения порядка есть метод Сдвинуть(Элемент, Смещение): положительное смещение двигает элемент вниз по списку, отрицательное — вверх. Это удобно при реализации кнопок «Вверх» и «Вниз» в пользовательских формах настройки порядка.
Выгрузка в массив и передача в запрос
Одна из самых частых задач — передать содержимое списка в запрос в качестве параметра для оператора В. Запрос не принимает список значений напрямую во всех контекстах, поэтому надёжный способ — выгрузить значения в массив методом ВыгрузитьЗначения():
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В (&СписокСсылок)";
Запрос.УстановитьПараметр("СписокСсылок", СписокНоменклатуры.ВыгрузитьЗначения());
Результат = Запрос.Выполнить().Выгрузить();
Обратная операция — ЗагрузитьЗначения(Массив) — заполняет список из массива, например из колонки таблицы значений, полученной методом ВыгрузитьКолонку(). Эта пара методов образует стандартный мост между списком значений и другими коллекциями.
- 1Сформируйте список значений и заполните его нужными ссылками без дублей.
- 2В тексте запроса используйте условие В (&ИмяПараметра).
- 3Передайте параметр через УстановитьПараметр, указав СписокЗначений.ВыгрузитьЗначения().
- 4Выполните запрос и проверьте, что количество строк результата соответствует ожиданиям.
Интерактивный выбор: ОтметитьЭлементы и ВыбратьЭлемент
Главное преимущество списка значений перед массивом — встроенные диалоги. Метод ОтметитьЭлементы(Заголовок) показывает пользователю список с флажками и возвращает Истина, если выбор подтверждён. В управляемых формах вместо модальных вызовов применяется асинхронный вариант ПоказатьОтметкуЭлементов(ОписаниеОповещения, Заголовок).
// Обычные формы / толстый клиент
Если СписокСкладов.ОтметитьЭлементы("Выберите склады") Тогда
Для Каждого Элемент Из СписокСкладов Цикл
Если Элемент.Пометка Тогда
ОбработатьСклад(Элемент.Значение);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Для выбора одного элемента используются ВыбратьЭлемент() и асинхронный ПоказатьВыборЭлемента(). Перед показом диалога имеет смысл проставить пометки по текущему состоянию данных — например, отметить склады, которые уже выбраны в документе, чтобы пользователь видел актуальную картину.
В управляемых формах список значений часто хранится как реквизит формы с соответствующим типом. Это позволяет привязать его к полю списка на форме и получать интерактивное редактирование без дополнительного кода.
В тонком и веб-клиенте модальные методы ОтметитьЭлементы и ВыбратьЭлемент могут быть запрещены настройками конфигурации. Переносимый код пишите сразу через асинхронные ПоказатьОтметкуЭлементов и ПоказатьВыборЭлемента с описанием оповещения.
Когда список значений не подходит: альтернативы
Список значений — не универсальное решение. Если нужен только программный обход без представлений и пометок, проще и быстрее массив. Если требуется быстрый поиск по ключу на больших объёмах — соответствие. Для табличных данных с несколькими колонками правильный выбор — таблица значений.
| Коллекция | Сильные стороны | Когда выбрать |
|---|---|---|
| Список значений | Представление, пометка, диалоги выбора | Интерактивный выбор, передача наборов ссылок в формы |
| Массив | Простота, скорость, минимальные накладные расходы | Чисто программная обработка однотипных данных |
| Соответствие | Быстрый поиск по ключу | Частые проверки наличия, кэширование |
| Таблица значений | Несколько колонок, свёртка, поиск по отбору | Структурированные данные с несколькими полями |
Ещё одно ограничение: список значений не сериализуется в строку штатными средствами. Для сохранения в хранилище значений или передачи через веб-сервис его обычно преобразуют в массив структур или выгружают значения в массив, а представления восстанавливают на приёмной стороне.
Выбор коллекции
Подходит для диалогов выбора и передачи ссылок с представлениями; ограничение — медленный поиск на больших объёмах.
Подходит для быстрой программной обработки; ограничение — нет представлений, пометок и встроенных диалогов.
Подходит для мгновенной проверки наличия ключа; ограничение — нет порядка по индексу и диалогов выбора.
Проверка результата и отладка
При отладке содержимое списка удобно выводить в цикле через Сообщить() или смотреть в табло конфигуратора — список значений раскрывается там как дерево с полями каждого элемента. Перед передачей списка в запрос или процедуру проверяйте три вещи: количество элементов, отсутствие дублей и корректность типов значений.
// Быстрая диагностика списка
Сообщить("Элементов: " + СписокСкладов.Количество());
Для Каждого Элемент Из СписокСкладов Цикл
Сообщить(Строка(Элемент.Значение) + " | пометка: " + Элемент.Пометка);
КонецЦикла;
Как проверить результат
Совпадает с числом источников данных
Меньше ожидаемого — возможны дубли при загрузке из массива или пропуски в логике
Возвращаются строки по всем переданным ссылкам
Пустой результат — проверьте, что передан ВыгрузитьЗначения(), а типы ссылок совпадают
Отмечены именно те элементы, что выбрал пользователь
Пометки сброшены — диалог был отменён, а возврат Истина/Ложь не проверялся
Частые вопросы
Как проверить, пуст ли список значений?
Вызовите метод Количество() и сравните с нулём: Если Список.Количество() = 0 Тогда ... КонецЕсли. Отдельного метода Пустой() у списка значений нет.
Можно ли хранить в списке значения разных типов?
Да, ограничений по типам нет: в одном списке могут быть ссылки, строки, числа и даты. Но сортировка по значению для несравнимых типов вызовет ошибку, поэтому для смешанных списков используйте СортироватьПоПредставлению.
Почему запрос с параметром-списком возвращает пустой результат?
Чаще всего причина в несовпадении типов: в список попали ссылки одного вида, а поле в запросе имеет другой тип, либо значения не выгружены в массив. Проверьте, что параметр заполнен через ВыгрузитьЗначения() и типы ссылок совпадают с типом поля отбора.
Как скопировать список значений в другой список?
Простое присваивание Список2 = Список1 скопирует ссылку на тот же объект, и изменения отразятся в обоих. Для независимой копии создайте новый список и загрузите значения: Список2.ЗагрузитьЗначения(Список1.ВыгрузитьЗначения()) — при этом представления и пометки придётся переносить отдельным циклом, если они важны.
Работает ли список значений на сервере и на клиенте?
Да, тип доступен в обоих контекстах и передаётся между ними. Однако интерактивные методы (ПоказатьВыборЭлемента, ПоказатьОтметкуЭлементов) доступны только на клиенте — вызов на сервере приведёт к ошибке.
Чем список значений отличается от массива структур?
Список — готовый объект платформы с диалогами, пометками и сортировкой из коробки. Массив структур гибче по составу полей и легче сериализуется, но всю логику отображения и выбора придётся реализовывать вручную.
Что важно запомнить
Список значений — коллекция с полями Значение, Представление, Пометка и Картинка. Наполняйте через Добавить с контролем дублей, обходите циклом Для Каждого, удаляйте с конца по индексу, в запрос передавайте через ВыгрузитьЗначения(), а для интерактивного выбора в управляемых формах используйте асинхронные методы ПоказатьОтметкуЭлементов и ПоказатьВыборЭлемента.