Как исправить ошибку «Индекс находится за границами массива» при разборе текстового файла в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Анализ причины возникновения ошибки

Разберем типичную ситуацию, описанную в обсуждении. Программист считывает строки из текстового файла, где данные разделены дефисом (символом "-"), и преобразует каждую строку в массив подстрок. Ошибка возникает в тот момент, когда код обращается, например, к пятому элементу массива (индекс [4]), в то время как в строке оказалось меньше разделителей, чем ожидалось, и массив содержит всего 3 или 4 элемента.

Проанализируем фрагмент проблемного кода:


Для Каждого Фаил из МассивФаилов Цикл
    Текст.Прочитать(Фаил.ПолноеИмя);
    Для НомерСтроки = 1 по Текст.КоличествоСтрок Цикл
        Стр = Текст.ПолучитьСтроку(НомерСтроки);
        МассивРеквизитов = СтрРазделить(Стр, "-", Ложь);
        
        // Попытка обращения к индексам
        Объект.Реквизит1 = МассивРеквизитов[0];
        Объект.Реквизит2 = МассивРеквизитов[1];
        Объект.Реквизит3 = МассивРеквизитов[2];
        Объект.Реквизит4 = МассивРеквизитов[3];
        Объект.Реквизит5 = МассивРеквизитов[4]; // Здесь часто происходит вылет
    КонецЦикла;
КонецЦикла;

Выясним основную причину: если в файле встретится строка вида "Товар-Склад-100-ШТ", функция СтрРазделить создаст массив из 4-х элементов (индексы от 0 до 3). Попытка получить МассивРеквизитов[4] немедленно приведет к аварийному завершению обработки.

Влияние параметра «ВключатьПустые»

В функции СтрРазделить(Стр, "-", Ложь) третий параметр Ложь играет критическую роль. Рассмотрим подробнее, как он работает:

  1. Если параметр установлен в значение Ложь, платформа игнорирует пустые подстроки. Если в данных встретятся два дефиса подряд (например, "Арт1--Склад1"), результатом будет массив из двух элементов, а не трех.
  2. Если в конце строки стоит лишний разделитель, он также не создаст новый элемент.

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

Безопасные методы работы с массивом

Чтобы наш код работал стабильно даже при наличии некорректных данных в файле, мы должны применять «оборонительное программирование». Разберем по шагам, как это реализовать.

Способ №1: Проверка количества элементов

Перед тем как присваивать значения реквизитам объекта, необходимо убедиться, что индекс существует в полученном массиве. Для этого используется метод Количество().


КолВоЭлементов = МассивРеквизитов.Количество();

Объект.Реквизит1 = ?(КолВоЭлементов > 0, МассивРеквизитов[0], "");
Объект.Реквизит2 = ?(КолВоЭлементов > 1, МассивРеквизитов[1], "");
Объект.Реквизит3 = ?(КолВоЭлементов > 2, МассивРеквизитов[2], "");

Способ №2: Использование конструкции Попытка...Исключение

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


Попытка
    Объект.Реквизит5 = МассивРеквизитов[4];
Исключение
    ЗаписьЖурналаРегистрации("Ошибка обработки строки", УровеньЖурналаРегистрации.Предупреждение,,, "Строка №" + НомерСтроки + " не содержит 5-й сегмент.");
КонецПопытки;

Проблема «невидимых» строк и символов

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

Современный подход: Переход на «ЧтениеТекста»

В новых версиях платформы 1С рекомендуется отказаться от использования объекта Текст в пользу ЧтениеТекста. Это более производительный и гибкий инструмент. Посмотрим на пример реализации правильного чтения файла:


ТекстовыйФайл = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
Стр = ТекстовыйФайл.ПрочитатьСтроку();

Пока Стр <> Неопределено Цикл
    // Пропускаем совсем пустые строки
    Если ЗначениеЗаполнено(Стр) Тогда
        МассивРеквизитов = СтрРазделить(Стр, "-", Истина);
        
        // Безопасное заполнение через цикл или проверку границ
        МаксИндекс = МассивРеквизитов.ВГраница();
        
        Если МаксИндекс >= 4 Тогда
             Объект.Реквизит5 = СокрЛП(МассивРеквизитов[4]);
        КонецЕсли;
    КонецЕсли;
    
    Стр = ТекстовыйФайл.ПрочитатьСтроку();
КонецЦикла;

Важный момент: Обратите внимание на использование метода ВГраница(). Он возвращает индекс последнего доступного элемента массива. Если массив пустой, метод вернет -1. Это идеальный способ проверки перед обращением к данным.

Итоги и рекомендации

Подводя итог, проанализируем основные правила, которые помогут навсегда забыть об ошибке «Индекс находится за границами массива»:

  1. Всегда проверяйте входящие данные. Никогда не доверяйте структуре внешнего файла на 100%.
  2. Используйте метод Массив.Количество() или Массив.ВГраница() перед любым обращением по индексу.
  3. Очищайте данные. Применяйте СокрЛП() к результатам разделения строки, чтобы избежать проблем с лишними пробелами.
  4. Следите за пустой строкой в конце файла. Добавляйте условие Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда... внутрь цикла обработки.

Соблюдение этих простых принципов сделает ваш код устойчивым к ошибкам и обеспечит корректную загрузку данных из любых текстовых источников.

← На главную