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