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

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

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

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

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

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

Как устроена индексация коллекций в 1С

Главное правило, которое нужно запомнить: индексы всех стандартных коллекций 1С — массивов, списков значений, таблиц значений — начинаются с нуля. Первый элемент имеет индекс 0, второй — 1, последний имеет индекс «Количество() − 1». Это отличается от нумерации строк запроса и некоторых других объектов, поэтому путаница встречается часто.

Если обратиться по индексу, которого нет в коллекции (отрицательному или большему либо равному количеству элементов), платформа выдаст ошибку выполнения «Индекс находится за границами массива» и выполнение процедуры прервётся. В отладочном режиме это удобно, а в рабочей базе такая ошибка может оборвать проведение документа или обмен данными.

Поэтому перед обращением по индексу стоит убедиться, что коллекция не пуста и индекс находится в допустимых пределах. Минимальная проверка выглядит так:

Если Список.Количество() > 0 Тогда

ПервыйЭлемент = Список.Получить(0);

КонецЕсли;

Обращение к элементу массива по индексу

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

Массив = Новый Массив;

Массив.Добавить("Первый");

Массив.Добавить("Второй");

Значение1 = Массив[0]; // "Первый"

Значение2 = Массив.Получить(1); // "Второй"

Через квадратные скобки можно не только читать, но и изменять элемент: Массив[0] = "Новое значение";. Метод Установить(Индекс, Значение) делает то же самое. Выбор между синтаксисами — вопрос стиля; квадратные скобки короче и чаще встречаются в типовом коде.

Для получения последнего элемента удобно использовать выражение Массив[Массив.Количество() - 1]. Отдельного метода «последний элемент» в массиве нет, поэтому такая конструкция — стандартная практика. Не забудьте проверить, что массив не пуст, иначе получите индекс −1 и ошибку.

Работа со списком значений: Получить, НайтиПоЗначению, НайтиПоПредставлению

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

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

Список.Добавить("Москва", "Столица");

Список.Добавить("Казань");

Элемент = Список.Получить(0); // элемент списка

Город = Элемент.Значение; // "Москва"

Подпись = Элемент.Представление; // "Столица"

// Краткая форма через квадратные скобки:

Город2 = Список[1].Значение; // "Казань"

Если известно значение, а не индекс, используйте метод НайтиПоЗначению(). Он вернёт элемент списка или Неопределено, если значение не найдено. Результат обязательно нужно проверять:

Найденный = Список.НайтиПоЗначению("Казань");

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

Индекс = Список.Индекс(Найденный); // позиция элемента

КонецЕсли;

Метод НайтиПоПредставлению() ищет по видимой подписи элемента. Он полезен, когда список заполняется для выбора пользователем, но помните: представления могут совпадать у разных элементов, и метод вернёт первое совпадение.

Получение строки таблицы значений и табличной части

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

Строка = ТаблицаТоваров[0];

Сумма = Строка.Сумма; // через точку

Цена = Строка["Цена"]; // через имя колонки строкой

Обращение через строку с именем колонки удобно, когда имя колонки хранится в переменной — например, при универсальной обработке произвольных таблиц. Через точку код читается легче, но работает только с фиксированным именем.

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

Отбор = Новый Структура("Номенклатура", ИскомыйТовар);

Строки = ТаблицаТоваров.НайтиСтроки(Отбор);

Если Строки.Количество() > 0 Тогда

ПерваяСтрока = Строки[0];

КонецЕсли;

Метод НайтиСтроки выполняет полный перебор таблицы. Если поиск по одному и тому же отбору выполняется многократно в цикле, таблицу лучше заранее проиндексировать методом Индексы.Добавить("ИмяКолонки") — на больших таблицах это заметно ускоряет работу.
ПЗ
Практическое замечание

Перебор элементов в цикле: когда индекс не нужен

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

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

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

КонецЦикла;

Цикл со счётчиком Для ... По ... Цикл нужен, когда важен сам индекс — например, при параллельном обходе двух коллекций одинаковой длины или при выводе нумерованного списка:

Для Инд = 0 По Список.Количество() - 1 Цикл

Сообщить(Строка(Инд + 1) + ". " + Список[Инд].Значение);

КонецЦикла;

Обратите внимание: верхняя граница цикла — «Количество() − 1», а не «Количество()». Запись «Для Инд = 1 По Список.Количество()» — типичная ошибка, которая пропускает первый элемент и выходит за границу на последнем шаге.

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

Безопасные приёмы и проверка результата

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

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

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

Индекс перед обращением
Норма

Индекс от 0 до Количество() - 1, коллекция не пуста

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

Индекс равен Количество() или отрицательный — будет исключение

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

Возвращён элемент или строка, свойства читаются без ошибок

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

Возвращено Неопределено — обращение к свойству прервёт код

Тип полученного значения
Норма

Переменная содержит ожидаемый тип (проверка ТипЗнч)

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

Вместо значения — элемент списка или Неопределено

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

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

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

Сравнение способов обращения к элементам

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

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

По индексу: Список[0] / Получить(0)

Самый быстрый способ, когда позиция известна. Требует проверки границ, иначе исключение

НайтиПоЗначению()

Для списка значений, когда известно значение, но не позиция. Возвращает Неопределено при отсутствии — нужна проверка

Найти() / НайтиСтроки()

Для таблиц значений и табличных частей: поиск по одной или нескольким колонкам. На больших таблицах стоит добавить индекс

Цикл Для Каждого

Когда нужны все элементы. Безопаснее индексного цикла, но не подходит, если требуется позиция элемента

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

С какого числа начинается нумерация элементов списка в 1С?

С нуля. Первый элемент любой стандартной коллекции (массив, список значений, таблица значений) имеет индекс 0, последний — индекс «Количество() − 1». Исключения встречаются редко, например нумерация строк в некоторых текстовых объектах, но для коллекций правило нулевого индекса действует всегда.

Чем отличается Список[0] от Список.Получить(0)?

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

Почему Список.Получить(0) возвращает не значение, а какой-то объект?

Потому что список значений хранит элементы, у которых есть свойства Значение и Представление. Чтобы получить само значение, обратитесь к свойству: Список.Получить(0).Значение. Это отличие списка значений от массива, где элемент — это само значение.

Что вернёт НайтиПоЗначению(), если элемента нет в списке?

Значение Неопределено. Любая попытка обратиться к свойству или методу Неопределено вызовет ошибку выполнения, поэтому результат поиска всегда проверяйте сравнением «<> Неопределено» до дальнейшего использования.

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

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

Можно ли обращаться к элементам списка на клиенте и на сервере одинаково?

Да, синтаксис обращения одинаков. Различие в другом: таблица значений недоступна на тонком клиенте в некоторых контекстах, поэтому в управляемых формах данные часто передают через ДанныеФормыКоллекция, где обращение к строкам выполняется по индексу аналогично, а поиск — через НайтиСтроки().

Итог

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

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