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

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

Как получить номер строки табличной части в 1С

Как получить номер строки табличной части в 1С: свойство НомерСтроки, метод Индекс(), получение текущей строки на форме и перенумерация строк. Примеры кода и типичные ошибки.

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

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

Ниже разобраны все рабочие варианты с примерами кода, указаны типичные ошибки и способы проверить результат. Материал применим как к управляемым, так и к обычным формам на платформе 8.3.

Получение номера через свойство НомерСтроки

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

Доступ к свойству выглядит так:

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

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

КонецЦикла;

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

Получение позиции строки методом Индекс()

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

СтрокаТовары = Объект.Товары.Найти(ИскомаяНоменклатура, "Номенклатура");

Если СтрокаТовары <> Неопределено Тогда

ИндексСтроки = Объект.Товары.Индекс(СтрокаТовары);

НомерСтроки = ИндексСтроки + 1; // приводим к привычной нумерации

КонецЕсли;

Ключевой момент: индексация коллекций в 1С начинается с нуля, а НомерСтроки — с единицы. Поэтому между значениями всегда разница в единицу: НомерСтроки = Индекс + 1. Путаница здесь — самая частая причина ошибок «вылезли за границы массива» и обращения не к той строке.

Если переданная строка не принадлежит данной коллекции, метод вернёт -1. Это удобно использовать как проверку принадлежности строки конкретной табличной части.

Номер текущей строки на форме документа

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

&НаКлиенте

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

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

Если ТекущиеДанные <> Неопределено Тогда

НомерТекущейСтроки = ТекущиеДанные.НомерСтроки;

КонецЕсли;

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

Обратите внимание: Элементы.Товары.ТекущаяСтрока возвращает не номер, а идентификатор строки (число, по которому строку можно получить через Объект.Товары.НайтиПоИдентификатору()). Идентификатор не совпадает с номером строки — это внутреннее служебное значение коллекции данных формы. Чтобы получить именно номер, сначала получите данные строки, а затем прочитайте свойство НомерСтроки.

Типичные ошибки
01
Использование ТекущаяСтрока как номера строки — это идентификатор, а не номер, значения не совпадают
02
Забытая поправка +1 при переводе Индекс() в номер строки — обращение идёт не к той позиции
03
Обращение к ТекущиеДанные без проверки на Неопределено — ошибка при пустой табличной части
04
Попытка присвоить значение свойству НомерСтроки — оно доступно только для чтения

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

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

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

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

"ВЫБРАТЬ

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

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

| РеализацияТовары.Количество КАК Количество

|ИЗ

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

|ГДЕ

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

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

| НомерСтроки";

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

Перенумерация строк после программных изменений

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

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

// Пример: переместить строку с индексом 5 на первую позицию

Объект.Товары.Сдвинуть(5, -5);

Как получить номер строки: порядок действий
  1. 1
    Определите контекст: модуль объекта, модуль формы или запрос
  2. 2
    В модуле объекта или формы прочитайте СтрокаТЧ.НомерСтроки напрямую
  3. 3
    Если есть только ссылка на строку — используйте ТабличнаяЧасть.Индекс(СтрокаТЧ) и прибавьте 1
  4. 4
    На форме получите данные через Элементы.ИмяТаблицы.ТекущиеДанные, затем прочитайте НомерСтроки
  5. 5
    В запросе выберите поле НомерСтроки из таблицы табличной части
  6. 6
    Проверьте результат на документе с несколькими строками, включая первую и последнюю

Проверка корректности полученного номера

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

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

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

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

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

НомерСтроки = 1, Индекс = 0

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

Номер начинается с 0 или с 2 — сбита логика обхода

Совпадение НомерСтроки и Индекс()+1
Норма

Значения равны для всех строк

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

Расхождение после программной вставки или удаления

Текущая строка на форме
Норма

ТекущиеДанные.НомерСтроки совпадает с номером в интерфейсе

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

Использован идентификатор ТекущаяСтрока вместо номера

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

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

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

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

Свойство НомерСтроки

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

Метод Индекс()

Подходит, когда есть ссылка на строку и нужна её позиция для Сдвинуть() или Вставить(). Ограничение: нумерация с нуля, требуется +1

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

Подходит для отчётов и выгрузок. Ограничение: работает только с таблицей табличной части, а не с коллекцией в памяти

ТекущиеДанные на форме

Подходит для интерактивных сценариев. Ограничение: возвращает Неопределено, если строка не выбрана

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

Почему НомерСтроки нельзя изменить напрямую?

Это системное свойство, которое платформа вычисляет на основе позиции строки в коллекции. Чтобы изменить порядок, используйте методы Сдвинуть(), Вставить() или Удалить() — после изменения позиции номера пересчитаются автоматически.

Чем ТекущаяСтрока отличается от НомерСтроки?

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

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

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

Можно ли получить номер строки в обработчике ПередЗаписью?

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

Почему после программной сортировки номера строк стали неправильными?

Метод Сортировать() меняет порядок строк в коллекции, и в некоторых сценариях (особенно при работе с данными формы) номера требуется обновить. На управляемой форме обычно достаточно, чтобы порядок в коллекции был корректным — платформа отобразит номера по позиции. Если номера «застыли», проверьте, не работаете ли вы с копией таблицы значений вместо реквизита формы.

Как вывести пользователю сообщение с номером строки при ошибке заполнения?

В цикле проверки сформируйте текст вида «В строке № " + СтрокаТЧ.НомерСтроки + " не заполнено количество» и выведите его через Сообщить() или объект СообщениеПользователю с привязкой к полю формы — тогда сообщение будет кликабельным и приведёт пользователя к нужной строке.

Итог

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

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