Приветствуем вас! Сегодня мы с вами разберем одну из частых и порой обескураживающих ошибок в 1С:Предприятии — «Индекс находится за границами массива». Эта ошибка возникает, когда программа пытается обратиться к элементу коллекции (массива, табличной части, списка) по индексу, который не существует, то есть выходит за пределы допустимого диапазона (обычно от 0 до количества элементов минус 1).
В контексте работы с управляемыми формами и табличными частями, как показала практика на форумах 1С, эта проблема очень часто связана с неправильным пониманием того, что на самом деле возвращает свойство ТекущаяСтрока элемента формы. Давайте выясним причину и найдем правильные решения.
Первым делом, давайте проясним ключевое заблуждение, которое приводит к ошибке «Индекс находится за границами массива» при работе с табличными частями на управляемых формах. Мы часто интуитивно ожидаем, что свойство Элементы.ИмяТаблицы.ТекущаяСтрока или ЭтаФорма.ТекущийЭлемент.ТекущаяСтрока вернет нам порядковый номер (индекс) выбранной строки в табличной части, как это было в обычных формах или при работе с простыми массивами. Однако это не так.
На самом деле, свойство ТекущаяСтрока возвращает не числовой индекс, а уникальный идентификатор строки табличной части формы.
Давайте рассмотрим подробнее, что это означает:
Объект.Товары[ТекСтрокаИдентификатор]), скорее всего, вы получите ошибку «Индекс находится за границами массива», потому что идентификатор не является порядковым номером и может быть гораздо больше фактического количества строк или иметь произвольное значение.
Итак, если свойство ТекущаяСтрока возвращает идентификатор, то как же нам получить саму строку данных? Для этого в 1С:Предприятии предусмотрен специальный метод НайтиПоИдентификатору(), который применяется к коллекции данных (например, к табличной части объекта).
Давайте разберем по шагам, как это работает:
ТекущаяСтрока элемента формы.
ТекСтрокаИдентификатор = Элементы.Товары.ТекущаяСтрока;
Элементы.Товары — это табличное поле на форме, а Товары — его источник данных.
ТекущиеДанные = Объект.Товары.НайтиПоИдентификатору(ТекСтрокаИдентификатор);
Объект.Товары — это табличная часть объекта, данные которой отображаются в табличном поле.
ТекущиеДанные будет содержать объект строки табличной части, и вы сможете безопасно обращаться к ее реквизитам.
ТекущиеДанные.Продавец = СтрокаРезультата.ВладелецКарты;
// Или, например:
// Сообщить("Выбран товар: " + ТекущиеДанные.Номенклатура);
Этот подход является наиболее корректным при работе с идентификаторами строк и позволяет избежать ошибки «Индекс находится за границами массива».
Помимо использования идентификатора, существует более прямой и часто более удобный способ получить данные текущей строки табличного поля на управляемой форме — это свойство ТекущиеДанные.
Давайте посмотрим, как это работает:
Элементы.ИмяТаблицы.ТекущиеДанные напрямую содержит объект с данными текущей строки табличного поля.
ТекущиеДанныеСтроки = Элементы.Товары.ТекущиеДанные;
Неопределено. Поэтому важно всегда проверять его на заполненность перед использованием.
Если ТекущиеДанныеСтроки <> Неопределено Тогда
ТекущиеДанныеСтроки.Продавец = СтрокаРезультата.ВладелецКарты;
// Или:
// Сообщить("Количество: " + ТекущиеДанныеСтроки.Количество);
КонецЕсли;
Преимущества `ТекущиеДанные`:
* Простота: Не нужно выполнять дополнительные вызовы методов, таких как НайтиПоИдентификатору().
* Производительность: Особенно на клиенте, это может быть быстрее, так как данные уже считаны и доступны.
* Удобство: Более интуитивный способ получить данные текущей строки.
Мы рекомендуем использовать свойство ТекущиеДанные для большинства случаев, когда вам нужен прямой доступ к реквизитам текущей строки табличного поля на управляемой форме.
Иногда, несмотря на все вышесказанное, нам все-таки может понадобиться именно числовой индекс строки в коллекции (например, для работы с таблицами значений, или при специфических манипуляциях с массивами). В таких случаях мы можем получить индекс с помощью метода Индекс().
Давайте проанализируем ситуацию:
ТекущиеДанные.
ТекущаяСтрокаДанных = Элементы.Товары.ТекущиеДанные;
Индекс() для коллекции, передав ему полученный объект строки.
Если ТекущаяСтрокаДанных <> Неопределено Тогда
ИндексСтроки = Объект.Товары.Индекс(ТекущаяСтрокаДанных);
Сообщить("Индекс выбранной строки: " + ИндексСтроки);
КонецЕсли;
Объект.Товары — это коллекция, в которой мы ищем индекс.
Полученный ИндексСтроки будет числовым значением, начинающимся с 0. Теперь вы сможете использовать его для доступа к элементам коллекции по индексу, например:
Если ИндексСтроки <> Неопределено Тогда
// Обращение к строке по индексу, например, в таблице значений
СтрокаПоИндексу = МояТаблицаЗначений[ИндексСтроки];
КонецЕсли;
Помните, что метод Индекс() может быть не самым производительным решением для больших коллекций, так как он ищет переданный объект в коллекции. Используйте его, когда это действительно необходимо.
Хотя мы подробно разобрали случай с ТекущаяСтрока, ошибка «Индекс находится за границами массива» может возникать и по другим причинам. Давайте рассмотрим общие рекомендации, которые помогут вам избежать этой проблемы в различных сценариях:
КоличествоЭлементов - 1).
МойМассив = Новый Массив();
МойМассив.Добавить("Элемент 0");
МойМассив.Добавить("Элемент 1");
ИндексДляДоступа = 2; // Этот индекс выходит за границы массива
Если ИндексДляДоступа >= 0 И ИндексДляДоступа < МойМассив.Количество() Тогда
// Доступ безопасен
Значение = МойМассив[ИндексДляДоступа];
Иначе
Сообщить("Попытка доступа по недопустимому индексу: " + ИндексДляДоступа);
КонецЕсли;
// Неправильно (может пропустить элементы или вызвать ошибку)
// Для Каждого Элемент Из МояКоллекция Цикл
// Если НужноУдалить(Элемент) Тогда
// МояКоллекция.Удалить(Элемент);
// КонецЕсли;
// КонецЦикла;
// Правильно (обход с конца)
Для Индекс = МояКоллекция.Количество() - 1 По 0 СШагом -1 Цикл
Если НужноУдалить(МояКоллекция[Индекс]) Тогда
МояКоллекция.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Если МояКоллекция.Количество() > 0 Тогда
ПервыйЭлемент = МояКоллекция[0];
Иначе
Сообщить("Коллекция пуста, невозможно получить первый элемент.");
КонецЕсли;
Мы надеемся, что это подробное руководство поможет вам понять причины возникновения ошибки «Индекс находится за границами массива» при работе с текущей строкой табличной части в 1С:Предприятии и эффективно ее предотвращать. Используйте правильные методы и всегда помните о проверке границ, чтобы ваш код был надежным и стабильным!
← К списку