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

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

Как получить последнюю строку таблицы значений в 1С

Способы получить последнюю строку таблицы значений в 1С: по индексу, через Количество()-1, в цикле и через запрос. Примеры кода, ошибки и проверка пустой таблицы.

Таблица значений — один из самых используемых объектов встроенного языка 1С. Задача получить последнюю строку возникает постоянно: при поиске последней проводки, последнего курса валюты, последнего движения по регистру, скопированного в таблицу, или при построчной обработке данных. Способов несколько, и выбор зависит от того, отсортирована ли таблица, нужна ли строка целиком или только значение одной колонки, и есть ли гарантия, что таблица не пустая.

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

Ниже разобраны основные приёмы: прямое обращение по индексу, безопасный вариант с проверкой пустой таблицы, получение последней строки через запрос, а также типичные сценарии, когда «последняя строка» на самом деле означает «строку с максимальным значением» — и тогда индекс не поможет.

Получение последней строки по индексу

Самый прямой способ — обратиться к строке по индексу. Таблица значений поддерживает обращение через квадратные скобки, как массив. Поскольку нумерация идёт с нуля, последний элемент имеет индекс на единицу меньше общего количества строк.

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Номенклатура");

ТЗ.Колонки.Добавить("Количество");

Строка1 = ТЗ.Добавить();

Строка1.Номенклатура = "Товар А";

Строка1.Количество = 5;

Строка2 = ТЗ.Добавить();

Строка2.Номенклатура = "Товар Б";

Строка2.Количество = 12;

// Последняя строка — индекс Количество() - 1

ПоследняяСтрока = ТЗ[ТЗ.Количество() - 1];

Сообщить(ПоследняяСтрока.Номенклатура); // "Товар Б"

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

Этот же приём работает и для табличных частей документов и справочников: Документ.Товары[Документ.Товары.Количество() - 1] вернёт последнюю строку табличной части «Товары».

Безопасный вариант с проверкой пустой таблицы

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

Если ТЗ.Количество() > 0 Тогда

ПоследняяСтрока = ТЗ[ТЗ.Количество() - 1];

// работаем со строкой

Иначе

// таблица пуста — обрабатываем ситуацию

Сообщить("Таблица не содержит данных");

КонецЕсли;

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

Функция ПолучитьПоследнююСтроку(ТЗ)

Если ТЗ.Количество() = 0 Тогда

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

КонецЕсли;

Возврат ТЗ[ТЗ.Количество() - 1];

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

Порядок действий
  1. 1
    Убедитесь, что таблица значений заполнена: проверьте ТЗ.Количество() > 0
  2. 2
    Получите строку по индексу: ТЗ[ТЗ.Количество() - 1]
  3. 3
    Прочитайте нужные колонки через точку: ПоследняяСтрока.ИмяКолонки
  4. 4
    Если таблица может быть пустой, обработайте эту ветку отдельно

Последняя строка в цикле и при обходе

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

Определить, что текущая строка последняя, можно двумя способами. Первый — сравнение индекса текущей строки с индексом последней:

ИндексПоследней = ТЗ.Количество() - 1;

Для Инд = 0 По ИндексПоследней Цикл

Строка = ТЗ[Инд];

Если Инд = ИндексПоследней Тогда

// это последняя строка

КонецЕсли;

КонецЦикла;

Второй способ — использовать метод Индекс() внутри цикла «Для Каждого». Он возвращает позицию строки в таблице:

Для Каждого Строка Из ТЗ Цикл

Если ТЗ.Индекс(Строка) = ТЗ.Количество() - 1 Тогда

// последняя строка

КонецЕсли;

КонецЦикла;

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

Когда нужна не последняя по индексу, а последняя по смыслу

Сортировка перед получением строки

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

// Последняя по дате запись

ТЗ.Сортировать("Дата Возр");

ПоследняяПоДате = ТЗ[ТЗ.Количество() - 1];

// Или наоборот — сортировка по убыванию, тогда нужная строка первая

ТЗ.Сортировать("Дата Убыв");

ПоследняяПоДате = ТЗ[0];

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

Поиск максимума без сортировки

Если менять порядок строк нельзя и копию делать не хочется, можно найти строку с максимальным значением перебором:

Если ТЗ.Количество() > 0 Тогда

ИскомаяСтрока = ТЗ[0];

Для Каждого Строка Из ТЗ Цикл

Если Строка.Дата > ИскомаяСтрока.Дата Тогда

ИскомаяСтрока = Строка;

КонецЕсли;

КонецЦикла;

КонецЕсли;

Сравнение способов

Обращение по индексу ТЗ[Количество()-1]

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

Сортировка + индекс

Нужна последняя по смыслу строка (по дате, номеру). Меняет порядок исходной таблицы — при необходимости работайте с копией

Запрос с УПОРЯДОЧИТЬ ПО ... УБЫВ

Оптимально, если данные ещё не выгружены в таблицу: СУБД вернёт нужную строку первой, лишние данные в память не попадут

Перебор с поиском максимума

Когда нельзя менять порядок строк и нежелательно создавать копию таблицы

Получение последней строки через запрос

Если таблица значений формируется выгрузкой результата запроса, часто эффективнее получить «последнюю» запись прямо в запросе, не загружая в память весь набор данных. Для этого используют упорядочивание по убыванию и ограничение количества строк ключевым словом ПЕРВЫЕ 1.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Курсы.Период,

| Курсы.Курс

|ИЗ

| РегистрСведений.КурсыВалют КАК Курсы

|ГДЕ

| Курсы.Валюта = &Валюта

|УПОРЯДОЧИТЬ ПО

| Курсы.Период УБЫВ";

Запрос.УстановитьПараметр("Валюта", Валюта);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ПоследнийКурс = Выборка.Курс;

КонецЕсли;

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

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

Типичные ошибки и как их проверить

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

Типичные ошибки
01
Обращение ТЗ[ТЗ.Количество()] вместо ТЗ[ТЗ.Количество()-1] — индексация с нуля, поэтому такой код всегда даёт ошибку выхода за границы
02
Отсутствие проверки на пустую таблицу — при Количество() = 0 обращение по индексу -1 падает с ошибкой
03
Ожидание, что последняя по индексу строка — самая свежая по дате, хотя таблица не отсортирована: порядок строк определяется тем, как они добавлялись
04
Сортировка исходной таблицы без копии, из-за чего ломается порядок строк, нужный другой логике или отображению на форме
05
Использование Найти() или НайтиСтроки() для поиска последней строки — эти методы ищут по значению, а не по позиции

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

Контрольные точки

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

Индекс последней строки
Норма

Равен ТЗ.Количество() - 1

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

Равен ТЗ.Количество() — обращение вызовет ошибку

Поведение на пустой таблице
Норма

Код проходит ветку Иначе и не обращается по индексу

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

Ошибка «Индекс находится за границами массива»

Смысловая корректность
Норма

Строка содержит ожидаемые данные (например, максимальную дату после сортировки)

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

Строка случайная — таблица не была отсортирована

Порядок остальных строк
Норма

Исходный порядок сохранён, если он нужен

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

Порядок изменён из-за Сортировать() без копии

FAQ

Как получить последнюю строку табличной части документа?

Точно так же, как для таблицы значений: Документ.Товары[Документ.Товары.Количество() - 1]. Табличная часть поддерживает обращение по индексу и метод Количество(). Не забудьте проверить, что табличная часть не пуста.

Можно ли получить последнюю строку без знания имён колонок?

Да. Обращение по индексу ТЗ[ТЗ.Количество() - 1] не требует знания колонок — вы получаете объект строки. Прочитать значения можно и по индексу колонки: Строка[0] вернёт значение первой колонки.

Чем отличается последняя строка таблицы от среза последних регистра?

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

Как получить последние N строк таблицы значений?

Используйте цикл от ТЗ.Количество() - N до ТЗ.Количество() - 1 с обращением по индексу, предварительно проверив, что строк в таблице не меньше N. Альтернатива — скопировать таблицу и удалить лишние строки с начала.

Что вернёт ТЗ.Количество() - 1 для пустой таблицы?

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

Влияет ли метод Добавить() на то, какая строка последняя?

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

Итог

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

Последняя строка таблицы значений — это ТЗ[ТЗ.Количество() - 1], поскольку индексация начинается с нуля. Всегда проверяйте, что таблица не пуста. Если нужна последняя по смыслу строка (по дате, сумме), сначала отсортируйте копию таблицы или получите данные запросом с упорядочиванием по убыванию и ПЕРВЫЕ 1.