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

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

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

Как получить значение из списка значений 1С: методы Получить, НайтиПоЗначению, обход в цикле, работа с представлением и пометками. Примеры кода и типичные ошибки.

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

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

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

Что хранит элемент списка значений

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

Именно эта структура — источник главной ошибки новичков. Вызов Список[0] возвращает элемент списка, а не хранящееся в нём значение. Если попытаться сравнить результат со строкой или числом, сравнение сработает не так, как ожидалось, либо выдаст ошибку типов.

Получение значения по индексу

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

Элемент = Список[0];

ПервоеЗначение = Элемент.Значение;

// или в одну строку

ПервоеЗначение = Список.Получить(0).Значение;

Количество элементов определяется методом Количество(). Перед обращением по индексу убедитесь, что список не пуст и индекс находится в диапазоне от 0 до Количество() - 1, иначе получите ошибку «Индекс находится за границами массива».

Последний элемент удобно получать так: Список[Список.Количество() - 1].Значение. Отрицательных индексов, как в некоторых других языках, в 1С нет.

Поиск значения методом НайтиПоЗначению

Когда позиция неизвестна, но известно само значение, используйте метод НайтиПоЗначению(). Он возвращает элемент списка или Неопределено, если совпадений нет:

Найденный = Список.НайтиПоЗначению(ИскомаяСсылка);

Если Найденный <> Неопределено Тогда

Сообщить("Позиция: " + Список.Индекс(Найденный));

Иначе

Сообщить("Значение не найдено");

КонецЕсли;

Сравнение выполняется по значению с учётом типа: строка «100» не будет равна числу 100, а две ссылки на один и тот же элемент справочника считаются равными. Для ссылочных типов поиск работает надёжно, а вот для строк учитывайте регистр и пробелы — перед поиском часто применяют СокрЛП().

Метод Индекс() выполняет обратную задачу: по известному элементу возвращает его позицию в списке. Это удобно, когда нужно узнать, где нашлось значение, а не только факт его наличия.

Обход списка в цикле и работа с пометками

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

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

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

ОбработатьЗначение(Элемент.Значение);

КонецЕсли;

КонецЦикла;

Такой код типичен для диалогов, где пользователь отметил флажками несколько строк. Пометки устанавливаются методом УстановитьПометки(), снимаются — СнятьПометки(), а проверить, есть ли вообще отмеченные элементы, можно методом ОтметитьЭлементы() в интерактивном режиме или перебором со сравнением Пометка = Истина.

Если внутри цикла нужен номер позиции, добавьте счётчик или используйте классический цикл Для Инд = 0 По Список.Количество() - 1 Цикл. Важное ограничение: удалять элементы списка внутри цикла Для Каждого нельзя — коллекция изменится, и обход сломается. Для удаления идите по индексам в обратном порядке или собирайте элементы для удаления во временный массив.

Типичные ошибки
01
Сравнение элемента списка со значением вместо элемента.Значение — сравнение всегда ложно или падает с ошибкой типов
02
Удаление элементов внутри цикла Для Каждого — пропуск элементов или ошибка обхода коллекции
03
Обращение Список[0] к пустому списку — ошибка выхода за границы
04
Поиск строки без СокрЛП — значение с лишним пробелом не находится

Интерактивный выбор: ВыбратьЭлемент и ВыбратьЭлементАсинх

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

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

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

// в отдельной процедуре

&НаКлиенте

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

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

ВыбранноеЗначение = ВыбранныйЭлемент.Значение;

КонецЕсли;

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

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

Особые сценарии и смежные типы

Получение представления вместо значения

Иногда нужно не само значение, а его текстовое отображение. Свойство Представление может отличаться от строкового представления значения — например, для ссылки на контрагента представление может содержать «Иванов И.И. (ООО Ромашка)». Если представление не задано явно, оно формируется автоматически из значения.

Отличие от массива и таблицы значений

Из массива значение получают напрямую по индексу: Массив[0] — промежуточного элемента там нет. Из таблицы значений данные извлекают по строке и имени колонки: Таблица[0].НаименованиеКолонки. Путаница между этими тремя коллекциями — частая причина ошибок, поэтому при получении переменной из чужого кода проверяйте её тип через ТипЗнч().

Загрузка и выгрузка списка

Для массового заполнения используются методы ЗагрузитьЗначения(Массив) и ВыгрузитьЗначения(). Второй возвращает обычный массив значений без обёрток — удобно, когда результат нужно передать в запрос как параметр для оператора В (&СписокЗначений).

Маршрут решения

Как выбрать способ получения значения

Известна позиция элементаСписок[Индекс].Значение с проверкой Количество()
Известно само значение, позиция неизвестнаСписок.НайтиПоЗначению() с проверкой на Неопределено
Нужно обработать все или отмеченные элементыЦикл Для Каждого с проверкой Элемент.Пометка
Значение должен выбрать пользовательПоказатьВыборЭлемента() с описанием оповещения
Список нужен как параметр запросаВыгрузитьЗначения() и передача массива в запрос

Проверка результата и отладка

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

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

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

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

Тип извлечённой переменной
Норма

Соответствует ожидаемому типу данных (ссылка, строка, число)

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

Тип «ЭлементСпискаЗначений» — забыли обратиться к свойству Значение

Результат НайтиПоЗначению
Норма

Возвращён элемент списка

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

Неопределено — значение отсутствует или не совпал тип/регистр

Выбор пользователя
Норма

В оповещение пришёл элемент, значение извлечено

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

При отмене выбора код падает — нет проверки на Неопределено

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

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

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

Почему НайтиПоЗначению не находит строку, которая точно есть в списке?

Чаще всего причина в непечатаемых символах, лишних пробелах или разном регистре. Примените СокрЛП() к обеим сравниваемым строкам, а при необходимости приведите их к одному регистру через НРег(). Также проверьте, что в списке хранится именно строка, а не число или ссылка.

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

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

Как узнать позицию найденного значения?

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

Чем список значений отличается от соответствия?

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

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

Нельзя удалять элементы внутри цикла Для Каждого. Обходите список по индексам в обратном порядке от Количество() - 1 до 0 и вызывайте Удалить(Индекс), либо сначала соберите элементы для удаления в отдельный массив и удаляйте их после завершения обхода.

Итог

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

Список значений хранит элементы, а не сами значения: всегда извлекайте данные через свойство Значение. По позиции обращайтесь через Список[Индекс].Значение, ищите через НайтиПоЗначению(), обрабатывайте всё циклом Для Каждого, а интерактивный выбор делайте через ПоказатьВыборЭлемента с обработкой отмены.