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