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

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

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

Использование свойства Пустая для объектов ВыборкаИзРезультата

Самым распространенным и интуитивно понятным способом проверки является обращение к свойству Пустая объекта выборки. Это свойство возвращает булево значение: Истина, если в наборе нет ни одной строки, и Ложь в противном случае. Данный подход работает во всех актуальных версиях платформы и является стандартом де-факто для большинства задач.

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

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

⚠️ Внимание: Свойство Пустая доступно только у объектов типа ВыборкаИзРезультата. Если вы пытаетесь проверить свойство у самого объекта Запрос до выполнения метода Выполнить(), вы получите ошибку или некорректный результат.

☑️ Проверка перед обработкой

Выполнено: 0 / 4

Рассмотрим пример кода, где мы безопасно проверяем наличие записей перед началом работы:

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

Запрос.Текст = "ВЫБРАТЬ Справочник.Номенклатура.Ссылка ИЗ Справочник.Номенклатура ГДЕ ПометкаУдаления = FALSE";

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

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

Если Выборка.Пустая() Тогда

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

Иначе

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

// Обработка данных

КонецЦикла;

КонецЕсли;

Метод IsEmpty() и работа с ПостроителемОтчета

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

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

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

Особенности работы IsEmpty в разных версиях

В старых версиях платформы 1С (до 8.3.10) метод IsEmpty мог работать медленнее из-за отсутствия внутренней оптимизации на уровне СУБД. В современных релизах система пытается сформировать запрос типа SELECT TOP 1, что значительно ускоряет проверку.

Следует учитывать, что не все объекты поддерживают этот метод напрямую. Например, у обычного объекта Запрос его нет, он появляется у результата выполнения. Всегда сверяйтесь со справкой по синтаксису для конкретного типа объекта, с которым вы работаете в данный момент.

Сравнение с Неопределено при получении первой строки

Альтернативным и часто используемым паттерном является попытка перехода к первой записи с помощью метода Следующий(). Этот метод возвращает Истина, если переход удался (запись существует), и Ложь, если выборка пуста. Это позволяет совместить проверку и начало обработки в одном логическом блоке.

Такой подход избавляет от необходимости писать лишние условия и дублировать код внутри цикла и вне его. Вы сразу занимаете позицию на первой записи, если она есть, и можете приступать к обработке полей текущей строки выборки без дополнительных проверок.

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

Метод проверки Возвращаемое значение Влияние на курсор Производительность
Свойство Пустая Булево (Истина/Ложь) Не меняет позицию Высокая
Метод Следующий Булево (Истина/Ложь) Перемещает на 1-ю строку Высокая
Подсчет Количество() Число Не меняет позицию Низкая (перебор всех)
💡

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

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

Оптимизация запросов: почему Неопределено лучше Количества

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

Задача проверки на пустоту решается на уровне логики "есть хоть одна запись или нет". Для этого достаточно найти первую строку. Использование счетчика всех записей является избыточным действием, которое не несет никакой пользы для условия Если, но потребляет ресурсы.

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

⚠️ Внимание: Никогда не используйте выборка.Количество() в условиях ветвления if. Это одна из самых частых причин падения производительности в высоконагруженных системах 1С.

📊 Как вы чаще всего проверяете выборку на пустоту?
Свойство Пустая
Метод Следующий
Метод Количество
Другой способ

Правильная оптимизация начинается с понимания того, что делает движок 1С под капотом. Когда вы вызываете Пустая() или делаете первый Следующий(), система отправляет в СУБД запрос с ограничением. Как только первая строка получена, дальнейшее чтение прекращается, и управление возвращается в код 1С.

Обработка пустых выборок в циклах и временных таблицах

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

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

Также стоит учитывать сценарии, когда выборка может стать пустой в процессе обработки. Хотя стандартный цикл Для Каждого просто не выполнится ни разу, если набор пуст изначально, явная проверка перед циклом позволяет вывести пользователю понятное сообщение, а не молча завершать процедуру.

💡

Главная цель проверки — избежать ошибок выполнения и предоставить пользователю обратную связь, если данные для работы отсутствуют.

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

Типичные ошибки и исключения при работе с данными

Одной из самых распространенных ошибок является обращение к полям выборки без предварительной проверки или без вызова метода Следующий(). В этом случае система выдает ошибку: "Текущая строка не установлена". Это происходит потому, что сразу после создания выборки курсор находится перед первой записью.

Другая ошибка — игнорирование типа данных. Иногда разработчики ожидают получить число, а получают пустую строку или Null. В контексте проверки на пустоту важно различать "нет строк в выборке" и "в строке есть пустые поля". Свойство Пустая относится именно к количеству строк, а не к заполненности полей внутри них.

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

Что делать, если свойство Пустая возвращает неверный результат?

Обычно это связано с тем, что выборка уже была пройдена до конца в предыдущем цикле. В таком случае свойство будет возвращать Истина. Используйте метод Выборка.Первый() или создайте новую выборку через Результат.Выбрать() для сброса состояния.

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

Нет, объект Запрос сам по себе не содержит данных. Проверять можно только результат выполнения запроса (объект РезультатЗапроса) или созданную на его основе выборку. До вызова метода Выполнить() вопрос о пустоте не имеет смысла.

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

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

Как обработать ситуацию, когда выборка пуста, но нужно создать запись?

Используйте конструкцию: Если Выборка.Пустая() Тогда // Создать новый элемент справочника или документа. Это стандартный паттерн для инициализации данных по умолчанию при первом запуске обработки.