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

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

Ошибка «Индекс находится за границами массива» в 1С: причины и способы исправления

Разбираем ошибку «Индекс находится за границами массива» в 1С: почему возникает, как найти строку с ошибкой, исправить код и проверить данные.

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

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

Хорошая новость в том, что это не сбой базы данных и не «поломка платформы» — в подавляющем большинстве случаев данные не повреждаются. Ошибку можно локализовать за несколько минут, если знать, где искать, и устранить либо исправлением кода, либо корректировкой данных, которые этот код обрабатывает.

Что именно означает эта ошибка

Встроенный язык 1С работает с несколькими типами коллекций, к которым применимо индексированное обращение: массивы, таблицы значений, строки (обращение к символу по номеру), коллекции строк дерева значений, а также результат разбиения строки функцией СтрРазделить(). У каждой коллекции есть границы: от нуля до Количество() - 1.

Когда код выполняет обращение вида Массив[5] при размере массива 3, платформа не может вернуть значение — элемента с таким номером просто нет. Вместо аварийного завершения всей программы 1С выбрасывает управляемое исключение с текстом «Индекс находится за границами массива» и останавливает текущий обработчик.

Важно понимать: текст ошибки не говорит, какая именно коллекция оказалась «короче» ожиданий. Это может быть массив из пяти строк файла загрузки, колонки табличной части, части ФИО после разбиения по пробелам или строки результата запроса. Поэтому диагностика всегда начинается с поиска конкретной строки кода.

Где возникает ошибка: типичные сценарии

На практике ситуации повторяются, и их можно разбить на несколько характерных групп. Знание сценария сразу сужает область поиска.

Собственный код и доработки

Самый частый случай — обращение к элементу без проверки размера коллекции. Примеры: ЧастиСтроки[2] после разбиения строки, в которой оказалось только две части; ТаблицаТоваров[НомерСтроки], когда номер вычислен неверно; обращение к РезультатЗапроса.Выгрузить()[0], когда запрос ничего не вернул.

Загрузка и обмен данными

Обработки загрузки из Excel, CSV или XML часто рассчитывают на строгое число колонок. Если в файле пропущена колонка, лишний разделитель или пустая строка, код, обращающийся к Колонки[7], упадёт с этой ошибкой. То же происходит при обмене, когда формат данных изменился, а правила конвертации — нет.

Типовые конфигурации без доработок

Если ошибка возникает в типовой конфигурации при проведении документа или формировании отчёта, причина обычно в данных: незаполненное обязательное поле, некорректное значение в регистре, «битая» ссылка. Реже — известная ошибка конкретного релиза, исправленная в следующих обновлениях.

Ошибка в тексте модуля с номером строкиПроблема в коде

Открыть указанный модуль и строку, проверить обращение к коллекции

Ошибка только на конкретном документе или файлеПроблема в данных

Проверить заполненность полей, количество колонок, пустые строки

Ошибка появилась после обновленияНесовместимость версий

Проверить доработки, внешние обработки и список исправленных ошибок релиза

Ошибка у всех пользователей на одной операцииСистемная причина

Воспроизвести в копии базы и локализовать через отладчик

Как найти строку кода с ошибкой

Окно ошибки в 1С обычно содержит не только текст, но и указание на место: имя модуля и номер строки в формате {ОбщийМодуль.ЗагрузкаДанных.Модуль(145)}. Это первое, на что нужно смотреть. Если окно закрыто, ту же информацию можно найти в журнале регистрации (раздел «Администрирование» → «Журнал регистрации») — там ошибка фиксируется с полным контекстом.

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

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

Порядок действий при появлении ошибки
  1. 1
    Сфотографируйте или скопируйте полный текст ошибки с указанием модуля и строки
  2. 2
    Проверьте журнал регистрации — там может быть расширенный контекст
  3. 3
    Определите, повторяется ли ошибка на других данных или только на конкретных
  4. 4
    Если есть доступ к конфигуратору — включите остановку по ошибке и воспроизведите ситуацию
  5. 5
    В отладчике сравните значение индекса и размер коллекции (Количество())
  6. 6
    Исправьте код или данные, затем повторите операцию на тех же данных для проверки

Как исправить ошибку в коде

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

Типовой безопасный шаблон выглядит так:

Части = СтрРазделить(СтрокаДанных, ";");

Если Части.Количество() >= 3 Тогда

Артикул = Части[2];

Иначе

// обработка неполной строки: пропуск, сообщение, значение по умолчанию

КонецЕсли;

Аналогично для таблиц значений и результатов запросов: перед обращением к Таблица[0] проверяйте Таблица.Количество() > 0. Для перебора всех элементов вместо цикла по индексу надёжнее использовать цикл Для Каждого Элемент Из Коллекция Цикл — он в принципе не может выйти за границы.

Отдельный частый дефект — неправильная граница цикла: Для Инд = 0 По Массив.Количество() Цикл вместо Количество() - 1. Такой цикл всегда падает на последней итерации, потому что максимальный допустимый индекс на единицу меньше количества элементов.

bsl
// Небезопасно:
Значение = Массив[Индекс];

// Безопасно:
Если Индекс >= 0 И Индекс < Массив.Количество() Тогда
    Значение = Массив[Индекс];
КонецЕсли;

Когда проблема в данных, а не в коде

Если код типовой или давно работал, а ошибка появилась внезапно, почти всегда виноваты входные данные. Типичные примеры: в файле загрузки появилась строка с меньшим числом колонок; в справочнике у элемента не заполнено поле, которое код разбирает на части; в документе пустая табличная часть, которую обработка пытается прочитать по индексу.

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

Исправлять такую ситуацию нужно на двух уровнях: устранить конкретные некорректные данные (заполнить поле, поправить файл) и, если есть возможность, добавить в код проверку, чтобы в следующий раз вместо падения пользователь получил понятное сообщение вида «В строке 15 файла отсутствует колонка "Артикул"».

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

Как выбрать действие

Ошибка указывает на модуль доработки или внешней обработкиИсправляйте код: добавьте проверку размера коллекции перед обращением по индексу
Ошибка в типовом коде и только на конкретных данныхИщите и исправляйте данные: незаполненные поля, пустые табличные части, некорректный файл
Ошибка появилась сразу после обновления конфигурацииПроверьте совместимость доработок и внешних обработок с новым релизом, изучите список исправленных ошибок
Ошибка в типовом коде на любых данныхПроверьте, не исправлена ли она в более свежем релизе, и обратитесь к разработчику конфигурации

Ошибка в типовой конфигурации: что делать пользователю

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

Второй шаг — проверить актуальность релиза. Известные ошибки типового кода вендор исправляет в обновлениях; если ваша версия сильно устарела, есть шанс, что проблема уже решена. Обновление в рабочей базе выполняйте только после создания резервной копии и желательно после проверки на копии базы.

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

Профилактика: как не допустить повторения

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

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

Для пользователей профилактика сводится к дисциплине: своевременные обновления, аккуратное заполнение обязательных полей, проверка файлов загрузки на соответствие шаблону перед запуском обработки. Большинство «внезапных» ошибок такого рода — следствие изменившихся входных данных, а не деградации программы.

Типичные ошибки
01
Цикл «Для Инд = 0 По Массив.Количество()» вместо «Количество() - 1» — падение на последней итерации
02
Обращение к РезультатЗапроса.Выгрузить()[0] без проверки, что запрос что-то вернул
03
Разбор строки через СтрРазделить и обращение к фиксированному индексу без проверки числа частей
04
Правка типового кода в рабочей базе без копии — риск потери данных и проблем с обновлением
05
Игнорирование номера строки в тексте ошибки и поиск причины «методом тыка»
Контрольные точки

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

Повтор операции на тех же данных
Норма

Операция завершается без ошибки

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

Ошибка воспроизводится — причина не устранена

Повтор на других данных
Норма

Работает и на ранее проблемных, и на обычных данных

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

Работает только на «хороших» данных — проверка границ не добавлена

Журнал регистрации после исправления
Норма

Нет новых записей об ошибке

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

Ошибка появляется в другом месте — обращений по индексу без проверки несколько

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

Может ли эта ошибка повредить данные в базе?

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

Ошибка возникает только у одного пользователя. Что это значит?

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

Нумерация в 1С начинается с нуля или с единицы?

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

Поможет ли тестирование и исправление базы (chdbfl или конфигуратор)?

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

Ошибка появилась после обновления конфигурации. Откатывать обновление?

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

Как быстро понять, какая коллекция «вылетела», если в тексте ошибки этого нет?

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

Итог

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

Ошибка означает обращение к несуществующему элементу коллекции и не повреждает базу. Начинайте с номера строки в тексте ошибки, проверяйте размер коллекции перед обращением по индексу, а при типовом коде ищите причину в данных или устаревшем релизе. Любые правки кода — только после резервной копии и проверки на копии базы.