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