Разработка и Конфигурация · 10 мин
Как получить номер строки в 1С
Как получить номер строки в 1С: в запросе через АВТОНОМЕРЗАПИСИ, в табличной части документа, в таблице значений и на форме. Примеры кода, ошибки, ответы на вопросы.
Номер строки в 1С требуется в разных ситуациях: при выводе табличной части документа, при нумерации записей в отчёте, при обходе таблицы значений или при построении запроса. Универсальной функции «получить номер строки» нет — способ зависит от того, где именно находятся данные: в табличной части объекта, в таблице значений, в результате запроса или в динамическом списке на форме.
Чаще всего путаница возникает между номером строки табличной части (системное свойство НомерСтроки) и порядковым номером записи в выборке запроса, который приходится вычислять вручную или через временные таблицы. Ниже разобраны все основные сценарии с готовыми примерами кода, указаны ограничения каждого метода и типичные ошибки.
Номер строки табличной части документа или справочника
Самый простой случай — табличная часть объекта конфигурации. Каждая её строка имеет системное свойство НомерСтроки, которое платформа заполняет автоматически при добавлении строки. Обращаться к нему можно и в коде модуля, и в запросе:
Для Каждого СтрокаТЧ Из ДокументОбъект.Товары Цикл
Сообщить("Строка № " + СтрокаТЧ.НомерСтроки + ": " + СтрокаТЧ.Номенклатура);
КонецЦикла;
В запросе номер строки табличной части доступен как поле НомерСтроки:
ВЫБРАТЬ
Товары.НомерСтроки КАК НомерСтроки,
Товары.Номенклатура,
Товары.Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &Ссылка
УПОРЯДОЧИТЬ ПО
Товары.НомерСтроки
Важно понимать: при удалении строки из середины табличной части платформа автоматически перенумеровывает оставшиеся строки, поэтому номера всегда идут подряд без пропусков. А вот при программной сортировке табличной части методом Сортировать() номера строк сохраняются у строк и перестают отражать визуальный порядок — это частая причина путаницы.
Как пронумеровать строки в запросе
У результата запроса нет встроенного номера строки, поэтому задача «получить номер строки в запросе 1С» решается двумя способами: функцией АВТОНОМЕРЗАПИСИ() или нумерацией через временные таблицы и соединение.
Функция АВТОНОМЕРЗАПИСИ()
Функция возвращает уникальный целый номер каждой записи результата, начиная с единицы:
ВЫБРАТЬ
АВТОНОМЕРЗАПИСИ() КАК НомерПоПорядку,
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
Номенклатура.Наименование
Ключевое ограничение: АВТОНОМЕРЗАПИСИ() нумерует записи в порядке их физического получения, а не в порядке УПОРЯДОЧИТЬ ПО. На практике при простых запросах номера часто совпадают с сортировкой, но стандарт этого не гарантирует. Если критично, чтобы номер соответствовал отсортированному порядку (например, для печатной формы), надёжнее нумеровать выборку в цикле.
Нумерация в цикле по выборке
Самый предсказуемый способ — объявить счётчик и увеличивать его при обходе результата:
Выборка = Запрос.Выполнить().Выбрать();
НомерСтроки = 0;
Пока Выборка.Следующий() Цикл
НомерСтроки = НомерСтроки + 1;
// используем НомерСтроки и поля выборки
КонецЦикла;
Такой подход гарантирует, что номер соответствует порядку сортировки, и позволяет управлять нумерацией: начинать с любого числа, сбрасывать счётчик при смене группы, нумеровать только строки, прошедшие условие.
ВЫБРАТЬ
АВТОНОМЕРЗАПИСИ() КАК НомерПоПорядку,
Товары.Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &СсылкаНомер строки в таблице значений
У строк таблицы значений нет свойства «номер строки», но есть метод Индекс(), который возвращает позицию строки, начиная с нуля. Чтобы получить человеческий номер, прибавьте единицу:
Для Каждого СтрокаТЗ Из ТаблицаЗначений Цикл
НомерСтроки = ТаблицаЗначений.Индекс(СтрокаТЗ) + 1;
КонецЦикла;
Если номер нужен не один раз, а постоянно (например, для выгрузки или вывода на форму), эффективнее добавить в таблицу колонку «НомерСтроки» и заполнить её один раз:
ТаблицаЗначений.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число"));
Для Индекс = 0 По ТаблицаЗначений.Количество() - 1 Цикл
ТаблицаЗначений[Индекс].НомерСтроки = Индекс + 1;
КонецЦикла;
Учтите, что после сортировки или удаления строк значения в такой колонке перестанут соответствовать фактическому положению строк — нумерацию придётся обновлять заново. Колонку с номером лучше заполнять в последнюю очередь, когда структура таблицы уже не меняется.
Сравнение способов нумерации
Готово из коробки, всегда актуально, но доступно только для табличных частей объектов и не подлежит изменению.
Быстро и без кода, но порядок нумерации не гарантированно совпадает с УПОРЯДОЧИТЬ ПО.
Полный контроль над нумерацией и сбросом по группам, но требует программного обхода результата.
Удобно для форм и выгрузок, но требует перезаполнения после сортировки или удаления строк.
Номер строки на форме и в динамическом списке
Если табличная часть выведена на форму, получить номер текущей строки можно через свойство ТекущиеДанные элемента формы:
&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
Номер = ТекущиеДанные.НомерСтроки;
КонецЕсли;
КонецПроцедуры
С динамическими списками ситуация сложнее: у них нет номера строки как такового, потому что состав и порядок записей меняются в зависимости от отбора и сортировки. Если в динамическом списке нужна колонка с порядковым номером, её добавляют либо через АВТОНОМЕРЗАПИСИ() в произвольном тексте запроса списка, либо вычисляемым полем с обработчиком ПриПолученииДанныхНаСервере для обычных таблиц формы.
Для табличного поля, связанного с таблицей значений на форме, номер текущей строки получают через Индекс() коллекции данных формы, как и для обычной таблицы значений, с поправкой на нумерацию с нуля.
Проверка результата и типичные ошибки
После реализации нумерации проверьте три вещи: номера начинаются с ожидаемого значения (обычно 1), идут без пропусков и соответствуют визуальному порядку строк на экране или в печатной форме. Расхождение любого из этих признаков указывает на ошибку в логике.
Наиболее частые проблемы выглядят так:
Как выбрать подходящий способ
Выбор метода определяется источником данных и требованиями к нумерации. Ориентируйтесь на простое правило: если номер уже есть в данных — используйте его; если нет — решите, критична ли связь номера с сортировкой. Для внутренних выгрузок порядок обычно не важен, для печатных форм и документов с требованиями к оформлению — критичен.
Как выбрать действие
Часто задаваемые вопросы
Можно ли изменить номер строки табличной части программно?
Нет, свойство НомерСтроки доступно только для чтения. Изменить порядок строк можно методами Сдвинуть(), Сортировать() или удалением и повторным добавлением строк — платформа сама переназначит номера. Если нужен управляемый порядок, создайте отдельный числовой реквизит.
Почему АВТОНОМЕРЗАПИСИ() даёт номера не по порядку сортировки?
Функция нумерует записи в момент их физического извлечения из базы, а сортировка по УПОРЯДОЧИТЬ ПО может выполняться отдельным этапом. Стандарт не гарантирует совпадения. Для строгой нумерации по сортировке обходите выборку в цикле со счётчиком.
Как получить номер строки в СКД (системе компоновки данных)?
В СКД используйте вычисляемое поле с функцией языка выражений или добавьте АВТОНОМЕРЗАПИСИ() в запрос набора данных. Для нумерации внутри группировок применяйте функцию НумероватьВГруппировке в ресурсах или вычисляемых полях, если она поддерживается в вашей версии платформы, либо нумеруйте при выводе в шаблон.
Как узнать номер текущей строки при редактировании табличной части на форме?
В обработчике события таблицы формы (например, ПриАктивизацииСтроки) обратитесь к Элементы.ИмяТаблицы.ТекущиеДанные — у полученного объекта будет свойство НомерСтроки. Проверяйте ТекущиеДанные на Неопределено, чтобы избежать ошибки при пустой таблице.
Как пронумеровать строки с условием, пропуская часть записей?
Нумеруйте в цикле: увеличивайте счётчик только внутри ветки Если, когда строка удовлетворяет условию. В запросе аналогичного результата добиваются фильтрацией во временной таблице с последующей нумерацией отфильтрованного набора.
Чем заменить номер строки для связи строк между двумя таблицами?
Добавьте в обе таблицы реквизит с уникальным ключом строки — например, строковый идентификатор, формируемый функцией Новый УникальныйИдентификатор при добавлении строки. Такие связи устойчивы к удалению, перемещению и сортировке строк, в отличие от связи по номеру.
Что важно запомнить
В табличных частях объектов номер строки уже есть — это свойство НомерСтроки. В запросах используйте АВТОНОМЕРЗАПИСИ() или счётчик в цикле, если важен порядок сортировки. В таблицах значений номер получают через Индекс() + 1 или отдельную колонку. Для связей между строками применяйте уникальные ключи, а не номера.