Разработка и Конфигурация · 12 мин
Как проверить, пустой запрос или нет в 1С
Как проверить, пустой запрос или нет в 1С: метод Пустой(), ПустаяСтрока, выборка результата запроса, типичные ошибки и примеры кода для разработчика.
Проверка результата запроса на пустоту — одна из самых частых операций во встроенном языке 1С:Предприятие. Она нужна везде: перед обходом выборки, перед записью данных, при формировании отчётов, при проверке наличия документа или элемента справочника по заданным условиям. Ошибка в этой проверке приводит либо к падению кода с исключением, либо к тихой логической ошибке, когда программа считает, что данные есть, хотя запрос ничего не вернул.
В языке 1С есть несколько способов определить, пуст ли запрос: метод Пустой() у результата запроса, проверка количества строк через Выгрузить(), функция ПустаяСтрока() для строковых параметров и функция ЗначениеЗаполнено() для произвольных значений. У каждого способа своя область применения, и смешивать их нельзя — например, Пустой() вызывается у результата запроса, а не у выборки и не у таблицы значений.
Отдельная путаница возникает из-за того, что словом «запрос» называют разные объекты: сам объект Запрос, результат его выполнения (РезультатЗапроса), выборку из результата и текст запроса как строку. Для каждого из этих случаев проверка «пустоты» устроена по-разному. Ниже разобраны все основные сценарии с примерами кода.
Что именно вы проверяете: объект запроса, результат или выборку
Прежде чем писать проверку, определите, с каким объектом вы работаете. Объект Запрос сам по себе не бывает «пустым» в смысле данных — у него можно проверить только текст запроса. Данные появляются после вызова Выполнить(), который возвращает РезультатЗапроса. Именно у результата есть метод Пустой().
Выборка (ВыборкаИзРезультатаЗапроса) — это курсор для последовательного обхода строк. У неё нет метода Пустой(): попытка вызвать Выборка.Пустой() завершится ошибкой «Метод объекта не обнаружен». Пустоту выборки проверяют через первый вызов Следующий().
Таблица значений, полученная методом Выгрузить(), проверяется через Количество(). Это полезно, когда результат нужен не для обхода, а для дальнейшей обработки, передачи в другую процедуру или вывода на форму.
Основной способ: метод Пустой() у результата запроса
Стандартный и самый быстрый способ — вызвать Пустой() сразу после выполнения запроса. Метод возвращает Истина, если запрос не вернул ни одной строки, и Ложь, если данные есть. При этом данные физически не выгружаются в память — проверка выполняется на уровне результата.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул";
Запрос.УстановитьПараметр("Артикул", ИскомыйАртикул);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Сообщить("Товар с таким артикулом не найден");
Возврат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строк
КонецЦикла;
Такой шаблон — «выполнить, проверить Пустой(), затем обойти» — считается хорошей практикой: вы явно обрабатываете ситуацию отсутствия данных, а не полагаетесь на то, что цикл просто не выполнится. Это особенно важно, когда отсутствие данных — нештатная ситуация, о которой нужно сообщить пользователю или записать в журнал регистрации.
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
// данных нет
КонецЕсли;Проверка через выборку и таблицу значений
Если результат уже выгружен или вы работаете с выборкой, метод Пустой() недоступен. Для выборки признак пустоты — результат первого вызова Следующий(): если он вернул Ложь, строк нет. Это удобно, когда вам нужна первая (или единственная) запись.
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
НайденнаяСсылка = Выборка.Ссылка;
Иначе
// запрос ничего не вернул
КонецЕсли;
Для таблицы значений используйте Количество(). Этот способ оправдан, когда таблица всё равно нужна целиком — например, для построения отчёта или заполнения табличной части. Выгружать таблицу только ради проверки на пустоту нерационально: Пустой() делает это дешевле.
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Если ТаблицаРезультата.Количество() = 0 Тогда
Сообщить("Данные за период отсутствуют");
КонецЕсли;
Способы проверки на пустоту
Самый быстрый вариант, данные не выгружаются. Подходит, когда нужна только проверка или последующий обход выборкой.
Удобен, когда нужна одна запись. Не подходит, если потом нужен повторный обход той же выборки.
Оправдан, когда таблица значений нужна для дальнейшей работы. Расточителен, если нужна только проверка.
Проверка текста запроса и параметров
Иногда под «пустым запросом» понимают объект запроса без текста. Вызов Выполнить() у запроса с пустым текстом приводит к ошибке, поэтому в универсальных процедурах, где текст формируется динамически, стоит проверить его заранее функцией ПустаяСтрока(). Она корректно обрабатывает и пустую строку, и строку из одних пробелов и переводов строк.
Если ПустаяСтрока(Запрос.Текст) Тогда
ВызватьИсключение "Не задан текст запроса";
КонецЕсли;
Отдельный случай — пустые параметры. Если параметр не установлен через УстановитьПараметр(), при выполнении запроса возникнет ошибка. Если параметр установлен, но содержит пустое значение (пустая строка, пустая ссылка, Неопределено), запрос выполнится, но условие отбора может отсечь все строки — и вы получите пустой результат. Проверять такие параметры удобно функцией ЗначениеЗаполнено() до выполнения запроса.
Специальные сценарии: NULL, пакетные запросы и СКД
Проверка на NULL в тексте запроса
Если речь о проверке поля на пустоту внутри текста запроса, используйте конструкции языка запросов: ЕСТЬ NULL для полей, которые могут быть не заполнены из-за левого соединения, и сравнение с пустым значением для примитивных типов. Для ссылочных полей пустое значение сравнивают с ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).
ВЫБРАТЬ
Заказы.Ссылка
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ Документ.Реализация КАК Реализация
ПО Заказы.Ссылка = Реализация.ЗаказПокупателя
ГДЕ
Реализация.Ссылка ЕСТЬ NULL
Пакетные запросы
При выполнении пакетного запроса метод ВыполнитьПакет() возвращает массив результатов. Проверять на пустоту нужно каждый элемент массива отдельно — у самого массива метода Пустой() нет. Не забывайте, что промежуточные результаты (помещение во временные таблицы) тоже входят в массив.
Схема компоновки данных
В отчётах на СКД результат выводится через ПроцессорКомпоновкиДанных, и метода Пустой() там нет. Практический приём — установить признак, что данные были выведены, в процессе вывода элементов результата, либо выполнить тот же запрос отдельно с проверкой Пустой(), если нужно заранее решить, показывать ли отчёт.
Производительность и типичные ошибки
С точки зрения производительности Пустой() — оптимальный метод: платформа проверяет наличие хотя бы одной строки без полной выгрузки данных. Худший вариант — выгрузить таблицу значений только ради Количество() и затем её выбросить. Если запрос тяжёлый, а нужен только факт наличия данных, добавьте в текст запроса ВЫБРАТЬ ПЕРВЫЕ 1 — это заметно сократит время выполнения.
Ещё одна тонкость: запрос с итогами или группировкой может вернуть строку даже тогда, когда детальных данных нет. Например, запрос с СУММА() без СГРУППИРОВАТЬ ПО всегда возвращает одну строку, где сумма будет NULL. В таком случае Пустой() вернёт Ложь, и проверять нужно само значение поля на NULL.
Порядок действий и проверка результата
Соберите типовой шаблон проверки в одну последовательность: сформировали запрос, проверили текст, установили параметры, выполнили, проверили Пустой(), обработали обе ветки. Такой шаблон легко переносить между процедурами и он защищает от большинства ошибок, описанных выше.
- 1Сформируйте текст запроса и убедитесь через ПустаяСтрока(Запрос.Текст), что он задан
- 2Установите все параметры через УстановитьПараметр(); при необходимости проверьте их через ЗначениеЗаполнено()
- 3Выполните запрос: РезультатЗапроса = Запрос.Выполнить()
- 4Проверьте РезультатЗапроса.Пустой() и обработайте ситуацию отсутствия данных (сообщение, возврат, запись в журнал)
- 5Если данные есть — получите выборку через Выбрать() или таблицу через Выгрузить() и обработайте строки
- 6Проверьте код на тестовых данных: вариант «строки есть» и вариант «строк нет» должны отрабатывать без исключений
Проверять результат удобно в консоли запросов или через отладчик: поставьте точку останова после Выполнить() и посмотрите значение РезультатЗапроса.Пустой() в табло. Если выражение вычисляется корректно и меняется в зависимости от данных — проверка написана правильно.
Что важно запомнить
Пустоту результата проверяют методом Пустой() после Выполнить(). У выборки используют Следующий(), у таблицы значений — Количество(), у текста запроса — ПустаяСтрока(), у параметров — ЗначениеЗаполнено(). Для тяжёлых запросов добавляйте ВЫБРАТЬ ПЕРВЫЕ 1, а запросы с агрегатами проверяйте на NULL по значению поля, а не по Пустой().
Частые вопросы
Чем Пустой() отличается от проверки Выборка.Количество()?
У выборки нет метода Количество() — она предназначена для последовательного обхода и не знает общего числа строк заранее. Пустой() вызывается у результата запроса и проверяет наличие строк без их выгрузки. Если нужно именно количество, выгружайте таблицу через Выгрузить() и используйте Количество() у неё.
Можно ли проверить пустоту запроса, не выполняя его?
Нет. Узнать, вернёт ли запрос строки, можно только выполнив его — платформа не анализирует текст запроса на предмет результата. Можно лишь проверить, что текст запроса задан (ПустаяСтрока) и параметры заполнены (ЗначениеЗаполнено), до вызова Выполнить().
Почему Пустой() возвращает Ложь, хотя данных вроде бы нет?
Чаще всего это запрос с агрегатной функцией без группировки: СУММА, КОЛИЧЕСТВО и подобные всегда возвращают одну строку, даже если исходных записей ноль — значения полей в ней будут NULL. Проверяйте в этом случае сами поля: Выборка.Следующий(), затем сравнение значения поля с NULL или проверка через ЕСТЬNULL в тексте запроса.
Как проверить пустоту результата пакетного запроса?
Метод ВыполнитьПакет() возвращает массив результатов запросов. Обратитесь к нужному элементу по индексу и вызовите у него Пустой(): Результаты = Запрос.ВыполнитьПакет(); Если Результаты[1].Пустой() Тогда ... Учтите, что в массив попадают и промежуточные результаты помещений во временные таблицы.
Что быстрее: Пустой() или ВЫБРАТЬ ПЕРВЫЕ 1 с выборкой?
Они решают разные задачи и хорошо дополняют друг друга. Пустой() — способ проверки, а ПЕРВЫЕ 1 — способ ограничить объём данных, которые СУБД должна найти. Для тяжёлого запроса оптимально сочетание: добавить ПЕРВЫЕ 1 в текст и проверить результат через Пустой() — тогда поиск остановится на первой найденной строке.
Как проверить, что параметр запроса — пустая ссылка?
До выполнения запроса используйте ЗначениеЗаполнено(Параметр) — функция вернёт Ложь для пустой ссылки, пустой строки, Неопределено и пустой даты. Внутри текста запроса пустую ссылку сравнивают с конструкцией ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка) или передают пустую ссылку как параметр и сравнивают с ним.