Как определить последнюю итерацию при обходе выборки результата запроса в 1С?

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

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

Способ 1. Использование счетчика и метода Количество()

Объект ВыборкаИзРезультатаЗапроса имеет метод Количество(), который возвращает общее число записей в выборке. Мы можем вести счетчик обработанных строк и сравнивать его с общим количеством элементов.

Рассмотрим пример кода:


Выборка = РезультатЗапроса.Выбрать();
ОбщееКоличество = Выборка.Количество();
ТекущийИндекс = 0;

Пока Выборка.Следующий() Цикл
    ТекущийИндекс = ТекущийИндекс + 1;
    
    // Основная обработка строки
    
    Если ТекущийИндекс = ОбщееКоличество Тогда
        Сообщить("Это последняя итерация цикла!");
    КонецЕсли;
КонецЦикла;

Важное замечание: Метод Количество() доступен непосредственно у объекта выборки (для этого не требуется предварительно выгружать результат запроса в таблицу значений). Однако если выполняется обход по группировкам (параметр ОбходРезультатаЗапроса.ПоГруппировкам), метод возвращает количество элементов только текущего уровня группировки.

Способ 2. Вынос завершающего действия за пределы цикла

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

Проанализируем пример реализация данного подхода:


Если НЕ РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        // Обработка всех элементов
    КонецЦикла;
    
    // Действие, которое должно выполниться после обработки всей выборки
    Сообщить("Обработка успешно завершена!");
КонецЕсли;

Этот подход делает код чище, так как исключает лишнюю проверку условия Если ... Тогда на каждом шаге цикла.

Способ 3. Выгрузка в ТаблицуЗначений и обход по индексу

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

Посмотрим на пример работы с таблицей значений:


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

Для Индекс = 0 По ВсегоСтрок - 1 Цикл
    СтрокаДанных = ТаблицаДанных[Индекс];
    
    Если Индекс = ВсегоСтрок - 1 Тогда
        Сообщить("Обработка последней строки таблицы");
    КонецЕсли;
КонецЦикла;

Обратите внимание, что обращаться по индексу через квадратные скобки вида Выборка[Индекс] непосредственно к объекту ВыборкаИзРезультатаЗапроса нельзя — это вызовет ошибку времени выполнения. Прямая индексация работает только с коллекциями вроде ТаблицаЗначений или Массив.

Рекомендации по повышению производительности

Если внутри цикла обхода выборки выполняются обращения к внешним системам (например, вызов веб-сервисов, HTTP-запросы или транзакции СУБД), выполнение запросов на каждой итерации может создавать высокую нагрузку и риски сбоев связи.

В таких сценариях рекомендуется использовать пакетную обработку:

  1. Собрать все данные из выборки в единую коллекцию (массив или таблицу).
  2. Инициализировать соединение (например, HTTPСоединение) до входа в цикл.
  3. Передать данные единым пакетом за один запрос либо завершить сессию во внешней базе явным вызовом команды после окончания цикла.
← На главную