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

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

Как узнать номер строки в 1С

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

Номер строки в 1С встречается в нескольких разных контекстах: у строк табличной части документа, у строк таблицы значений, в результате запроса, на управляемой форме и в табличном документе. В каждом случае способ получения номера свой, и попытка применить один метод к другому объекту приводит к ошибке «Поле объекта не обнаружено» или к неверному результату.

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

Номер строки табличной части объекта

У любой табличной части документа или справочника каждая строка имеет стандартное свойство НомерСтроки. Нумерация начинается с единицы и соответствует тому, что пользователь видит в колонке «N» на форме. Свойство доступно только для чтения — присвоить его напрямую нельзя.

Для Каждого СтрокаТовары Из Объект.Товары Цикл

Сообщить("Строка " + СтрокаТовары.НомерСтроки + ": " + СтрокаТовары.Номенклатура);

КонецЦикла;

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

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

Номер строки в таблице значений

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

ТЗ = Объект.Товары.Выгрузить();

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

НомерДляВывода = ТЗ.Индекс(СтрокаТЗ) + 1;

КонецЦикла;

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

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

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

Номер строки на управляемой форме

Когда пользователь стоит курсором на строке таблицы формы и нужно узнать её номер (например, в обработчике команды), используют свойство ТекущиеДанные элемента формы:

&НаКлиенте

Процедура ТоварыПриАктивизацииСтроки(Элемент)

ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;

Если ТекущаяСтрока <> Неопределено Тогда

Номер = ТекущаяСтрока.НомерСтроки;

КонецЕсли;

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

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

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

Номер строки в запросе

В языке запросов 1С нет прямой функции «номер строки результата». Доступные варианты зависят от задачи. Если нужен номер строки табличной части документа — он уже есть в виртуальной и физической таблице как поле НомерСтроки:

ВЫБРАТЬ

РеализацияТовары.НомерСтроки КАК НомерСтроки,

РеализацияТовары.Номенклатура КАК Номенклатура

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары

ГДЕ

РеализацияТовары.Ссылка = &Ссылка

Если требуется пронумеровать строки произвольного результата, применяют функцию АВТОНОМЕРЗАПИСИ(). Она возвращает уникальный номер записи, но не гарантирует последовательность без пропусков и порядок, соответствующий сортировке. Для строгой сквозной нумерации результат выгружают в таблицу значений и нумеруют в цикле либо строят соединение таблицы самой с собой с подсчётом — такой приём ресурсоёмок на больших выборках.

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

В табличном документе (объект ТабличныйДокумент, макеты, печатные формы) номер строки — это координата области. Текущую высоту документа даёт свойство ВысотаТаблицы: следующая пустая строка для вывода — это ВысотаТаблицы + 1. К конкретной ячейке обращаются через Область("R" + НомерСтроки + "C" + НомерКолонки).

Обратная задача — найти строку по номеру, который сообщил пользователь. Для табличной части это Найти по индексу, для таблицы значений с колонкой номера — метод Найти(Номер, "НомерСтроки"). Метод Найти возвращает строку или Неопределено, поэтому результат всегда проверяют перед обращением к полям.

Как найти строку по номеру
  1. 1
    Уточните, с какой коллекцией работаете: табличная часть, таблица значений или форма
  2. 2
    Для табличной части: Строка = Объект.Товары[НомерСтроки - 1]
  3. 3
    Для таблицы значений с колонкой номера: Строка = ТЗ.Найти(НомерСтроки, "НомерСтроки")
  4. 4
    Проверьте результат на Неопределено и выход за границы коллекции
  5. 5
    Только после проверки обращайтесь к полям найденной строки

Проверка результата и выбор подхода

Правильность полученного номера легко проверить: выведите в сообщении номер и содержимое строки, затем сравните с тем, что видно на форме документа. Если номера смещены на единицу — почти наверняка перепутаны индекс (с 0) и номер (с 1). Если номер «скачет» после сортировки — используется сохранённая колонка вместо пересчёта.

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

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

Совпадение номера с колонкой «N» на форме
Норма

Номер в сообщении равен номеру строки на форме

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

Смещение на 1 — перепутаны индекс и номер

Поведение после удаления строки
Норма

Номера оставшихся строк пересчитаны платформой

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

В данных есть «дырки» в нумерации — значит, номер хранился вручную

Обход пустой таблицы
Норма

Код отрабатывает без ошибок

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

Ошибка при обращении к ТекущиеДанные или элементу по индексу

Маршрут решения

Как выбрать способ

Нужен номер строки табличной части документаИспользуйте свойство Строка.НомерСтроки, нумерация с 1
Работаете с таблицей значенийИспользуйте ТЗ.Индекс(Строка) + 1 или собственный счётчик в цикле
Нужен номер строки, на которой стоит пользовательБерите Элементы.ИмяТаблицы.ТекущиеДанные.НомерСтроки с проверкой на Неопределено
Нужно пронумеровать результат запросаВыгрузите в таблицу значений и пронумеруйте в цикле — это надёжнее АВТОНОМЕРЗАПИСИ()

Часто задаваемые вопросы

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

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

Можно ли изменить номер строки вручную?

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

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

Используйте Количество(): Объект.Товары.Количество() — это и есть номер последней строки, так как нумерация идёт с единицы без пропусков. Для пустой табличной части результат равен 0.

Как получить номер строки в обработчике ПриИзменении поля таблицы?

Через Элементы.ИмяТаблицы.ТекущиеДанные.НомерСтроки — в момент изменения поля текущая строка уже установлена. Не забудьте проверку на Неопределено, чтобы обработчик не падал при очистке таблицы.

Чем отличается НомерСтроки от КлючСтроки?

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

Итог

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

У табличной части номер берётся из свойства НомерСтроки (с 1), у таблицы значений — через Индекс() (с 0), на форме — из ТекущиеДанные с обязательной проверкой на Неопределено. Номер строки не подходит как постоянный идентификатор: для связей используйте уникальные ключи.