Как обратиться к последней строке табличной части в 1С?

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

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

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

В платформе 1С:Предприятие 8 во всех коллекциях (массивы, строки табличной части, таблицы значений) нумерация элементов всегда начинается с 0. При этом общее количество строк возвращается методом Количество(). Таким образом, индекс самой последней строки всегда равен общему числу строк минус единица.

Рассмотрим два основных способа обращения к строке по индексу:

  1. Через оператор прямого доступа (квадратные скобки): наиболее распространенный и лаконичный вариант.
  2. Через метод коллекции Получить(): функциональный аналог индексного обращения.

Посмотрим на пример базового кода:


// Вариант 1: Прямой доступ по индексу
ПоследняяСтрока = Объект.Товары[Объект.Товары.Количество() - 1];

// Вариант 2: Использование метода Получить()
ПоследняяСтрока = Объект.Товары.Получить(Объект.Товары.Количество() - 1);

Безопасная работа и проверка на наличие строк

Проанализируем критически важный нюанс: если табличная часть пуста (Количество() = 0), выражение Количество() - 1 вернет индекс -1. Попытка обратиться по отрицательному индексу вызовет системную ошибку «Индекс находится за границами массива».

Перед обращением всегда необходимо выполнять явную проверку на заполненность коллекции. Разберем правильный алгоритм:


ПоследняяСтрока = Неопределено;

Если Объект.Товары.Количество() > 0 Тогда
    ПоследняяСтрока = Объект.Товары[Объект.Товары.Количество() - 1];
    // Выполняем дальнейшие действия со строкой
    ПоследняяСтрока.Цена = 100;
КонецЕсли;

Подводные камни тернарного оператора ?()

Выясним причину распространенной ошибки начинающих разработчиков. Попытка сократить код проверки с помощью тернарного оператора ?() приводит к сбою программы:


// ОШИБОЧНЫЙ КОД! Приведет к падению, если табличная часть пуста:
ПоследняяСтрока = ?(Объект.Товары.Количество() > 0, Объект.Товары[Объект.Товары.Количество() - 1], Неопределено);

Особенность встроенного языка 1С заключается в том, что функция ?() всегда заранее вычисляет оба переданных выражения, независимо от истинности первого условия. Если строк нет, ветка обращения по индексу все равно будет вычислена и вызовет исключение. Поэтому безопасную проверку следует реализовывать только через полноценное ветвление Если ... Тогда.

Позиционирование на последней строке в управляемой форме

Рассмотрим ситуацию, когда требуется не просто прочитать значения, а программно выделить и активировать последнюю строку в таблице на форме. На клиенте табличная часть представлена типом ДанныеФормыКоллекция. Для установки свойства ТекущаяСтрока элемента формы необходимо передавать не сам объект строки, а ее числовой идентификатор.

Разберем по шагам, как активировать строку на клиенте:


&НаКлиенте
Процедура АктивироватьПоследнююСтроку()
    
    Если Объект.Товары.Количество() > 0 Тогда
        ПоследняяСтрока = Объект.Товары[Объект.Товары.Количество() - 1];
        Элементы.Товары.ТекущаяСтрока = ПоследняяСтрока.ПолучитьИдентификатор();
    КонецЕсли;
    
КонецПроцедуры

Чтение данных последней строки запросом без загрузки объекта

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

Посмотрим на пример эффективного извлечения данных через запрос с сортировкой по убыванию номера строки:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	ТЧ.Номенклатура КАК Номенклатура,
    |	ТЧ.Количество КАК Количество,
    |	ТЧ.Сумма КАК Сумма
    |ИЗ
    |	Документ.РеализацияТоваровУслуг.Товары КАК ТЧ
    |ГДЕ
    |	ТЧ.Ссылка = &Ссылка
    |УПОРЯДОЧИТЬ ПО
    |	ТЧ.НомерСтроки УБЫВ";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    // Обрабатываем полученные значения
    Сообщить("Последний товар: " + Выборка.Номенклатура);
КонецЕсли;

Удаление строк с конца таблицы

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

Удаление строго последней строки:


Если Объект.Товары.Количество() > 0 Тогда
    Объект.Товары.Удалить(Объект.Товары.Количество() - 1);
КонецЕсли;

Удаление нескольких строк с конца к началу по условию:


Для Индекс = Объект.Товары.Количество() - 1 По 0 Цикл
    Если Объект.Товары[Индекс].Количество = 0 Тогда
        Объект.Товары.Удалить(Индекс);
    КонецЕсли;
КонецЦикла;

Различие понятий «Индекс» и «НомерСтроки»

Необходимо четко разграничивать свойства системной нумерации:

  1. Индекс строки: внутренний программный номер элемента в коллекции. Нумерация всегда начинается с 0, а максимальный индекс равен Количество() - 1.
  2. Свойство НомерСтроки: пользовательский порядковый номер строки в табличной части прикладного объекта. Нумерация начинается с 1.

Помните, что в устаревшей версии 1С 7.7 использовались методы КоличествоСтрок() и нумерация с единицы, однако в 1С 8.х стандартом является строгая индексация с нуля и метод Количество().

← На главную