Когда в 1С правильно использовать метод РезультатЗапроса.Пустой()?

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

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

Как на самом деле работают запросы в 1С

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

  1. Запрос.Выполнить(): На этом шаге текст вашего запроса отправляется на сервер СУБД (например, MS SQL или PostgreSQL). СУБД выполняет запрос и готовит результирующую таблицу данных. Важно понимать, что в этот момент все данные еще не передаются обратно в 1С. Метод возвращает специальный объект РезультатЗапроса, который, по сути, является "указателем" или курсором на эти данные на сервере.
  2. РезультатЗапроса.Пустой(): Этот метод выполняет очень быструю и легковесную операцию. Он просто спрашивает у СУБД: "В результирующей таблице есть хотя бы одна строка?". Он не требует передачи самих данных и поэтому выполняется практически мгновенно.
  3. РезультатЗапроса.Выбрать(): Вопреки распространенному мнению, этот метод сам по себе не является ресурсоемкой операцией. Он не загружает все данные в память. Вместо этого он создает другой объект — ВыборкаИзРезультатаЗапроса, который является итератором. Этот итератор готов к последовательному "вытягиванию" строк с сервера.
  4. Выборка.Следующий(): А вот здесь и происходит основная работа. При каждом вызове этого метода из СУБД в 1С передается очередная порция данных (одна или несколько строк). Именно этот процесс в цикле потребляет ресурсы, если результат запроса большой.

Из этого следует ключевой вывод: создание выборки через Выбрать() само по себе почти ничего не стоит с точки зрения производительности. Поэтому опасения "дернуть лишний раз" этот метод необоснованны.

Сценарий 1: Когда проверка на `Пустой()` необходима и правильна

Проверку на пустоту следует использовать тогда, когда вам не нужно содержимое результата запроса, а важен лишь сам факт его наличия или отсутствия. То есть, когда вам нужен ответ на вопрос "да/нет?".

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

В таких случаях использование Пустой() — самый оптимальный и читаемый способ. Посмотрим на код.

Как делать не стоит:

Создавать выборку, делать один шаг и на основании этого принимать решение. Это неэффективно и избыточно.


Функция ПроверитьНаличиеДоговора(Контрагент)

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    ДоговорыКонтрагентов.Ссылка
        |ИЗ
        |    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
        |ГДЕ
        |    ДоговорыКонтрагентов.Владелец = &Контрагент";
    
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    // Неправильно: создаем выборку только для одной проверки
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Истина;
    Иначе
        Возврат Ложь;
    КонецЕсли;

КонецФункции

Как правильно:

Использовать метод Пустой(), чтобы получить прямой ответ на свой вопрос. Код становится короче, чище и эффективнее.


Функция ПроверитьНаличиеДоговора(Контрагент)

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    ДоговорыКонтрагентов.Ссылка
        |ИЗ
        |    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
        |ГДЕ
        |    ДоговорыКонтрагентов.Владелец = &Контрагент";
    
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // Правильно и лаконично: возвращаем результат проверки
    Возврат НЕ РезультатЗапроса.Пустой();

КонецФункции

Сценарий 2: Когда проверка на `Пустой()` избыточна

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

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

Как делать не стоит (избыточный код):


// Избыточная и ненужная проверка
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда // <-- Этот блок кода лишний
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        НоваяСтрока = ТабличнаяЧасть.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
    КонецЦикла;
КонецЕсли;

Как правильно и чисто:

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


// Правильный и лаконичный вариант
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    НоваяСтрока = ТабличнаяЧасть.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;

Особый случай: сложные запросы с итогами и иерархией

Иногда можно услышать аргумент, что для сложных запросов (например, с несколькими уровнями итогов, иерархией, дополнениями периодов) вызов Выбрать() может быть не таким уж и "легким". Это отчасти верно.

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

Итоги: простое правило

В итоге мы можем сформулировать очень простое и понятное правило, которое поможет вам писать чистый и эффективный код:

  1. Если вам нужен ответ на вопрос "есть ли данные?" (да/нет), а сами данные не нужны — используйте НЕ РезультатЗапроса.Пустой().
  2. Если вам нужны сами данные для обработки (например, для заполнения таблицы в цикле) — сразу вызывайте Выбрать() и организуйте цикл обхода, без предварительной проверки на пустоту.

Следование этому простому принципу сделает ваш код более лаконичным, читаемым и профессиональным.

← На главную