Обращение к элементу массива во встроенном языке 1С:Предприятия 8.3: индексы, проверки, циклы и вложенные массивы

· 9 мин

Содержание

Значение элемента массива в 1С получают по индексу в квадратных скобках: Значение = Массив[0];. Нумерация начинается с нуля, поэтому первый элемент — Массив[0], а последний — Массив[Массив.ВГраница()]. Тот же результат даёт метод Массив.Получить(Индекс).

Правила одинаковы для всего встроенного языка платформы 8.3: обработки, общие модули, модули форм, внешние отчёты. От конфигурации (БП, ЗУП, УТ) ничего не зависит. Чаще всего проблемы возникают не с самим синтаксисом, а с границами: пустой массив, счёт с единицы вместо нуля, удаление элементов в цикле.

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

Массив во встроенном языке 1С — упорядоченная коллекция значений любого типа. В одном массиве могут лежать число, строка, ссылка на справочник и даже другой массив.

Прочитать элемент можно двумя способами:

Города = Новый Массив;
Города.Добавить("Москва");
Города.Добавить("Казань");
Города.Добавить("Пермь");

Первый = Города[0];          // "Москва"
Второй = Города.Получить(1); // "Казань"

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

Изменить значение тоже можно двумя способами: присваиванием Города[2] = "Самара"; или методом Города.Установить(2, "Самара");.

Методы массива, которые нужны для чтения

МетодЧто возвращаетПример
Количество()Число элементов3
ВГраница()Наибольший индекс, для пустого массива −12
Получить(Индекс)Значение элемента“Казань”
Найти(Значение)Индекс найденного элемента или Неопределено1

💡 ВГраница() всегда на единицу меньше Количество(). Путаница между ними — главный источник ошибок при работе с массивами.

Индекс в переменной

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

Номер = 2;
Значение = Города[Номер];
Предпоследний = Города[Города.Количество() - 2];

Индексация с нуля: первый, последний и граничные элементы

Нулевая нумерация непривычна тем, кто пришёл из табличных частей. Там у строки есть реквизит НомерСтроки, который начинается с 1. У массива такого реквизита нет, есть только позиция с нуля.

Для массива из трёх элементов допустимые индексы выглядят так:

Что нужноВыражениеИндекс
Первый элементМассив[0]0
Второй элементМассив[1]1
Последний элементМассив[Массив.ВГраница()]2
N-й по счёту (с единицы)Массив[N - 1]N − 1

Всё, что меньше 0 или больше ВГраница(), вызывает ошибку времени выполнения.

Массив, созданный с размером

Конструктор Новый Массив(5) создаёт массив из пяти элементов, и каждый из них равен Неопределено. Чтение Массив[4] не упадёт, но вернёт пустое значение.

Буфер = Новый Массив(5);
Сообщить(Буфер.Количество()); // 5
Сообщить(Буфер[4] = Неопределено); // Истина

⚠️ Если массив создан с размером, а потом в него добавляют значения через Добавить(), новые элементы встают после пяти пустых. Отсюда частая ошибка: данные лежат в индексах 5, 6, 7, а код читает 0, 1, 2 и получает Неопределено. Для заполнения такого массива используют присваивание по индексу.

Пустой массив

У пустого массива Количество() равно 0, а ВГраница() равна −1. Обращение Массив[0] к нему уже ошибка. Перед чтением первого элемента всегда проверяйте, что массив не пуст.

Безопасное получение значения с проверкой индекса

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

Проверка границ перед чтением

Если Индекс >= 0 И Индекс <= Массив.ВГраница() Тогда
    Значение = Массив[Индекс];
Иначе
    Значение = Неопределено;
КонецЕсли;

Проверка на ВГраница() сразу покрывает и пустой массив: у него граница −1, и условие ложно для любого неотрицательного индекса.

Универсальная функция

Если чтение повторяется во многих местах, удобнее вынести его в общий модуль с признаком «Клиент» и «Сервер»:

// Возвращает элемент массива или значение по умолчанию,
// если индекс вне диапазона или передан не массив.
Функция ЭлементМассиваИлиПоУмолчанию(Коллекция, Индекс, ПоУмолчанию = Неопределено) Экспорт

    ТипКоллекции = ТипЗнч(Коллекция);
    Если ТипКоллекции <> Тип("Массив")
        И ТипКоллекции <> Тип("ФиксированныйМассив") Тогда
        Возврат ПоУмолчанию;
    КонецЕсли;

    Если ТипЗнч(Индекс) <> Тип("Число") Или Индекс <> Цел(Индекс) Тогда
        Возврат ПоУмолчанию;
    КонецЕсли;

    Если Индекс < 0 Или Индекс > Коллекция.ВГраница() Тогда
        Возврат ПоУмолчанию;
    КонецЕсли;

    Возврат Коллекция[Индекс];

КонецФункции

Вызов: Город = ЭлементМассиваИлиПоУмолчанию(Города, 5, "не указан");. Для массива из трёх элементов вернётся строка «не указан», а не ошибка.

Почему не Попытка…Исключение

Обернуть Массив[Индекс] в Попытка технически можно. Но так прячутся настоящие ошибки логики, а в отладке исключения мешают ловить реальную причину. Попытку оставляйте для внешних источников: файлов, COM, HTTP-ответов. Для индекса достаточно одного условия.

Поиск вместо индекса

Иногда нужен не элемент по номеру, а ответ на вопрос «есть ли такое значение». Для этого есть Найти():

Позиция = Города.Найти("Пермь");
Если Позиция <> Неопределено Тогда
    Сообщить("Пермь на позиции " + Формат(Позиция, "ЧН=0; ЧГ=0"));
КонецЕсли;

Сравнивайте результат именно с Неопределено. Проверка Если Позиция Тогда даст неверный ответ для первого элемента: у него индекс 0.

Перебор элементов массива в цикле

Получить сразу все значения массива можно двумя видами цикла.

Для Каждого — когда индекс не нужен

Для Каждого Город Из Города Цикл
    Сообщить(Город);
КонецЦикла;

Самый короткий и надёжный вариант. Выйти за границы здесь невозможно, пустой массив просто пропускается.

Для по индексу — когда важна позиция

Для Индекс = 0 По Города.ВГраница() Цикл
    Сообщить(Формат(Индекс + 1, "ЧГ=0") + ". " + Города[Индекс]);
КонецЦикла;

Индекс нужен, если требуется номер для вывода, сравнение с соседним элементом или параллельное чтение второго массива той же длины.

Для пустого массива цикл Для Индекс = 0 По -1 не выполнится ни разу, отдельная проверка не нужна.

Сравнение с соседним элементом

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

Для Индекс = 1 По Цены.ВГраница() Цикл
    Если Цены[Индекс] > Цены[Индекс - 1] Тогда
        Сообщить("Рост на позиции " + Формат(Индекс, "ЧН=0; ЧГ=0"));
    КонецЕсли;
КонецЦикла;

Цикл начинается с 1, а не с 0: у нулевого элемента нет предыдущего, и Цены[-1] вызвал бы ошибку. Для массива из одного элемента цикл Для Индекс = 1 По 0 не выполнится, это корректно.

Если нужно сравнивать со следующим элементом, верхнюю границу уменьшают: По Цены.ВГраница() - 1.

Удаление элементов при переборе

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

Всего = Суммы.Количество();
Для Сч = 1 По Всего Цикл
    Индекс = Всего - Сч;
    Если Суммы[Индекс] = 0 Тогда
        Суммы.Удалить(Индекс);
    КонецЕсли;
КонецЦикла;

Граница Всего вычислена до цикла и не меняется. Удаление из хвоста не трогает элементы, которые ещё предстоит проверить.

ЦиклКогда братьРиск
Для Каждого … ИзПросто прочитать все значенияНет индекса; удалять нельзя
Для Индекс = 0 По ВГраница()Нужен номер или соседний элементОшибка при удалении внутри
Обратный Для Сч = 1 По ВсегоУдаление по условиюНужно аккуратно считать индекс

Вложенные и многомерные массивы

В 1С нет отдельного типа «двумерный массив». Многомерность — это массив, элементы которого тоже массивы.

Создание и чтение

Таблица = Новый Массив(3, 4); // 3 строки по 4 элемента
Таблица[0][0] = "A1";
Таблица[2][3] = "C4";

Значение = Таблица[2][3]; // "C4"

Конструктор с несколькими размерами сам создаёт вложенные массивы. Все элементы при этом равны Неопределено.

Первая пара скобок выбирает строку, вторая — элемент в ней. Индексы снова с нуля: Таблица[2][3] — третья строка, четвёртый столбец.

Вложенные массивы разной длины

Если внутренние массивы собирались вручную, их длина может отличаться. Тогда граница считается для каждого уровня отдельно:

Для Стр = 0 По Таблица.ВГраница() Цикл
    Строка = Таблица[Стр];
    Для Кол = 0 По Строка.ВГраница() Цикл
        Сообщить(Таблица[Стр][Кол]);
    КонецЦикла;
КонецЦикла;

При неизвестном содержимом проверяйте тип: Если ТипЗнч(Таблица[Стр]) = Тип("Массив") Тогда. Иначе на элементе-строке или Неопределено вторая пара скобок даст ошибку.

Массив структур

На практике чаще встречается не матрица, а массив структур. Элемент получают по индексу, а поле — через точку:

Строка = Новый Структура("Номенклатура, Количество", "Бумага А4", 10);
Позиции = Новый Массив;
Позиции.Добавить(Строка);

Количество = Позиции[0].Количество; // 10

Если поля может не быть, читайте через Позиции[0].Свойство("Количество", Значение), а не напрямую.

💡 Для данных с колонками часто удобнее ТаблицаЗначений: у неё есть поиск по колонкам, сортировка и группировка. Массив хорош для простых списков и передачи значений между клиентом и сервером.

Откуда берутся массивы: типовые случаи чтения

Чаще всего массив не создают руками, а получают из другого механизма. Знание источника подсказывает, какие проверки нужны.

  • 🧩 Разбор строки. СтрРазделить("12.05.2026", ".") возвращает массив строк. Год лежит в Части[2]. Если в строке нет точки, массив будет из одного элемента, и Части[2] упадёт. Проверяйте Части.Количество() = 3.
  • 📊 Колонка запроса. РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка") даёт массив ссылок. Если запрос пустой, массив тоже пустой.
  • 🔒 Фиксированный массив. Читается так же: ФиксМассив[0], ВГраница(), Найти(). Изменить его нельзя. Чтобы получить изменяемую копию, создайте Новый Массив(ФиксМассив).
  • 📨 Параметры с клиента на сервер. Массив передаётся в серверную процедуру, если все его элементы сериализуемы. Читать элементы на сервере — обычным индексом.

Присваивание не копирует массив

Копия = Города;
Копия[0] = "Тверь";
Сообщить(Города[0]); // "Тверь"

Обе переменные указывают на один и тот же массив. Изменение через одну видно через другую. Это легко принять за «значение элемента поменялось само». Нужна независимая копия — соберите новый массив циклом или через фиксированный массив.

Ошибки при обращении к элементам массива и как их найти

Главное сообщение платформы при неверном индексе — Значение индекса выходит за пределы диапазона. В тексте ошибки указаны модуль и номер строки, по ним сразу видно, какое обращение упало.

Диагностика: выберите симптом

Как посмотреть массив в отладчике

  1. Поставьте точку останова на строке с обращением к массиву: курсор на строку, клавиша F9.
  2. Запустите отладку и дождитесь остановки.
  3. Выделите имя массива и откройте вычисление выражения сочетанием Shift+F9.
  4. Разверните массив: отладчик покажет количество элементов и значение каждого с индексом.

Удобно сразу вычислить Массив.ВГраница() и само проблемное выражение, например Таблица[2]. Так видно, что именно лежит на нужной позиции и какого оно типа.

Можно ли в 1С обратиться к элементу массива с конца, отрицательным индексом?
Нет. Отрицательный индекс вызывает ошибку. Последний элемент берут как Массив[Массив.ВГраница()], предпоследний — как Массив[Массив.ВГраница() - 1].
Чем Массив[Индекс] отличается от Массив.Получить(Индекс)?
Результатом ничем: оба возвращают значение элемента и одинаково падают при неверном индексе. Разница только в записи.
Как получить значение элемента массива по значению, а не по номеру?
Методом Найти(Значение): он вернёт индекс или Неопределено. Затем элемент читается по найденному индексу.
Как проверить, что массив пустой?
Сравните Массив.Количество() с нулём. Обращаться к Массив[0] без этой проверки нельзя.
Можно ли получить элемент массива в языке запросов?
Нет. В запрос массив передают параметром для условия В (&Массив), а отдельный элемент читают во встроенном языке до или после запроса.