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

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

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

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

Таблица значений в 1С — это универсальная коллекция, в которой разработчики хранят промежуточные данные: результаты расчётов, выгрузки для обмена, строки будущих документов. У строк таблицы нет видимого пользователю номера, поэтому задача «пронумеровать строки» возникает часто: при выводе в макет печатной формы, при формировании XML-файла, при сопоставлении данных между системами.

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

Ниже разобраны конкретные приёмы с примерами кода на встроенном языке 1С, а также ситуации, когда нумерация «слетает» после сортировки или свёртки таблицы и как этого избежать.

Как добавить колонку с номером строки

Самый прямой способ — создать в таблице значений дополнительную колонку числового типа и заполнить её последовательными номерами. Колонка добавляется методом Колонки.Добавить() с указанием имени и типа.

ТЗ.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0)));

Номер = 0;

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

Номер = Номер + 1;

СтрокаТЗ.НомерСтроки = Номер;

КонецЦикла;

Такой код работает в любой версии платформы 1С:Предприятие 8. Описание типов с квалификатором «10 разрядов, 0 знаков после запятой» гарантирует, что в колонке будут целые числа без дробной части. Если таблица может быть очень большой, разрядность стоит увеличить, но для большинства прикладных задач десяти разрядов достаточно.

Важно добавлять колонку до заполнения таблицы данными или до цикла нумерации, иначе обращение к СтрокаТЗ.НомерСтроки вызовет ошибку «Поле объекта не обнаружено». Если таблица приходит извне (из запроса, из функции), проверьте наличие колонки через ТЗ.Колонки.Найти("НомерСтроки"), чтобы не добавить её повторно.

Нумерация через индекс строки

У каждой строки таблицы значений есть внутренний индекс, который можно получить методом ТЗ.Индекс(СтрокаТЗ). Индексация начинается с нуля, поэтому для привычной нумерации с единицы к индексу прибавляют единицу.

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

СтрокаТЗ.НомерСтроки = ТЗ.Индекс(СтрокаТЗ) + 1;

КонецЦикла;

Альтернатива — цикл со счётчиком по индексам, когда нужен доступ к строке по позиции:

Для Индекс = 0 По ТЗ.Количество() - 1 Цикл

ТЗ[Индекс].НомерСтроки = Индекс + 1;

КонецЦикла;

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

bsl
Для Каждого СтрокаТЗ Из ТЗ Цикл
    СтрокаТЗ.НомерСтроки = ТЗ.Индекс(СтрокаТЗ) + 1;
КонецЦикла;

Нумерация при заполнении таблицы из запроса

Часто таблица значений строится выгрузкой результата запроса: ТЗ = Запрос.Выполнить().Выгрузить(). В этом случае нумеровать строки нужно после выгрузки, потому что в самом языке запросов 1С нет встроенной функции порядкового номера строки.

Типовая последовательность такая: выполнить запрос, выгрузить результат в таблицу значений, добавить колонку «НомерСтроки», пройти циклом и заполнить номера. Порядок строк при выгрузке соответствует упорядочиванию в запросе, поэтому если нужна нумерация в определённом порядке — задайте УПОРЯДОЧИТЬ ПО в тексте запроса до выгрузки.

Если результат выгружается не в таблицу значений, а обходится выборкой (Выборка = Запрос.Выполнить().Выбрать()), нумеровать можно прямо в цикле обхода — например, при построчном выводе в табличный документ или заполнении другой таблицы:

Номер = 0;

Пока Выборка.Следующий() Цикл

Номер = Номер + 1;

// использование Номер при заполнении строк

КонецЦикла;

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

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

Таблица уже существует и заполненаДобавьте колонку и пронумеруйте в цикле Для Каждого
Таблица строится запросомЗадайте УПОРЯДОЧИТЬ ПО в запросе и нумеруйте после Выгрузить()
Данные обходятся выборкой без таблицыВедите счётчик прямо в цикле Пока Выборка.Следующий()
Нужен номер только на печатиНумеруйте при выводе в табличный документ, не меняя саму таблицу

Нумерация только для печати или выгрузки

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

Номер = 0;

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

Номер = Номер + 1;

ОбластьСтрока.Параметры.НомерСтроки = Номер;

ТабДок.Вывести(ОбластьСтрока);

КонецЦикла;

Тот же приём применяется при записи XML или JSON: номер строки вычисляется в момент формирования узла и не засоряет исходные данные. Такой подход особенно удобен в обменах, где состав колонок таблицы строго согласован с форматом принимающей стороны и лишняя колонка может нарушить выгрузку.

Если номер нужен только для отображения пользователю в табличном поле формы, отдельная колонка не обязательна: у динамических списков и таблиц формы есть стандартная колонка «НомерСтроки», которую платформа заполняет автоматически.
ПЗ
Практическое замечание

Что происходит с нумерацией после сортировки и свёртки

Главный источник ошибок — изменение порядка строк после того, как номера уже проставлены. Методы Сортировать(), Свернуть() и Скопировать() с отбором меняют состав или порядок строк, а значения в колонке «НомерСтроки» остаются прежними. В результате номера идут не по порядку или дублируются.

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

Отдельный случай — свёртка таблицы методом Свернуть(). Она группирует строки и суммирует числовые колонки, поэтому колонка с номерами при свёртке просуммируется и потеряет смысл. Если свёртка планируется, колонку «НомерСтроки» нужно добавлять строго после неё.

Типичные ошибки
01
Нумерация до сортировки — после Сортировать() номера идут вразнобой
02
Колонка номера добавлена до Свернуть() — метод просуммировал номера как обычные числа
03
Повторный вызов Колонки.Добавить() с тем же именем — исключение и остановка кода
04
Нумерация с нуля вместо единицы — пользователи печатной формы видят строку «0»
05
Индекс строки вместо номера при выгрузке — во внешней системе нумерация смещена на единицу

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

После заполнения номеров полезно выполнить быструю проверку, особенно если таблица прошла через несколько этапов обработки. Минимальный контроль — убедиться, что номер последней строки равен количеству строк, а дубликатов нет.

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

И ТЗ[ТЗ.Количество() - 1].НомерСтроки <> ТЗ.Количество() Тогда

// нумерация нарушена — требуется пересчёт

КонецЕсли;

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

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

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

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

Равен 1

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

Равен 0 или другому значению

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

Равен количеству строк таблицы

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

Меньше или больше количества строк

Последовательность номеров
Норма

Каждый следующий номер на 1 больше предыдущего

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

Есть пропуски или повторы

Нумерация после сортировки
Норма

Номера пересчитаны после изменения порядка

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

Номера соответствуют старому порядку строк

Ограничения и частые вопросы производительности

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

Если внутри цикла нумерации нужно сопоставлять строки с другой таблицей, используйте НайтиСтроки() с предварительно построенным соответствием или индексом: ТЗ.Индексы.Добавить("КлючеваяКолонка"). Это ускоряет поиск на больших объёмах на порядки.

Для управляемых форм помните: таблица значений, отображаемая на форме, — это реквизит формы, и добавление колонки в неё программно требует работы через ИзменитьРеквизиты(), а не прямого вызова Колонки.Добавить(). Если нужен просто видимый номер строки — включите стандартную колонку нумерации в свойствах таблицы формы в конфигураторе.

Итог

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

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

Частые вопросы

Можно ли пронумеровать строки прямо в запросе 1С?

Встроенной функции порядкового номера строки в языке запросов 1С нет. Практический путь — выгрузить результат запроса в таблицу значений и пронумеровать её циклом. Упорядочивание задайте в запросе через УПОРЯДОЧИТЬ ПО, чтобы нумерация шла в нужном порядке.

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

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

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

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

Что делать, если Колонки.Добавить() выдаёт ошибку?

Чаще всего колонка с таким именем уже существует. Проверьте её наличие: Если ТЗ.Колонки.Найти("НомерСтроки") = Неопределено Тогда — добавить. Также убедитесь, что имя колонки — допустимый идентификатор без пробелов и спецсимволов.

Как пронумеровать строки в таблице на управляемой форме?

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

Влияет ли нумерация на производительность больших таблиц?

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