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

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

Как сделать нумерацию строк в 1С

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

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

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

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

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

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

Чтобы получить номер строки программно, обратитесь к свойству при обходе табличной части. Это самый частый сценарий при формировании печатных форм и обработок.

Для Каждого СтрокаТовары Из Документ.Товары Цикл

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

КонецЦикла;

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

Нумерация в печатной форме документа

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

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

НомерПоПорядку = 0;

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

НомерПоПорядку = НомерПоПорядку + 1;

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

ОбластьСтрока.Параметры.Заполнить(Выборка);

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

КонецЦикла;

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

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

В языке запросов 1С нет встроенной функции ранжирования наподобие ROW_NUMBER в классическом SQL. Поэтому нумерацию в запросе получают обходными путями, и каждый из них имеет свою цену по производительности.

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

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

ВЫБРАТЬ

Товары.НомерСтроки КАК НомерСтроки,

Товары.Номенклатура,

Товары.Количество

ИЗ

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

ГДЕ

Товары.Ссылка = &Ссылка

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

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

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

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

Результат = Запрос.Выполнить().Выгрузить();

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

Номер = 0;

Для Каждого Строка Из Результат Цикл

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

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

КонецЦикла;

Нумерация в отчете на СКД

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

Более надежный способ — пронумеровать данные до компоновки: в наборе данных-объекте передать в СКД уже пронумерованную таблицу значений. Это удобно, когда нумерация должна идти внутри групп (например, отдельная нумерация строк в каждом документе отчета) и логика сложнее, чем позволяет выражение вычисляемого поля.

При нумерации внутри группировки проверяйте, чтобы сортировка в настройках отчета совпадала с ожидаемым порядком нумерации. Если пользователь меняет сортировку в режиме предприятия, номера, зашитые в данные, останутся прежними — это нормально для «№ п/п» по исходному порядку, но может смутить пользователя.

Сравнение вариантов

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

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

Счетчик в цикле при выводе

Универсально для печатных форм и таблиц значений. Требует программного формирования результата.

Вычисляемое поле в СКД

Хорошо для отчетов без программной доработки. Ограничение: сложную нумерацию по группам выразить трудно.

Самосоединение в запросе

Работает без кода на встроенном языке. Не подходит для больших выборок из-за производительности.

Нумерация в динамическом списке и на форме

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

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

Порядок действий для таблицы на форме
  1. 1
    Добавьте в таблицу значений колонку НомерСтроки типа Число
  2. 2
    Создайте процедуру ПересчитатьНомераСтрок с циклом по строкам и счетчиком
  3. 3
    Вызывайте процедуру после заполнения таблицы и после добавления или удаления строк
  4. 4
    Выведите колонку в элемент таблицы на форме и установите свойство ТолькоПросмотр
  5. 5
    Проверьте: после удаления средней строки номера должны пересчитаться без разрывов

Нумерация при обмене и выгрузке данных

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

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

Типичные ошибки
01
Использовать НомерСтроки документа как номер в отсортированной печатной форме — порядок номеров перестанет совпадать с порядком строк на бумаге
02
Нумеровать большой результат запроса самосоединением — отчет начинает выполняться неприемлемо долго
03
Не пересчитывать номера после удаления строки в таблице значений на форме — в нумерации появляются дыры
04
Начинать счетчик заново в каждом пакете порционной выгрузки — в файлах дублируются номера
05
Пытаться добавить колонку номера в динамический список настройкой — это невозможно, нужен другой подход

Проверка результата

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

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

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

Непрерывность нумерации
Норма

Номера идут 1, 2, 3... без пропусков и дублей

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

Есть разрывы или повторяющиеся номера

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

Номера оставшихся строк пересчитались

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

После удаления в нумерации дыра

Соответствие порядку вывода
Норма

Номер растет в том порядке, в котором строки видны пользователю

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

Номера идут вразнобой из-за сортировки

Большой объем данных
Норма

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

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

Отчет или обработка зависает на больших выборках

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

Итог

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

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

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

Есть ли в запросах 1С аналог ROW_NUMBER?

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

Почему в печатной форме номера строк идут не по порядку?

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

Как пронумеровать строки внутри каждой группы отчета на СКД?

Выражением вычисляемого поля это сделать сложно. Надежнее сформировать данные программно: в наборе данных-объекте передать таблицу, где номер присвоен внутри каждой группы, и вывести это поле в отчет.

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

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

Что делать, если нумерация через самосоединение работает слишком медленно?

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

Изменится ли НомерСтроки, если удалить строку из табличной части?

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