Как получить порядковый номер строки в выборке запроса и для чего нужен метод Уровень()?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с результатами запросов в платформе 1С:Предприятие у начинающих разработчиков часто возникает вопрос: как узнать порядковый номер текущей записи при обходе выборки? Нередко за номер строки ошибочно принимают метод Уровень() объекта ВыборкаИзРезультатаЗапроса. Выясним причину этого заблуждения, разберем точное назначение метода Уровень() и рассмотрим правильные практические способы получения номера строки.

Что возвращает метод Выборка.Уровень()?

Метод Уровень() не имеет никакого отношения к порядковому номеру записи (индексу строки). Он предназначен исключительно для определения глубины текущей записи в иерархических структурах и многоуровневых группировках, созданных с помощью предложений ИТОГИ или ИЕРАРХИЯ.

Проанализируем поведение этого метода в различных ситуациях:

  1. Простая (плоская) выборка: если в тексте запроса нет секции ИТОГИ, а обход выполняется методом РезультатЗапроса.Выбрать(), то для абсолютно каждой записи метод Выборка.Уровень() вернет значение 0.
  2. Иерархическая выборка и группировки: при использовании итогов значение увеличивается с каждым шагом погружения во вложенные подвыборки. Например, уровень общего итога равен 0, группировки первого уровня — 1, детальных записей — 2.

Таким образом, использовать Выборка.Уровень() в качестве счетчика строк нельзя. В объекте ВыборкаИзРезультатаЗапроса также отсутствуют встроенные свойства вроде НомерСтроки или Индекс, а в языке запросов 1С нет прямых аналогов оконной функции ROW_NUMBER().

Способ 1. Использование переменной-счетчика в цикле (рекомендуемый вариант)

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

Посмотрим на пример реализации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Номенклатура,
    |	Номенклатура.Артикул КАК Артикул
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура";

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

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    
    НомерСтроки = 0;
    
    Пока Выборка.Следующий() Цикл
        НомерСтроки = НомерСтроки + 1;
        
        // Используем полученный номер в алгоритме
        Сообщить("Строка № " + НомерСтроки + ": " + Выборка.Номенклатура);
    КонецЦикла;
КонецЕсли;

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

Способ 2. Выгрузка результата запроса в таблицу значений

Если для решения задачи требуется коллекция с возможностью прямого доступа к строкам по индексу, результат запроса можно выгрузить в объект ТаблицаЗначений.

Рассмотрим код выгрузки и работы с индексами строк:


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

// Вариант А: получение номера через метод Индекс()
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
    // Индексация в ТаблицеЗначений начинается с 0, поэтому прибавляем 1
    ТекущийНомер = ТаблицаДанных.Индекс(СтрокаТЗ) + 1;
    Сообщить("Номер строки: " + ТекущийНомер);
КонецЦикла;

// Вариант Б: добавление явной колонки с номером
ТаблицаДанных.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число"));
Счетчик = 0;
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
    Счетчик = Счетчик + 1;
    СтрокаТЗ.НомерСтроки = Счетчик;
КонецЦикла;

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

Способ 3. Нумерация строк в схеме компоновки данных (СКД)

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

  1. НомерПоПорядку() — формирует сквозную непрерывную нумерацию строк по всему отчету.
  2. НомерПоПорядкуВГруппировке() — вычисляет порядковый номер строки локально в пределах текущей родительской группировки (сбрасывается в 1 при переходе к новой группе).

Эти функции достаточно указать в качестве выражения для вычисляемого поля или ресурса на соответствующих вкладках схемы компоновки данных.

← На главную