Индекс находится за границами массива в 1С: как исправить

Дата: 10.10.2026 08:35:46
Ошибки 1С
Массив
Коллекции значений
Встроенный язык
Отладка
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Индекс находится за границами массива в 1С — ошибка времени выполнения: код обратился к элементу коллекции по номеру, которого в ней нет. Индексы считаются с нуля, поэтому у коллекции из трёх элементов последний индекс — 2, а [3], [-1] или [0] у пустой коллекции дают одно и то же сообщение. Так падают массив, таблица значений, табличная часть, данные формы, список значений и строка таблицы значений, если колонку берут по номеру. Ниже — причины с защитным кодом, поиск места ошибки и разбор случая после обновления типовой.

Где встречается ошибка

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

Код в строке ошибкиЧто пошло не так
Для Инд = 0 По Товары.Количество() Циклиндекс доходит до количества строк
Товары[СтрокаТЧ.НомерСтроки]номер строки считается с 1, индекс — с 0
Товары.Удалить(Инд) в цикле Для … Пограница цикла вычислена до удалений
СтрРазделить(Стр, ";")[2]полей меньше, чем ждали
Запрос.Выполнить().Выгрузить()[0]запрос ничего не вернул
Запрос.ВыполнитьПакет()[3]запросов в пакете стало меньше
СтрокаПрайса[3]в таблице меньше колонок
Объект.Товары[Элементы.Товары.ТекущаяСтрока]это идентификатор строки, а не индекс
Элементы.Список.ВыделенныеСтроки[0], Элементы.Склад.СписокВыбора[0]список пуст или ничего не выделено

Условие для всех случаев одно: индекс не меньше нуля и меньше Количество(). Устройство массива и разница между ВГраница() и Количество() — в статье Массив в 1С 8.3.

Индекс находится за границами массива в 1С: как найти место ошибки

Полный текст: {ОбщийМодуль.ЗагрузкаПрайсов.Модуль(214)}: Индекс находится за границами массива — в фигурных скобках модуль и номер строки. Если исключение выбросил метод коллекции, перед текстом стоит его имя: Ошибка при вызове метода контекста (Получить): Индекс находится за границами массива.

  1. Откройте модуль в конфигураторе и перейдите к строке (Ctrl+G). Если обращений по индексу несколько, ищите то, что ломается на пустой или короткой коллекции.
  2. В окне «Отладка → Остановка по ошибке» включите «Останавливаться по ошибке» и «Останавливаться только на ошибках, содержащих текст», добавьте строку «за границами массива». Под отладкой выполнение встанет на строке ошибки, даже внутри Попытка.
  3. Вычислите размер коллекции и индекс (Shift+F9), в «Стеке вызовов» найдите, откуда пришла короткая коллекция. Подробнее — в статье Отладка 1С 8.3.

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

// Общий модуль РаботаСКоллекциями: флажки «Клиент (управляемое приложение)»,
// «Сервер», «Внешнее соединение».
// Подходит для массива, списка значений, таблицы значений, табличной части
// и данных формы: у всех есть Количество() и обращение [Индекс].

// Истина, если элемент с таким индексом есть в коллекции
Функция ИндексВГраницах(Коллекция, Индекс) Экспорт

	Если ТипЗнч(Индекс) <> Тип("Число") Тогда
		Возврат Ложь; // например, Неопределено из Найти()
	КонецЕсли;

	Возврат Индекс >= 0 И Индекс < Коллекция.Количество();

КонецФункции

// Элемент по индексу. Вместо «Индекс находится за границами массива»
// исключение называет коллекцию, индекс и фактический размер.
Функция ЭлементПоИндексу(Коллекция, Индекс, ИмяКоллекции) Экспорт

	Если Не ИндексВГраницах(Коллекция, Индекс) Тогда
		ВызватьИсключение СтрШаблон("%1: нет элемента с индексом %2, всего элементов %3",
			ИмяКоллекции, Индекс, Коллекция.Количество());
	КонецЕсли;

	Возврат Коллекция[Индекс];

КонецФункции

// Последний элемент или ЗначениеПоУмолчанию, если коллекция пустая
Функция ПоследнийЭлемент(Коллекция, ЗначениеПоУмолчанию = Неопределено) Экспорт

	ВсегоЭлементов = Коллекция.Количество();
	Если ВсегоЭлементов = 0 Тогда
		Возврат ЗначениеПоУмолчанию;
	КонецЕсли;

	Возврат Коллекция[ВсегоЭлементов - 1];

КонецФункции

Вызов РаботаСКоллекциями.ЭлементПоИндексу(Поля, 2, "Поля строки прайса") вместо Поля[2] даёт текст «Поля строки прайса: нет элемента с индексом 2, всего элементов 2» — причина видна без отладчика.

Индекс с нуля, номер строки с единицы

С нуля считаются только индексы. Всё, что видит пользователь, нумеруется с единицы: НомерСтроки, строки и колонки табличного документа, позиция в СтрНайти(). Ошибка на единицу даёт два симптома: код берёт соседнюю строку, а на последней падает. У таблицы значений и табличной части нет ВГраница(), последний индекс — Количество() - 1. Вторая частая причина — общий индекс для двух таблиц разной длины.

// Сервер: модуль документа, обработки или общий модуль.
// ТоварыЗаказа, ТоварыРеализации — табличные части или таблицы значений
// с колонками Номенклатура и Количество.
//
// Было:
//	Для Индекс = 0 По ТоварыЗаказа.Количество() Цикл
//		СтрокаЗаказа = ТоварыЗаказа[Индекс];
//		СтрокаРеализации = ТоварыРеализации[Индекс];
// ТоварыЗаказа[Индекс] выходит за границу на последнем проходе (индекс равен
// количеству строк), ТоварыРеализации[Индекс] — раньше, если в реализации строк меньше.
Функция РасхожденияПоСтрокам(ТоварыЗаказа, ТоварыРеализации) Экспорт

	Расхождения = Новый Массив;
	ОбщихСтрок = Мин(ТоварыЗаказа.Количество(), ТоварыРеализации.Количество());

	// У таблиц нет ВГраница(): последний индекс равен Количество() - 1
	Для Индекс = 0 По ОбщихСтрок - 1 Цикл
		СтрокаЗаказа = ТоварыЗаказа[Индекс];
		СтрокаРеализации = ТоварыРеализации[Индекс];
		Если СтрокаЗаказа.Номенклатура <> СтрокаРеализации.Номенклатура
			Или СтрокаЗаказа.Количество <> СтрокаРеализации.Количество Тогда
			// Пользователю — номер строки, он на единицу больше индекса
			Расхождения.Добавить(СтрШаблон("Строка %1: в заказе %2 (%3), в реализации %4 (%5)",
				Индекс + 1, СтрокаЗаказа.Номенклатура, СтрокаЗаказа.Количество,
				СтрокаРеализации.Номенклатура, СтрокаРеализации.Количество));
		КонецЕсли;
	КонецЦикла;

	Если ТоварыЗаказа.Количество() <> ТоварыРеализации.Количество() Тогда
		Расхождения.Добавить(СтрШаблон("Строк в заказе: %1, в реализации: %2",
			ТоварыЗаказа.Количество(), ТоварыРеализации.Количество()));
	КонецЕсли;

	Возврат Расхождения;

КонецФункции

// Строка табличной части по НомерСтроки (из запроса или из текста сообщения).
// Было: Возврат Товары[НомерСтроки];
// Номер считается с 1, индекс с 0: код берёт следующую строку, а на последней падает.
Функция СтрокаПоНомеру(Товары, НомерСтроки) Экспорт

	Индекс = НомерСтроки - 1;
	Если Индекс < 0 Или Индекс >= Товары.Количество() Тогда
		Возврат Неопределено; // строку удалили после того, как получили номер
	КонецЕсли;

	Возврат Товары[Индекс];

КонецФункции
  • Мин() ограничивает цикл короткой таблицей, а разница в длине уходит в сообщение, а не в исключение.
  • Построчное сравнение годится, когда строки идут в одном порядке; иначе сопоставляйте по номенклатуре.

Удаление строк в цикле по индексу

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

// Сервер или клиент: табличная часть, таблица значений, данные формы.
//
// Было:
//	Для Индекс = 0 По Товары.Количество() - 1 Цикл
//		Если Товары[Индекс].Количество = 0 Тогда
//			Товары.Удалить(Индекс);
//		КонецЕсли;
//	КонецЦикла;
// Граница цикла вычислена до первого удаления. Строк становится меньше,
// последние индексы указывают за конец таблицы, а строка, вставшая
// на место удалённой, не проверяется.

// Условие на равенство: строки находит НайтиСтроки(), удаляем по самой строке
Процедура УдалитьСтрокиБезКоличества(Товары) Экспорт

	НайденныеСтроки = Товары.НайтиСтроки(Новый Структура("Количество", 0));
	Для Каждого СтрокаТоваров Из НайденныеСтроки Цикл
		Товары.Удалить(СтрокаТоваров);
	КонецЦикла;

КонецПроцедуры

// Сложное условие: сначала собираем строки, потом удаляем
Процедура УдалитьНезаполненныеСтроки(Товары) Экспорт

	КУдалению = Новый Массив;
	Для Каждого СтрокаТоваров Из Товары Цикл
		Если Не ЗначениеЗаполнено(СтрокаТоваров.Номенклатура) Или СтрокаТоваров.Количество <= 0 Тогда
			КУдалению.Добавить(СтрокаТоваров);
		КонецЕсли;
	КонецЦикла;

	Для Каждого СтрокаТоваров Из КУдалению Цикл
		Товары.Удалить(СтрокаТоваров);
	КонецЦикла;

КонецПроцедуры

// Массив значений: ничего не удаляем, собираем новый
Функция БезПустыхЗначений(Значения) Экспорт

	Результат = Новый Массив;
	Для Каждого Значение Из Значения Цикл
		Если ЗначениеЗаполнено(Значение) Тогда
			Результат.Добавить(Значение);
		КонецЕсли;
	КонецЦикла;

	Возврат Результат;

КонецФункции
  • НайтиСтроки() возвращает отдельный массив, удаление из таблицы его не сокращает.
  • По синтакс-помощнику Массив.Удалить() с индексом больше ВГраница() ничего не делает и ошибку не выдаёт — в прямом цикле падает чтение Массив[Индекс] в условии.

СтрРазделить вернул меньше частей

Разбор файлов, выгрузок ТСД и ФИО — главный источник ошибки в загрузках: в данных попадаются пустые строки, строки без последнего поля и двойные пробелы. Многое решает третий параметр ВключатьПустые:

СтрокаСтрРазделить(С, ";")СтрРазделить(С, ";", Ложь)
пустая1 элемент — пустая строка0 элементов
4601234567890;22 элемента2 элемента
4601234567890;;1503, средний пустой2 — цена встала на место количества

Для полей по позициям Ложь не ставьте — пустое поле сдвинет следующие. Для списка слов, наоборот, нужен Ложь. Функция БСП СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок() без третьего параметра для пустой строки возвращает пустой массив (с разделителем-пробелом — массив из одной пустой строки), поэтому замена одной функции другой меняет число элементов.

// Клиент или сервер: разбор строки из файла ТСД "штрихкод;количество;цена".
// Цена есть не в каждой строке, в конце файла бывает пустая строка.
//
// Было:
//	Части = СтрРазделить(СтрокаФайла, ";");
//	Штрихкод = Части[0];
//	Количество = Число(Части[1]);
//	Цена = Число(Части[2]);
// Строка без цены — два элемента, и Части[2] за границей;
// пустая строка — один пустой элемент, и падает уже Части[1].
Функция РазобратьСтрокуТСД(СтрокаФайла, ТекстОшибки) Экспорт

	ТекстОшибки = "";
	Если ПустаяСтрока(СтрокаФайла) Тогда
		Возврат Неопределено; // пустую строку пропускаем без ошибки
	КонецЕсли;

	// Третий параметр не указан (Истина): пустое поле в середине
	// остаётся на своём месте и не сдвигает цену на место количества
	Части = СтрРазделить(СтрокаФайла, ";");
	Если Части.Количество() < 2 Тогда
		ТекстОшибки = СтрШаблон("Меньше двух полей в строке: %1", СтрокаФайла);
		Возврат Неопределено;
	КонецЕсли;

	Результат = Новый Структура("Штрихкод, Количество, Цена", СокрЛП(Части[0]), 0, 0);
	Результат.Количество = ЧислоИзТекста(Части[1]);
	Если Части.Количество() > 2 Тогда // цена необязательна
		Результат.Цена = ЧислоИзТекста(Части[2]);
	КонецЕсли;

	Возврат Результат;

КонецФункции

// Нечисловой текст даёт 0, а не исключение
Функция ЧислоИзТекста(Текст)

	ТипЧисло = Новый ОписаниеТипов("Число");
	Возврат ТипЧисло.ПривестиЗначение(СтрЗаменить(СокрЛП(Текст), ",", "."));

КонецФункции

// Фамилия, имя и отчество из одной строки.
// Было: Отчество = Слова[2]; — у сотрудника без отчества два слова.
Функция ЧастиФИО(ФИО) Экспорт

	Результат = Новый Структура("Фамилия, Имя, Отчество", "", "", "");
	// Здесь Ложь: двойной пробел не должен давать пустое слово
	Слова = СтрРазделить(СокрЛП(ФИО), " ", Ложь);

	Если Слова.Количество() > 0 Тогда
		Результат.Фамилия = Слова[0];
	КонецЕсли;
	Если Слова.Количество() > 1 Тогда
		Результат.Имя = Слова[1];
	КонецЕсли;
	Если Слова.Количество() > 2 Тогда
		// Всё после имени — отчество, в том числе из двух слов
		Слова.Удалить(1);
		Слова.Удалить(0);
		Результат.Отчество = СтрСоединить(Слова, " ");
	КонецЕсли;

	Возврат Результат;

КонецФункции

Условие проверки всегда на единицу больше максимального индекса: для Части[2] — Части.Количество() > 2. Другие функции — в справочнике Строковые функции 1С.

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

Запрос.Выполнить().Выгрузить()[0] работает, пока запрос что-то находит. Нет данных или прав на часть записей — таблица пустая. Первую запись берут через Выбрать() и Следующий(), другие проверки — в статье Пустой запрос 1С.

У пакета своя ловушка: ВыполнитьПакет() возвращает результаты в порядке запросов в тексте, включая служебные: для ПОМЕСТИТЬ — результат с числом записей, для УНИЧТОЖИТЬ — Неопределено. Результаты[3] ломается, как только в пакет добавили или убрали временную таблицу, например в типовом запросе после обновления. Надёжнее искать результат по колонкам.

// Сервер. Товар по артикулу.
// Было: Возврат Запрос.Выполнить().Выгрузить()[0].Ссылка;
// Артикула нет в базе — таблица пустая, строки с индексом 0 в ней нет.
Функция ТоварПоАртикулу(Артикул) Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	Номенклатура.Ссылка КАК Ссылка
		|ИЗ
		|	Справочник.Номенклатура КАК Номенклатура
		|ГДЕ
		|	Номенклатура.Артикул = &Артикул
		|	И НЕ Номенклатура.ЭтоГруппа
		|	И НЕ Номенклатура.ПометкаУдаления";
	Запрос.УстановитьПараметр("Артикул", Артикул);

	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() Тогда
		Возврат Выборка.Ссылка;
	КонецЕсли;

	Возврат Справочники.Номенклатура.ПустаяСсылка();

КонецФункции

// Результат пакета по составу колонок, а не по номеру.
// Было: Товары = Запрос.ВыполнитьПакет()[3].Выгрузить();
// Из пакета убрали временную таблицу — результатов стало три, и [3] за границей;
// добавили — код молча берёт чужой результат.
// Вызов: РезультатСКолонками(Запрос.ВыполнитьПакет(), "Номенклатура, Склад, Количество")
Функция РезультатСКолонками(Результаты, ИменаКолонок) Экспорт

	НужныеКолонки = СтрРазделить(ИменаКолонок, ",", Ложь);
	Индекс = Результаты.ВГраница(); // с конца: итоговая выборка обычно последняя
	Пока Индекс >= 0 Цикл
		Результат = Результаты[Индекс];
		Индекс = Индекс - 1;
		Если Результат = Неопределено Тогда
			Продолжить; // так в массиве выглядит запрос УНИЧТОЖИТЬ
		КонецЕсли;
		ВсеКолонкиЕсть = Истина;
		Для Каждого ИмяКолонки Из НужныеКолонки Цикл
			Если Результат.Колонки.Найти(СокрЛП(ИмяКолонки)) = Неопределено Тогда
				ВсеКолонкиЕсть = Ложь;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если ВсеКолонкиЕсть Тогда
			Возврат Результат;
		КонецЕсли;
	КонецЦикла;

	Возврат Неопределено;

КонецФункции

Ищите по двум-трём характерным колонкам: у служебного результата ПОМЕСТИТЬ тоже есть колонка. Что вернул каждый запрос пакета, видно в бесплатной консоли запросов.

Строка таблицы значений: колонка по номеру

Строка таблицы значений отдаёт значение и по номеру колонки: СтрокаТаблицы[3] — четвёртая колонка. Так читают таблицы из файлов, где колонки без имён: у одного поставщика их четыре, у другого три, и [3] падает на первой строке. Колонки проверяют один раз до цикла. Подробнее о таблице — в статье Таблица значений 1С.

// Сервер. Таблица — прайс из файла, колонки по порядку: 0 — артикул,
// 1 — наименование, 2 — цена, 3 — остаток (есть не у всех поставщиков).
// Было: Позиция.Остаток = СтрокаПрайса[3];
// В прайсе без остатков три колонки — ошибка на первой же строке.
Функция ПозицииПрайса(Таблица) Экспорт

	ЧислоКолонок = Таблица.Колонки.Количество();
	Если ЧислоКолонок < 3 Тогда
		ВызватьИсключение СтрШаблон(
			"В прайсе колонок: %1. Нужны минимум артикул, наименование и цена", ЧислоКолонок);
	КонецЕсли;
	ЕстьОстаток = ЧислоКолонок > 3;

	Позиции = Новый Массив;
	Для Каждого СтрокаПрайса Из Таблица Цикл
		Позиция = Новый Структура("Артикул, Наименование, Цена, Остаток");
		Позиция.Артикул = СтрокаПрайса[0];
		Позиция.Наименование = СтрокаПрайса[1];
		Позиция.Цена = СтрокаПрайса[2];
		Если ЕстьОстаток Тогда
			Позиция.Остаток = СтрокаПрайса[3];
		КонецЕсли;
		Позиции.Добавить(Позиция);
	КонецЦикла;

	Возврат Позиции;

КонецФункции

Данные формы: идентификатор вместо индекса

Элементы.Товары.ТекущаяСтрока и элементы ВыделенныеСтроки — идентификаторы строк данных формы, а не индексы. Идентификатор закреплён за строкой и не обязан совпадать с её позицией, особенно после удалений, поэтому Объект.Товары[Элементы.Товары.ТекущаяСтрока] берёт чужую строку или выходит за границу — строку ищут через НайтиПоИдентификатору(). В динамическом списке ВыделенныеСтроки[0] падает, если список пуст, — см. Строки динамического списка 1С; так же ведёт себя пустой список значений в СписокВыбора.

// Модуль формы документа с табличной частью Товары.

&НаКлиенте
Процедура ЦенуТекущейСтрокиВоВсеСтроки(Команда)

	// Было: Образец = Объект.Товары[Элементы.Товары.ТекущаяСтрока];
	// ТекущаяСтрока — идентификатор строки, а не индекс. После удаления
	// строк он может оказаться больше их количества, и обращение
	// по нему выходит за границу.
	Идентификатор = Элементы.Товары.ТекущаяСтрока;
	Если Идентификатор = Неопределено Тогда
		Возврат; // в таблице нет строк
	КонецЕсли;
	Образец = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
	Если Образец = Неопределено Тогда
		Возврат;
	КонецЕсли;

	// Цена текущей строки — во все строки с тем же товаром
	// (пересчёт суммы упрощён: без скидок и НДС)
	Для Каждого СтрокаТоваров Из Объект.Товары Цикл
		Если СтрокаТоваров.Номенклатура = Образец.Номенклатура Тогда
			СтрокаТоваров.Цена = Образец.Цена;
			СтрокаТоваров.Сумма = СтрокаТоваров.Цена * СтрокаТоваров.Количество;
		КонецЕсли;
	КонецЦикла;
	Модифицированность = Истина;

КонецПроцедуры

&НаКлиенте
Процедура УдалитьВыделенныеСтроки(Команда)

	// Было: Объект.Товары.Удалить(Идентификатор) в цикле по ВыделенныеСтроки.
	// Число Удалить() понимает как индекс, а не идентификатор:
	// удаляются не те строки.
	СтрокиКУдалению = Новый Массив;
	Для Каждого Идентификатор Из Элементы.Товары.ВыделенныеСтроки Цикл
		СтрокаТоваров = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
		Если СтрокаТоваров <> Неопределено Тогда
			СтрокиКУдалению.Добавить(СтрокаТоваров);
		КонецЕсли;
	КонецЦикла;

	Для Каждого СтрокаТоваров Из СтрокиКУдалению Цикл
		Объект.Товары.Удалить(СтрокаТоваров);
	КонецЦикла;
	Модифицированность = Истина;

КонецПроцедуры

Удаление идёт по найденным строкам, а не по числам. Больше о курсоре — в статье Таблица формы 1С.

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

Порядок разбора, если ошибка появилась сразу после обновления:

  1. Чей код. Модуль в фигурных скобках начинается с ВнешняяОбработка или ВнешнийОтчет — виновата внешняя печатная форма или обработка под старый релиз. Отключите её и отдайте автору.
  2. Расширения. Повторите действие на копии базы с отключёнными расширениями, в УТ 11.4 — «НСИ и администрирование → Администрирование → Печатные формы, отчеты и обработки → Расширения». Ошибка пропала — виновато расширение: его код рассчитан на прежнюю версию типовой.
  3. Отложенное обновление. В УТ 11.4: «НСИ и администрирование → Администрирование → Обслуживание», группа «Обновление программы», ссылка «Результаты обновления и дополнительная обработка данных». Пока обработчики не завершены, часть данных в старом формате.
  4. Чистая типовая. Ошибка повторяется без расширений и внешних обработок — просмотрите перечни исправленных ошибок в описаниях следующих релизов. Исправления нет — пишите в поддержку, в УТ 11.4: «НСИ и администрирование → Администрирование → Интернет-поддержка и сервисы → Сообщение в службу технической поддержки». Приложите полный текст ошибки, версии конфигурации и платформы, порядок действий.
  5. Временное исправление — расширением, а не правкой типового модуля.
// Расширение конфигурации, модуль заимствованного общего модуля.
// Имена типовых методов условные — подставьте метод из текста ошибки.

// Вариант 1: копия типового метода с контролем изменений.
// Тело копируется целиком, своё — только между #Вставка и #КонецВставки.
&ИзменениеИКонтроль("ДанныеПервогоОснования")
Функция Расш1_ДанныеПервогоОснования(Основания)

	#Вставка
	Если Основания.Количество() = 0 Тогда
		Возврат Неопределено; // пустой список оснований больше не роняет печать
	КонецЕсли;
	#КонецВставки
	Основание = Основания[0];
	Возврат Новый Структура("Ссылка, Представление", Основание, Строка(Основание));

КонецФункции

// Вариант 2: для пустых данных типовой код не вызывается.
&Вместо("ЗаполнитьТоварыПоОснованиям")
Процедура Расш1_ЗаполнитьТоварыПоОснованиям(ДокументОбъект, Основания)

	Если Основания.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	ПродолжитьВызов(ДокументОбъект, Основания);

КонецПроцедуры

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

Типичные ошибки

  • Проверка Индекс <= Количество(). Пропускает индекс, равный количеству; нужно <.
  • Проверили не ту границу. После Если Части.Количество() > 0 безопасна только Части[0].
  • Обратный цикл с пересчётом. Товары[Товары.Количество() - Сч] в цикле Для Сч = 1 По Товары.Количество() после удаления перескакивает строку, а к концу даёт отрицательный индекс. Запомните количество до цикла.
  • Индекс из копии таблицы. Индекс строки из свёрнутой (Свернуть()) или отсортированной копии применили к исходной табличной части.
  • Попытка вокруг обращения. Сообщение пропадает, а загрузка «успешна» без половины строк. Исключение ловите только, чтобы записать причину в журнал регистрации.

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

Почему проверка модулей не находит эту ошибку?

Размер коллекции известен только при выполнении, а код с индексом за границей массива синтаксически правилен. Её ловят проверки размера и остановка по ошибке в отладчике.

Почему ошибка только у одного пользователя?

У него другие данные: меньше строк, файл без колонки, ничего не выделено. Или права: при ограничении доступа на уровне записей запрос ВЫБРАТЬ РАЗРЕШЕННЫЕ возвращает ему меньше строк, и Выгрузить()[0] падает только у него, — см. RLS в 1С.

Бывает ли такая ошибка у строк?

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

Что значит «Значение индекса выходит за границы диапазона»?

Тот же выход за границу у COMSafeArray — массива для обмена с COM-объектами, например с Excel. Нижняя граница у него не обязательно 0: допустимые индексы возвращают GetLowerBound() и GetUpperBound().

Когда проще заказать

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

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.