Разработка и Конфигурация · 9 мин
Как убрать пустые строки в запросе 1С
Как убрать пустые строки в запросе 1С: фильтрация через ГДЕ, исключение NULL и пустых ссылок, работа с итогами и объединениями. Примеры кода и типичные ошибки.
Пустые строки в результате запроса 1С — частая проблема: они появляются из-за ЛЕВОГО СОЕДИНЕНИЯ, значений NULL, пустых ссылок, незаполненных реквизитов и группировок по пустым измерениям. Такие строки ломают отчёты, мешают обходу выборки и приводят к ошибкам при обращении к полям.
Убрать их можно несколькими способами: отбором в секции ГДЕ, проверкой на NULL, фильтрацией пустых ссылок, корректным выбором типа соединения и постобработкой результата. Выбор зависит от того, откуда именно берутся пустые строки.
Ниже разобраны основные причины появления пустых строк, конкретные приёмы их устранения с примерами кода и способы проверить, что результат запроса стал чистым.
Откуда берутся пустые строки в результате запроса
Прежде чем фильтровать, нужно понять источник пустых строк, потому что универсального условия не существует. Основных причин четыре.
Первая — ЛЕВОЕ СОЕДИНЕНИЕ: когда в присоединяемой таблице нет подходящей записи, все её поля возвращаются как NULL. Вторая — пустые ссылки и незаполненные реквизиты: документ или регистр физически содержит запись, но нужное поле в ней не заполнено. Третья — группировка по виртуальным таблицам, где встречаются пустые измерения. Четвёртая — ОБЪЕДИНИТЬ ВСЕ, когда одна из частей объединения возвращает строки с пустыми колонками.
Ищите ЛЕВОЕ СОЕДИНЕНИЕ в тексте запроса
Проверьте сами записи в базе
Проверьте СГРУППИРОВАТЬ ПО и ИТОГИ
Смотрите ОБЪЕДИНИТЬ ВСЕ
Фильтрация через ГДЕ: базовый способ
Самый прямой метод — добавить условие в секцию ГДЕ. Чтобы исключить строки, где поле не заполнено или равно NULL, используют проверку ЕСТЬ NULL в отрицании.
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Количество
ИЗ
РегистрНакопления.Продажи КАК Продажи
ГДЕ
НЕ Продажи.Номенклатура ЕСТЬ NULL
И Продажи.Количество > 0
Важно: сравнение Поле = NULL в языке запросов 1С не работает — NULL не равен ничему, даже самому себе. Для проверки используется только оператор ЕСТЬ NULL (или IS NULL). Это одна из самых частых ошибок начинающих разработчиков.
Если нужно отсечь строки с пустым строковым реквизитом, условие выглядит так: ГДЕ Поле <> "". Для дат пустое значение — это ДАТАВРЕМЯ(1,1,1), для чисел — 0, поэтому условие подбирается под тип поля.
ГДЕ НЕ Таблица.Поле ЕСТЬ NULL И Таблица.Поле <> ""Как исключить пустые ссылки
Пустая ссылка — это не NULL, а вполне конкретное значение, поэтому проверка ЕСТЬ NULL её не отфильтрует. Для исключения пустых ссылок используют сравнение со значением ЗНАЧЕНИЕ(...).
ВЫБРАТЬ
Реализация.Контрагент,
Реализация.Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
Для составных полей (например, реквизит, который может хранить и контрагента, и организацию) потребуется несколько условий по каждому типу, либо проверка через ВЫРАЗИТЬ с приведением к нужному типу. Учтите, что приведение составного поля к типу через ВЫРАЗИТЬ превращает несоответствующие значения в NULL — и их уже можно отсечь проверкой ЕСТЬ NULL.
ЛЕВОЕ СОЕДИНЕНИЕ и NULL: как не плодить пустые строки
Если пустые строки появляются из-за ЛЕВОГО СОЕДИНЕНИЯ, задайте себе вопрос: нужны ли вообще строки без пары? Если нет — замените ЛЕВОЕ СОЕДИНЕНИЕ на ВНУТРЕННЕЕ, и пустые строки исчезнут на уровне соединения, без дополнительных условий.
ВЫБРАТЬ
Заказы.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
Документ.ЗаказПокупателя.Товары КАК Заказы
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Заказы.Номенклатура = Остатки.Номенклатура
Если строки без пары нужны (например, показать товары без остатков), но NULL мешает дальнейшей обработке, используйте функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Она не убирает строку, но заменяет NULL на осмысленное значение — 0 для чисел, пустую строку для строк.
ВЫБРАТЬ
Заказы.Номенклатура,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
ИЗ ...
Сравнение подходов
Убирает строки без пары полностью. Подходит, когда они не нужны в результате
Гибкая фильтрация после соединения. Подходит, когда условие сложнее простого наличия пары
Строка остаётся, NULL заменяется значением. Подходит для отчётов, где нужны все строки
Пустые строки при группировках и итогах
При использовании СГРУППИРОВАТЬ ПО и ИТОГИ ПО пустые строки часто возникают из-за записей с незаполненным группировочным полем. Решение — отфильтровать такие записи до группировки в секции ГДЕ, а не после.
Отдельный случай — секция ИМЕЮЩИЕ. Если нужно убрать группы с нулевой или пустой суммой, условие пишется именно там, потому что ГДЕ работает до агрегации и агрегатные функции в нём недоступны.
ВЫБРАТЬ
Продажи.Контрагент,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
ГДЕ
Продажи.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
СГРУППИРОВАТЬ ПО
Продажи.Контрагент
ИМЕЮЩИЕ
СУММА(Продажи.СуммаОборот) > 0
Обратите внимание: итоговые записи при обходе выборки с обходом ПоГруппировкам — это не «пустые строки», а служебные записи итогов. Если они мешают, проверяйте тип записи через ТипЗаписи() или выполняйте обход с параметром Прямой.
Постобработка: фильтрация при обходе выборки
Иногда проще не усложнять запрос, а пропустить пустые строки при обходе результата в коде. Это оправдано, когда условие сложное или зависит от вычислений вне запроса.
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Номенклатура.Пустая()
Или Выборка.Номенклатура = Null Тогда
Продолжить;
КонецЕсли;
// обработка строки
КонецЦикла;
У этого подхода есть минус: лишние строки всё равно передаются из СУБД, что при больших объёмах снижает производительность. Поэтому фильтрацию в запросе следует предпочитать, а обход с пропуском использовать как запасной вариант.
Типичные ошибки и проверка результата
Разработчики, убирая пустые строки, регулярно допускают одни и те же промахи. Ниже — самые распространённые.
После доработки запроса обязательно проверьте результат в консоли запросов: количество строк, отсутствие NULL в ключевых полях и корректность итогов. Сравните итоговую сумму до и после фильтрации — если она изменилась, значит, вы отсекли не только пустые строки, но и значимые данные.
Как проверить результат
Уменьшилось ровно на число пустых строк
Уменьшилось сильнее — отсечены нужные данные
Нет NULL и пустых ссылок в ключевых колонках
NULL остались — проверка не сработала
Совпадают с контрольным отчётом
Расходятся — условие слишком широкое
Что важно запомнить
Определите источник пустых строк: NULL из соединений убирают через ЕСТЬ NULL или ВНУТРЕННЕЕ СОЕДИНЕНИЕ, пустые ссылки — сравнением со ЗНАЧЕНИЕ(...ПустаяСсылка), пустые группы — через ИМЕЮЩИЕ. После доработки сверяйте итоги, чтобы не потерять значимые данные.
Частые вопросы
Чем NULL отличается от пустой ссылки в запросе 1С?
NULL означает отсутствие значения и появляется, когда соединение не нашло пару или поле не заполнено на уровне СУБД. Пустая ссылка — это конкретное значение типа «ссылка», которое записано в реквизит. NULL проверяют оператором ЕСТЬ NULL, пустую ссылку — сравнением со ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка).
Почему условие «Поле = NULL» не работает?
В языке запросов NULL не равен ничему, включая сам NULL, поэтому сравнение всегда даёт ложь и строки не отбираются. Для проверки на NULL существует специальный оператор ЕСТЬ NULL (IS NULL), а для исключения — НЕ Поле ЕСТЬ NULL.
Как убрать строки с нулевой суммой после группировки?
Используйте секцию ИМЕЮЩИЕ с условием на агрегатную функцию, например: ИМЕЮЩИЕ СУММА(Сумма) > 0. В секции ГДЕ агрегатные функции недоступны, так как она применяется до группировки.
Что лучше: отфильтровать в запросе или пропустить при обходе выборки?
Фильтрация в запросе предпочтительнее: лишние строки не передаются из СУБД и не занимают память. Пропуск при обходе оправдан, когда условие сложно выразить в запросе или зависит от логики в коде.
Почему после ОБЪЕДИНИТЬ ВСЕ появились пустые колонки?
В объединении все части должны возвращать одинаковый набор полей. Если в какой-то части поля нет, туда подставляют NULL или пустые значения-заглушки. Решение — явно указать осмысленные значения по умолчанию в каждой части объединения или отфильтровать такие строки во внешнем запросе.
Как убрать итоговые записи при обходе результата запроса?
Это не пустые строки, а служебные записи группировок. Выполните обход с типом обхода «Прямой» (Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.Прямой)) или проверяйте тип записи через метод ТипЗаписи() и пропускайте итоги.