Обращение к элементу массива во встроенном языке 1С:Предприятия 8.3: индексы, проверки, циклы и вложенные массивы
Содержание
Значение элемента массива в 1С получают по индексу в квадратных скобках: Значение = Массив[0];. Нумерация начинается с нуля, поэтому первый элемент — Массив[0], а последний — Массив[Массив.ВГраница()]. Тот же результат даёт метод Массив.Получить(Индекс).
Правила одинаковы для всего встроенного языка платформы 8.3: обработки, общие модули, модули форм, внешние отчёты. От конфигурации (БП, ЗУП, УТ) ничего не зависит. Чаще всего проблемы возникают не с самим синтаксисом, а с границами: пустой массив, счёт с единицы вместо нуля, удаление элементов в цикле.
Синтаксис: как обратиться к элементу массива по индексу
Массив во встроенном языке 1С — упорядоченная коллекция значений любого типа. В одном массиве могут лежать число, строка, ссылка на справочник и даже другой массив.
Прочитать элемент можно двумя способами:
Города = Новый Массив;
Города.Добавить("Москва");
Города.Добавить("Казань");
Города.Добавить("Пермь");
Первый = Города[0]; // "Москва"
Второй = Города.Получить(1); // "Казань"
Оба способа работают одинаково, включая реакцию на неверный индекс. Квадратные скобки короче и читаются привычнее, поэтому в типовых конфигурациях встречаются чаще.
Изменить значение тоже можно двумя способами: присваиванием Города[2] = "Самара"; или методом Города.Установить(2, "Самара");.
Методы массива, которые нужны для чтения
| Метод | Что возвращает | Пример |
|---|---|---|
Количество() | Число элементов | 3 |
ВГраница() | Наибольший индекс, для пустого массива −1 | 2 |
Получить(Индекс) | Значение элемента | “Казань” |
Найти(Значение) | Индекс найденного элемента или Неопределено | 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]); // "Тверь"
Обе переменные указывают на один и тот же массив. Изменение через одну видно через другую. Это легко принять за «значение элемента поменялось само». Нужна независимая копия — соберите новый массив циклом или через фиксированный массив.
Ошибки при обращении к элементам массива и как их найти
Главное сообщение платформы при неверном индексе — Значение индекса выходит за пределы диапазона. В тексте ошибки указаны модуль и номер строки, по ним сразу видно, какое обращение упало.
Как посмотреть массив в отладчике
- Поставьте точку останова на строке с обращением к массиву: курсор на строку, клавиша
F9. - Запустите отладку и дождитесь остановки.
- Выделите имя массива и откройте вычисление выражения сочетанием
Shift+F9. - Разверните массив: отладчик покажет количество элементов и значение каждого с индексом.
Удобно сразу вычислить Массив.ВГраница() и само проблемное выражение, например Таблица[2]. Так видно, что именно лежит на нужной позиции и какого оно типа.