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