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

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

1С: как определить, что запрос пустой

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

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

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

Метод Пустой() — основной способ проверки результата запроса

Метод Пустой() вызывается у объекта «РезультатЗапроса», который возвращает метод Запрос.Выполнить(). Это самый быстрый и корректный способ узнать, есть ли данные, до того как вы начали их обходить. Метод не требует обхода записей и не расходует ресурсы на выборку.

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

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

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

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

Сообщить("По артикулу ничего не найдено");

Иначе

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

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

// обработка записей

КонецЦикла;

КонецЕсли;

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

bsl
Если РезультатЗапроса.Пустой() Тогда
	Возврат; // данных нет, дальнейшая обработка не нужна
КонецЕсли;

Проверка пустоты при работе с выборкой

Если вы работаете через выборку (Выборка = РезультатЗапроса.Выбрать()), отдельная проверка на пустоту часто вообще не нужна. Метод Выборка.Следующий() возвращает Ложь, когда записей нет, поэтому цикл Пока Выборка.Следующий() Цикл просто не выполнится ни разу. Это безопасное поведение, и ошибки здесь не возникнет.

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

Правильный шаблон для одиночной записи выглядит так:

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

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

НайденнаяСсылка = Выборка.Ссылка;

Иначе

ВызватьИсключение "Элемент не найден по заданным условиям";

КонецЕсли;

Проверка пустой таблицы значений после Выгрузить()

Когда результат запроса выгружается в таблицу значений методом Выгрузить(), метод Пустой() у таблицы отсутствует. Здесь проверка выполняется через количество строк: ТаблицаРезультата.Количество() = 0.

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

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

Сообщить("Данные для отчёта отсутствуют");

Возврат;

КонецЕсли;

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

Способы проверки на пустоту

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

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

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

Естественная проверка при обходе. Цикл сам не выполнится при пустом результате. Для одиночной записи требует явной проверки возвращаемого значения.

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

Применяется после Выгрузить(). Требует загрузки всех данных в память, неэффективно для больших результатов.

ВЫБРАТЬ ПЕРВЫЕ 1

Оптимизация запроса, когда нужно только узнать о существовании записи. Снижает нагрузку на СУБД.

Оптимизация: когда нужно только узнать, есть ли данные

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

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

"ВЫБРАТЬ ПЕРВЫЕ 1

| ИСТИНА КАК ЕстьДанные

|ИЗ

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

|ГДЕ

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

| И Реализация.Проведен";

Если Запрос.Выполнить().Пустой() Тогда

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

КонецЕсли;

Такой приём стандартен для проверок вида «есть ли дубли», «были ли движения по регистру», «существует ли элемент с таким кодом». Он снижает нагрузку на сервер базы данных по сравнению с полным перечнем полей и подсчётом строк на клиенте.

Особые случаи: NULL, пакетные запросы, СКД

Левое соединение и NULL в полях

Частая ловушка: запрос с левым соединением всегда возвращает строки основной таблицы, даже если в присоединяемой таблице совпадений нет. Метод Пустой() в этом случае вернёт Ложь, но поля присоединённой таблицы будут содержать NULL. Проверять нужно не пустоту результата, а значения полей: Если Выборка.Остаток = NULL Тогда или через ЗначениеЗаполнено() после преобразования.

Пакетные запросы

При использовании Запрос.ВыполнитьПакет() возвращается массив результатов. Метод Пустой() применяется к каждому элементу массива отдельно: Результаты[0].Пустой(). Не забудьте, что временные таблицы в пакете тоже занимают элементы массива, поэтому индекс нужного результата легко ошибочно указать неверно — это типичный источник «пустых» данных.

Запрос внутри СКД

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

Типичные ошибки
01
Обращение к полям выборки без проверки Следующий() — код не падает, но записывает пустые значения в базу
02
Проверка Пустой() при левом соединении — метод вернёт Ложь, хотя фактически связанных данных нет, поля содержат NULL
03
Вызов Пустой() у таблицы значений — у таблицы нет такого метода, будет ошибка «Метод объекта не обнаружен», используйте Количество() = 0
04
Неверный индекс результата в пакетном запросе — проверяется не тот элемент массива, и данные кажутся пустыми
05
Выгрузка всего результата ради проверки наличия записей — лишняя нагрузка на память вместо ВЫБРАТЬ ПЕРВЫЕ 1

Практический порядок действий

Соберите проверку в единый шаблон, чтобы не дублировать логику по всему коду. Для сценария «найти или сообщить об отсутствии» удобна такая последовательность:

Порядок действий
  1. 1
    Сформируйте запрос; если нужна только проверка существования — используйте ВЫБРАТЬ ПЕРВЫЕ 1
  2. 2
    Выполните запрос и сохраните результат в переменную: РезультатЗапроса = Запрос.Выполнить()
  3. 3
    Проверьте РезультатЗапроса.Пустой() до начала обхода данных
  4. 4
    При пустом результате выполните альтернативную ветку: сообщение, создание элемента или выход из процедуры
  5. 5
    При непустом результате обходите выборку или выгружайте таблицу значений
  6. 6
    Если в запросе есть левые соединения — дополнительно проверяйте поля на NULL внутри цикла

Для повторяющихся проверок существования записей имеет смысл вынести логику в общий модуль: функция принимает текст запроса и параметры, возвращает Булево. Это убирает дублирование и централизует обработку ошибок выполнения запроса.

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

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

Поведение при отсутствии данных
Норма

Выполняется ветка «Иначе» или цикл не запускается, ошибок нет

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

Обращение к полям выборки даёт пустые значения, которые записываются в базу

Запрос с левым соединением
Норма

Поля без совпадений проверяются на NULL или через ЗначениеЗаполнено()

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

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

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

Используется ВЫБРАТЬ ПЕРВЫЕ 1 и Пустой()

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

Весь результат выгружается в таблицу значений ради подсчёта строк

Отладка: как убедиться, что запрос действительно пустой

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

Второй инструмент — точка останова в конфигураторе после Выполнить(): в табло или через РезультатЗапроса.Выгрузить() в окне «Вычислить выражение» можно посмотреть фактическое содержимое. Также полезно временно вывести параметры запроса через Сообщить(), чтобы увидеть, что реально ушло в запрос.

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

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

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

Метод Пустой() вызывается у объекта «РезультатЗапроса» и не требует обхода или выгрузки данных — это самый дешёвый способ проверки. Количество() = 0 применяется к таблице значений, которая уже полностью загружена в память. Если данные ещё не выгружены, предпочтителен Пустой().

Можно ли вызвать Пустой() у выборки?

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

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

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

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

Метод ВыполнитьПакет() возвращает массив результатов, где каждый элемент соответствует одному запросу пакета, включая запросы создания временных таблиц. Обратитесь к нужному элементу по индексу и вызовите у него Пустой(), например: Результаты[2].Пустой(). Чтобы не ошибиться с индексом, посчитайте запросы в тексте пакета с учётом временных таблиц.

Что быстрее: Пустой() или ВЫБРАТЬ ПЕРВЫЕ 1 с Пустой()?

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

Как вывести пользователю сообщение вместо пустого отчёта СКД?

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

Итог

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

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