К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как проверить запрос на пустоту в 1С

Способы проверки результата запроса на пустоту в 1С: метод Пустой(), Выбрать(), выгрузка в таблицу значений. Примеры кода, типичные ошибки и советы по производительности.

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

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

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

Базовый способ: метод Пустой() результата запроса

Объект «РезультатЗапроса», который возвращает метод Выполнить(), имеет встроенный метод Пустой(). Он возвращает Истина, если запрос не вернул ни одной строки, и Ложь, если записи есть. Это самый читаемый и распространённый вариант проверки.

Типовой код выглядит так:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Артикул = &Артикул";

Запрос.УстановитьПараметр("Артикул", ИскомыйАртикул);

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

Если РезультатЗапроса.Пустой() Тогда

Сообщить("Товар с таким артикулом не найден");

Иначе

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

Пока Выборка.Следующий() Цикл

// обработка найденных строк

КонецЦикла;

КонецЕсли;

Обратите внимание: метод Пустой() вызывается у результата запроса, а не у выборки и не у объекта «Запрос». Попытка написать Запрос.Пустой() приведёт к ошибке, потому что у объекта запроса такого метода нет.

Проверка через Пустой() не «сбрасывает» результат: после неё можно спокойно получать выборку или выгружать данные — результат запроса остаётся доступным, пока существует переменная.

Проверка через выборку: Следующий() без предварительного Пустой()

Если после проверки данные всё равно нужно обойти, двойная работа не требуется. Метод Следующий() выборки возвращает Ложь, когда записей больше нет — в том числе когда их не было изначально. Поэтому пустоту можно определить первым же вызовом.

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

// запись найдена, работаем с Выборка.Ссылка и другими полями

Иначе

// выборка пустая

КонецЕсли;

Такой приём особенно удобен, когда из запроса ожидается ровно одна строка — например, поиск элемента справочника по уникальному коду или получение остатка по конкретному товару. Первый вызов Следующий() одновременно и проверяет наличие данных, и позиционирует выборку на первую запись.

Если записей может быть много и нужен полный обход, обычно пишут классический цикл Пока Выборка.Следующий() Цикл — пустая выборка просто не войдёт в цикл, и отдельная проверка на пустоту становится необязательной, если пустой результат не требует особой реакции.

Когда нужна только проверка существования записи, а сами данные не нужны, добавьте в текст запроса ВЫБРАТЬ ПЕРВЫЕ 1 и выбирайте одно лёгкое поле (например, Ссылка). Это заметно снижает нагрузку на СУБД по сравнению с выборкой всех строк.
ПЗ
Практическое замечание

Проверка через таблицу значений и количество строк

Третий вариант — выгрузить результат в таблицу значений методом Выгрузить() и посмотреть количество строк. Таблица значений даёт дополнительные возможности: индексацию, поиск, свёртку, передачу между процедурами.

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

Если ТаблицаРезультата.Количество() = 0 Тогда

// данных нет

Иначе

// есть ТаблицаРезультата.Количество() строк

КонецЕсли;

Способ оправдан, когда таблица нужна для дальнейшей логики: заполнения табличной части документа, передачи в функцию, построения отчёта. Но если цель — только проверка на пустоту, выгрузка всего результата в память избыточна: при большом объёме данных это лишний расход памяти и времени.

Отдельный частный случай — запрос с агрегатной функцией КОЛИЧЕСТВО(*). Такой запрос всегда возвращает одну строку, даже если записей ноль, поэтому Пустой() для него всегда даст Ложь. Проверять нужно значение поля:

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Контрагент = &Контрагент";

Выборка = Запрос.Выполнить().Выбрать();

Выборка.Следующий();

Если Выборка.КоличествоЗаписей = 0 Тогда

// документов по контрагенту нет

КонецЕсли;

Сравнение вариантов

РезультатЗапроса.Пустой()

Лучший вариант, когда нужна только проверка. Читаемо, быстро, не тратит память на выгрузку.

Выборка.Следующий()

Оптимально, когда после проверки данные сразу обходятся или ожидается одна строка. Совмещает проверку и доступ к полям.

Выгрузить().Количество() = 0

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

КОЛИЧЕСТВО(*) в запросе

Уместен, когда важно само число записей. Помните: результат такого запроса никогда не пуст, проверяется значение поля.

Нюансы: итоги, группировки и пакетные запросы

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

В пакетных запросах (несколько запросов в одном тексте, разделённых точкой с запятой) метод ВыполнитьПакет() возвращает массив результатов. Проверку Пустой() нужно применять к конкретному элементу массива, а не к массиву целиком:

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

Если Результаты[1].Пустой() Тогда

// второй запрос пакета не вернул данных

КонецЕсли;

Ещё один нюанс — временные таблицы. Если запрос помещает данные во временную таблицу (ПОМЕСТИТЬ), результат такого подзапроса обычно не анализируют напрямую: проверять на пустоту следует финальный запрос пакета, который выбирает из временной таблицы.

Типичные ошибки при проверке запроса на пустоту

Первая и самая частая ошибка — вызов Пустой() не у того объекта. Метод существует только у результата запроса. Конструкции Запрос.Пустой() или Выборка.Пустой() вызовут ошибку выполнения.

Вторая ошибка — проверка результата запроса с КОЛИЧЕСТВО(*) через Пустой(). Такой запрос всегда возвращает строку, поэтому проверка бессмысленна: нужно читать значение поля-количества.

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

Четвёртая ошибка — использование выгрузки в таблицу значений только ради Количество() = 0 на больших выборках. На сотнях тысяч строк это приводит к заметному расходу памяти сервера там, где достаточно Пустой() с конструкцией ВЫБРАТЬ ПЕРВЫЕ 1.

Типичные ошибки
01
Вызов Пустой() у объекта Запрос или у выборки — метод есть только у результата запроса, код падает с ошибкой.
02
Проверка Пустой() у запроса с КОЛИЧЕСТВО(*) — результат всегда непустой, условие никогда не срабатывает.
03
Двойное выполнение запроса: сначала для проверки, потом для данных — лишняя нагрузка и риск получить разные результаты.
04
Выгрузка большого результата в таблицу значений ради одного сравнения Количество() = 0 — неоправданный расход памяти.
05
Поиск ошибки в методе проверки, когда пустой результат вызван неверным параметром запроса.

Какой способ выбрать в разных сценариях

Единого «правильного» метода нет — выбор зависит от того, что происходит с данными после проверки. Используйте простое правило: проверка должна совмещаться с тем, как вы дальше потребляете результат.

Если нужно только узнать, есть ли записи (например, перед созданием нового элемента справочника), — берите Пустой() с запросом ВЫБРАТЬ ПЕРВЫЕ 1. Если ожидается одна строка и нужны её поля — Выборка.Следующий() в условии. Если данные выгружаются для дальнейшей обработки — проверяйте Количество() уже выгруженной таблицы, не дублируя проверки.

Маршрут решения

Как выбрать действие

Нужно только узнать, есть ли записи, данные не требуютсяЗапрос с ВЫБРАТЬ ПЕРВЫЕ 1 и проверка Результат.Пустой()
Ожидается одна строка, нужны её поляВыборка = Результат.Выбрать(); Если Выборка.Следующий() Тогда ...
Нужен полный обход всех строкЦикл Пока Выборка.Следующий() — пустая выборка просто не войдёт в цикл
Результат передаётся дальше как таблицаВыгрузить() и проверка Таблица.Количество() = 0
Нужно само число записейЗапрос с КОЛИЧЕСТВО(*) и сравнение значения поля с нулём

В клиент-серверном варианте помните, что запрос выполняется на сервере. Проверка на пустоту — это тоже серверный вызов, поэтому объединяйте её с остальной логикой в одном серверном методе, чтобы не плодить лишние обращения между клиентом и сервером.

Как убедиться, что проверка работает правильно

После внедрения проверки протестируйте оба сценария: когда записи есть и когда их нет. Для второго случая удобно заведомо «пустой» параметр — несуществующий артикул, дату в далёком прошлом, тестового контрагента без документов.

Полезно временно добавить отладочный вывод: количество строк выборки или значение Пустой() в сообщение. Это позволяет быстро отличить ситуацию «запрос пуст» от ситуации «запрос вернул данные, но условие написано неверно».

Контрольные точки

Как проверить результат

Ветка «данных нет»
Норма

При заведомо пустом параметре срабатывает сообщение или альтернативная логика

Тревожный признак

Код молча проходит дальше или падает с ошибкой обращения к полям выборки

Ветка «данные есть»
Норма

Выборка обходится, поля доступны, итоговое действие выполняется

Тревожный признак

Проверка Пустой() возвращает Истина при существующих записях — ищите ошибку в параметрах

Количество выполнений запроса
Норма

Запрос выполняется один раз, результат хранится в переменной

Тревожный признак

Один и тот же Выполнить() вызывается дважды — для проверки и для данных

Часто задаваемые вопросы

Чем Пустой() отличается от проверки Количество() = 0?

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

Почему Пустой() возвращает Ложь, хотя записей нет?

Почти всегда это запрос с агрегатной функцией без группировки: КОЛИЧЕСТВО(*), СУММА и подобные всегда возвращают одну строку, даже если данных ноль. Проверяйте не Пустой(), а значение поля агрегата. Реже причина — итоговая запись при обходе по группировкам.

Можно ли проверить пустоту выборки, не выполняя запрос дважды?

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

Что быстрее: Пустой() или Следующий()?

Разница в производительности несущественна — оба метода работают с уже полученным результатом. Выбирайте по смыслу: Пустой() читается яснее, когда нужна только проверка; Следующий() удобнее, когда сразу требуются поля первой записи. Реальный выигрыш даёт оптимизация самого запроса (ВЫБРАТЬ ПЕРВЫЕ 1, индексы по полям отбора), а не выбор метода проверки.

Как проверить на пустоту конкретный запрос в пакете?

Метод ВыполнитьПакет() возвращает массив результатов в порядке следования запросов в тексте. Обратитесь к нужному элементу по индексу (нумерация с нуля) и вызовите у него Пустой(): Результаты[0].Пустой(). Следите, чтобы индекс соответствовал именно проверяемому запросу, особенно если среди них есть запросы с ПОМЕСТИТЬ — они тоже занимают позицию в массиве.

Работает ли Пустой() для запроса к виртуальным таблицам регистров?

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

Итог

Что важно запомнить

Основной способ проверки запроса на пустоту — метод Пустой() у результата запроса. Если данные нужны дальше, совмещайте проверку с получением выборки через Следующий(). Запрос с КОЛИЧЕСТВО(*) никогда не пуст — проверяется значение поля. Выполняйте запрос один раз и используйте ВЫБРАТЬ ПЕРВЫЕ 1, когда нужна только проверка существования записей.