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

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

Значение индекса выходит за границы диапазона в 1С: причины и исправление

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

Ошибка «Значение индекса находится за границами массива» (в диалогах также встречается формулировка «выходит за границы диапазона») — одна из самых частых проблем при работе с 1С. Она возникает, когда программа пытается обратиться к элементу массива, таблицы значений, строки или коллекции по номеру, которого в этой коллекции нет. Например, массив содержит три элемента (индексы 0, 1, 2), а код запрашивает элемент с индексом 3 или -1.

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

Хорошая новость в том, что ошибка почти всегда локализуема: платформа указывает строку модуля, где произошло обращение за границу коллекции. Зная это место и понимая типичные сценарии, проблему можно устранить за короткое время, не прибегая к переустановке программы или восстановлению базы.

Что означает ошибка и когда она возникает

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

Типичные ситуации появления ошибки:

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

Как найти место ошибки в коде

Текст сообщения об ошибке обычно содержит указание на модуль и номер строки, например: «{Документ.РеализацияТоваровУслуг.МодульОбъекта(145)}: Значение индекса находится за границами массива». Число в скобках — это номер строки в указанном модуле. Именно с этой строки начинается диагностика.

Порядок поиска места сбоя:

  1. Скопируйте полный текст ошибки или сфотографируйте окно до нажатия «ОК».
  2. Откройте конфигуратор и найдите указанный объект и модуль.
  3. Перейдите к строке с указанным номером (Ctrl+G или меню «Правка — Перейти к строке»).
  4. Определите, к какой коллекции идёт обращение в этой строке, и проследите, откуда берётся индекс.

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

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

Типичные сценарии и способы исправления

Ошибка в цикле перебора коллекции

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

// Неправильно: последняя итерация даст индекс за границей

Для Инд = 0 По Массив.Количество() Цикл

Значение = Массив[Инд];

КонецЦикла;

// Правильно

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

Значение = Массив[Инд];

КонецЦикла;

Более надёжная альтернатива — цикл «Для Каждого», который вообще исключает ручную работу с индексами:

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

// работа с Элемент напрямую

КонецЦикла;

Обращение к пустому результату запроса или разбору строки

Код вида «Выборка[0]» или «ЧастиСтроки[1]» без проверки, что элементы вообще есть, — второй по частоте источник проблемы. Перед обращением по индексу всегда проверяйте размер:

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

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

ВтороеПоле = Части[1];

Иначе

// обработка ситуации: частей меньше, чем ожидалось

КонецЕсли;

Удаление строк и устаревшие индексы

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

Типичные ошибки при исправлении
01
Использовать Количество() как верхнюю границу цикла без вычитания единицы — ошибка останется на последней итерации
02
Удалять строки таблицы при прямом обходе по индексу — индексы сдвигаются и цикл выходит за границу
03
Исправлять симптом через Попытка/Исключение без анализа причины — ошибка маскируется и проявляется в другом месте
04
Править код в рабочей базе без копии — при неудачном изменении откат затруднён

Что делать пользователю без доступа к коду

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

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

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

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

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

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

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

Полезные приёмы профилактики при разработке:

  • используйте «Для Каждого» вместо индексных циклов, где не нужен сам индекс;
  • перед обращением по индексу проверяйте Количество() или используйте метод ВГраница() для массивов;
  • после СтрРазделить и подобных функций всегда проверяйте число полученных частей;
  • не храните индексы строк между операциями, изменяющими коллекцию — храните сами строки или их ключевые значения;
  • покрывайте алгоритмы, работающие с коллекциями, проверками на пустые и минимальные наборы данных.
Контрольные точки

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

Повторный запуск операции, вызывавшей ошибку
Норма

Операция завершается штатно, данные корректны

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

Ошибка повторяется или появляется другое исключение

Запуск с пустой коллекцией (без строк/данных)
Норма

Код отрабатывает без обращения по индексу, срабатывает ветка проверки

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

Снова возникает ошибка выхода за границы

Запуск с минимальным набором (один элемент)
Норма

Обрабатывается ровно один элемент, цикл завершается корректно

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

Лишняя итерация или пропуск единственного элемента

Когда обращаться к специалисту и что ему передать

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

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

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

Итог

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

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

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

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

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

Можно ли просто обернуть проблемный код в Попытка/Исключение?

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

Ошибка появляется в типовой конфигурации без доработок. Кто виноват?

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

Как быстро проверить массив перед обращением к элементу?

Используйте сравнение размера: «Если Массив.Количество() > Индекс Тогда». Для массивов также удобен метод ВГраница(), возвращающий максимально допустимый индекс: условие «Индекс <= Массив.ВГраница()» гарантирует, что обращение будет корректным.

Ошибка возникает при обмене данными или загрузке файла. Что проверить в первую очередь?

Проверьте структуру входящих данных: состав полей, разделители, количество колонок в файле могли измениться на стороне источника. Код загрузки, рассчитанный на фиксированное число частей, падает именно при расхождении структуры. Сравните актуальный файл с эталонным, который загружался успешно.

Нужно ли запускать тестирование и исправление базы при этой ошибке?

Нет, эта ошибка относится к логике кода, а не к повреждению данных. Тестирование и исправление её не устранит. Запускать эту процедуру имеет смысл только если есть независимые признаки повреждения базы: сбои при чтении таблиц, ошибки СУБД, внезапные отключения сервера перед появлением проблемы.