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